The CLI is the API
Every sandbox product ships with a Python SDK. Some also ship TypeScript. A few have Go bindings. Everyone races to wrap their execution runtime in language-idiomatic helpers, because that's what developers expect.
boxd's interface is a single static binary — the boxd CLI — and every command it exposes is the API. There's a gRPC API under it, and thin Python and TypeScript SDKs if you want them, but the CLI is the surface everything else wraps. One command, --json on everything.
Why a CLI first
SDKs are convenient. They're also a commitment.
Every SDK has to be maintained across language ecosystems, kept in sync with the backend, updated for every API change, documented for every method. That's real engineering work — and it's work that steers your API design toward what fits cleanly in a Python decorator, not what fits cleanly in an agent's shell.
Worse: leading with an SDK binds your users to the languages you support. A JS-shop team can use your JS SDK. A Python shop uses your Python SDK. A Rust shop waits. An agent whose runtime is a prompt-to-shell loop can't use an SDK at all — not without a bespoke integration layer that translates prompt intent into method calls.
A CLI where every command speaks --json has none of these problems. The SDKs we ship are a thin convenience over it, not the thing you have to reach for.
What a CLI gives you
Anything that can run a command can drive boxd. Bash can. A Makefile can. CI can. An agent with shell access can — in fact, an agent with shell access is a CLI driver, because that's what agents fundamentally know how to do: run commands.
When the CLI is the API:
- Any language works. Shell out to
boxdfrom Python, Node, Go, Rust, Bash, a Justfile, your grandmother's Tcl. Every command takes--json, so the output parses anywhere. - Agents work natively. An agent that can run shell commands can use boxd without a wrapper. No tool definition, no "teach the agent how our API works" step — it just runs
boxd. - The documentation is self-describing.
boxd --helpworks. So does every subcommand's--help. The tool documents itself. - Shell ecosystem comes free. Tab completion, shell history, piping, grep,
jqon the--jsonoutput. Nothing else has that ecosystem.
What about ergonomics
This is the objection we hear most: "Python users expect Python-idiomatic wrappers."
Fair — so there's a Python SDK and a TypeScript one, each a thin layer over the same CLI and gRPC surface. Prefer to wrap it yourself in fifteen lines around subprocess? Do that instead. We shipped the primitive; you pick the ergonomics.
The inverse doesn't work. You can always wrap a CLI. You can't unwrap an SDK that hid the primitive from you.
For agents specifically
An agent is a model that types commands and reads output. That's not a metaphor — it's what the runtime actually does. Model generates a tool call, harness executes, output returns, model generates next tool call. In that shape, "run boxd machine new and read what comes back" is the simplest possible tool: it's just shell, and the model already knows shell.
Every sandbox that leads with an SDK is a layer of translation between prompt and execution. The agent decides what to do. The harness converts to an SDK call. The SDK calls the runtime. The runtime runs it. The result comes back through the same layers. Every layer is a place bugs hide and a place latency accumulates.
An agent driving boxd skips the layers. It runs a command. It reads the output. That's the entire tool interface. And once it's inside a machine — one ssh <name>.boxd away — the interface is the whole Linux userland.
A primitive, not a framework
We're not anti-SDK. Other tools ship great SDKs for different primitives — Modal's Python decorators, E2B's agent helpers. If your shape matches those primitives, those tools will beat us.
But a computer is not a framework. You don't need a Python wrapper to run a command or to log into a machine; you just run it, and you just log in. The primitive we ship is a real Linux machine. The interface is one binary — and the SSH you've used for forty years to get inside.
One CLI. --json on everything. That's the API.
For the operational consequence — what an agent harness gets when one CLI is the whole interface — read on. For how this stacks against the closest competitor by stated positioning: boxd vs exe.dev.
Read next
boxd vs exe.dev: persistent SSH VMs, compared honestly
Two products in the same lane: persistent Linux VMs over SSH, batteries included. An honest comparison of the design choices that fall out of the shared thesis.
Where to run an agent harness in production
Anthropic and LangChain define what an agent harness is. This piece answers the question they don't: where does the harness actually live in production?
boxd 101
A short tour of boxd: SSH in, install things, fork the machine, share a URL. The basics in 5 minutes.