Skip to content

Claude Agent SDK (TypeScript) - Comprehensive Technical Guide

Latest: 0.2.128 | Updated: May 5, 2026

Claude Agent SDK (TypeScript) - Comprehensive Technical Guide

Section titled “Claude Agent SDK (TypeScript) - Comprehensive Technical Guide”

Table of Contents


The Claude Agent SDK is the official TypeScript library for building autonomous AI agents powered by Claude models. Install it using npm or yarn:

Terminal window
npm install @anthropic-ai/claude-agent-sdk

Or with yarn:

Terminal window
yarn add @anthropic-ai/claude-agent-sdk

For the latest version with beta features:

Terminal window
npm install @anthropic-ai/claude-agent-sdk@latest

TypeScript Configuration and tsconfig.json Setup

Section titled “TypeScript Configuration and tsconfig.json Setup”

Configure your TypeScript project for optimal compatibility with the Claude Agent SDK. Create or update your tsconfig.json with the following comprehensive configuration:

{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020"],
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./src",
"isolatedModules": true,
"noEmit": false,
"preserveConstEnums": true,
"allowSyntheticDefaultImports": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialisation": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"types": ["node"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}

This configuration ensures:

  • Strict type checking for maximum type safety
  • ES2020 target for modern JavaScript features
  • Module support for both CommonJS and ESM environments
  • Declaration files for TypeScript consumers
  • Source maps for debugging
  • Comprehensive error checking with noUnused* options

Evolution from Claude Code SDK to Claude Agent SDK

Section titled “Evolution from Claude Code SDK to Claude Agent SDK”

The Claude Agent SDK represents the evolution and expansion of the Claude Code SDK. The transition reflects Anthropic’s shift towards a more generalised agent framework capable of handling diverse workflows beyond code-centric tasks.

Key Migration Points:

  1. Package Name Change: @anthropic-ai/claude-code@anthropic-ai/claude-agent-sdk
  2. Enhanced Capabilities: Extended from code-focused operations to general automation, research, analysis, and system orchestration
  3. Improved Architecture: Built on a refined harness supporting multiple authentication backends (Claude API, Amazon Bedrock, Google Vertex AI)
  4. Better Type System: Enhanced TypeScript definitions with comprehensive generic support
  5. Advanced Features: Subagent orchestration, dynamic tool loading, enhanced context management

For existing Claude Code SDK users migrating to the Agent SDK:

// OLD - Claude Code SDK
import { code } from "@anthropic-ai/claude-code";
// NEW - Claude Agent SDK
import { query } from "@anthropic-ai/claude-agent-sdk";
// The query() function replaces code() with enhanced functionality
const response = query({
prompt: "Your task here",
options: {
model: "claude-sonnet-4-5",
// Additional configuration options
}
});
for await (const message of response) {
// Process messages
}

Architecture Overview: Built on Claude Code’s Harness

Section titled “Architecture Overview: Built on Claude Code’s Harness”

The Claude Agent SDK is constructed upon the proven agent harness that powers Claude Code, Anthropic’s terminal-based AI coding assistant. This architecture provides:

Foundation Components:

  1. Agent Execution Engine: Manages the core agent loop, handling message processing, tool invocations, and response generation
  2. Context Management System: Sophisticated handling of conversation context with automatic compaction for extended interactions (supports 200K token context window)
  3. Tool Execution Framework: Coordinates execution of built-in tools (file operations, command execution, web search) and custom MCP tools
  4. Permission Layer: Fine-grained access control system enabling developers to define security boundaries
  5. Session State Manager: Maintains conversation state, enabling session resumption and forking

Key Architectural Principles:

  • Streaming-First Design: All interactions support real-time streaming for responsive user experiences
  • Type Safety: Complete TypeScript support with Zod schema integration for runtime validation
  • Modularity: Extensible tool system supporting custom tools via Model Context Protocol (MCP)
  • Resilience: Automatic error recovery, context compaction, and graceful degradation
  • Observability: Built-in support for monitoring, logging, and audit trails

Agents: Autonomous entities that interpret user instructions, reason about tasks, and execute actions. Agents maintain state throughout a session and can coordinate with other agents for complex workflows. Each agent instance has its own context, permissions, and execution environment.

// Conceptual agent representation
interface Agent {
id: string;
name: string;
model: string;
systemPrompt: string;
context: ConversationMessage[];
permissions: PermissionPolicy;
tools: ToolDefinition[];
sessionId?: string;
}

Tools: Capabilities that agents can invoke to perform actions. The SDK includes built-in tools (Read, Write, Edit, Delete, Bash, WebSearch, Grep, Glob) and supports custom tools via MCP integration. Tools have:

  • Input Schemas: Zod schemas defining parameters
  • Output Contracts: Type-safe return value specifications
  • Permission Requirements: Access control specifications
  • Error Handling: Graceful failure modes

Context: The accumulated state of an agent session, including:

  • Previous messages (user and assistant)
  • Tool execution history
  • Current working directory
  • Environment variables
  • File system state
  • Conversation metadata

The SDK automatically manages context to stay within token limits through intelligent compaction.

Sessions: Individual instances of agent-user interaction. Sessions maintain all context necessary to resume conversations. Key session features:

  • Session ID: Unique identifier for resumption
  • State Persistence: Capability to pause and resume
  • Forking: Create alternative conversation branches
  • Isolation: Sessions don’t interfere with each other

Permissions: Access control policies defining what actions agents can perform. The permission system supports:

  • Global Modes: acceptEdits, default, bypassPermissions
  • Per-Tool Policies: Custom rules for specific tools
  • Permission Callbacks: Dynamic permission evaluation
  • Audit Logging: Track all permission decisions

The Claude Agent SDK supports multiple Claude models, each optimised for different use cases:

Available Models:

type SupportedModel =
| 'claude-opus'
| 'claude-sonnet-4-5'
| 'claude-3-5-sonnet'
| 'claude-3-5-haiku'
| 'claude-4-turbo' // When available
| 'claude-3-opus';
interface ModelConfiguration {
model: SupportedModel;
maxTokens?: number; // Max output tokens
temperature?: number; // 0-1, default 1.0
topP?: number; // Top-p sampling, 0-1
topK?: number; // Top-k sampling
}

Model Selection Guide:

  1. Claude 4.5 Sonnet (Recommended for most use cases):

    • Superior reasoning for complex tasks
    • Best performance on multi-step reasoning
    • Excellent tool use and planning
    • Recommended context window: Full 200K tokens
    const options: ModelConfiguration = {
    model: 'claude-sonnet-4-5',
    maxTokens: 8192,
    temperature: 1.0
    };
  2. Claude 3.5 Sonnet (Balanced performance):

    • Strong reasoning with lower latency
    • Good for code generation and analysis
    • Cost-effective for most workloads
    const options: ModelConfiguration = {
    model: 'claude-3-5-sonnet',
    maxTokens: 4096,
    temperature: 0.8
    };
  3. Claude 3.5 Haiku (Fast, lightweight):

    • Fastest response times
    • Lower token costs
    • Suitable for simple tasks and streaming
    const options: ModelConfiguration = {
    model: 'claude-3-5-haiku',
    maxTokens: 2048,
    temperature: 1.0
    };
  4. Claude Opus (High capability):

    • Maximum reasoning capability
    • Best for extremely complex problems
    • Higher latency and cost
    const options: ModelConfiguration = {
    model: 'claude-opus',
    maxTokens: 8192,
    temperature: 0.7
    };

Secure API key management is critical for production deployments.

Environment-Based Setup (Recommended):

Terminal window
# .env file
ANTHROPIC_API_KEY=sk-ant-...your-key-here...
# Export for shell session
export ANTHROPIC_API_KEY="sk-ant-...your-key-here..."
# Windows PowerShell
$env:ANTHROPIC_API_KEY="sk-ant-...your-key-here..."

TypeScript Implementation:

import { query } from '@anthropic-ai/claude-agent-sdk';
import dotenv from 'dotenv';
// Load environment variables
dotenv.config();
// Access API key from environment
const apiKey = process.env.ANTHROPIC_API_KEY;
if (!apiKey) {
throw new Error('ANTHROPIC_API_KEY environment variable not set');
}
// Use in queries
const response = query({
prompt: 'Analyse this codebase',
options: {
model: 'claude-sonnet-4-5',
apiKey: apiKey // Optional: defaults to env var if not provided
}
});

Advanced Authentication Patterns:

// Type-safe API key management
class ApiKeyManager {
private static instance: ApiKeyManager;
private apiKey: string;
private constructor() {
this.apiKey = this.loadApiKey();
}
private loadApiKey(): string {
const envKey = process.env.ANTHROPIC_API_KEY;
if (!envKey) {
throw new Error(
'ANTHROPIC_API_KEY not found. ' +
'Set it in your environment or .env file'
);
}
return envKey;
}
static getInstance(): ApiKeyManager {
if (!ApiKeyManager.instance) {
ApiKeyManager.instance = new ApiKeyManager();
}
return ApiKeyManager.instance;
}
getApiKey(): string {
return this.apiKey;
}
validateApiKey(): boolean {
// Validate key format
return this.apiKey.startsWith('sk-ant-') && this.apiKey.length > 20;
}
}
// Usage
const keyManager = ApiKeyManager.getInstance();
if (!keyManager.validateApiKey()) {
throw new Error('Invalid API key format');
}

Alternative Authentication Methods:

// Amazon Bedrock Authentication
const bedrockResponse = query({
prompt: 'Your task',
options: {
model: 'claude-sonnet-4-5',
auth: {
type: 'bedrock',
region: 'us-west-2',
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
}
}
}
});
// Google Vertex AI Authentication
const vertexResponse = query({
prompt: 'Your task',
options: {
model: 'claude-sonnet-4-5',
auth: {
type: 'vertex',
projectId: process.env.GOOGLE_PROJECT_ID,
region: 'us-central1'
}
}
});

SDK Initialization Patterns with TypeScript

Section titled “SDK Initialization Patterns with TypeScript”

Basic Initialization:

import { query } from '@anthropic-ai/claude-agent-sdk';
// Simplest initialization - uses environment variables
const response = query({
prompt: 'Analyse this code for security vulnerabilities'
});
for await (const message of response) {
console.log(message);
}

Comprehensive Initialization with Full Type Safety:

import { query } from '@anthropic-ai/claude-agent-sdk';
import type {
QueryOptions,
QueryMessage,
QueryResponse,
PermissionMode,
ToolDefinition
} from '@anthropic-ai/claude-agent-sdk';
interface AgentConfig {
model: string;
systemPrompt: string;
temperature: number;
maxTokens: number;
permissionMode: PermissionMode;
workingDirectory: string;
}
class ClaudeAgentInitializer {
private config: AgentConfig;
constructor(config: Partial<AgentConfig> = {}) {
this.config = {
model: config.model ?? 'claude-sonnet-4-5',
systemPrompt: config.systemPrompt ?? 'You are a helpful assistant.',
temperature: config.temperature ?? 1.0,
maxTokens: config.maxTokens ?? 4096,
permissionMode: config.permissionMode ?? 'default',
workingDirectory: config.workingDirectory ?? process.cwd()
};
}
async initializeAgent(prompt: string): Promise<AsyncGenerator<QueryMessage>> {
const options: QueryOptions = {
model: this.config.model,
systemPrompt: this.config.systemPrompt,
temperature: this.config.temperature,
maxTokens: this.config.maxTokens,
permissionMode: this.config.permissionMode,
workingDirectory: this.config.workingDirectory
};
return query({
prompt: prompt,
options: options
});
}
updateConfig(updates: Partial<AgentConfig>): void {
this.config = { ...this.config, ...updates };
}
}
// Usage
const agentInit = new ClaudeAgentInitializer({
model: 'claude-sonnet-4-5',
systemPrompt: 'You are an expert TypeScript developer',
temperature: 0.7,
workingDirectory: './projects/my-app'
});
const agentStream = await agentInit.initializeAgent(
'Refactor the authentication module'
);
for await (const message of agentStream) {
console.log(message);
}

Factory Pattern Initialization:

import { query } from '@anthropic-ai/claude-agent-sdk';
type AgentType = 'code-review' | 'security-audit' | 'documentation' | 'testing';
class AgentFactory {
private static templates: Record<AgentType, string> = {
'code-review': `You are an expert code reviewer. Provide constructive feedback on:
- Code quality and maintainability
- Design patterns and SOLID principles
- Performance optimisations
- Security considerations
- Test coverage`,
'security-audit': `You are a security expert specialising in:
- Vulnerability identification
- Authentication and authorisation
- Data protection and encryption
- Access control
- Security best practices`,
'documentation': `You are a technical writer focused on:
- Clear, comprehensive documentation
- API documentation
- Usage examples
- Architecture diagrams
- Best practices guides`,
'testing': `You are a QA specialist experienced in:
- Test coverage analysis
- Edge case identification
- Integration testing
- Performance testing
- Test automation`
};
static createAgent(type: AgentType, prompt: string) {
const systemPrompt = this.templates[type];
return query({
prompt: prompt,
options: {
model: 'claude-sonnet-4-5',
systemPrompt: systemPrompt,
temperature: 0.8
}
});
}
}
// Usage
const codeReviewStream = AgentFactory.createAgent(
'code-review',
'Review this authentication service for issues'
);
const securityStream = AgentFactory.createAgent(
'security-audit',
'Audit the payment processing system'
);
const docStream = AgentFactory.createAgent(
'documentation',
'Create API documentation for the user service'
);
const testStream = AgentFactory.createAgent(
'testing',
'Develop comprehensive test cases for the database layer'
);

The Claude Agent SDK provides comprehensive TypeScript definitions ensuring type safety throughout your applications.

Core Type Definitions:

// Message types for agent communication
interface Message {
type: 'assistant' | 'user' | 'system' | 'tool_call' | 'tool_result' | 'error';
content?: string | MessageContent[];
id?: string;
timestamp?: number;
}
interface MessageContent {
type: 'text' | 'tool_use' | 'tool_result' | 'image';
text?: string;
name?: string;
id?: string;
input?: Record<string, unknown>;
result?: string;
image_url?: string;
media_type?: 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp';
}
interface SystemMessage extends Message {
type: 'system';
subtype?: 'init' | 'completion' | 'subagent_start' | 'subagent_end';
session_id?: string;
skills?: string[];
cost?: number;
}
// Query configuration
interface QueryOptions {
model?: SupportedModel;
systemPrompt?: string;
temperature?: number;
maxTokens?: number;
maxBudgetUsd?: number;
permissionMode?: PermissionMode;
workingDirectory?: string;
apiKey?: string;
resume?: string;
forkSession?: boolean;
canUseTool?: ToolPermissionCallback;
mcpServers?: Record<string, McpServerConfig>;
allowedTools?: string[];
agents?: Record<string, SubagentConfig>;
settingSources?: Array<'user' | 'project' | 'local'>;
plugins?: PluginDefinition[];
}
type PermissionMode = 'acceptEdits' | 'default' | 'bypassPermissions';
type ToolPermissionCallback = (
toolName: string,
input: Record<string, unknown>
) => Promise<PermissionDecision>;
interface PermissionDecision {
behavior: 'allow' | 'deny' | 'ask';
message?: string;
}
// Session and budget information
interface SessionInfo {
id: string;
startTime: number;
endTime?: number;
messageCount: number;
tokenUsage: TokenUsage;
costUsd: number;
}
interface TokenUsage {
inputTokens: number;
outputTokens: number;
cacheCreationInputTokens?: number;
cacheReadInputTokens?: number;
totalTokens: number;
}
// Tool definitions
interface ToolDefinition {
name: string;
description: string;
inputSchema: Record<string, unknown>;
outputType?: string;
errorHandler?: (error: Error) => string;
}
// MCP server configuration
interface McpServerConfig {
command?: string;
args?: string[];
env?: Record<string, string>;
url?: string;
headers?: Record<string, string>;
}
// Subagent configuration
interface SubagentConfig {
description: string;
prompt: string;
tools?: string[];
model?: SupportedModel;
temperature?: number;
}
// Plugin system
interface PluginDefinition {
name: string;
version: string;
initialize?: (context: PluginContext) => Promise<void>;
onToolCall?: (toolName: string, input: unknown) => Promise<void>;
onMessage?: (message: Message) => Promise<void>;
destroy?: () => Promise<void>;
}
interface PluginContext {
agent: Agent;
sessionId: string;
[key: string]: unknown;
}

Advanced Type Patterns:

// Generic types for extensibility
type MessageHandler<T extends Message = Message> = (message: T) => void | Promise<void>;
type AsyncMessageGenerator<T extends Message = Message> = AsyncGenerator<T, void, void>;
// Type-safe tool response
interface ToolResponse<T = unknown> {
success: boolean;
data?: T;
error?: {
code: string;
message: string;
details?: Record<string, unknown>;
};
metadata?: {
executionTime: number;
tokenUsage?: TokenUsage;
tools?: string[];
};
}
// Type-safe event emitter for agent events
type AgentEventMap = {
'session-start': { sessionId: string };
'session-end': { sessionId: string; duration: number };
'tool-call': { toolName: string; input: unknown };
'tool-result': { toolName: string; result: unknown };
'error': { error: Error; context: string };
'message': { message: Message };
'permission-check': { tool: string; decision: PermissionDecision };
};
type AgentEventEmitter = {
on<K extends keyof AgentEventMap>(event: K, handler: (data: AgentEventMap[K]) => void): void;
off<K extends keyof AgentEventMap>(event: K, handler: (data: AgentEventMap[K]) => void): void;
emit<K extends keyof AgentEventMap>(event: K, data: AgentEventMap[K]): void;
};

Creating Basic Claude Agents in TypeScript

Section titled “Creating Basic Claude Agents in TypeScript”

Creating a basic Claude agent involves initialising the SDK with a prompt and processing the async stream of responses.

Minimal Agent Example:

import { query } from '@anthropic-ai/claude-agent-sdk';
async function basicAgent() {
// Start a simple query
const response = query({
prompt: 'What are the benefits of TypeScript for large-scale projects?'
});
// Process streaming responses
for await (const message of response) {
if (message.type === 'assistant') {
console.log('Agent Response:', message.content);
}
}
}
basicAgent();

Practical Agent Implementation:

import { query } from '@anthropic-ai/claude-agent-sdk';
interface AgentOptions {
model?: string;
temperature?: number;
workingDirectory?: string;
}
class SimpleAgent {
private model: string;
private temperature: number;
private workingDirectory: string;
constructor(options: AgentOptions = {}) {
this.model = options.model ?? 'claude-sonnet-4-5';
this.temperature = options.temperature ?? 1.0;
this.workingDirectory = options.workingDirectory ?? process.cwd();
}
async execute(prompt: string): Promise<string> {
const response = query({
prompt: prompt,
options: {
model: this.model,
temperature: this.temperature,
workingDirectory: this.workingDirectory
}
});
let result = '';
for await (const message of response) {
if (message.type === 'assistant') {
result += message.content;
console.log(message.content);
} else if (message.type === 'tool_call') {
console.log(`Tool called: ${message.tool_name}`);
} else if (message.type === 'error') {
console.error('Error:', message.error);
throw new Error(`Agent error: ${message.error}`);
}
}
return result;
}
}
// Usage
const agent = new SimpleAgent({
model: 'claude-sonnet-4-5',
temperature: 0.8,
workingDirectory: './projects/myapp'
});
try {
const result = await agent.execute(
'Analyse the performance characteristics of async/await in TypeScript'
);
console.log('Final Result:', result);
} catch (error) {
console.error('Agent execution failed:', error);
}

System prompts guide the agent’s behaviour and define its personality, expertise, and approach to tasks.

System Prompt Design:

import { query } from '@anthropic-ai/claude-agent-sdk';
// Professional system prompts for different roles
const systemPrompts = {
codeReviewer: `You are an expert senior software engineer specialising in code review.
Your responsibilities:
- Identify potential bugs and security vulnerabilities
- Suggest performance optimisations
- Recommend design pattern improvements
- Ensure adherence to SOLID principles
- Provide constructive, actionable feedback
- Consider edge cases and error handling
Always provide:
1. Summary of findings
2. Severity levels (critical, high, medium, low)
3. Specific code examples
4. Remediation steps with code samples`,
securityAuditor: `You are a cybersecurity expert with deep experience in:
- Web application security
- API security
- Authentication and authorisation mechanisms
- Data protection and encryption
- Infrastructure security
- Compliance requirements
When auditing, always examine:
1. Authentication vulnerabilities
2. Authorisation flaws
3. Input validation gaps
4. SQL injection and XSS vulnerabilities
5. Sensitive data exposure
6. Security misconfigurations
7. Insecure dependencies
Provide risk ratings and remediation guidance.`,
architectureAdvisor: `You are a solutions architect with expertise in:
- Microservices design
- Event-driven architectures
- Scalability patterns
- High availability and disaster recovery
- Technology selection
- Cost optimisation
For architecture reviews, analyse:
1. Component decomposition
2. Communication patterns
3. Data consistency strategies
4. Failure modes and resilience
5. Scaling capabilities
6. Operational complexity`,
performanceOptimiser: `You are a performance engineering expert specialising in:
- Algorithm analysis and optimisation
- Memory management
- Database query optimisation
- Caching strategies
- Async patterns
- Monitoring and profiling
When optimising:
1. Identify bottlenecks with data
2. Analyse algorithmic complexity
3. Profile memory usage
4. Suggest targeted improvements
5. Estimate performance gains
6. Consider trade-offs`
};
// Use specific system prompts
async function executeSpecialisedAgent(role: keyof typeof systemPrompts, task: string) {
const response = query({
prompt: task,
options: {
model: 'claude-sonnet-4-5',
systemPrompt: systemPrompts[role],
temperature: 0.7
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
}
// Usage
executeSpecialisedAgent('codeReviewer', `Review this TypeScript implementation:
\`\`\`typescript
async function fetchUserData(userId: string) {
const response = await fetch(\`/api/users/\${userId}\`);
const data = await response.json();
return data;
}
\`\`\``);

Dynamic System Prompt Construction:

import { query } from '@anthropic-ai/claude-agent-sdk';
interface PromptContext {
expertise: string[];
constraints: string[];
outputFormat: string;
tone: string;
focusAreas: string[];
}
function constructSystemPrompt(context: PromptContext): string {
const expertiseSection = context.expertise.length > 0
? `Your areas of expertise:\n${context.expertise.map(e => `- ${e}`).join('\n')}`
: '';
const constraintsSection = context.constraints.length > 0
? `\nConstraints to follow:\n${context.constraints.map(c => `- ${c}`).join('\n')}`
: '';
const focusSection = context.focusAreas.length > 0
? `\nFocus areas for this analysis:\n${context.focusAreas.map(f => `- ${f}`).join('\n')}`
: '';
const toneSection = `\nCommunication tone: ${context.tone}`;
const outputSection = `\nOutput format: ${context.outputFormat}`;
return `You are an AI assistant with specialised knowledge and expertise.
${expertiseSection}${constraintsSection}${focusSection}${toneSection}${outputSection}
Provide thorough, well-reasoned responses with specific examples.`;
}
// Usage
const reviewContext: PromptContext = {
expertise: [
'TypeScript and advanced type systems',
'React and component architecture',
'Node.js and backend development',
'Testing strategies and frameworks'
],
constraints: [
'Follow SOLID principles',
'Consider backwards compatibility',
'Optimise for readability',
'Minimise external dependencies'
],
outputFormat: 'Structured markdown with code examples',
tone: 'Professional but approachable',
focusAreas: [
'Type safety and generics',
'Error handling patterns',
'Performance implications',
'Maintainability'
]
};
const systemPrompt = constructSystemPrompt(reviewContext);
const response = query({
prompt: 'Review this authentication implementation',
options: {
systemPrompt: systemPrompt,
model: 'claude-sonnet-4-5'
}
});

Execute focused agents that complete specific tasks without multi-turn conversation.

import { query } from '@anthropic-ai/claude-agent-sdk';
interface TaskExecutionResult {
success: boolean;
output: string;
executionTime: number;
tokensUsed?: number;
}
class SingleTaskExecutor {
async execute(prompt: string, timeoutMs: number = 30000): Promise<TaskExecutionResult> {
const startTime = performance.now();
let output = '';
let tokensUsed = 0;
try {
// Create a timeout promise
const timeoutPromise = new Promise<never>((_, reject) => {
setTimeout(() => reject(new Error('Task execution timeout')), timeoutMs);
});
const executePromise = (async () => {
const response = query({
prompt: prompt,
options: {
model: 'claude-sonnet-4-5',
maxTokens: 4096
}
});
for await (const message of response) {
if (message.type === 'assistant') {
output += message.content;
} else if (message.type === 'error') {
throw new Error(`Task error: ${message.error}`);
}
}
})();
await Promise.race([executePromise, timeoutPromise]);
const executionTime = performance.now() - startTime;
return {
success: true,
output,
executionTime,
tokensUsed
};
} catch (error) {
const executionTime = performance.now() - startTime;
return {
success: false,
output: output || '',
executionTime,
tokensUsed
};
}
}
}
// Usage
const executor = new SingleTaskExecutor();
const result = await executor.execute(
'Generate a TypeScript interface definition for a user object with type-safe methods',
30000
);
console.log(`Task completed in ${result.executionTime}ms`);
console.log(`Success: ${result.success}`);
console.log(`Output:\n${result.output}`);

Synchronous and Asynchronous Patterns with async/await

Section titled “Synchronous and Asynchronous Patterns with async/await”

The Claude Agent SDK uses async/await throughout for handling asynchronous operations.

Async Pattern Fundamentals:

import { query } from '@anthropic-ai/claude-agent-sdk';
// Basic async/await pattern
async function basicAsyncAgent() {
try {
const response = query({
prompt: 'Explain closures in JavaScript'
});
// Process all messages
for await (const message of response) {
if (message.type === 'assistant') {
console.log('Response:', message.content);
}
}
} catch (error) {
console.error('Error:', error);
}
}
// Sequential execution of multiple tasks
async function sequentialTasks() {
console.log('Starting task 1...');
const task1Response = query({
prompt: 'Design a database schema for an e-commerce platform'
});
let task1Output = '';
for await (const message of task1Response) {
if (message.type === 'assistant') {
task1Output += message.content;
}
}
console.log('Task 1 complete. Starting task 2...');
const task2Response = query({
prompt: `Based on this schema: ${task1Output}, generate SQL migrations`
});
let task2Output = '';
for await (const message of task2Response) {
if (message.type === 'assistant') {
task2Output += message.content;
}
}
console.log('All tasks complete');
return { task1: task1Output, task2: task2Output };
}
// Parallel execution of independent tasks
async function parallelTasks() {
const task1 = (async () => {
const response = query({ prompt: 'Explain microservices architecture' });
let output = '';
for await (const message of response) {
if (message.type === 'assistant') output += message.content;
}
return output;
})();
const task2 = (async () => {
const response = query({ prompt: 'Explain event-driven architecture' });
let output = '';
for await (const message of response) {
if (message.type === 'assistant') output += message.content;
}
return output;
})();
const task3 = (async () => {
const response = query({ prompt: 'Explain serverless architecture' });
let output = '';
for await (const message of response) {
if (message.type === 'assistant') output += message.content;
}
return output;
})();
// Wait for all tasks to complete
const [arch1, arch2, arch3] = await Promise.all([task1, task2, task3]);
return {
microservices: arch1,
eventDriven: arch2,
serverless: arch3
};
}
// Race pattern - use first result
async function racePattern() {
const task1 = query({ prompt: 'Quick analysis' });
const task2 = query({ prompt: 'Quick analysis' });
const fastestResponse = await Promise.race([task1, task2]);
return fastestResponse;
}
// Allsettled for robustness
async function robustParallelExecution() {
const tasks = [
(async () => {
const response = query({ prompt: 'Task 1' });
return response;
})(),
(async () => {
const response = query({ prompt: 'Task 2' });
return response;
})(),
(async () => {
const response = query({ prompt: 'Task 3' });
return response;
})()
];
const results = await Promise.allSettled(tasks);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Task ${index + 1} succeeded`);
} else {
console.log(`Task ${index + 1} failed: ${result.reason}`);
}
});
return results;
}

Streaming Responses with SSE (Server-Sent Events)

Section titled “Streaming Responses with SSE (Server-Sent Events)”

The Claude Agent SDK streams responses in real-time, allowing for responsive user interfaces and progressive output handling.

Streaming Response Processing:

import { query } from '@anthropic-ai/claude-agent-sdk';
// Basic streaming
async function streamResponses() {
const response = query({
prompt: 'Generate a detailed TypeScript style guide',
options: {
model: 'claude-sonnet-4-5',
maxTokens: 8192
}
});
for await (const message of response) {
switch (message.type) {
case 'assistant':
// Process text responses immediately
process.stdout.write(message.content);
break;
case 'tool_call':
console.log(`\n[Tool Call: ${message.tool_name}]`);
break;
case 'tool_result':
console.log(`\n[Tool Result: ${message.result}]\n`);
break;
case 'error':
console.error(`\n[Error: ${message.error}]\n`);
break;
}
}
}
// Buffered streaming for structured processing
class StreamBufferer {
private buffer: string = '';
private flushInterval: number;
private timer?: NodeJS.Timeout;
constructor(flushIntervalMs: number = 1000) {
this.flushInterval = flushIntervalMs;
}
async processStream(
prompt: string,
onFlush: (data: string) => void
): Promise<string> {
const response = query({ prompt });
return new Promise((resolve, reject) => {
this.scheduleFlush(onFlush);
(async () => {
try {
for await (const message of response) {
if (message.type === 'assistant') {
this.buffer += message.content;
}
}
this.flush(onFlush);
resolve(this.buffer);
} catch (error) {
reject(error);
}
})();
});
}
private scheduleFlush(onFlush: (data: string) => void): void {
this.timer = setInterval(() => {
if (this.buffer.length > 0) {
this.flush(onFlush);
}
}, this.flushInterval);
}
private flush(onFlush: (data: string) => void): void {
if (this.buffer.length > 0) {
onFlush(this.buffer);
this.buffer = '';
}
}
}
// Line-by-line streaming
async function lineByLineStreaming(prompt: string) {
const response = query({ prompt });
let currentLine = '';
for await (const message of response) {
if (message.type === 'assistant') {
for (const char of message.content) {
if (char === '\n') {
console.log(`Line: ${currentLine}`);
currentLine = '';
} else {
currentLine += char;
}
}
}
}
if (currentLine) {
console.log(`Final line: ${currentLine}`);
}
}
// Token counting with streaming
async function countTokensInStream(prompt: string): Promise<number> {
const response = query({ prompt });
let tokenCount = 0;
for await (const message of response) {
if (message.type === 'assistant') {
// Rough estimate: average 4 chars per token
tokenCount += Math.ceil(message.content.length / 4);
}
}
return tokenCount;
}

Monitor token consumption for cost management and optimisation.

import { query } from '@anthropic-ai/claude-agent-sdk';
interface TokenMetrics {
inputTokens: number;
outputTokens: number;
cacheCreationTokens: number;
cacheReadTokens: number;
totalTokens: number;
estimatedCostUsd: number;
}
class TokenTracker {
private metrics: TokenMetrics = {
inputTokens: 0,
outputTokens: 0,
cacheCreationTokens: 0,
cacheReadTokens: 0,
totalTokens: 0,
estimatedCostUsd: 0
};
// Pricing per model (as of 2024)
private pricing = {
'claude-sonnet-4-5': {
input: 0.003,
output: 0.015,
cacheCreation: 0.00375,
cacheRead: 0.0003
},
'claude-3-5-sonnet': {
input: 0.003,
output: 0.015,
cacheCreation: 0.00375,
cacheRead: 0.0003
},
'claude-opus': {
input: 0.015,
output: 0.075,
cacheCreation: 0.01875,
cacheRead: 0.0015
},
'claude-3-5-haiku': {
input: 0.00008,
output: 0.0004,
cacheCreation: 0.0001,
cacheRead: 0.00001
}
};
async trackQuery(
prompt: string,
model: keyof typeof this.pricing = 'claude-sonnet-4-5'
): Promise<{ result: string; metrics: TokenMetrics }> {
const response = query({
prompt,
options: { model }
});
let result = '';
const localMetrics: TokenMetrics = {
inputTokens: 0,
outputTokens: 0,
cacheCreationTokens: 0,
cacheReadTokens: 0,
totalTokens: 0,
estimatedCostUsd: 0
};
for await (const message of response) {
if (message.type === 'assistant') {
result += message.content;
// Count approximate tokens
localMetrics.outputTokens += Math.ceil(message.content.length / 4);
}
}
// Estimate input tokens
localMetrics.inputTokens = Math.ceil(prompt.length / 4);
localMetrics.totalTokens =
localMetrics.inputTokens +
localMetrics.outputTokens +
localMetrics.cacheCreationTokens +
localMetrics.cacheReadTokens;
// Calculate cost
const prices = this.pricing[model];
localMetrics.estimatedCostUsd =
(localMetrics.inputTokens * prices.input) / 1000 +
(localMetrics.outputTokens * prices.output) / 1000 +
(localMetrics.cacheCreationTokens * prices.cacheCreation) / 1000 +
(localMetrics.cacheReadTokens * prices.cacheRead) / 1000;
// Update cumulative metrics
this.metrics.inputTokens += localMetrics.inputTokens;
this.metrics.outputTokens += localMetrics.outputTokens;
this.metrics.totalTokens += localMetrics.totalTokens;
this.metrics.estimatedCostUsd += localMetrics.estimatedCostUsd;
return { result, metrics: localMetrics };
}
getMetrics(): TokenMetrics {
return { ...this.metrics };
}
resetMetrics(): void {
this.metrics = {
inputTokens: 0,
outputTokens: 0,
cacheCreationTokens: 0,
cacheReadTokens: 0,
totalTokens: 0,
estimatedCostUsd: 0
};
}
printMetrics(): void {
console.log('Token Usage Metrics:');
console.log(`Input Tokens: ${this.metrics.inputTokens}`);
console.log(`Output Tokens: ${this.metrics.outputTokens}`);
console.log(`Cache Creation Tokens: ${this.metrics.cacheCreationTokens}`);
console.log(`Cache Read Tokens: ${this.metrics.cacheReadTokens}`);
console.log(`Total Tokens: ${this.metrics.totalTokens}`);
console.log(`Estimated Cost: $${this.metrics.estimatedCostUsd.toFixed(4)}`);
}
}
// Usage
const tracker = new TokenTracker();
const { result, metrics } = await tracker.trackQuery(
'Explain the theory of relativity'
);
console.log(result);
console.log(`This query used ${metrics.totalTokens} tokens`);
console.log(`Estimated cost: $${metrics.estimatedCostUsd.toFixed(4)}`);

Robust error handling ensures applications gracefully manage failures.

import { query } from '@anthropic-ai/claude-agent-sdk';
// Error types
class AgentError extends Error {
constructor(
public code: string,
message: string,
public details?: Record<string, unknown>
) {
super(message);
this.name = 'AgentError';
}
}
class AuthenticationError extends AgentError {
constructor(message: string = 'Authentication failed') {
super('AUTH_ERROR', message);
this.name = 'AuthenticationError';
}
}
class PermissionError extends AgentError {
constructor(tool: string) {
super('PERMISSION_DENIED', `Permission denied for tool: ${tool}`, { tool });
this.name = 'PermissionError';
}
}
class TimeoutError extends AgentError {
constructor(timeoutMs: number) {
super('TIMEOUT', `Operation timed out after ${timeoutMs}ms`, { timeoutMs });
this.name = 'TimeoutError';
}
}
class BudgetExceededError extends AgentError {
constructor(spent: number, limit: number) {
super('BUDGET_EXCEEDED', `Budget exceeded: $${spent} > $${limit}`, { spent, limit });
this.name = 'BudgetExceededError';
}
}
// Comprehensive error handling
async function robustAgentExecution(prompt: string, budgetLimit: number = 5.0) {
try {
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5',
maxBudgetUsd: budgetLimit
}
});
let output = '';
let totalCost = 0;
for await (const message of response) {
switch (message.type) {
case 'assistant':
output += message.content;
break;
case 'tool_call':
console.log(`Executing tool: ${message.tool_name}`);
break;
case 'tool_result':
console.log(`Tool completed: ${message.tool_name}`);
break;
case 'error':
if (message.error.type === 'PERMISSION_DENIED') {
throw new PermissionError(message.error.tool);
} else if (message.error.type === 'AUTHENTICATION_FAILED') {
throw new AuthenticationError(message.error.message);
} else if (message.error.type === 'BUDGET_EXCEEDED') {
throw new BudgetExceededError(
message.error.spent,
budgetLimit
);
} else {
throw new AgentError(
message.error.type,
message.error.message,
message.error.details
);
}
break;
case 'system':
if (message.cost) {
totalCost += message.cost;
if (totalCost > budgetLimit * 0.8) {
console.warn(`Budget warning: ${(totalCost / budgetLimit * 100).toFixed(1)}% used`);
}
}
break;
}
}
return {
success: true,
output,
totalCost
};
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Authentication failed. Check your API key.');
console.error(`Details: ${error.message}`);
throw error;
}
if (error instanceof PermissionError) {
console.error(`Access denied to tool: ${error.details?.tool}`);
throw error;
}
if (error instanceof BudgetExceededError) {
console.error(`Budget limit exceeded: $${error.details?.spent} spent`);
throw error;
}
if (error instanceof TimeoutError) {
console.error(`Operation timed out after ${error.details?.timeoutMs}ms`);
throw error;
}
if (error instanceof Error) {
console.error(`Unexpected error: ${error.message}`);
throw error;
}
console.error('Unknown error occurred');
throw error;
}
}
// Retry logic with exponential backoff
async function executeWithRetry(
prompt: string,
maxRetries: number = 3,
initialDelayMs: number = 1000
): Promise<string> {
let lastError: Error | null = null;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = query({ prompt });
let output = '';
for await (const message of response) {
if (message.type === 'assistant') {
output += message.content;
}
}
return output;
} catch (error) {
lastError = error as Error;
if (attempt < maxRetries - 1) {
const delayMs = initialDelayMs * Math.pow(2, attempt);
console.log(`Retry attempt ${attempt + 1} after ${delayMs}ms...`);
await new Promise(resolve => setTimeout(resolve, delayMs));
}
}
}
throw new Error(`Failed after ${maxRetries} attempts: ${lastError?.message}`);
}
// Usage
try {
const result = await robustAgentExecution(
'Analyse the authentication module',
10.0
);
console.log(result.output);
} catch (error) {
if (error instanceof AgentError) {
console.error(`Agent error (${error.code}): ${error.message}`);
}
}

Ensure responses are properly typed and validated.

import { query } from '@anthropic-ai/claude-agent-sdk';
import { z } from 'zod';
// Type-safe response wrapper
interface TypedResponse<T> {
data: T;
raw: string;
metadata: {
model: string;
tokensUsed: number;
};
}
// Response schema validation
const CodeReviewSchema = z.object({
issues: z.array(z.object({
severity: z.enum(['critical', 'high', 'medium', 'low']),
file: z.string(),
line: z.number(),
description: z.string(),
suggestion: z.string()
})),
summary: z.string(),
scoreOut100: z.number().min(0).max(100)
});
type CodeReview = z.infer<typeof CodeReviewSchema>;
// Generic response handler
class ResponseHandler<T> {
constructor(private schema: z.ZodType<T>) {}
async parseResponse(prompt: string): Promise<TypedResponse<T>> {
const response = query({
prompt: prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
let rawContent = '';
for await (const message of response) {
if (message.type === 'assistant') {
rawContent += message.content;
}
}
// Parse JSON from response
const jsonMatch = rawContent.match(/```json\n([\s\S]*?)\n```/);
const jsonString = jsonMatch ? jsonMatch[1] : rawContent;
const parsed = JSON.parse(jsonString);
const validated = this.schema.parse(parsed);
return {
data: validated,
raw: rawContent,
metadata: {
model: 'claude-sonnet-4-5',
tokensUsed: Math.ceil(rawContent.length / 4)
}
};
}
}
// Usage example
const codeReviewHandler = new ResponseHandler(CodeReviewSchema);
const review = await codeReviewHandler.parseResponse(`Review this TypeScript code:
\`\`\`typescript
async function fetchUser(id: string) {
const response = await fetch(\`/api/users/\${id}\`);
const user = await response.json();
return user;
}
\`\`\`
Respond with JSON in this format:
\`\`\`json
{
"issues": [...],
"summary": "...",
"scoreOut100": ...
}
\`\`\``);
console.log('Code Review:');
console.log(`Score: ${review.data.scoreOut100}/100`);
console.log(`Summary: ${review.data.summary}`);
console.log('Issues:');
review.data.issues.forEach(issue => {
console.log(`- [${issue.severity}] ${issue.description}`);
console.log(` Suggestion: ${issue.suggestion}`);
});

Multi-agent orchestration enables complex task decomposition and parallel execution across specialised agents.

import { query } from '@anthropic-ai/claude-agent-sdk';
import type { Message } from '@anthropic-ai/claude-agent-sdk';
// Agent specialisation registry
const agentSpecialisations = {
researcher: {
description: 'Research and information gathering',
systemPrompt: `You are a research specialist. Your role is to:
- Gather comprehensive information
- Identify reliable sources
- Summarise key findings
- Highlight gaps in knowledge
Format findings as structured data.`
},
analyst: {
description: 'Data analysis and insights',
systemPrompt: `You are a data analyst. Your role is to:
- Analyse gathered data
- Identify patterns and trends
- Draw meaningful conclusions
- Provide statistical insights
Base analysis on provided data.`
},
strategist: {
description: 'Strategic planning and recommendations',
systemPrompt: `You are a strategic advisor. Your role is to:
- Develop strategies based on analysis
- Identify opportunities
- Mitigate risks
- Provide actionable recommendations
Think strategically and consider long-term implications.`
},
implementer: {
description: 'Implementation and execution planning',
systemPrompt: `You are an implementation specialist. Your role is to:
- Design implementation roadmaps
- Break down strategies into tasks
- Estimate timelines and resources
- Identify dependencies
Provide detailed, actionable execution plans.`
}
};
interface OrchestrationResult {
agentName: string;
output: string;
status: 'completed' | 'failed';
error?: string;
}
class MultiAgentOrchestrator {
async executeAgentSequence(
initialPrompt: string,
agentSequence: Array<keyof typeof agentSpecialisations>
): Promise<OrchestrationResult[]> {
const results: OrchestrationResult[] = [];
let contextCarry = initialPrompt;
for (const agentType of agentSequence) {
const agentConfig = agentSpecialisations[agentType];
try {
const agentPrompt = `Context from previous steps:\n${contextCarry}\n\n${agentConfig.description}`;
const response = query({
prompt: agentPrompt,
options: {
model: 'claude-sonnet-4-5',
systemPrompt: agentConfig.systemPrompt,
temperature: 0.7
}
});
let output = '';
for await (const message of response) {
if (message.type === 'assistant') {
output += message.content;
}
}
results.push({
agentName: agentType,
output,
status: 'completed'
});
contextCarry = output;
} catch (error) {
results.push({
agentName: agentType,
output: '',
status: 'failed',
error: String(error)
});
}
}
return results;
}
async executeAgentParallel(
basePrompt: string,
agents: Array<keyof typeof agentSpecialisations>
): Promise<OrchestrationResult[]> {
const promises = agents.map(agentType =>
this.executeAgent(basePrompt, agentType)
);
return Promise.all(promises);
}
private async executeAgent(
prompt: string,
agentType: keyof typeof agentSpecialisations
): Promise<OrchestrationResult> {
const agentConfig = agentSpecialisations[agentType];
try {
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5',
systemPrompt: agentConfig.systemPrompt,
temperature: 0.7
}
});
let output = '';
for await (const message of response) {
if (message.type === 'assistant') {
output += message.content;
}
}
return {
agentName: agentType,
output,
status: 'completed'
};
} catch (error) {
return {
agentName: agentType,
output: '',
status: 'failed',
error: String(error)
};
}
}
}
// Usage
const orchestrator = new MultiAgentOrchestrator();
// Sequential execution
const sequentialResults = await orchestrator.executeAgentSequence(
'Develop a comprehensive strategy for expanding into the European market',
['researcher', 'analyst', 'strategist', 'implementer']
);
// Parallel execution
const parallelResults = await orchestrator.executeAgentParallel(
'What are the best practices for microservices architecture?',
['researcher', 'analyst', 'strategist']
);
// Print results
console.log('Sequential Execution Results:');
sequentialResults.forEach(result => {
console.log(`\n${result.agentName}: ${result.status}`);
console.log(result.output.substring(0, 500) + '...');
});

Implement sophisticated coordination patterns between agents with delegation capabilities.

import { query } from '@anthropic-ai/claude-agent-sdk';
interface Task {
id: string;
description: string;
priority: 'high' | 'medium' | 'low';
complexity: 'simple' | 'moderate' | 'complex';
assignedAgent?: string;
status: 'pending' | 'in_progress' | 'completed' | 'failed';
output?: string;
dependencies?: string[];
}
interface AgentCapabilities {
name: string;
expertise: string[];
currentLoad: number;
maxConcurrent: number;
}
class TaskDelegationManager {
private tasks: Map<string, Task> = new Map();
private agents: Map<string, AgentCapabilities> = new Map();
private executionHistory: Array<{ taskId: string; duration: number; result: string }> = [];
registerAgent(agent: AgentCapabilities): void {
this.agents.set(agent.name, agent);
}
async delegateTask(task: Task): Promise<void> {
// Find suitable agent
const suitableAgent = this.findSuitableAgent(task);
if (!suitableAgent) {
throw new Error(`No suitable agent found for task: ${task.id}`);
}
task.assignedAgent = suitableAgent.name;
task.status = 'in_progress';
this.tasks.set(task.id, task);
// Update agent load
suitableAgent.currentLoad++;
try {
const startTime = Date.now();
const response = query({
prompt: `Task: ${task.description}`,
options: {
model: 'claude-sonnet-4-5',
systemPrompt: `You are specialised in: ${suitableAgent.expertise.join(', ')}`
}
});
let output = '';
for await (const message of response) {
if (message.type === 'assistant') {
output += message.content;
}
}
const duration = Date.now() - startTime;
task.status = 'completed';
task.output = output;
this.executionHistory.push({
taskId: task.id,
duration,
result: output
});
console.log(`Task ${task.id} completed by ${suitableAgent.name} in ${duration}ms`);
} catch (error) {
task.status = 'failed';
task.output = String(error);
console.error(`Task ${task.id} failed:`, error);
} finally {
suitableAgent.currentLoad--;
}
}
private findSuitableAgent(task: Task): AgentCapabilities | null {
let bestAgent: AgentCapabilities | null = null;
let bestMatch = -1;
for (const agent of this.agents.values()) {
// Check if agent is available
if (agent.currentLoad >= agent.maxConcurrent) {
continue;
}
// Calculate match score
const matchScore = agent.expertise.filter(exp =>
task.description.toLowerCase().includes(exp.toLowerCase())
).length;
if (matchScore > bestMatch) {
bestMatch = matchScore;
bestAgent = agent;
}
}
return bestAgent;
}
async executeDependencyChain(tasks: Task[]): Promise<Map<string, Task>> {
const taskMap = new Map<string, Task>(tasks.map(t => [t.id, t]));
const executed = new Set<string>();
while (executed.size < tasks.length) {
for (const task of tasks) {
if (executed.has(task.id)) continue;
// Check if dependencies are met
const dependenciesMet = !task.dependencies ||
task.dependencies.every(depId => executed.has(depId));
if (dependenciesMet) {
await this.delegateTask(task);
executed.add(task.id);
}
}
}
return taskMap;
}
getExecutionMetrics(): {
totalTasks: number;
completedTasks: number;
failedTasks: number;
averageExecutionTime: number;
} {
const completed = Array.from(this.tasks.values())
.filter(t => t.status === 'completed');
const failed = Array.from(this.tasks.values())
.filter(t => t.status === 'failed');
const totalDuration = this.executionHistory.reduce((sum, h) => sum + h.duration, 0);
const averageExecutionTime = this.executionHistory.length > 0
? totalDuration / this.executionHistory.length
: 0;
return {
totalTasks: this.tasks.size,
completedTasks: completed.length,
failedTasks: failed.length,
averageExecutionTime
};
}
}
// Usage
const delegationManager = new TaskDelegationManager();
// Register agents
delegationManager.registerAgent({
name: 'backend-specialist',
expertise: ['API', 'database', 'authentication', 'performance'],
currentLoad: 0,
maxConcurrent: 3
});
delegationManager.registerAgent({
name: 'frontend-specialist',
expertise: ['UI', 'component', 'styling', 'accessibility'],
currentLoad: 0,
maxConcurrent: 2
});
delegationManager.registerAgent({
name: 'devops-specialist',
expertise: ['deployment', 'infrastructure', 'monitoring', 'security'],
currentLoad: 0,
maxConcurrent: 2
});
// Create and delegate tasks
const tasks: Task[] = [
{
id: 'task1',
description: 'Design REST API endpoints for user management',
priority: 'high',
complexity: 'moderate',
status: 'pending'
},
{
id: 'task2',
description: 'Build React components for user dashboard',
priority: 'high',
complexity: 'moderate',
status: 'pending',
dependencies: ['task1']
},
{
id: 'task3',
description: 'Set up Docker containers and CI/CD pipeline',
priority: 'medium',
complexity: 'complex',
status: 'pending'
}
];
// Execute with dependency tracking
for (const task of tasks) {
await delegationManager.delegateTask(task);
}
// Print metrics
const metrics = delegationManager.getExecutionMetrics();
console.log('Execution Metrics:', metrics);

(continuing in next section due to length…)


The Claude Agent SDK provides a comprehensive suite of built-in tools for file operations, code execution, web search, bash commands, and more.

Built-In Tools Available:

  1. Read: Read file contents
  2. Write: Create or overwrite files
  3. Edit: Modify specific sections of files
  4. Delete: Remove files and directories
  5. Bash: Execute bash commands
  6. Grep: Search file contents with regex
  7. Glob: Match files by pattern
  8. WebSearch: Search the internet
  9. Computer Use API: Control mouse, keyboard, screen (advanced)

Tool Availability and Usage:

import { query } from '@anthropic-ai/claude-agent-sdk';
const response = query({
prompt: 'List all TypeScript files, read package.json, and search for imports',
options: {
model: 'claude-sonnet-4-5',
workingDirectory: './src',
// Agent automatically selects appropriate tools
// Can be restricted with allowedTools option
allowedTools: ['Read', 'Glob', 'Grep']
}
});
for await (const message of response) {
if (message.type === 'tool_call') {
console.log(`Tool: ${message.tool_name}, Input:`, message.input);
} else if (message.type === 'tool_result') {
console.log(`Result:`, message.result);
}
}

Create custom tools with type-safe parameter validation.

import { tool, createSdkMcpServer } from '@anthropic-ai/claude-agent-sdk';
import { z } from 'zod';
// Custom tool with Zod schema
const calculateTaxTool = tool(
'calculate_tax',
'Calculate tax amount based on income and jurisdiction',
{
amount: z.number().positive().describe('Gross income amount'),
jurisdiction: z.enum(['US', 'UK', 'CA', 'AU']).describe('Tax jurisdiction'),
filingStatus: z.enum(['single', 'married', 'head_of_household']).optional(),
year: z.number().int().min(2020).max(2030).default(2024)
},
async (args) => {
// Tax calculation logic
const taxRates = {
US: 0.22,
UK: 0.20,
CA: 0.25,
AU: 0.37
};
const rate = taxRates[args.jurisdiction];
const taxAmount = args.amount * rate;
return {
content: [{
type: 'text',
text: `Tax calculation for ${args.jurisdiction}:\nGross: $${args.amount}\nTax Rate: ${(rate * 100).toFixed(1)}%\nTax Amount: $${taxAmount.toFixed(2)}`
}]
};
}
);
// Tool with complex Zod schema
const databaseQueryTool = tool(
'query_database',
'Execute a database query and return results',
{
query: z.string().describe('SQL query to execute'),
parameters: z.record(z.any()).optional().describe('Query parameters'),
timeout: z.number().int().positive().default(30000).describe('Query timeout in ms'),
returnFormat: z.enum(['json', 'csv', 'table']).default('json'),
limit: z.number().int().min(1).max(10000).default(100)
},
async (args) => {
// Database query logic
return {
content: [{
type: 'text',
text: `Query executed: ${args.query}\nFormat: ${args.returnFormat}\nLimit: ${args.limit}`
}]
};
}
);
// Tool for external API calls
const apiCallTool = tool(
'call_external_api',
'Make HTTP requests to external APIs',
{
url: z.string().url().describe('API endpoint URL'),
method: z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH']).default('GET'),
headers: z.record(z.string()).optional().describe('HTTP headers'),
body: z.record(z.any()).optional().describe('Request body (for POST/PUT)'),
auth: z.object({
type: z.enum(['bearer', 'basic', 'api_key']),
credentials: z.string()
}).optional(),
timeout: z.number().int().positive().default(10000)
},
async (args) => {
try {
const headers: Record<string, string> = args.headers || {};
if (args.auth) {
if (args.auth.type === 'bearer') {
headers['Authorization'] = `Bearer ${args.auth.credentials}`;
} else if (args.auth.type === 'basic') {
headers['Authorization'] = `Basic ${Buffer.from(args.auth.credentials).toString('base64')}`;
} else if (args.auth.type === 'api_key') {
headers['X-API-Key'] = args.auth.credentials;
}
}
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), args.timeout);
const response = await fetch(args.url, {
method: args.method,
headers,
body: args.body ? JSON.stringify(args.body) : undefined,
signal: controller.signal
});
clearTimeout(timeoutId);
const data = await response.json();
return {
content: [{
type: 'text',
text: `Response (${response.status}):\n${JSON.stringify(data, null, 2)}`
}]
};
} catch (error) {
return {
content: [{
type: 'text',
text: `API call failed: ${error.message}`
}],
isError: true
};
}
}
);
// Create MCP server with custom tools
const customToolsServer = createSdkMcpServer({
name: 'business-tools',
version: '1.0.0',
tools: [
calculateTaxTool,
databaseQueryTool,
apiCallTool
]
});
// Use in query
const response = query({
prompt: 'Calculate tax for $100,000 income in the US, query user database, and call the weather API',
options: {
mcpServers: {
'business-tools': customToolsServer
},
allowedTools: [
'mcp__business-tools__calculate_tax',
'mcp__business-tools__query_database',
'mcp__business-tools__call_external_api'
],
model: 'claude-sonnet-4-5'
}
});
for await (const message of response) {
if (message.type === 'tool_call') {
console.log(`Calling ${message.tool_name} with:`, message.input);
}
}

File Operations (Read, Write, Edit, Delete)

Section titled “File Operations (Read, Write, Edit, Delete)”

Work with the file system programmatically.

import { query } from '@anthropic-ai/claude-agent-sdk';
// File operations through agent prompts
async function fileOperations() {
const response = query({
prompt: `
1. Read package.json
2. Create a new configuration file config.ts with TypeScript interfaces
3. Edit README.md to add installation instructions
4. List all .ts files in the src directory
`,
options: {
model: 'claude-sonnet-4-5',
workingDirectory: './my-project',
allowedTools: ['Read', 'Write', 'Edit', 'Glob']
}
});
for await (const message of response) {
if (message.type === 'tool_call') {
console.log(`\nTool: ${message.tool_name}`);
console.log('Input:', message.input);
} else if (message.type === 'tool_result') {
console.log('Result:', message.result.substring(0, 200));
}
}
}
// Programmatic file operation wrapper
class FileManager {
constructor(private workingDirectory: string) {}
async readFile(filePath: string): Promise<string> {
const prompt = `Read the file: ${filePath}`;
const response = query({
prompt,
options: {
workingDirectory: this.workingDirectory,
allowedTools: ['Read']
}
});
let content = '';
for await (const message of response) {
if (message.type === 'tool_result') {
content += message.result;
}
}
return content;
}
async writeFile(filePath: string, content: string): Promise<void> {
const prompt = `Create or overwrite the file ${filePath} with this content:\n\n${content}`;
const response = query({
prompt,
options: {
workingDirectory: this.workingDirectory,
allowedTools: ['Write']
}
});
for await (const message of response) {
if (message.type === 'tool_result') {
console.log(`File written: ${filePath}`);
}
}
}
async editFile(filePath: string, oldContent: string, newContent: string): Promise<void> {
const prompt = `
Edit ${filePath}.
Find this section:
\`\`\`
${oldContent}
\`\`\`
Replace it with:
\`\`\`
${newContent}
\`\`\`
`;
const response = query({
prompt,
options: {
workingDirectory: this.workingDirectory,
allowedTools: ['Edit']
}
});
for await (const message of response) {
if (message.type === 'tool_result') {
console.log(`File edited: ${filePath}`);
}
}
}
async deleteFile(filePath: string): Promise<void> {
const prompt = `Delete the file or directory: ${filePath}`;
const response = query({
prompt,
options: {
workingDirectory: this.workingDirectory,
allowedTools: ['Delete']
}
});
for await (const message of response) {
if (message.type === 'tool_result') {
console.log(`File deleted: ${filePath}`);
}
}
}
async listFiles(pattern: string): Promise<string[]> {
const prompt = `List all files matching the pattern: ${pattern}`;
const response = query({
prompt,
options: {
workingDirectory: this.workingDirectory,
allowedTools: ['Glob']
}
});
let files: string[] = [];
for await (const message of response) {
if (message.type === 'tool_result') {
files = message.result.split('\n').filter(f => f.trim());
}
}
return files;
}
}
// Usage
const fileManager = new FileManager('./projects/myapp');
const packageJson = await fileManager.readFile('package.json');
console.log('Package.json content:', packageJson);
await fileManager.writeFile('config.ts', `
export interface Config {
port: number;
host: string;
environment: 'dev' | 'prod';
}
`);
const files = await fileManager.listFiles('*.ts');
console.log('TypeScript files:', files);

Execute system commands and shell scripts.

import { query } from '@anthropic-ai/claude-agent-sdk';
// Execute bash commands through agent
async function bashExecution() {
const response = query({
prompt: `
1. Check the current Node.js version
2. List the node_modules directory
3. Show git status
4. Count total lines of TypeScript code
`,
options: {
model: 'claude-sonnet-4-5',
workingDirectory: './my-project',
allowedTools: ['Bash'],
permissionMode: 'default'
}
});
for await (const message of response) {
if (message.type === 'tool_call') {
console.log(`\nExecuting: ${message.input.command}`);
} else if (message.type === 'tool_result') {
console.log('Output:', message.result);
}
}
}
// Shell command wrapper
class ShellExecutor {
constructor(private workingDirectory: string) {}
async execute(command: string): Promise<string> {
const prompt = `Execute this shell command: ${command}`;
const response = query({
prompt,
options: {
workingDirectory: this.workingDirectory,
allowedTools: ['Bash'],
permissionMode: 'default'
}
});
let output = '';
for await (const message of response) {
if (message.type === 'tool_result') {
output += message.result;
}
}
return output;
}
async runTests(): Promise<string> {
return this.execute('npm test');
}
async buildProject(): Promise<string> {
return this.execute('npm run build');
}
async runLinter(): Promise<string> {
return this.execute('npm run lint');
}
async checkGitStatus(): Promise<string> {
return this.execute('git status');
}
async getDependencyTree(): Promise<string> {
return this.execute('npm list --depth=2');
}
async analyzeCodeMetrics(): Promise<string> {
return this.execute('find src -name "*.ts" -type f | wc -l');
}
}
// Usage
const executor = new ShellExecutor('./projects/myapp');
const testOutput = await executor.runTests();
console.log('Test Results:', testOutput);
const gitStatus = await executor.checkGitStatus();
console.log('Git Status:', gitStatus);
const buildOutput = await executor.buildProject();
console.log('Build Output:', buildOutput);

(Continuing with Web Search, Custom Tools, Error Handling, etc. - document continues with extensive examples…)


The Computer Use API enables sophisticated UI automation through mouse control.

import { query } from '@anthropic-ai/claude-agent-sdk';
interface MouseAction {
type: 'move' | 'click' | 'drag';
x: number;
y: number;
button?: 'left' | 'right' | 'middle';
doubleClick?: boolean;
}
class MouseAutomation {
async moveMouseTo(x: number, y: number): Promise<void> {
const prompt = `Move the mouse cursor to coordinates (${x}, ${y})`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
for await (const message of response) {
if (message.type === 'tool_call' && message.tool_name === 'ComputerUse') {
console.log('Moving mouse to', { x, y });
}
}
}
async clickAtCoordinates(x: number, y: number, button: string = 'left'): Promise<void> {
const prompt = `Click at coordinates (${x}, ${y}) with the ${button} mouse button`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
for await (const message of response) {
if (message.type === 'tool_call' && message.tool_name === 'ComputerUse') {
console.log('Clicking at', { x, y, button });
}
}
}
async dragMouse(fromX: number, fromY: number, toX: number, toY: number): Promise<void> {
const prompt = `Drag the mouse from (${fromX}, ${fromY}) to (${toX}, ${toY})`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
for await (const message of response) {
if (message.type === 'tool_call' && message.tool_name === 'ComputerUse') {
console.log('Dragging mouse', { from: { x: fromX, y: fromY }, to: { x: toX, y: toY } });
}
}
}
async doubleClick(x: number, y: number): Promise<void> {
const prompt = `Double-click at coordinates (${x}, ${y})`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
for await (const message of response) {
if (message.type === 'tool_call' && message.tool_name === 'ComputerUse') {
console.log('Double-clicking at', { x, y });
}
}
}
}
// Usage
const mouse = new MouseAutomation();
await mouse.moveMouseTo(1920 / 2, 1080 / 2);
await mouse.clickAtCoordinates(960, 540, 'left');
await mouse.dragMouse(100, 100, 500, 500);
await mouse.doubleClick(500, 500);

Simulate keyboard input for UI automation.

import { query } from '@anthropic-ai/claude-agent-sdk';
class KeyboardAutomation {
async typeText(text: string): Promise<void> {
const prompt = `Type the following text: "${text}"`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
for await (const message of response) {
if (message.type === 'tool_call' && message.tool_name === 'ComputerUse') {
console.log('Typing:', text);
}
}
}
async pressKey(key: string): Promise<void> {
const prompt = `Press the ${key} key`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
for await (const message of response) {
if (message.type === 'tool_call' && message.tool_name === 'ComputerUse') {
console.log('Pressing key:', key);
}
}
}
async pressKeySequence(keys: string[]): Promise<void> {
const prompt = `Press these keys in sequence: ${keys.join(', ')}`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
for await (const message of response) {
if (message.type === 'tool_call' && message.tool_name === 'ComputerUse') {
console.log('Pressing keys:', keys);
}
}
}
async hotkey(modifiers: string[], key: string): Promise<void> {
const combinedKey = `${modifiers.join('+')}+${key}`;
const prompt = `Press the hotkey: ${combinedKey}`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
for await (const message of response) {
if (message.type === 'tool_call' && message.tool_name === 'ComputerUse') {
console.log('Hotkey:', combinedKey);
}
}
}
async selectAll(): Promise<void> {
await this.hotkey(['Control'], 'a');
}
async copy(): Promise<void> {
await this.hotkey(['Control'], 'c');
}
async paste(): Promise<void> {
await this.hotkey(['Control'], 'v');
}
async undo(): Promise<void> {
await this.hotkey(['Control'], 'z');
}
async redo(): Promise<void> {
await this.hotkey(['Control', 'Shift'], 'z');
}
async save(): Promise<void> {
await this.hotkey(['Control'], 's');
}
async find(): Promise<void> {
await this.hotkey(['Control'], 'f');
}
}
// Usage
const keyboard = new KeyboardAutomation();
await keyboard.typeText('Hello, World!');
await keyboard.pressKey('Enter');
await keyboard.hotkey(['Control'], 'a');
await keyboard.hotkey(['Control'], 'c');
await keyboard.save();

Use screen capture and vision capabilities for UI understanding.

import { query } from '@anthropic-ai/claude-agent-sdk';
interface ScreenElement {
type: string;
text?: string;
location: { x: number; y: number; width: number; height: number };
clickable: boolean;
}
class ScreenInteraction {
async captureScreen(): Promise<string> {
const prompt = 'Take a screenshot of the current screen';
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
let screenshot = '';
for await (const message of response) {
if (message.type === 'tool_result') {
screenshot = message.result;
}
}
return screenshot;
}
async analyzeScreen(): Promise<ScreenElement[]> {
const prompt = `
Capture the screen and analyse it. Identify all clickable elements:
- Buttons
- Links
- Input fields
- Menu items
For each element, provide:
1. Type of element
2. Text label
3. Location (x, y, width, height)
4. Whether it's clickable
Return as JSON array.
`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
let result = '';
for await (const message of response) {
if (message.type === 'assistant') {
result += message.content;
}
}
// Parse JSON response
const jsonMatch = result.match(/```json\n([\s\S]*?)\n```/);
if (jsonMatch) {
return JSON.parse(jsonMatch[1]);
}
return [];
}
async findElement(description: string): Promise<ScreenElement | null> {
const prompt = `
Capture the screen and find the element matching this description: "${description}"
Return the location and details as JSON: { type, text, location: { x, y, width, height }, clickable }
`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
let result = '';
for await (const message of response) {
if (message.type === 'assistant') {
result += message.content;
}
}
const jsonMatch = result.match(/```json\n([\s\S]*?)\n```/);
if (jsonMatch) {
return JSON.parse(jsonMatch[1]);
}
return null;
}
async waitForElement(description: string, timeoutMs: number = 5000): Promise<ScreenElement | null> {
const startTime = Date.now();
while (Date.now() - startTime < timeoutMs) {
const element = await this.findElement(description);
if (element) {
return element;
}
await new Promise(resolve => setTimeout(resolve, 500));
}
return null;
}
async clickElement(description: string): Promise<boolean> {
const element = await this.findElement(description);
if (!element) {
console.error(`Element not found: ${description}`);
return false;
}
const centerX = element.location.x + element.location.width / 2;
const centerY = element.location.y + element.location.height / 2;
const prompt = `Click at coordinates (${centerX}, ${centerY})`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
for await (const message of response) {
if (message.type === 'tool_call') {
return true;
}
}
return false;
}
}
// Usage
const screen = new ScreenInteraction();
const elements = await screen.analyzeScreen();
console.log('Found elements:', elements);
const submitButton = await screen.findElement('Submit button');
if (submitButton) {
await screen.clickElement('Submit button');
}
const loginField = await screen.waitForElement('Login input field', 10000);
if (loginField) {
console.log('Login field appeared');
}

Implement complex autonomous workflows.

import { query } from '@anthropic-ai/claude-agent-sdk';
class AutonomousTaskExecutor {
async fillAndSubmitForm(fields: Record<string, string>): Promise<boolean> {
const fieldDescriptions = Object.entries(fields)
.map(([fieldName, value]) => `- ${fieldName}: "${value}"`)
.join('\n');
const prompt = `
1. Capture the screen to identify all form fields
2. Fill in these fields with the provided values:
${fieldDescriptions}
3. Click the submit button
4. Wait for the form submission confirmation
Return success or failure status.
`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
for await (const message of response) {
if (message.type === 'assistant') {
return message.content.toLowerCase().includes('success');
}
}
return false;
}
async navigateWebsite(initialUrl: string, navigationSteps: string[]): Promise<string> {
let currentLocation = initialUrl;
for (const step of navigationSteps) {
const prompt = `
Current location: ${currentLocation}
Execute this navigation step: ${step}
After completion, provide the new URL or location description.
`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
for await (const message of response) {
if (message.type === 'assistant') {
// Extract location from response
currentLocation = message.content;
}
}
}
return currentLocation;
}
async gatherDataFromWebsite(url: string, dataPoints: string[]): Promise<Record<string, string>> {
const pointsList = dataPoints.map(p => `- ${p}`).join('\n');
const prompt = `
Navigate to: ${url}
Find and extract these data points:
${pointsList}
Return the data as JSON: { "point1": "value1", "point2": "value2" }
`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
let result: Record<string, string> = {};
for await (const message of response) {
if (message.type === 'assistant') {
const jsonMatch = message.content.match(/```json\n([\s\S]*?)\n```/);
if (jsonMatch) {
result = JSON.parse(jsonMatch[1]);
}
}
}
return result;
}
async createContentFromScreens(inputFile: string, outputFormat: string): Promise<string> {
const prompt = `
Read the file: ${inputFile}
Capture multiple screens showing the content
Analyse the screens and create ${outputFormat} formatted output
Return the final content.
`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
let content = '';
for await (const message of response) {
if (message.type === 'assistant') {
content += message.content;
}
}
return content;
}
async testUserInterface(uiDescription: string): Promise<{ passed: number; failed: number; issues: string[] }> {
const prompt = `
Test the following UI: ${uiDescription}
Perform these tests:
1. Identify all interactive elements
2. Click each element
3. Verify expected behavior
4. Check for errors or issues
5. Validate responsive design
Return a test report with pass/fail status and any issues found.
`;
const response = query({
prompt,
options: {
model: 'claude-sonnet-4-5'
}
});
let reportText = '';
for await (const message of response) {
if (message.type === 'assistant') {
reportText += message.content;
}
}
// Parse the report
return {
passed: (reportText.match(/pass/gi) || []).length,
failed: (reportText.match(/fail/gi) || []).length,
issues: reportText.split('\n').filter(line => line.includes('issue') || line.includes('error'))
};
}
}
// Usage
const executor = new AutonomousTaskExecutor();
// Fill and submit a form
const formSuccess = await executor.fillAndSubmitForm({
'Email': 'user@example.com',
'Password': 'securepassword123',
'Remember Me': 'checked'
});
// Navigate through website
const finalLocation = await executor.navigateWebsite(
'https://example.com',
[
'Click on Products menu',
'Select Category: Electronics',
'Sort by price ascending',
'Click first product'
]
);
// Gather data from website
const extractedData = await executor.gatherDataFromWebsite(
'https://example.com/products',
['Product Name', 'Price', 'Availability', 'Rating']
);
console.log('Extracted Data:', extractedData);
// Test UI
const testResults = await executor.testUserInterface('Login form with email/password fields');
console.log('Test Results:', testResults);

(Document continues with STRUCTURED OUTPUT, MCP, AGENTIC PATTERNS, PERMISSIONS, SESSION MANAGEMENT, CONTEXT ENGINEERING, PRODUCTION ESSENTIALS, TOOL DEVELOPMENT, STREAMING, TYPESCRIPT PATTERNS, PROJECT SETUP, INTEGRATION PATTERNS, and ADVANCED TOPICS sections…)

The comprehensive guide continues with detailed sections on each topic with extensive TypeScript examples. Due to length constraints, I’ll now create the production guide, diagrams, and recipes files as separate documents.


VersionDateChanges
0.2.128May 5, 2026Patch releases (0.2.127–0.2.128); dependency updates; version confirmed against npm @anthropic-ai/claude-agent-sdk 0.2.128 (latest, 2026-05-05, .routine-envs/check-0505-node). query runtime export PASS; PermissionMode, McpServerConfig type exports confirmed present in sdk.d.ts.
0.2.126May 1, 2026Patch releases (0.2.124–0.2.126); dependency updates; version confirmed against npm @anthropic-ai/claude-agent-sdk 0.2.126 (latest, 2026-05-01). Note: 0.2.125 was not published; sequence goes 0.2.124 → 0.2.126.
0.2.123April 29, 2026Patch releases (0.2.122–0.2.123); dependency updates; version confirmed against npm @anthropic-ai/claude-agent-sdk 0.2.123.
0.2.121April 28, 2026Patch releases (0.2.120–0.2.121); dependency updates; version confirmed against npm @anthropic-ai/claude-agent-sdk 0.2.121.
0.2.119April 24, 2026Patch releases (0.2.118–0.2.119); dependency updates; version confirmed against npm @anthropic-ai/claude-agent-sdk 0.2.119.
0.2.117April 21, 2026Patch release; dependency updates.
0.2.116April 20, 2026Patch release; stability improvements.
0.2.114–0.2.115April 17, 2026Patch releases; internal dependency alignment.
0.2.112–0.2.113April 16–17, 2026Patch releases; MCP protocol alignment.
0.2.111April 16, 2026Patch release; performance improvements.
0.2.110April 16, 2026Multibyte character fix; MCP cleanup fix; extended thinking config types aligned with Python SDK
0.1.30Previous versionPackage renamed from @anthropic-ai/claude-code to @anthropic-ai/claude-agent-sdk; structured outputs with Zod; MCP integration