The TypeScript Agent SDK provides a fully typed interface to the Claude Code agent loop. All APIs use Promises and async/await. Types are exported from the package root.
npm install @anthropic-ai/agent-sdk # Requires Node.js 18+ or Deno 1.40+ # ANTHROPIC_API_KEY must be set in the environment
import { ClaudeAgent, type ClaudeAgentOptions } from "@anthropic-ai/agent-sdk";
const agent = new ClaudeAgent({
model: "claude-opus-4-8", // required: model ID string
allowedTools: ["Read", "Write", "Bash"], // optional: whitelist tools
deniedTools: ["Bash"], // optional: blacklist (overrides allowedTools)
maxTokens: 8192, // optional: max tokens per response turn
} satisfies ClaudeAgentOptions);
import { type AgentResult } from "@anthropic-ai/agent-sdk";
const result: AgentResult = await agent.run(
"List all TypeScript files and count lines in each."
);
console.log(result.text); // string: final text response
console.log(result.stopReason); // "end_turn" | "tool_use" | "max_tokens"
console.log(result.usage); // { inputTokens: number, outputTokens: number }
import { type StreamEvent } from "@anthropic-ai/agent-sdk";
for await (const event of agent.runStream("Explain the project structure.")) {
if (event.type === "text_delta") {
process.stdout.write(event.text);
} else if (event.type === "tool_use") {
console.log(`\n[Tool: ${event.toolName}]`);
} else if (event.type === "stop") {
console.log(`\nStop reason: ${event.stopReason}`);
}
}
import { type Session } from "@anthropic-ai/agent-sdk";
// Create a session that persists conversation history
const session: Session = await agent.createSession();
const r1 = await session.run("What files are in src/?");
const r2 = await session.run("Now summarize the largest one.");
// Persist the session ID (string) and resume later
const sessionId: string = session.id;
const restored = await agent.resumeSession(sessionId);
const r3 = await restored.run("Continue from before.");
import { type UsageSummary } from "@anthropic-ai/agent-sdk";
const usage: UsageSummary = await agent.getUsage();
console.log(usage);
// => { totalInputTokens: 12400, totalOutputTokens: 3100,
// totalCostUsd: 0.187, sessionCount: 3 }
import { type ToolDefinition } from "@anthropic-ai/agent-sdk";
agent.addTool({
name: "search_kb",
description: "Search the internal knowledge base",
inputSchema: {
type: "object",
properties: {
query: { type: "string", description: "Search query" },
},
required: ["query"],
},
handler: async (input: { query: string }): Promise<string> => {
return `Results for: ${input.query}`;
},
} satisfies ToolDefinition);
import { type ToolCallContext, type ToolResultContext } from "@anthropic-ai/agent-sdk";
agent.beforeTool(async (ctx: ToolCallContext) => {
console.log(`[BEFORE] ${ctx.toolName}:`, ctx.toolInput);
// Return modified toolInput to transform the call, or undefined to pass through
return ctx.toolInput;
});
agent.afterTool(async (ctx: ToolResultContext) => {
console.log(`[AFTER] ${ctx.toolName} ->`, ctx.toolOutput);
});
import { type SubagentOptions, type AgentResult } from "@anthropic-ai/agent-sdk";
const subResult: AgentResult = await agent.spawnSubagent(
"Audit all SQL queries in src/ for injection vulnerabilities.",
{
allowedTools: ["Read", "Bash"],
model: "claude-sonnet-4-6", // optional: cheaper model for sub-tasks
} satisfies SubagentOptions
);
console.log(subResult.text);