# How to give a Mastra agent a code sandbox Mastra agents take AI SDK tools as they are, so `runtimeTools(sbx)` from `withruntime/ai` gives one a Linux microVM to work in. **On Runtime the integration is one line in the agent's constructor, and the machine costs $0.03125 an hour for 2 vCPU and 4 GiB while the agent waits on its model.** `runtimeTools(sbx)` returns four tools, to run a command and to read, write and list files, bound to one Firecracker microVM with its own Linux kernel. `@mastra/core` 1.71.0 was the current npm release on 25 September 2026; the tools ran in a Mastra agent's own loop with Mastra 1.69.0 on 23 September 2026. ## Install ```bash no-run npm install withruntime @mastra/core ai npx withruntime login ``` `withruntime/ai` needs the `ai` package, version 5 or later. The login prints a link to approve in your browser; a deployed app reads `RUNTIME_API_KEY`. ## An agent with a sandbox ```ts check import { Agent, type ToolsInput } from "@mastra/core/agent"; import { Sandbox } from "withruntime"; import { runtimeTools } from "withruntime/ai"; const sbx = await Sandbox.create({ timeoutSeconds: 900, onLeaseEnd: "stop" }); try { const coder = new Agent({ id: "coder", name: "Coder", instructions: "Solve tasks by writing and running code in the sandbox. Check exit codes.", model: "anthropic/claude-sonnet-4-6", tools: runtimeTools(sbx) as unknown as ToolsInput, }); const response = await coder.generate( "Write a Node script that lists the 10 largest files in /usr and run it.", { maxSteps: 15, }, ); console.log(response.text); } finally { await sbx.stop(); } ``` The tools go to Mastra as they are. The cast is for TypeScript alone: with `ai` 7 and `@mastra/core` 1.71.0 (25 September 2026), the AI SDK's tool type allows things Mastra's `tools` type does not, although these tools use none of them. In plain JavaScript on Node.js 24, drop the `type ToolsInput` import and the cast. `await using sbx = await Sandbox.create()` can replace the `try`/`finally`. `maxSteps` bounds how many model calls one `generate` makes. The four tools the model sees are `runtime_exec` (with `command`, `cwd` and `timeoutSeconds`), `runtime_read_file`, `runtime_write_file` and `runtime_list_files`. Relative paths are under `/workspace`, and each output is cut to 20,000 characters, keeping the end ([frameworks](/docs/frameworks#mastra)). ## Mastra's own sandboxes, compared Mastra also has workspaces, which attach a sandbox to an agent through `workspace: new Workspace({ sandbox })`. From Mastra's docs, read on 25 September 2026: | Option | Where commands run | What Mastra's docs say | | ----------------------------------------- | ----------------------------------- | ---------------------------------------------------------------------------------- | | `LocalSandbox`, `isolation: "none"` | The app's own host | The default; "isn't isolated or secure" | | `LocalSandbox`, `"bwrap"` or `"seatbelt"` | The host, in Bubblewrap or Seatbelt | Writes limited to the workspace; reads allowed system-wide; network off by default | | Remote sandbox providers | The provider's machines | Daytona, E2B, Modal, Vercel, Docker and others are listed | | `runtimeTools(sbx)` | A Runtime microVM your code created | Ordinary tools on the agent; no workspace needed | Native isolation still runs on your host's kernel and lets the code read the host's files. A Runtime sandbox holds nothing of the host: the model's code sees only what you write into it. ## Per-user sandboxes A Mastra app often serves many users. Give each user a named sandbox so their files survive between requests, and let it pause when they go quiet: ```ts check import { Sandbox } from "withruntime"; import { runtimeTools } from "withruntime/ai"; export async function toolsFor(userId: string) { const sbx = await Sandbox.getOrCreate(`user-${userId}`, { idlePauseSeconds: 600, maxCostMicros: 50_000, }); return runtimeTools(sbx, { timeoutSeconds: 120 }); } ``` `Sandbox.getOrCreate` returns the same sandbox for the same name, woken if it was paused ([sandboxes by name](/docs/javascript#sandboxes-by-name)). After ten idle minutes it pauses with files, memory and processes kept, and compute billing stops. Build the agent with `tools: await toolsFor(userId)` in the request handler. ## What else your code can do with the sandbox - **Previews.** `sbx.previews.create(3000)` shares an app the agent started at a private HTTPS address under `runtimehost.com` ([share a port](/docs/javascript#share-a-port)). - **Forks.** `sbx.fork({ count: 2 })` makes two running copies with memory included, for a workflow step that tries two approaches at once. - **Images.** Build a [custom image](/docs/images) with your toolchain and create sandboxes from it, so the agent's first command does not wait on an install. - **Docker.** `sudo enable-docker` inside the sandbox runs containers the agent builds ([run Docker in a sandbox](/how-to/run-docker-in-a-sandbox)). ## Keep keys and spending safe - **The model key** stays with Mastra in your server process; the sandbox gets only commands and file contents. - **`maxCostMicros`** at create refuses a sandbox whose first lease would cost more than that many microdollars. - **A daily spending limit** on the Runtime key bounds all users' sandboxes together: a create or wake past it fails with `spending_limit_reached`, and nothing is charged ([read-only keys and daily limits](/docs/security#read-only-keys-and-daily-limits)). - **A read-only key** for an admin dashboard sees every sandbox and its cost and can change nothing. - **Network rules** at create, such as `network: { internet: true, allow: ["registry.npmjs.org"] }`, bind root in the sandbox because the host enforces them. - **Secrets** for services the agent's code calls: the sandbox holds a placeholder, and the host adds the value on HTTPS requests to the hosts you name ([secrets](/docs/security#secrets-sandboxes-never-see)). ## What it costs CPU is billed as used, $0.025 per vCPU-hour with a floor of 50 millicores, and reserved memory at $0.0075 per GiB-hour. With both CPUs busy, 2 vCPU and 4 GiB is $0.08 an hour, and a paused user sandbox pays only storage ([pricing](/docs/pricing)). New accounts get 50 free sandbox hours, no card. The same tools in the AI SDK directly are in [Vercel AI SDK](/integrations/vercel-ai-sdk), and per-user machines at scale are in [per-user dev environments](/use-cases/per-user-dev-environments). ## Sources Checked 25 September 2026. - [Mastra sandboxes](https://mastra.ai/docs/sandbox/overview): workspaces, the provider list and the `LocalSandbox` warning - [Mastra LocalSandbox reference](https://mastra.ai/reference/workspace/local-sandbox): the `isolation` levels and their limits - [Mastra Agent.generate](https://mastra.ai/reference/agents/generate): `maxSteps` and `response.text` - [Mastra Anthropic models](https://mastra.ai/models/providers/anthropic): the `anthropic/claude-sonnet-4-6` id - [@mastra/core on npm](https://www.npmjs.com/package/@mastra/core): version 1.71.0, which exports `@mastra/core/agent` Facts on this page were checked on 25 September 2026.