boxer

Quickstart

Install boxer, connect your agent, and let every workstream get its own sandbox without thinking about it.

You set boxer up once per repository. After that, every agent session in every worktree gets its own sandbox. You need a git repository; run git init if your project is not one yet.

Using Conductor, T3 Code or another orchestrator? Do step 1, then go to Orchestrators. Already use Docker? See the note in step 1.

What you need

Your machineBackendNotes
Mac with Apple Siliconsmolvm, the defaultApple container (macOS 26), docker and podman also work
Intel Macdocker or podmansmolvm and Apple container need Apple Silicon. You get a container per worktree and no egress allowlist
Linux, x86_64 or arm64smolvm (needs /dev/kvm), docker or podman
Windowsnot supportedboxer ships no Windows build. WSL 2 is Linux, and is untested

Plus a git repository, and one of the supported agents.

1. Install boxer

curl -sSL https://smolmachines.com/install.sh | bash
curl -fsSL https://raw.githubusercontent.com/BarakChamo/boxer/main/install.sh | sh

smolvm runs the sandboxes. On Linux, smolvm needs /dev/kvm (sudo usermod -aG kvm $USER, then log in again).

The script installs boxer into ~/.local/bin, so that directory must be on your PATH, and it checks the download against the release's checksums. BOXER_VERSION=v1.4.2 pins a version, and BOXER_INSTALL_DIR=/usr/local/bin changes where it goes (GUI apps such as Conductor need a directory they can see). Both go to the right of the pipe, where the script reads them: curl -fsSL .../install.sh | sudo BOXER_INSTALL_DIR=/usr/local/bin sh.

On an Intel Mac, or prefer Docker, podman or Apple container? Skip smolvm. Add backend = "docker" (or "podman", "container") and [network] mode = "on" to your boxer.toml in step 3. You get a container per worktree instead of a microVM. See Bring your Docker setup.

2. Connect your agent

cd your-repo
boxer install claude-code
git add .claude .mcp.json
git commit -m "Run agent commands in boxer"

The first time you open the repository, Claude Code asks you to approve the boxer MCP server. Approve it.

For Claude Code, boxer install writes four things. Other agents get the same pieces where their format supports them:

PieceWhat it does
HooksThe SessionStart hook creates the sandbox. The PreToolUse hook rewrites each shell command to run in it. This is the part that enforces.
MCP serverGives the agent a boxer_run tool and a description of its sandbox.
SkillExplains to the agent how commands run here.
SubagentA helper agent that runs everything through boxer (Claude Code only).

Existing hooks and settings are kept. Claude Code reads the files from each worktree, so they need to be on the branch worktrees are cut from. Codex reads them from the main checkout.

Just trying it?

Run boxer install claude-code --user instead. It writes the hooks to ~/.claude/settings.json, so they apply to every repository and nothing changes in this one. Codex has the same --user option.

For other agents (Gemini CLI, Copilot CLI, OpenCode, pi, Grok, Kimi Code), see Set up your agent.

3. Describe your project

A boxer.toml tells boxer how to set up the sandbox. Without one:

  • boxer picks an image from your lockfile and installs nothing, so the sandbox uses the node_modules or .venv built on your machine, which may not run on Linux.
  • The sandbox reaches only the image registry, so an agent's npm install fails.

Add a boxer.toml to the repository root. This one is for a Next.js app:

boxer.toml
image = "mirror.gcr.io/library/node:24-alpine"
setup = ["npm ci"]                                       # runs when a worktree's sandbox is created
start = ["npx next dev --webpack -H 0.0.0.0 -p 3000"]    # starts with the sandbox
ready = "wget -q -O /dev/null http://127.0.0.1:3000/"    # the sandbox is ready when this passes

[network]
allow_hosts = ["registry.npmjs.org"]                     # everything else is blocked
ports = ["auto:3000"]                                    # a free host port per worktree

boxer runs setup and start when it creates each worktree's sandbox. The dev server must listen on 0.0.0.0 for the forwarded port to reach it.

To give each worktree a named URL instead of a port, install portless (npm install -g portless) and add [urls] enabled = true. See Dev server URLs.

Examples has configurations for Vite, Python, Go and monorepos.

4. Work as usual

Start your agent in the repository, or in any worktree of it. If you never make worktrees, your repository folder is the one worktree, and it gets one sandbox. At session start, boxer creates the worktree's sandbox, runs npm ci, starts the dev server, and tells the agent:

This repository runs commands inside a boxer sandbox: a microVM per worktree with the worktree
mounted at /workspace. Files you edit on the host are the same files the sandbox sees.
Shell commands that start with npm, npx, pnpm, yarn, bun, bunx, node, deno, python, python3, pip,
uv, pytest, cargo, rustc, go, make, cmake are transparently executed in the sandbox; write them
normally. git, gh, ssh, boxer, smolvm run on the host on their own; a line that also runs one of the programs above runs whole in the sandbox.

On docker or podman, the first line says "a container" instead of "a microVM".

When the agent runs npm test, the hook turns it into boxer run -c 'npm test'. The test runs in the sandbox and the agent sees the usual output. When it runs git status, the hook leaves it alone and it runs on your machine.

  • Another worktree gets another sandbox, with its own dev server and port. The two do not share ports, installed tools or processes. It does not matter who created the worktree.
  • Two sessions in the same worktree share its sandbox by default. For separate ones, give each session its own worktree (claude --worktree fix-ui), or set isolation = "session" for a sandbox per session, or "subagent" for one per subagent.
  • A deleted worktree's sandbox is removed. Any command that uses a sandbox (boxer run, boxer up, a session starting) starts this cleanup in the background, at most every 6 hours. boxer gc runs it now.

The first session in a new worktree waits for the image to download and setup to run. Later sessions start in seconds. See Benchmarks.

5. Check it

$ boxer doctor              # the resolved setup, and anything that will not work
$ boxer ls                  # every sandbox, its branch and where it serves (some columns left out)
NAME         STATE    BRANCH    SERVES
mild-lynx    running  add-auth  http://127.0.0.1:52341
olive-comet  running  fix-ui    http://127.0.0.1:52388

Open the SERVES address in your browser to see that worktree's dev server. To confirm a command really runs in the sandbox, ask the agent to run node -p process.platform. It prints linux, even on a Mac.

Turn it off or remove it

ToDo
Watch what boxer would do, without changing anythingset enforcement = "audit" in boxer.toml
Run one session on your machinestart the agent with BOXER_MODE=off
Turn it off for the repositoryset mode = "off" in boxer.toml
Remove it from the repositoryboxer uninstall all (or the harness you installed) and commit the result. boxer rm --all -A --volumes -y deletes the sandboxes and their data
Remove it from this machinealso boxer uninstall <harness> --user if you used --user, then delete ~/.local/bin/boxer, ~/.local/state/boxer (packs, volumes, logs) and ~/.local/share/boxer (shims)

Next

  • Orchestrators if something else creates the worktrees.
  • Environment for images, dependency installs, services, caches and secrets.
  • Security for what the sandbox isolates, and what stays on your machine.

On this page