# How to run an AI SDK HarnessAgent in a Runtime sandbox Pass `createRuntimeSandbox()` as the `HarnessAgent`'s `sandbox`, and Claude Code, Codex or Pi runs its whole loop in a microVM. **The agent definition stays the same: only the `sandbox` line changes, and the microVM costs $0.03125 an hour for 2 vCPU and 4 GiB while the harness waits on its model.** `HarnessAgent` from `@ai-sdk/harness` runs a coding agent's own loop, with its bootstrap, its bridge and every shell command, in whatever sandbox provider it is given. Runtime's provider gives each session a Firecracker microVM with its own Linux kernel. `@ai-sdk/harness` 1.0.124 was the current npm release on 25 September 2026, and on that day the provider passed all 19 checks of its end-to-end script against production sandboxes in 12.6 seconds. ## Install ```bash no-run npm install withruntime @ai-sdk/harness @ai-sdk/harness-claude-code npx withruntime login ``` The login opens a browser approval and saves the key on the machine. A deployed app sets `RUNTIME_API_KEY` instead. Swap `@ai-sdk/harness-claude-code` for the harness package you use. ## One session, one turn ```ts check import { HarnessAgent, type HarnessAgentAdapter } from "@ai-sdk/harness/agent"; import { createRuntimeSandbox } from "withruntime/ai-harness"; export async function reviewRepo(harness: HarnessAgentAdapter) { const agent = new HarnessAgent({ harness, sandbox: createRuntimeSandbox({ ports: [4000] }), instructions: "Read the repository and list its three riskiest functions.", }); const session = await agent.createSession(); try { const result = await agent.generate({ session, prompt: "Start with src/." }); return result.text; } finally { await session.destroy(); } } ``` `harness` is the adapter from the harness package, such as `claudeCode` from `@ai-sdk/harness-claude-code`. Bridge harnesses (Claude Code, Codex, OpenCode, Deep Agents) reach a bridge process in the sandbox over a WebSocket on the first port in `ports`; Pi runs on the host and needs none. `session.destroy()` stops the machine, so billing ends with the session. ## What the live run exercised The script drives a real `HarnessAgent` with a scripted harness adapter, so no model is called and every step is repeatable: | Step | What was checked against a production sandbox | | ----------------- | ------------------------------------------------------------------------------------------------ | | Session and turn | Create, the bootstrap recipe, env, working directory, stdin, a timeout, file I/O | | Port for a bridge | A private preview reached over HTTPS with its token, and by WebSocket with the token in a header | | Network policy | `deny-all` refuses an outbound request; `allow-all` brings it back | | Pause and resume | `pauseOnStop` pauses; `resumeFrom` wakes the same machine with its files | | Destroy | The sandbox reads `stopped`, and nothing carrying the run's label is left running | ## Keep a session between requests A chat app that answers one turn per HTTP request can keep the same machine for a user: - **Name it.** `agent.createSession({ sessionId: "user-42" })` names the sandbox `ai-harness-user-42`. - **Pause instead of stopping.** `createRuntimeSandbox({ pauseOnStop: true })` makes `session.stop()` pause: memory, processes and files are kept, and only paused storage is billed ([paused storage](/docs/pricing#paused-storage)). - **Resume.** `agent.createSession({ sessionId: "user-42", resumeFrom })` wakes that machine where it left off. Without `pauseOnStop`, `session.stop()` stops the sandbox, the default for batch jobs that should leave nothing behind. ## Keys and limits - **The model key** stays with the harness configuration you pass; Runtime sees commands and files. - **A refused Runtime key** raises the AI SDK's `HarnessSandboxAuthenticationError`, so an app can tell a configuration mistake from an outage. - **`create`** sets the machine: `vcpu`, `memoryMiB`, `image`, `network` and the lease, as `Sandbox.create` takes them. - **A daily spending limit** on the key bounds every session together ([daily limits](/docs/security#read-only-keys-and-daily-limits)). ## What it costs CPU is billed as used at $0.025 per vCPU-hour, with a floor of 50 millicores, and reserved memory at $0.0075 per GiB-hour. A harness spends most of a turn waiting for model tokens, near the floor; a turn that compiles and tests keeps both CPUs busy at $0.08 an hour for 2 vCPU and 4 GiB ([pricing](/docs/pricing)). New accounts get 100 free sandbox hours without a card. The full option table is in the [Vercel AI SDK guide](/docs/vercel-ai-sdk). To give a plain `generateText` call four sandbox tools instead of a whole harness, see [Vercel AI SDK tools](/integrations/vercel-ai-sdk); the harnesses on their own are in [Claude Code](/integrations/claude-code), [Codex](/integrations/codex) and [OpenCode](/integrations/opencode). ## Sources Checked 25 September 2026. - [AI SDK HarnessAgent](https://ai-sdk.dev/docs/ai-sdk-harnesses/harness-agent): the `sandbox` option, sessions and `resumeFrom` - [@ai-sdk/harness on npm](https://www.npmjs.com/package/@ai-sdk/harness): version 1.0.124 - [withruntime on npm](https://www.npmjs.com/package/withruntime): version 0.6.1, which exports `withruntime/ai-harness` Facts on this page were checked on 25 September 2026.