Preface

When giving AI Agents the ability to “run code”, the biggest bottleneck is often not the model itself, but the execution environment. Scripts submitted by users, temporary Python code generated by LLMs, and test commands run during every CI build should never be executed directly in Worker processes. Building your own virtual machine or container cluster can provide isolation, but it comes with high costs and heavy integration work, and does not align with the Cloudflare Workers edge runtime.

Cloudflare offers the Sandbox SDK as a solution: using a TypeScript API within Workers to spin up isolated Linux containers, execute commands, read/write files, run code interpreters, and expose preview URLs. The accompanying Agent Skill was originally named sandbox-sdk, designed to formalize this workflow for coding assistants like Cursor, Claude Code, and Codex, preventing the model from generating incorrect configurations based on outdated knowledge.

This article is based on Cloudflare’s official documentation, the cloudflare/skills repository, and the original Skill content, explaining what this Skill is, how it was later split, how to install it, and how to build a minimal working sandbox using the stable version of the SDK.

What It Is

The sandbox-sdk is an Agent Skill maintained by Cloudflare, hosted in the cloudflare/skills repository. It targets development tasks requiring isolated code execution on Cloudflare, covering sandbox lifecycle management, command execution, file operations, code interpreters, and preview URLs. The Skill’s description states that it should be loaded when building AI code execution tools, code interpreters, CI/CD pipelines, interactive development environments, or running untrusted code, and explicitly recommends retrieving information from Cloudflare’s documentation rather than relying on the model’s pre-trained knowledge.

The product it teaches Agents to use is the Sandbox SDK (npm package @cloudflare/sandbox, source repository cloudflare/sandbox-sdk). The official documentation states its positioning directly: based on Cloudflare Containers, safely run untrusted code in isolated environments, execute commands, manage files, run background processes, and expose services from within a Workers application. Each sandbox is an independent Linux container that also exists as a Durable Object. This capability is only available for the Workers Paid plan.

In one sentence: The Skill ensures coding assistants write code according to official conventions; the SDK actually runs the code inside edge containers.

The Name Has Been Split—Read This Section Before Installing

On February 5, 2026, Cloudflare added a Skill named sandbox-sdk to the cloudflare/skills repository. The skills.sh / officialskills.sh directory still lists it under this name today, with the installation example:

npx skills add https://github.com/cloudflare/skills --skill sandbox-sdk

On August 7, 2026, the repository split this single Skill into three separate tracks in a single commit (PR #92). The main branch’s skills/ directory no longer contains a sandbox-sdk folder, and the official README now lists:

Skill Purpose
sandbox-stable Current stable version of @cloudflare/sandbox (default npm tag)
sandbox-next @cloudflare/sandbox@next (Sandbox SDK 1.0 preview), officially recommended for new projects
sandbox-migrate-to-next Migrate existing stable version applications to @next

The official Sandbox documentation and Agent setup page align with this repository structure: use sandbox-stable for development on the stable package, use sandbox-next for new projects, and use sandbox-migrate-to-next when migrating. The --skill sandbox-sdk flag from the directory site corresponds to the pre-split name. Based on the current state of the repository, you should install the entire cloudflare/skills package and let the Agent automatically load the corresponding Skill based on dependencies, rather than assuming the sandbox-sdk directory still exists.

The installation commands below follow the repository README and the Agent setup guide; code examples are based on the current stable version documentation.

Core Features

Comparing the pre-split sandbox-sdk SKILL.md and the current stable version documentation, the capabilities Agents are expected to master can be divided into several categories.

1. Sandbox Lifecycle
Use getSandbox(env.Sandbox, sandboxId) to retrieve a sandbox instance. The same ID will always map to the same sandbox; getSandbox() returns immediately, and the container is lazily launched only when the first actual operation is performed. By default, the container will sleep after approximately 10 minutes of inactivity (configurable via sleepAfter). After sleeping, subsequent requests will spin up a brand new container, and all previously written files, processes, and interpreter context will be lost. For temporary tasks, call destroy() to release resources immediately.

2. Command Execution and Code Interpreters
Use sandbox.exec(command) to run shell commands, returning stdout, stderr, exitCode, and success. This is suitable for scripts, builds, and tests. For code generated by LLMs, createCodeContext() + runCode() is recommended: it supports Python, JavaScript, and TypeScript, preserves variables and imports within the same context, and can output rich content such as charts and tables. The official advice is: use exec() for shell/build pipelines, and runCode() for data analysis and model-generated code.

3. File System
Use mkdir, writeFile, readFile, and listFiles to operate on paths inside the sandbox, with the common working directory being /workspace. Files persist while the container is running; once the container sleeps or is destroyed, these files are deleted. To retain data across lifecycle events, the official offers the ability to mount object storage such as R2/S3 into the sandbox, which is only available in production deployments.

4. Preview URLs and Tunnels
The pre-split Skill used exposePort(8080) to obtain a preview URL, and required the Worker entry point to first run proxyToSandbox(). Production preview subdomains require wildcard DNS for custom domains; .workers.dev does not support such subdomains. The current stable version documentation additionally offers sandbox.tunnels.get(port) to get configuration-free addresses such as *.trycloudflare.com; the 2026 deprecation guide marks HTTP/WebSocket transport and exposePort() for removal, with new code prioritizing RPC transport and the Tunnels API.

5. Configuration Contracts
The Worker must re-export the Sandbox class, otherwise deployment will fail. wrangler.jsonc requires three sections to be configured: containers, durable_objects.bindings, and migrations. The npm package version and the base image tag in the Dockerfile must be aligned: the stable package cannot use the cloudflare/sandbox:next image, and vice versa.

Installation and Activation

The Skill itself is a SKILL.md instruction package, and does not replace @cloudflare/sandbox. Local development also requires Docker to be available on your machine, which you can check with docker info.

Install Cloudflare Skills

Universal (npx skills): The repository README provides the command to install the entire package:

npx skills add https://github.com/cloudflare/skills

You can also clone the repository and copy the corresponding Skill directory to each tool’s Skill path:

Tool Directory
Claude Code ~/.claude/skills/
Cursor ~/.cursor/skills/
OpenCode ~/.config/opencode/skills/
Codex ~/.codex/skills/

Claude Code: The official Agent setup requires using the plugin marketplace, do not run npx skills separately:

/plugin marketplace add cloudflare/skills
/plugin install cloudflare@cloudflare

Cursor: You can run /add-plugin cloudflare, or install from the Cursor Marketplace; alternatively, go to Settings > Rules > Add Rule > Remote Rule (Github) and enter cloudflare/skills.

Codex: Open /plugins in a session, search for, and install the Cloudflare plugin.

Once installed, when a conversation includes requests like “run untrusted code with Sandbox SDK / build a code interpreter / create isolated environments for each CI run”, the Agent will load sandbox-stable or sandbox-next based on the trigger conditions.

Create a Runnable Sandbox Worker

The official onboarding guide uses a template to generate a minimal project (for the current stable package):

npm create cloudflare@latest -- my-sandbox --template=cloudflare/sandbox-sdk/examples/minimal
cd my-sandbox

The template will include src/index.ts, wrangler.jsonc, and Dockerfile. The core structure of wrangler.jsonc is as follows (use the field names from the official onboarding guide, do not modify the class_name / binding names arbitrarily):

{
  "containers": [
    {
      "class_name": "Sandbox",
      "image": "./Dockerfile",
      "instance_type": "lite",
      "max_instances": 1
    }
  ],
  "durable_objects": {
    "bindings": [
      {
        "class_name": "Sandbox",
        "name": "Sandbox"
      }
    ]
  },
  "migrations": [
    {
      "new_sqlite_classes": ["Sandbox"],
      "tag": "v1"
    }
  ]
}

Increase max_instances if you need multiple instances. For local debugging:

npm run dev

The first run will build the Docker image, which the official documentation says will take approximately 2–3 minutes. For deployment:

npx wrangler deploy

wrangler deploy will build the image, push it to the Cloudflare Container Registry, and then publish the Worker. After the first deployment, the container image still needs to be provisioned; the official recommends waiting a few minutes before making sandbox requests; you can check the status with npx wrangler containers list.

Typical Usage

The code below comes from the official Get Started template, and is also the minimal structure required by the sandbox-stable Skill for Agents to follow: you must export { Sandbox }, retrieve the sandbox with a stable ID, and use the exec / file APIs to perform work. In user-facing applications, the ID should be derived per logged-in user, do not use a hardcoded ID shared by all users.

import { getSandbox, proxyToSandbox, type Sandbox } from "@cloudflare/sandbox";

export { Sandbox } from "@cloudflare/sandbox";

type Env = {
  Sandbox: DurableObjectNamespace<Sandbox>;
};

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);
    const sandbox = getSandbox(env.Sandbox, "my-sandbox");

    if (url.pathname === "/run") {
      const result = await sandbox.exec('python3 -c "print(2 + 2)"');
      return Response.json({
        output: result.stdout,
        error: result.stderr,
        exitCode: result.exitCode,
        success: result.success,
      });
    }

    if (url.pathname === "/file") {
      await sandbox.writeFile("/workspace/hello.txt", "Hello, Sandbox!");
      const file = await sandbox.readFile("/workspace/hello.txt");
      return Response.json({
        content: file.content,
      });
    }

    return new Response("Try /run or /file");
  },
};

You can verify this locally with:

curl http://localhost:8787/run
curl http://localhost:8787/file

If you need to run model-generated Python code and preserve variables across multiple calls, use the code interpreter (stable version API):

const sandbox = getSandbox(env.Sandbox, "user-123");
const ctx = await sandbox.createCodeContext({ language: "python" });

await sandbox.runCode("data = [1, 2, 3]", { context: ctx.id });
const result = await sandbox.runCode("sum(data)", { context: ctx.id });

The pre-split Skill also listed a set of quick reference methods, which still apply to the stable version documentation:

const sandbox = getSandbox(env.Sandbox, "user-123");
await sandbox.exec("python script.py");
await sandbox.mkdir("/workspace/src", { recursive: true });
await sandbox.writeFile("/workspace/app.py", content);
await sandbox.readFile("/workspace/app.py");
await sandbox.listFiles("/workspace");
await sandbox.destroy();

When you need to expose an HTTP service inside the sandbox, the Worker’s fetch handler should first handle the preview proxy:

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const proxyResponse = await proxyToSandbox(request, env);
    if (proxyResponse) return proxyResponse;
    // Add your business routing here
  },
};

When collaborating with an Agent, you can clearly state the task, for example:

Build an isolated Python code execution interface in Workers using the Cloudflare Sandbox SDK.
Write it according to the current stable version @cloudflare/sandbox, load sandbox-stable.
You need exec, read/write /workspace files, and correct wrangler.jsonc and export { Sandbox }.

For new projects planning to use the 1.0 preview, change the dependency to @cloudflare/sandbox@next and explicitly ask the Agent to load sandbox-next. The stable version’s exec accepts a command string and waits for the command to finish before returning; @next’s exec accepts an argv list and returns a process handle immediately after startup—the two APIs are not compatible.

Applicable Scenarios and Notes

The official documentation lists typical scenarios including: AI Agents / coding assistants executing model-generated code; data analysis environments with pandas and chart output; cloud IDEs and coding playgrounds; running tests and builds in isolated containers. The original Skill also emphasizes: do not run tool-call code directly on the host Worker.

Before using, you must accept these limitations:
1. Plan and Billing: The Sandbox SDK is marked for Workers Paid; costs are incurred from underlying Containers, plus Workers, Durable Objects, and optional Workers Logs. See the Containers pricing page for specific rates.
2. Ephemeral State: Files, processes, and interpreter context are all cleared after inactivity-induced sleep or destroy(). For persistent storage, use external storage or mount object storage as per the official guide.
3. Package and Image Must Be Aligned: Only upgrading the npm package without updating the FROM tag in the Dockerfile will cause version warnings at startup and potential functionality issues.
4. Local Docker Dependency: Both wrangler deploy and local image builds require the Docker daemon to be running.
5. Subrequest Limit: By default with HTTP transport, each exec() / readFile() and similar call counts as one Worker subrequest. The Paid plan allows 1000 subrequests per request, while the Free plan allows 50. For high-frequency operations, set SANDBOX_TRANSPORT to rpc. The official also notes that HTTP/WebSocket transport is deprecated.
6. Do Not Put Secrets in Sandbox Environment Variables: Non-sensitive configuration can be passed to the sandbox; live credentials should stay on the Worker, injected via an outbound handler.
7. Do Not Mix stable / next: The Skill enforces this as a hard requirement. Self-hosted Bridge currently only works with the stable package and stable image.
8. Do Not Use Internal Clients Directly: The pre-split Skill explicitly prohibits direct use of CommandClient or FileClient, you should use the sandbox.* methods; also do not omit export { Sandbox }.

Summary

The core problem sandbox-sdk solves is very specific: enabling coding assistants to write Workers applications that execute untrusted code in isolated containers according to Cloudflare’s conventions. From a product perspective, this is @cloudflare/sandbox, and as of August 2026, the Skill side has been split into sandbox-stable, sandbox-next, and sandbox-migrate-to-next. After installing cloudflare/skills, first confirm whether your project uses the stable package or @next, then have the Agent load the corresponding Skill—this is more reliable than continuing to use the old directory site flag to install a folder that no longer exists.

Official Resources:
- Skill Repository: https://github.com/cloudflare/skills
- Pre-split sandbox-sdk Directory (historical path): https://github.com/cloudflare/skills/tree/main/skills/sandbox-sdk
- Directory Page: https://officialskills.sh/cloudflare/skills/sandbox-sdk
- Sandbox SDK Documentation: https://developers.cloudflare.com/sandbox/
- Get Started Guide: https://developers.cloudflare.com/sandbox/get-started/
- SDK Source Code: https://github.com/cloudflare/sandbox-sdk
- Tool-Specific Installation: https://developers.cloudflare.com/agent-setup/