A stupidly simple open-source agent SDK with pluggable brains and sandboxes.
Think of it as "IaC for agents" - declare your providers and go.
import { Agent } from "open-agent-sdk";
import { ClaudeCodeBrain } from "open-agent-sdk/brains/claude-code";
import { E2BSandbox } from "open-agent-sdk/sandboxes/e2b";
const agent = new Agent({
brain: new ClaudeCodeBrain(),
sandbox: new E2BSandbox(),
});
for await (const event of agent.run("Analyze this repo and fix the bug")) {
console.log(event);
}Every SaaS app shipping an embedded agent needs:
- A brain (the reasoning engine - Claude Code, Codex, etc.)
- A sandbox (isolated execution - E2B, Docker, Modal, etc.)
- Pluggability (swap providers without rewriting code)
This SDK gives you a simple abstraction layer. Bring your own brain, bring your own sandbox.
npm install open-agent-sdkYou'll also need a brain. Currently supported:
npm install @anthropic-ai/claude-agent-sdk # For ClaudeCodeBrainAnd optionally a sandbox:
npm install @e2b/code-interpreter # For E2BSandboximport { Agent } from "open-agent-sdk";
import { ClaudeCodeBrain } from "open-agent-sdk/brains/claude-code";
const agent = new Agent({
brain: new ClaudeCodeBrain({
allowedTools: ["Read", "Glob", "Grep", "Bash"],
}),
});
for await (const event of agent.run("What files are in this directory?")) {
if (event.type === "message") {
console.log(event.content);
}
}import { Agent } from "open-agent-sdk";
import { ClaudeCodeBrain } from "open-agent-sdk/brains/claude-code";
import { E2BSandbox } from "open-agent-sdk/sandboxes/e2b";
const agent = new Agent({
brain: new ClaudeCodeBrain({
permissionMode: "bypassPermissions", // Safe in sandbox
}),
sandbox: new E2BSandbox({
template: "base",
}),
});
for await (const event of agent.run("Create and run a Python script")) {
console.log(event);
}
// Sandbox is automatically cleaned upconst agent = new Agent({
brain: new ClaudeCodeBrain(),
hooks: {
onStart: () => console.log("Started"),
onToolUse: (e) => console.log(`Using: ${e.toolName}`),
onMessage: (e) => console.log(e.content),
onDone: (e) => console.log(`Done! Tokens: ${e.usage?.inputTokens}`),
onError: (e) => console.error(e.error),
},
});The orchestrator that ties everything together. It:
- Initializes the sandbox (if provided)
- Runs the brain with your prompt
- Streams events as the agent works
- Cleans up the sandbox when done
The reasoning engine. Implements the AgentBrain interface:
interface AgentBrain {
readonly name: string;
run(prompt: string, options?: BrainRunOptions): AsyncIterable<AgentEvent>;
abort(): void;
}Available brains:
ClaudeCodeBrain- Wraps the Claude Agent SDKCodexBrain- OpenAI Codex CLI agent
Coming soon:
OpenCodeBrain- Open source coding agents
Isolated execution environment. Implements the Sandbox interface:
interface Sandbox {
readonly name: string;
create(): Promise<void>;
destroy(): Promise<void>;
exec(command: string, options?: ExecOptions): Promise<ExecResult>;
writeFile(path: string, content: string | Buffer): Promise<void>;
readFile(path: string): Promise<string>;
listFiles(path: string): Promise<string[]>;
exists(path: string): Promise<boolean>;
}Available sandboxes:
LocalSandbox- Direct local execution (no isolation)E2BSandbox- Secure cloud sandbox via E2B
Coming soon:
DockerSandbox- Local Docker containersModalSandbox- Modal cloud functionsFlyMachineSandbox- Fly.io machines
new ClaudeCodeBrain({
model: "claude-sonnet-4-20250514", // Model to use
allowedTools: ["Read", "Edit", "Bash"], // Tools the agent can use
permissionMode: "acceptEdits", // "default" | "acceptEdits" | "bypassPermissions"
mcpServers: { // MCP servers to connect
playwright: { command: "npx", args: ["@playwright/mcp@latest"] }
},
});new CodexBrain({
model: "o4-mini", // Model to use (default: "o4-mini")
approvalMode: "full-auto", // "suggest" | "auto-edit" | "full-auto"
apiKey: "...", // Or set OPENAI_API_KEY env var
});new E2BSandbox({
template: "base", // E2B template name
apiKey: "...", // Or set E2B_API_KEY env var
timeout: 60000, // Sandbox creation timeout (ms)
});One of the key benefits of pluggable brains is automatic failover. If your primary brain provider (e.g., Anthropic) experiences downtime, you can seamlessly switch to a backup brain (e.g., Codex) without changing your agent logic.
import { Agent, AgentBrain } from "open-agent-sdk";
import { ClaudeCodeBrain } from "open-agent-sdk/brains/claude-code";
import { CodexBrain } from "open-agent-sdk/brains/codex";
function createBrainWithFailover(): AgentBrain {
// Try Claude first, fall back to Codex if unavailable
if (process.env.ANTHROPIC_API_KEY && !process.env.FORCE_CODEX) {
return new ClaudeCodeBrain({
allowedTools: ["Read", "Write", "Edit", "Bash"],
});
}
// Fallback to Codex
return new CodexBrain({
model: "o4-mini",
approvalMode: "full-auto",
});
}
const agent = new Agent({
brain: createBrainWithFailover(),
});import { Agent, AgentBrain, AgentEvent } from "open-agent-sdk";
import { ClaudeCodeBrain } from "open-agent-sdk/brains/claude-code";
import { CodexBrain } from "open-agent-sdk/brains/codex";
async function runWithFailover(prompt: string): Promise<void> {
const brains: AgentBrain[] = [
new ClaudeCodeBrain({ allowedTools: ["Read", "Glob", "Grep"] }),
new CodexBrain({ model: "o4-mini", approvalMode: "full-auto" }),
];
for (const brain of brains) {
try {
const agent = new Agent({ brain });
for await (const event of agent.run(prompt)) {
if (event.type === "error" && !event.recoverable) {
throw event.error;
}
// Process events...
}
return; // Success, exit
} catch (error) {
console.warn(`${brain.name} failed, trying next brain...`);
continue;
}
}
throw new Error("All brains failed");
}async function selectHealthyBrain(): Promise<AgentBrain> {
// Check Anthropic API health
const anthropicHealthy = await checkAnthropicHealth();
if (anthropicHealthy) {
return new ClaudeCodeBrain();
}
// Check OpenAI API health
const openaiHealthy = await checkOpenAIHealth();
if (openaiHealthy) {
return new CodexBrain();
}
throw new Error("No healthy brain providers available");
}
async function checkAnthropicHealth(): Promise<boolean> {
try {
const response = await fetch("https://status.anthropic.com/api/v2/status.json");
const data = await response.json();
return data.status?.indicator === "none";
} catch {
return false;
}
}
async function checkOpenAIHealth(): Promise<boolean> {
try {
const response = await fetch("https://status.openai.com/api/v2/status.json");
const data = await response.json();
return data.status?.indicator === "none";
} catch {
return false;
}
}This pattern ensures your agents remain operational even during provider outages.
The agent emits events as it works:
| Event | Description |
|---|---|
start |
Agent began execution |
message |
Text message from assistant or user |
tool_use |
Agent is invoking a tool |
tool_result |
Tool returned a result |
error |
An error occurred |
done |
Agent finished (includes token usage) |
import { AgentBrain, AgentEvent, BrainRunOptions } from "open-agent-sdk";
class MyBrain implements AgentBrain {
readonly name = "my-brain";
async *run(prompt: string, options?: BrainRunOptions): AsyncIterable<AgentEvent> {
yield { type: "start", timestamp: Date.now() };
// Your agent logic here...
yield { type: "message", timestamp: Date.now(), content: "Hello!", role: "assistant" };
yield { type: "done", timestamp: Date.now() };
}
abort(): void {
// Handle abort
}
}import { Sandbox, ExecResult, ExecOptions } from "open-agent-sdk";
class MySandbox implements Sandbox {
readonly name = "my-sandbox";
async create(): Promise<void> {
// Initialize your sandbox
}
async destroy(): Promise<void> {
// Clean up
}
async exec(command: string, options?: ExecOptions): Promise<ExecResult> {
// Execute command
return { exitCode: 0, stdout: "", stderr: "" };
}
// ... implement other methods
}| Variable | Description |
|---|---|
ANTHROPIC_API_KEY |
Required for ClaudeCodeBrain |
OPENAI_API_KEY |
Required for CodexBrain |
E2B_API_KEY |
Required for E2BSandbox |
See the examples/ directory:
basic.ts- Simple local usagewith-e2b.ts- Secure cloud sandboxcode-reviewer.ts- Code review agenttest-code-reviewer.ts- Test code reviewer with both Claude and Codex brains
Run examples:
npx tsx examples/basic.ts "What files are here?"
npx tsx examples/with-e2b.ts "Create a Python script"
npx tsx examples/code-reviewer.ts src/agent.ts
npx tsx examples/test-code-reviewer.ts src/agent.ts # Tests both brainsMIT