Sandbox Agent: One HTTP API in Front of Claude Code, Codex, OpenCode, Cursor, Amp and Pi
Run Coding Agents in Sandboxes. Control Them Over HTTP. Supports Claude Code, Codex, OpenCode, and Amp.
At a glance
- What is it?
- Sandbox Agent is a Rust daemon that runs inside a sandbox and exposes a uniform HTTP plus SSE interface to several coding agents. The pitch is agent portability and durable transcripts; the cost is a young API surface and a normalisation layer that can only be as complete as each adapter.
- Who is it for?
- Adopt Sandbox Agent if your product already runs untrusted code in E2B, Daytona, Modal, Cloudflare Containers or plain Docker and you want to switch between Codex, Claude Code and OpenCode without rewriting your integration. Do not adopt it if you need a stable API today: the newest published release in the material is v0.5.0-rc.3, a release candidate, and the README labels the OpenCode compatibility layer experimental.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 89 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem is not running an agent, it is controlling one that lives somewhere else
Coding agents want to execute arbitrary code. That is the point of them, and it is also why nobody sensible points one at a production server. The README states the constraint plainly: existing SDKs assume local execution. So the moment you move the agent into an isolated environment, the SDK you were using stops being useful. SSH is offered as the obvious workaround and the README rejects it on the grounds that it breaks TTY handling and streaming. That is a specific, checkable complaint rather than a generic one. The second problem is that Claude Code, Codex, OpenCode, Cursor, Amp and Pi each ship their own API, their own event format and their own quirks. Swapping the agent means rewriting the integration. The third problem is that agent transcripts live inside the sandbox and die with the process, which makes auditing and replay impossible unless something streams the events out. Sandbox Agent targets all three at once, and the intended user is a team building a product on top of coding agents rather than an individual running one in a terminal.
An adapter per agent, one universal schema out the other side
The README describes the daemon as a universal adapter sitting between a client application and the individual agents. Each agent gets its own adapter that translates between the universal API and that agent's specific interface. Two execution modes exist. Embedded mode runs agents locally as subprocesses, which is what SandboxAgent.start() gives you in the TypeScript SDK. Server mode runs the daemon as an HTTP server inside a sandbox, and that is the shape the deployment story is built around. The daemon itself is a Rust binary, described as lightweight and static, which matters because it has to be installed inside container images that you do not want to bloat. Events leave the server over SSE in what the README calls a universal session schema, normalising every agent's event format for storage and replay. The stated destinations are Postgres, ClickHouse or Rivet. A CLI mirrors the HTTP endpoints, and there is a built-in Inspector UI for reading sessions and events. The honest reading of this design: the universal schema is a lowest-common-denominator contract. Anything an agent exposes that the schema does not model is either dropped or smuggled through in a raw payload. The README does not say which, and that is the first thing to check against a real session.
Getting the daemon into a sandbox: two install paths and a token
The server route is a single install script followed by a run command. The README gives it as curl -fsSL https://releases.rivet.dev/sandbox-agent/0.4.x/install.sh | sh, then sandbox-agent server --token "$SANDBOX_TOKEN" --host 127.0.0.1 --port 2468. Binding to 127.0.0.1 inside the sandbox is the sensible default and the example uses it. For local work the README shows sandbox-agent server --no-token --host 127.0.0.1 --port 2468, which disables auth. Agent binaries install lazily on first use, or ahead of time with sandbox-agent install-agent --all, described as not requiring a running server. The SDK route is npm install sandbox-agent@0.4.x, followed by SandboxAgent.start() for embedded mode or SandboxAgent.connect({ baseUrl, token }) for a remote daemon. One Bun-specific detail worth repeating because it silently breaks things: the README notes that bun pm trust must be run against the five @sandbox-agent/cli-* native binary packages, including @sandbox-agent/cli-linux-x64 and @sandbox-agent/cli-darwin-arm64, or the postinstall scripts will not run and SandboxAgent.start() will fail. The CLI wrapper is npm install -g @sandbox-agent/cli@0.4.x, and the README's session example is sandbox-agent api sessions create my-session --agent codex --endpoint http://127.0.0.1:2468 --token "$SANDBOX_TOKEN", with send-message and send-message-stream as the follow-ups.
The API surface you actually write against
The README's SDK sample is short enough to read as a contract. client.listAgents() returns the available agents. client.createSession("demo", { agent: "codex", agentMode: "default" }) opens a session, and the agentMode field implies that a given agent has more than one operating mode, though the README does not enumerate them. client.postMessage("demo", { message: "..." }) sends input. The read side is an async iterator: for await (const event of client.streamEvents("demo", { offset: 0 })) yields event.type and event.data. That offset parameter is the most interesting thing in the sample. It means the event stream is addressable, so a client that disconnects can resume from a known position instead of losing the middle of a transcript. That is what makes the persistence claim credible rather than decorative. There is also an OpenAPI spec linked from the README, which is what lets you generate a client in a language other than TypeScript. The TypeScript SDK is the only SDK the material mentions.
Where the abstraction leaks
The README advertises full feature coverage across all six agents. Treat that as an aspiration to verify, not a property to rely on. Agents differ in ways a universal schema cannot paper over: permission prompts, tool approval flows and mode switching are the usual places where a normalisation layer either invents a common denominator or passes something through untouched. The README mentions handling permissions as a server responsibility but does not describe the permission model, so you cannot tell from the material whether a permission request from Claude Code and one from Codex arrive in the same shape. The OpenCode compatibility layer, which lets you point OpenCode's CLI, SDK or web UI at the daemon, is explicitly marked experimental, as is Gigacode. Versioning is the other leak. The README pins examples to 0.4.x while the newest release listed is v0.5.0-rc.3, a release candidate published before the stable v0.4.2. If you build against 0.4.x today, moving to 0.5.0 is a migration you have not seen the notes for. And if your workflow depends on one specific agent's unique behaviour, the adapter is a liability: you are paying a translation cost to get a feature set you did not need to generalise.
What this is not: a comparison with running the agent SDK directly
The direct alternative is importing the vendor SDK for whichever agent you use and running it in-process, or shelling out to the agent CLI inside the sandbox and parsing its stdout yourself. Anthropic's Claude Code SDK and OpenAI's Codex tooling both exist for exactly that. The difference in approach is where the abstraction sits. Vendor SDKs give you the agent's full surface with no translation layer, and they track that agent's releases closely. Sandbox Agent gives you one client for six agents and a schema you can persist, at the cost of a layer that has to be updated whenever any of the six changes. If you are certain you will only ever use Codex, the vendor SDK is less machinery. The moment you want a fallback agent, or a customer-selectable agent, the calculus inverts, because the alternative is maintaining your own adapter per agent, which is precisely the work the README says you would otherwise reimplement. The other alternative is running agents on a developer machine over SSH, which the README argues fails on TTY handling and streaming. That argument is plausible but the material does not demonstrate it.
Licence, upgrades and what you are signing up for
The repository is Apache-2.0, which permits commercial use, modification and redistribution provided you keep the licence and notice files intact and state significant changes. Apache-2.0 also includes an explicit patent grant, which is the practical difference from MIT for a dependency you might embed in a product. This is a description of the licence text, not legal advice; if you are redistributing the daemon inside a shipped container image, have counsel confirm the notice requirements. On maintenance: the daemon is a Rust binary installed into sandbox images, so every upgrade means rebuilding or re-running the install script inside those images, and the install script is version-pinned in its URL (0.4.x in the README). The npm packages carry the same pin. That is a deliberate friction: you cannot drift onto a new minor version by accident. The cost you should budget for is not the daemon, it is the adapters. Six agents, each shipping on its own schedule, means the surface that breaks is the one translating between them, and the release cadence visible in the material (three releases inside a week in March 2026, two of them release candidates) suggests that surface moves.
Editorial conclusion
Adopt Sandbox Agent if your product already runs untrusted code in E2B, Daytona, Modal, Cloudflare Containers or plain Docker and you want to switch between Codex, Claude Code and OpenCode without rewriting your integration. Do not adopt it if you need a stable API today: the newest published release in the material is v0.5.0-rc.3, a release candidate, and the README labels the OpenCode compatibility layer experimental. Before committing, run sandbox-agent server with --no-token on a throwaway host, open the Inspector at /ui/, and drive one session through createSession, postMessage and streamEvents to confirm the universal event schema actually carries the fields your storage layer needs.
Community notes