> This page is for version Dev.
> For other versions, use one of these documentation indexes:
> - Latest (v0.1.3) (default): https://docs.nvidia.com/openshell/latest/llms.txt
> - Dev: https://docs.nvidia.com/openshell/dev/llms.txt
> - v0.1.3: https://docs.nvidia.com/openshell/v0.1.3/llms.txt
> - v0.1.2: https://docs.nvidia.com/openshell/v0.1.2/llms.txt
> - v0.1.1: https://docs.nvidia.com/openshell/v0.1.1/llms.txt
> - v0.1.0: https://docs.nvidia.com/openshell/v0.1.0/llms.txt
> - v0.0.116: https://docs.nvidia.com/openshell/v0.0.116/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/openshell/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/openshell/_mcp/server.

# TypeScript SDK

> Install the OpenShell TypeScript SDK, connect to a gateway, and manage a sandbox.

Use the TypeScript SDK in Node.js applications and automation. It provides a
curated sandbox API and a raw generated client for the full gateway RPC surface.
Use the SDK and gateway from the same OpenShell release when possible.

## Install the SDK

The package requires Node.js 20.3 or later and is currently distributed through
GitHub Packages. Configure the `@nvidia` scope in your project `.npmrc`:

```text
@nvidia:registry=https://npm.pkg.github.com
```

Authenticate npm with a GitHub token that has `read:packages`, then install the
package:

```shell
npm install @nvidia/openshell-sdk
```

## Connect to a Gateway

`OpenShellClient.connect()` accepts a gateway URL. It constructs a lazy client,
so call `health()` when startup must verify connectivity:

```ts
import { OpenShellClient } from '@nvidia/openshell-sdk'

const client = await OpenShellClient.connect({
  gateway: 'https://gateway.example.com',
  oidcToken: process.env.OPENSHELL_TOKEN,
})

const health = await client.health()
console.log(`${health.status}: ${health.version}`)
```

For long-running OIDC service automation, use a renewable client-credentials
provider:

```ts
import { clientCredentials, OpenShellClient } from '@nvidia/openshell-sdk'

const client = await OpenShellClient.connect({
  gateway: 'https://gateway.example.com',
  oidcTokenProvider: clientCredentials({
    issuer: 'https://idp.example.com/realms/openshell',
    clientId: 'openshell-service',
    clientSecret: () => process.env.OPENSHELL_OIDC_CLIENT_SECRET!,
    audience: 'openshell-gateway',
  }),
})
```

The provider retains credentials and tokens in memory and renews the access
token before expiry.

## Retrieve Provider Credentials

Connect directly with a trusted `OU=operator` client certificate after enabling
[operator authentication](/how-it-works/gateways/authentication#mtls-operators).
Do not supply an OIDC or edge token for this connection. No sandbox creation or
provider attachment is required.

```ts
import { readFileSync } from 'node:fs'
import { OpenShellClient } from '@nvidia/openshell-sdk'

const operator = await OpenShellClient.connect({
  gateway: 'https://gateway.example.com',
  caCert: readFileSync('ca.crt'),
  clientCert: readFileSync('operator.crt'),
  clientKey: readFileSync('operator.key'),
})
const credentials = await operator.providers.getCredentials(
  'my-graph',
  ['MS_GRAPH_ACCESS_TOKEN'],
  { workspace: 'production', minimumRemainingLifetimeSecs: 300 },
)
const token = credentials.MS_GRAPH_ACCESS_TOKEN!.value
```

`ProviderClient.connect()` provides the same API as a standalone client. Unlike
sandbox operations, `getCredentials()` requires an explicit workspace. It returns
a record of `ProviderCredentialValue` objects with `value` and optional
`expirationTime`, a `Date`. Sub-millisecond expiration precision is truncated.
`minimumRemainingLifetimeSecs` accepts fractional seconds; omission or zero uses
the gateway default. Pass `signal` or `timeoutMs` in the operation options to
bound delivery. The helper does not retry or cache exports, and canceled delivery
does not roll back a gateway refresh that has already started.

Keep returned values out of logs and shared output. See
[Retrieve Runtime Credentials](/how-it-works/providers/overview#retrieve-runtime-credentials)
for freshness, supported credentials, and the export security boundary.

## Create and Use a Sandbox

The curated client uses the `default` workspace unless you pass `workspace` in
an operation's options:

```ts
const sandbox = await client.sandbox.create({
  name: 'sdk-example',
  image: 'registry.example.com/team/python-agent:1.0',
})

await client.sandbox.waitReady(sandbox.name, 120)

const result = await client.sandbox.exec(
  sandbox.name,
  ['python', '-c', "print('hello from OpenShell')"],
)
console.log(result.stdout.toString())

const deletion = await client.sandbox.delete(sandbox.name)
if (deletion.outcome === 'accepted') {
  await client.sandbox.waitDeleted(sandbox.name, 60, {
    expectedSandboxId: deletion.sandboxId,
  })
}
```

Sandbox refs returned by `create`, `get`, and `list` include `createdAtMs`, the
creation time in epoch milliseconds. It is absent when the gateway omits it.

`client.sandbox` also supports streaming and interactive exec, TCP forwarding,
SSH sessions, sandbox provider attachment, configuration, and policy. Close
operation-scoped streams and forwarding handles when finished. The root client
does not retain a dedicated session and has no `close()` method.

## Watch Logs and Events

`watchLogs` streams a sandbox's log lines and platform events with automatic
reconnect and loss-aware resume. Pass a previous item's `cursor` back in as
`resumeAfterCursor` to continue after a restart without gaps or duplicates:

```ts
for await (const item of client.sandbox.watchLogs(sandbox.name, { followLogs: true })) {
  if (item.kind === 'log') {
    console.log(`${item.line.level} ${item.line.message}`)
  } else if (item.kind === 'warning') {
    console.warn(`gap: ${item.message}`)
  }
}
```

See [Accessing Logs](/observability/accessing-logs) for the cursor and resume
contract this method implements.

## Use the Raw Client

Use `client.raw` for RPCs that the curated clients do not yet wrap. Import
generated message schemas and types from `@nvidia/openshell-sdk/raw`. Raw calls
return protobuf wire shapes, while curated calls return SDK-specific types.

## Next Steps

* Review [Gateway Authentication](/how-it-works/gateways/authentication) for OIDC and service authentication.
* Review [API Errors](/sdk/api-errors) for structured error handling.
* See the [TypeScript SDK source documentation](https://github.com/NVIDIA/OpenShell/tree/main/sdk/typescript) for streaming, forwarding, and raw client examples.