# Sandbox for a coding agent: give an AI agent its own computer Give the agent a Linux microVM with the repository cloned, let it run commands and tests there, and take back the diff when it is done. **On Runtime a coding agent's machine costs $0.03125 an hour while the agent waits on its model**, and $0.08 an hour with both CPUs busy, for 2 vCPUs and 4 GiB. Runtime bills the CPU the agent's commands use, not the CPUs it holds, which made it 42% to 88% cheaper than eleven other sandbox providers on an agent job that mostly waits, at rates checked 23 September 2026 ([the comparison](/docs/pricing#published-rate-comparison)). ## The short answer Create a sandbox, clone the repository, hand the model four tools bound to that sandbox, and read the diff at the end. ```ts check import { Sandbox } from "withruntime"; import { sandboxTools } from "withruntime/tools"; const repo = "https://github.com/your-org/your-repo.git"; await using sbx = await Sandbox.create({ diskMiB: 8192, timeoutSeconds: 3600, labels: { agent: "coder", task: "1234" }, network: { internet: true, allow: ["github.com", "*.github.com", "registry.npmjs.org"] }, }); await sbx.exec(["git", "clone", "--depth", "1", repo, "repo"], { check: true, timeoutMs: 300_000 }); await sbx.exec("cd repo && npm ci", { check: true, timeoutMs: 600_000 }); // runtime_exec, runtime_read_file, runtime_write_file, runtime_list_files: // a name, a description, a JSON Schema and a function each, for any tool format. const tools = sandboxTools(sbx); console.log(tools.map((t) => t.name)); // ... your model's tool-calling loop runs here ... const diff = await sbx.exec("git diff", { cwd: "/workspace/repo" }); const tests = await sbx.exec("npm test", { cwd: "/workspace/repo", timeoutMs: 900_000 }); console.log(tests.exitCode, diff.stdout); ``` ```python check from withruntime import Sandbox from withruntime.tools import sandbox_tools repo = "https://github.com/your-org/your-repo.git" with Sandbox.create( disk_mib=8192, timeout_seconds=3600, labels={"agent": "coder", "task": "1234"}, network={"internet": True, "allow": ["github.com", "*.github.com", "pypi.org", "*.pythonhosted.org"]}, ) as sbx: sbx.exec(["git", "clone", "--depth", "1", repo, "repo"], check=True, timeout_ms=300_000) sbx.exec("cd repo && pip install -e .", check=True, timeout_ms=600_000) run, read, write, ls = sandbox_tools(sbx) # give these to your agent framework # ... your model's tool-calling loop runs here ... diff = sbx.exec("git diff", cwd="/workspace/repo") tests = sbx.exec("python3 -m pytest -q", cwd="/workspace/repo", timeout_ms=900_000) print(tests.exit_code, diff.stdout) ``` The model chooses commands and paths, never the sandbox or the account. The tools cap their output, so one noisy command cannot flood the model's context. The same four tools come ready for the OpenAI Agents SDK, Vercel AI SDK, Claude Agent SDK, LangChain, Mastra and five more frameworks ([frameworks](/docs/frameworks)). ## What a coding agent needs from its sandbox | Need | How Runtime covers it | | ----------------------------------- | --------------------------------------------------------------------------------------------- | | A real Linux machine | Ubuntu 24.04 with Python 3.12, Node.js 24, Bun, git, gcc and `sudo` | | Isolation from your laptop and CI | A Firecracker microVM with its own kernel, on servers Runtime operates | | Dependencies ready at start | A [custom image](/docs/images) from a recipe, any container image or a Dockerfile | | Services the tests need | `sudo enable-docker`, then `docker compose up -d` | | A dev server to look at | A private HTTPS [preview](/docs/javascript#share-a-port) of any port | | Push access without leaking a token | A [secret](/docs/security#secrets-sandboxes-never-see) the sandbox only sees as a placeholder | | Long tasks | Commands up to 24 hours; leases up to an hour, extended as often as needed | | Waiting on review | Pause keeps files, memory and running processes for 1 to 365 days | | Several attempts at one task | `fork` makes 1 to 10 running copies of the prepared machine | | An agent that retries | Every write carries an idempotency key, so a retry never starts a second sandbox | | An agent that spends | A daily spending limit per key, which only a person can set | ## Try several approaches at once Set the repository up once, then fork it. Each copy starts from exactly that point, with the dependencies installed and any server still running, and the agent tries a different plan in each: ```ts check import { Sandbox } from "withruntime"; await using base = await Sandbox.create({ diskMiB: 8192 }); await base.exec("git clone --depth 1 https://github.com/your-org/your-repo.git repo", { check: true, timeoutMs: 300_000, }); const attempts = await base.fork({ count: 3 }); const results = await Promise.all( attempts.map((copy) => copy.exec("cd repo && npm test", { timeoutMs: 900_000 })), ); console.log(results.map((r) => r.exitCode)); await Promise.all(attempts.map((copy) => copy.stop())); ``` ```python check from withruntime import Sandbox with Sandbox.create(disk_mib=8192) as base: base.exec("git clone --depth 1 https://github.com/your-org/your-repo.git repo", check=True, timeout_ms=300_000) attempts = base.fork(count=3) results = [copy.exec("cd repo && npm test", timeout_ms=900_000) for copy in attempts] print([r.exit_code for r in results]) for copy in attempts: copy.stop() ``` The source pauses for the moment the fork takes, about a second for a fresh sandbox, then carries on ([sandbox forks](/glossary/sandbox-fork)). ## Push a branch without handing over the token Store the GitHub token as a Runtime secret. Each sandbox gets a placeholder; the host's proxy puts the real value into HTTPS requests to the hosts you name, and nowhere else, so a prompt injection cannot read it. `git push` over HTTPS goes to `github.com` with Basic credentials, the user name `x-access-token` and the token as the password, so the secret holds that pair: ```ts check import { Runtime } from "withruntime"; const runtime = new Runtime(); const token = process.env.GITHUB_TOKEN ?? ""; // a fine-grained token for this repository await runtime.secrets.set("GIT_GITHUB_AUTH", { value: Buffer.from(`x-access-token:${token}`).toString("base64"), hosts: ["github.com"], header: "Authorization", format: "Basic {value}", }); await using sbx = await runtime.sandboxes.create(); await sbx.exec("git clone https://github.com/acme/app.git app", { check: true, timeoutMs: 300_000, }); // ...the agent works on a branch... await sbx.exec("cd app && git push origin agent/fix-parser", { check: true, timeoutMs: 120_000 }); ``` The URL carries no credentials and git needs no helper: the proxy sets the header on every HTTPS request to `github.com`. To open the pull request through GitHub's API as well, store the token a second time for `api.github.com` with the format `token {value}` ([secrets sandboxes never see](/docs/security#secrets-sandboxes-never-see)). [Git in a sandbox](/integrations/git) covers SSH deploy keys and faster clones. ## Coding agents that run on their own Claude Code, Codex, Cursor and other MCP clients can drive Runtime sandboxes through Runtime's MCP server, approved once in the browser with no key to copy: ```bash no-run claude mcp add --scope user runtime -- npx -y withruntime mcp codex mcp add runtime -- npx -y withruntime mcp ``` To run the coding agent itself inside a sandbox, see [Claude Code](/integrations/claude-code) and [Codex](/integrations/codex). ## What it costs Take 1,000 agent tasks a month. Each keeps a 2 vCPU, 4 GiB sandbox running for 30 minutes, and its commands (installs, builds, tests) use 5 CPU-minutes, 300 CPU-seconds, while the rest is spent waiting on the model: ``` CPU: 1,000 × 300 s / 3,600 × $0.025 = $2.08 Memory: 1,000 × 1,800 s / 3,600 × 4 GiB × $0.0075 = $15.00 Total: $17.08 ``` That is under 2 cents a task, from Runtime's rates of $0.025 per vCPU-hour of measured CPU and $0.0075 per GiB-hour ([pricing](/docs/pricing)). A paused sandbox waiting on review costs no compute; it is billed as paused storage at $0.08 per GB per 30-day month. New accounts get 50 free sandbox hours, no card. ## Start ```bash no-run npx withruntime sandbox run --trial -- git --version ``` The first run prints a link to approve in your browser. Then use the [JavaScript](/docs/javascript) or [Python](/docs/python) SDK as above. Related: [run untrusted LLM code safely](/use-cases/run-untrusted-llm-code), [preview apps an agent builds](/use-cases/preview-agent-built-apps), [run Docker in a sandbox](/how-to/run-docker-in-a-sandbox), [what an agent sandbox is](/glossary/agent-sandbox). Facts on this page were checked on 25 September 2026.