Concepts

Sandbox

Isolated execution environments where agent tools run. Three built-in bindings — vercel, local, docker — with setup, snapshots, and full API.

Built-in tools like Read, Write, Bash, and JavaScript execute inside the sandbox. The agent can read files, run commands, and start dev servers without affecting your production system.

Sandbox Types

experimental-agent ships three sandbox bindings. Each has different isolation guarantees and deployment targets.

vercelSandbox() — Vercel Sandbox

Full Node.js and Python runtime, filesystem, and network. The production default when running on Vercel.

src/agent.ts
import { agent } from "experimental-agent";
import { vercelSandbox } from "experimental-agent/sandbox";

export const myAgent = agent("my-agent", {
  model: "anthropic/claude-opus-4.6",
  sandbox: vercelSandbox(),
});

Use vercelSandbox() for production deployments. The sandbox runs in a Vercel Sandbox with configurable vCPUs, exposed ports, and network policies.

localSandbox() — Host filesystem

Runs on your machine's filesystem. Great for development — no cloud setup required.

src/agent.ts
import { agent } from "experimental-agent";
import { localSandbox } from "experimental-agent/sandbox";

export const myAgent = agent("my-agent", {
  model: "anthropic/claude-opus-4.6",
  sandbox: localSandbox(),
});

Tools execute directly on the host. Use for fast iteration during development.

dockerSandbox() — Docker container

Runs inside a Docker container. Provides isolation without cloud dependencies.

src/agent.ts
import { agent } from "experimental-agent";
import { dockerSandbox } from "experimental-agent/sandbox";

export const myAgent = agent("my-agent", {
  model: "anthropic/claude-opus-4.6",
  sandbox: dockerSandbox(),
});

Requires Docker Desktop with Docker Sandboxes enabled.

Auto-detection

When no sandbox binding is provided, the SDK auto-detects:

  1. Vercel — if VERCEL_OIDC_TOKEN is set
  2. Docker — if the docker sandbox CLI is available
  3. Local — fallback

Sandbox Setup

Pass version, run, config, and networkPolicy directly to the binding factory. The sandbox is automatically set up when the session starts — no separate .setup() call needed:

src/agent.ts
import { agent } from "experimental-agent";
import { vercelSandbox } from "experimental-agent/sandbox";

export const myAgent = agent("my-agent", {
  model: "anthropic/claude-opus-4.6",
  sandbox: vercelSandbox({
    version: "my-env-v1",
    run: async (sandbox) => {
      await sandbox.exec({ command: "npm", args: ["install"] });
    },
  }),
});

Explicit setup

You can also call sandbox.setup() on a sandbox handle for more control:

src/session.ts
const sb = myAgent.sandbox("my-sandbox");
const { done } = await sb.setup({
  version: "my-env-v1",
  run: async (sandbox) => {
    await sandbox.exec({ command: "npm", args: ["install"] });
  },
});
await done;

Options passed to .setup() override any defaults set on the binding factory.

version + run

One-time initialization. run executes when the sandbox is first created (cold start, no snapshot). After it completes, the sandbox is snapshotted for fast resume.

  • version — Bump this string to invalidate the snapshot and re-run setup (e.g. "my-env-v2" after adding new dependencies).
  • run — Async function that receives the sandbox instance. Install deps, clone repos, or configure the environment.

Binding-specific config

Pass type and config to select a binding and configure it:

await sb.setup({
  type: "vercel",
  version: "v1",
  config: {
    ports: [3000],
    resources: { vcpus: 4 },
  },
  run: async (sandbox) => {
    await sandbox.exec({ command: "npm", args: ["install"] });
  },
});

Sandbox API

Inside setup.run or custom tools (via ToolContext), you get a sandbox instance with:

MethodDescription
exec({ command, args?, cwd?, env?, sudo?, signal? })Run a shell command. Returns ExecResult with stdout, stderr, exit code, and logs() stream.
readFile({ path, signal? })Read file contents. Returns Buffer | null.
writeFiles({ files, destPath, signal? })Write multiple files to a destination path. Creates parent directories.
getDomain({ port, signal? })Get the public domain URL for an exposed port.
kill({ commandId, signal? })Kill a running command by ID.
updateNetworkPolicy({ policy, signal? })Update network policy at runtime (Vercel sandboxes only).

Example:

await sandbox.exec({ command: "npm", args: ["install", "lodash"] });
const buf = await sandbox.readFile({ path: "/app/package.json" });
await sandbox.writeFiles({
  files: [{ path: "config.json", content: "{}" }],
  destPath: "/app",
});

Lifecycle Methods

Sandbox instances expose lifecycle methods directly on the instance:

MethodReturnsDescription
start()Promise<void>Start the sandbox.
stop()Promise<void>Stop the sandbox.
snapshot()Promise<{ snapshotId: string }>Create a snapshot for fast resume.
getStatus()Promise<SandboxStatus>Returns pending, running, stopping, stopped, or failed.
const status = await sandbox.getStatus();
if (status === "running") {
  await sandbox.snapshot();
}

Next Steps