# 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. Take back the diff when it is done. **On Runtime, a coding agent's machine costs $0.03125 per hour while the agent waits on its model**, and $0.08 per 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. That made it 42% to 88% cheaper than fourteen other sandbox providers on an agent job that mostly waits. The rates were checked on 25 October 2026 ([the comparison](/docs/pricing#published-rate-comparison)). ## The short answer Create a sandbox. Clone the repository. Give the model four tools bound to that sandbox. 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. It never chooses the sandbox or the account. The tools cap their output, so one noisy command cannot flood the model's context. The same four tools are 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; no time limit on the sandbox | | Waiting on review | Pause keeps files, memory and running processes while you have credit | | Several attempts at one task | `fork` makes 1 to 100 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 up the repository once, then fork it. Each copy starts from exactly that point, with the dependencies installed and any server still running. The agent tries a different plan in each copy: ```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 only for the capture. It is running again when the fork returns ([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 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 Assume 1,000 agent tasks a month. Each keeps a 2 vCPU, 4 GiB sandbox running for 30 minutes. Its commands (installs, builds, tests) use 5 CPU-minutes, or 300 CPU-seconds. The rest of the time 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, at Runtime's rates of $0.025 per vCPU-hour of measured CPU and $0.0075 per GiB-hour ([pricing](/docs/pricing)). A paused sandbox that waits for review costs no compute. It is billed as paused storage at $0.08 per GB per 30-day month. Every account gets 100 free hours of a 1 GB machine in its first 30 days, with no card. ## Start ```bash no-run npx withruntime sandboxes run -- git --version ``` The first run prints a link. Open it in your browser to approve the run. Then use the [JavaScript](/docs/javascript) or [Python](/docs/python) SDK as shown 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 26 October 2026.