Practical code patterns for the Claude Agent SDK.
import { query } from '@anthropic-ai/claude-agent-sdk';
const result = query({
prompt: 'Task description',
options: {model: 'claude-sonnet-4-5-20250929', cwd: '/path'}
});
for await (const msg of result) {
if (msg.type === 'result') {
console.log(msg.subtype === 'success' ? msg.result : msg.errors);
}
}import { unstable_v2_createSession } from '@anthropic-ai/claude-agent-sdk';
const session = unstable_v2_createSession({model: 'claude-sonnet-4-5-20250929'});
await session.send('First message');
for await (const msg of session.receive()) {
if (msg.type === 'result') break;
}
await session.send('Second message');
for await (const msg of session.receive()) {
if (msg.type === 'result') break;
}
session.close();const result = query({
prompt: 'Task',
options: {
canUseTool: async (toolName, input, {decisionReason}) => {
// Block dangerous commands
if (toolName === 'Bash' && (input.command as string).includes('rm -rf')) {
return {behavior: 'deny', message: 'Command not allowed', interrupt: true};
}
// Block sensitive files
if ((toolName === 'Write' || toolName === 'Edit') &&
(input.file_path as string).includes('.env')) {
return {behavior: 'deny', message: 'Cannot modify .env'};
}
return {behavior: 'allow', updatedInput: input};
}
}
});const result = query({
prompt: 'Task',
options: {
hooks: {
PreToolUse: [{
hooks: [async (input) => {
if (input.hook_event_name === 'PreToolUse') {
console.log(`[${input.tool_name}]`, input.tool_input);
}
return {continue: true};
}]
}],
PostToolUse: [{
hooks: [async (input) => {
if (input.hook_event_name === 'PostToolUse') {
console.log(`[${input.tool_name} ✓]`);
}
return {continue: true};
}]
}]
}
}
});import { query, createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk';
import { z } from 'zod';
const myServer = createSdkMcpServer({
name: 'my-tools',
tools: [
tool(
'calculate',
'Perform calculations',
{
op: z.enum(['add', 'sub', 'mul', 'div']),
a: z.number(),
b: z.number()
},
async (args) => {
const ops = {add: '+', sub: '-', mul: '*', div: '/'};
const result = eval(`${args.a} ${ops[args.op]} ${args.b}`);
return {content: [{type: 'text', text: `Result: ${result}`}]};
}
)
]
});
const result = query({
prompt: 'Calculate 15 + 27',
options: {mcpServers: {'my-tools': myServer}}
});const result = query({
prompt: 'Review and test the code',
options: {
agents: {
'reviewer': {
description: 'Reviews code for issues',
tools: ['Read', 'Grep', 'Glob'],
prompt: 'You are a code reviewer. Find bugs, style issues, security vulnerabilities.',
model: 'opus'
},
'tester': {
description: 'Writes and runs tests',
tools: ['Read', 'Write', 'Bash'],
prompt: 'You are a test engineer. Write comprehensive tests.',
model: 'sonnet'
}
}
}
});const result = query({
prompt: 'Build Docker container',
options: {
sandbox: {
enabled: true,
autoAllowBashIfSandboxed: true,
network: {
allowUnixSockets: ['/var/run/docker.sock'],
allowLocalBinding: true
},
excludedCommands: ['docker', 'npm'],
allowUnsandboxedCommands: true
}
}
});// Read-only access
const result1 = query({
prompt: 'Analyze code',
options: {allowedTools: ['Read', 'Grep', 'Glob']}
});
// No shell access
const result2 = query({
prompt: 'Modify files',
options: {
tools: {type: 'preset', preset: 'claude_code'},
disallowedTools: ['Bash', 'WebFetch', 'WebSearch']
}
});const result = query({
prompt: 'Analyze file complexity',
options: {
outputFormat: {
type: 'json_schema',
schema: {
type: 'object',
properties: {
complexity: {type: 'number'},
issues: {
type: 'array',
items: {
type: 'object',
properties: {
severity: {type: 'string'},
message: {type: 'string'}
}
}
}
},
required: ['complexity', 'issues']
}
}
}
});
for await (const msg of result) {
if (msg.type === 'result' && msg.subtype === 'success') {
console.log(msg.structured_output);
}
}const result = query({
prompt: 'Complex task',
options: {
maxTurns: 50,
maxBudgetUsd: 2.00,
maxThinkingTokens: 1000
}
});// Continue previous conversation
const result1 = query({prompt: 'Continue', options: {continue: true}});
// Resume specific session
const result2 = query({prompt: 'Resume', options: {resume: 'session-id'}});
// Fork session
const result3 = query({
prompt: 'Branch',
options: {resume: 'session-id', forkSession: true}
});const controller = new AbortController();
setTimeout(() => controller.abort(), 30000); // 30s timeout
try {
const result = query({
prompt: 'Task',
options: {
abortController: controller,
stderr: (data) => console.error('[STDERR]', data)
}
});
for await (const msg of result) {
if (msg.type === 'result') {
if (msg.subtype === 'success') {
console.log('Success:', msg.result);
console.log('Cost: $', msg.total_cost_usd);
console.log('Turns:', msg.num_turns);
} else {
console.error('Errors:', msg.errors);
console.log('Partial cost: $', msg.total_cost_usd);
}
if (msg.permission_denials.length > 0) {
console.warn('Denied:', msg.permission_denials.map(d => d.tool_name));
}
}
}
} catch (error) {
if (error instanceof AbortError) {
console.log('Aborted');
} else {
throw error;
}
}const result = query({
prompt: 'Find all TODO comments, update them, and create a report',
options: {
tools: ['Read', 'Grep', 'Glob', 'Write'],
permissionMode: 'acceptEdits'
}
});
// Agent will:
// 1. Glob: Find files matching pattern
// 2. Grep: Search for TODO comments
// 3. Read: Read files with TODOs
// 4. Write: Update files and create reportconst result = query({prompt: 'Task', options: {model: 'claude-sonnet-4-5-20250929'}});
// Interrupt execution
setTimeout(() => result.interrupt(), 10000);
// Change model mid-execution (streaming input mode only)
setTimeout(() => result.setModel('claude-opus-4-20250514'), 5000);
// Query session info
const models = await result.supportedModels();
const commands = await result.supportedCommands();
const mcpStatus = await result.mcpServerStatus();
const account = await result.accountInfo();const result = query({
prompt: 'Use external tools',
options: {
mcpServers: {
'database': {
command: 'node',
args: ['./servers/db-server.js'],
env: {DB_HOST: 'localhost'}
},
'api': {
type: 'http',
url: 'http://localhost:3000/mcp',
headers: {'Authorization': 'Bearer token'}
},
'realtime': {
type: 'sse',
url: 'http://localhost:4000/stream'
}
},
strictMcpConfig: true
}
});