Skip to content

Agents

Runra Sandbox is designed from the ground up to be the execution environment for AI agents. Whether you are running Claude Code, Codex, OpenCode, or building your own agent, Runra provides the secure, stateful workspace your agents need.

AI agents that write and execute code need a safe place to operate. Without sandboxing, an agent running on your local machine can:

  • Modify files outside its intended workspace
  • Access sensitive environment variables
  • Consume unbounded CPU and memory
  • Open network connections to arbitrary hosts

Runra Sandbox gives each agent a VM-backed isolated workspace with hard resource limits, network controls, and a full lifecycle — so agents can be powerful without being dangerous.

Claude Code is Anthropic’s official CLI agent. Runra provides a dedicated Claude Code adapter that routes all tool invocations into a sandbox:

import { Runra } from "@runra/sdk";
import { ClaudeCodeAdapter } from "@runra/runtime/agents";
const runra = new Runra({
sandbox: { provider: "runra-sandbox", apiKey: process.env.RUNRA_API_KEY },
});
const agent = new ClaudeCodeAdapter({
runra,
model: "claude-sonnet-4-20250514",
sandboxConfig: {
image: "node:22",
resources: { cpu: 4, memoryMb: 8192 },
},
});
await agent.run("Refactor the auth module and run all tests");

The adapter intercepts Bash, Write, Edit, and Read tools, redirecting them into the sandbox so the agent never touches your local filesystem.

Codex is OpenAI’s open-source CLI agent. Runra’s Codex adapter works similarly:

import { CodexAdapter } from "@runra/runtime/agents";
const agent = new CodexAdapter({
runra,
model: "gpt-4.1",
sandboxConfig: {
image: "python:3.12",
resources: { cpu: 2, memoryMb: 4096 },
},
});
await agent.run("Build a FastAPI endpoint for user authentication");

OpenCode is a general-purpose open-source CLI agent. Runra integrates with OpenCode via the same adapter pattern:

import { OpenCodeAdapter } from "@runra/runtime/agents";
const agent = new OpenCodeAdapter({
runra,
model: "claude-sonnet-4-20250514",
sandboxConfig: {
image: "node:22",
resources: { cpu: 4, memoryMb: 8192 },
timeoutMs: 600_000, // 10-minute timeout
},
});
await agent.run("Migrate this project from Express to Fastify");

Building your own agent? The Runra sandbox is just a programmable workspace. You can use the SDK directly to give your agent a safe execution environment:

const sandbox = await runra.sandboxes.create({
image: "node:22",
resources: { cpu: 2, memoryMb: 4096 },
});
// Your agent's tool-calling loop
async function agentStep(sandbox, instruction) {
const result = await sandbox.exec(instruction.command);
await sandbox.files.write(instruction.filePath, instruction.content);
return result;
}

CLI-based agents (Claude Code, Codex, OpenCode, Aider, etc.) run as terminal processes. With Runra, you can give them a sandboxed environment transparently:

Terminal window
# Run Claude Code in a Runra sandbox
npx @runra/cli agent run \
--agent claude-code \
--image node:22 \
--cpu 4 \
--memory 8192 \
"Build a REST API for the task manager"

This spins up a sandbox, mounts the current directory, and runs the CLI agent inside it. All file operations, shell commands, and processes stay in the sandbox.

For agents that use OpenAI-style tool calling, Runra provides sandbox-backed tool implementations:

const tools = runra.createSandboxTools(sandbox);
// Tools exposed to your LLM:
// - sandbox_exec(command, timeout?)
// - sandbox_read_file(path)
// - sandbox_write_file(path, content)
// - sandbox_list_files(directory?)
// - sandbox_search_code(pattern, path?)
// - sandbox_start_process(command, env?)
// - sandbox_expose_port(port)
const response = await openai.chat.completions.create({
model: "gpt-4.1",
messages: [{ role: "user", content: "Create a React component for a login form" }],
tools,
tool_choice: "auto",
});

Each tool invocation is executed inside the sandbox, with full isolation and resource controls.

Agents often need to work across multiple sessions. Runra’s pause/resume feature preserves the entire workspace state:

// Session 1: Agent starts work
const sandbox = await runra.sandboxes.create({ image: "node:22" });
await agent.run("Clone the repo and start refactoring");
// Pause preserves the full workspace
await sandbox.pause();
// Session 2: Agent resumes where it left off
const resumed = await runra.sandboxes.resume(sandbox.id);
await agent.run("Continue the refactoring and run tests");

See Pause & Resume for details.

Run multiple agents in parallel, each in its own sandbox:

const tasks = [
{ id: "frontend", instruction: "Build a React dashboard" },
{ id: "backend", instruction: "Build a FastAPI API" },
{ id: "docs", instruction: "Write OpenAPI documentation" },
];
const sandboxes = await Promise.all(
tasks.map((t) =>
runra.sandboxes.create({
image: "node:22",
resources: { cpu: 2, memoryMb: 4096 },
metadata: { taskId: t.id },
})
)
);
const results = await Promise.all(
sandboxes.map((sb, i) => agent.run(tasks[i].instruction, { sandbox: sb }))
);
  • Per-sandbox credentials: Use sandbox-scoped environment variables, never pass your main API keys.
  • Network egress control: Configure network policies to allow or deny outbound access per sandbox.
  • Timeout enforcement: Always set timeoutMs on sandboxes to prevent runaway agents.
  • Audit via observability: Export exec events to track every command an agent runs.