Install any skill in seconds. Free to start, no credit card required.
Get Started Free →This skill should be used when building applications with the Claude Agent SDK (Python). Use for creating orchestrators with subagents, configuring agents programmatically, setting up hooks and permissions, and following SDK best practices. Trigger when implementing agentic workflows, multi-agent systems, or SDK-based automation.
.claude/skills/majiayu000-claude-agent-sdk/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 120% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 64% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 101% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 408% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 119% | 0% |
Package: @anthropic-ai/claude-agent-sdk@0.1.50 (Nov 21, 2025) Breaking Changes: v0.1.45 - Structured outputs (Nov 2025), v0.1.0 - No default system prompt, settingSources required
Major Features:
outputFormat parameter - Define output structure with JSON schema or Zodmessage.structured_outputstructured-outputs-2025-11-13Example:
typescriptimport { query } from "@anthropic-ai/claude-agent-sdk"; import { z } from "zod"; const schema = z.object({ summary: z.string(), sentiment: z.enum(['positive', 'neutral', 'negative']), confidence: z.number().min(0).max(1) }); const response = query({ prompt: "Analyze this code review feedback", options: { model: "claude-sonnet-4-5", outputFormat: { type: "json_schema", json_schema: { name: "AnalysisResult", strict: true, schema: zodToJsonSchema(schema) } } } }); for await (const message of response) { if (message.type === 'result' && message.structured_output) { // Guaranteed to match schema const validated = schema.parse(message.structured_output); console.log(`Sentiment: ${validated.sentiment}`); } }
plugins array - Load local plugin pathsfallbackModel - Automatic model fallback on failuresmaxThinkingTokens - Control extended thinking budgetstrictMcpConfig - Strict MCP configuration validationcontinue - Resume with new prompt (differs from resume)permissionMode: 'plan' - New permission mode for planning workflows📚 Docs: https://platform.claude.com/docs/en/agent-sdk/structured-outputs
Key signature:
typescriptquery(prompt: string | AsyncIterable<SDKUserMessage>, options?: Options) -> AsyncGenerator<SDKMessage>
Critical Options:
outputFormat - Structured JSON schema validation (v0.1.45+)settingSources - Filesystem settings loading ('user'|'project'|'local')canUseTool - Custom permission logic callbackagents - Programmatic subagent definitionsmcpServers - MCP server configurationpermissionMode - 'default'|'acceptEdits'|'bypassPermissions'|'plan'Tool Control:
allowedTools - Whitelist (takes precedence)disallowedTools - BlacklistcanUseTool - Custom permission callback (see Permission Control section)Built-in Tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, Task, NotebookEdit, BashOutput, KillBash, ListMcpResources, ReadMcpResource
Server Types:
createSdkMcpServer() with tool() definitionsTool Definition:
typescripttool(name: string, description: string, zodSchema, handler)
Handler Return:
typescript{ content: [{ type: "text", text: "..." }], isError?: boolean }
typescriptconst response = query({ prompt: "List files and analyze Git history", options: { mcpServers: { // Filesystem server "filesystem": { command: "npx", args: ["@modelcontextprotocol/server-filesystem"], env: { ALLOWED_PATHS: "/Users/developer/projects:/tmp" } }, // Git operations server "git": { command: "npx", args: ["@modelcontextprotocol/server-git"], env: { GIT_REPO_PATH: "/Users/developer/projects/my-repo" } } }, allowedTools: [ "mcp__filesystem__list_files", "mcp__filesystem__read_file", "mcp__git__log", "mcp__git__diff" ] } });
typescriptconst response = query({ prompt: "Analyze data from remote service", options: { mcpServers: { "remote-service": { url: "https://api.example.com/mcp", headers: { "Authorization": "Bearer your-token-here", "Content-Type": "application/json" } } }, allowedTools: ["mcp__remote-service__analyze"] } });
Format: mcp__<server-name>__<tool-name>
CRITICAL:
__) as separatorsallowedTools arrayExamples: mcp__weather-service__get_weather, mcp__filesystem__read_file
typescripttype AgentDefinition = { description: string; // When to use this agent prompt: string; // System prompt for agent tools?: string[]; // Allowed tools (optional) model?: 'sonnet' | 'opus' | 'haiku' | 'inherit'; // Model (optional) }
Field Details:
haiku/sonnet/opus/inherit)Usage:
typescriptagents: { "security-checker": { description: "Security audits and vulnerability scanning", prompt: "You check security. Scan for secrets, verify OWASP compliance.", tools: ["Read", "Grep", "Bash"], model: "sonnet" } }
Options:
resume: sessionId - Continue previous sessionforkSession: true - Create new branch from sessioncontinue: prompt - Resume with new prompt (differs from resume)Session Forking Pattern (Unique Capability):
typescript// Explore alternative without modifying original const forked = query({ prompt: "Try GraphQL instead of REST", options: { resume: sessionId, forkSession: true // Creates new branch, original session unchanged } });
Capture Session ID:
typescriptfor await (const message of response) { if (message.type === 'system' && message.subtype === 'init') { sessionId = message.session_id; // Save for later resume/fork } }
Permission Modes:
typescripttype PermissionMode = "default" | "acceptEdits" | "bypassPermissions" | "plan";
default - Standard permission checksacceptEdits - Auto-approve file editsbypassPermissions - Skip ALL checks (use in CI/CD only)plan - Planning mode (v0.1.45+)typescriptconst response = query({ prompt: "Deploy application to production", options: { permissionMode: "default", canUseTool: async (toolName, input) => { // Allow read-only operations if (['Read', 'Grep', 'Glob'].includes(toolName)) { return { behavior: "allow" }; } // Deny destructive bash commands if (toolName === 'Bash') { const dangerous = ['rm -rf', 'dd if=', 'mkfs', '> /dev/']; if (dangerous.some(pattern => input.command.includes(pattern))) { return { behavior: "deny", message: "Destructive command blocked for safety" }; } } // Require confirmation for deployments if (input.command?.includes('deploy') || input.command?.includes('kubectl apply')) { return { behavior: "ask", message: "Confirm deployment to production?" }; } // Allow by default return { behavior: "allow" }; } } });
typescripttype CanUseToolCallback = ( toolName: string, input: any ) => Promise<PermissionDecision>; type PermissionDecision = | { behavior: "allow" } | { behavior: "deny"; message?: string } | { behavior: "ask"; message?: string };
Examples:
typescript// Block all file writes canUseTool: async (toolName, input) => { if (toolName === 'Write' || toolName === 'Edit') { return { behavior: "deny", message: "No file modifications allowed" }; } return { behavior: "allow" }; } // Require confirmation for specific files canUseTool: async (toolName, input) => { const sensitivePaths = ['/etc/', '/root/', '.env', 'credentials.json']; if ((toolName === 'Write' || toolName === 'Edit') && sensitivePaths.some(path => input.file_path?.includes(path))) { return { behavior: "ask", message: `Modify sensitive file ${input.file_path}?` }; } return { behavior: "allow" }; } // Log all tool usage canUseTool: async (toolName, input) => { console.log(`Tool requested: ${toolName}`, input); await logToDatabase(toolName, input); return { behavior: "allow" }; }
Setting Sources:
typescripttype SettingSource = 'user' | 'project' | 'local';
user - ~/.claude/settings.json (global)project - .claude/settings.json (team-shared)local - .claude/settings.local.json (gitignored overrides)Default: NO settings loaded (settingSources: [])
When multiple sources loaded, settings merge in this order (highest priority first):
query()) - Always win.claude/settings.local.json).claude/settings.json)~/.claude/settings.json)Example:
typescript// .claude/settings.json { "allowedTools": ["Read", "Write", "Edit"] } // .claude/settings.local.json { "allowedTools": ["Read"] // Overrides project settings } // Programmatic const response = query({ options: { settingSources: ["project", "local"], allowedTools: ["Read", "Grep"] // ← This wins } }); // Actual allowedTools: ["Read", "Grep"]
Best Practice: Use settingSources: ["project"] in CI/CD for consistent behavior.
Message Types:
system - Session init/completion (includes session_id)assistant - Agent responsestool_call - Tool execution requeststool_result - Tool execution resultserror - Error messagesresult - Final result (includes structured_output for v0.1.45+)Streaming Pattern:
typescriptfor await (const message of response) { if (message.type === 'system' && message.subtype === 'init') { sessionId = message.session_id; // Capture for resume/fork } if (message.type === 'result' && message.structured_output) { // Structured output available (v0.1.45+) const validated = schema.parse(message.structured_output); } }
Error Codes:
| Error Code | Cause | Solution | |------------|-------|----------| | CLI_NOT_FOUND | Claude Code not installed | Install: npm install -g @anthropic-ai/claude-code | | AUTHENTICATION_FAILED | Invalid API key | Check ANTHROPIC_API_KEY env var | | RATE_LIMIT_EXCEEDED | Too many requests | Implement retry with backoff | | CONTEXT_LENGTH_EXCEEDED | Prompt too long | Use session compaction, reduce context | | PERMISSION_DENIED | Tool blocked | Check permissionMode, canUseTool | | TOOL_EXECUTION_FAILED | Tool error | Check tool implementation | | SESSION_NOT_FOUND | Invalid session ID | Verify session ID | | MCP_SERVER_FAILED | Server error | Check server configuration |
This skill prevents 12 documented issues:
Error: "Claude Code CLI not installed" Source: SDK requires Claude Code CLI Why It Happens: CLI not installed globally Prevention: Install before using SDK: npm install -g @anthropic-ai/claude-code
Error: "Invalid API key" Source: Missing or incorrect ANTHROPIC_API_KEY Why It Happens: Environment variable not set Prevention: Always set export ANTHROPIC_API_KEY="sk-ant-..."
Error: Tool execution blocked Source: permissionMode restrictions Why It Happens: Tool not allowed by permissions Prevention: Use allowedTools or custom canUseTool callback
Error: "Prompt too long" Source: Input exceeds model context window Why It Happens: Large codebase, long conversations Prevention: SDK auto-compacts, but reduce context if needed
Error: Tool doesn't respond Source: Long-running tool execution Why It Happens: Tool takes too long (>5 minutes default) Prevention: Implement timeout handling in tool implementations
Error: "Invalid session ID" Source: Session expired or invalid Why It Happens: Session ID incorrect or too old Prevention: Capture session_id from system init message
Error: Server not responding Source: Server not running or misconfigured Why It Happens: Command/URL incorrect, server crashed Prevention: Test MCP server independently, verify command/URL
Error: Invalid AgentDefinition Source: Missing required fields Why It Happens: description or prompt missing Prevention: Always include description and prompt fields
Error: "Cannot read settings" Source: Settings file doesn't exist Why It Happens: settingSources includes non-existent file Prevention: Check file exists before including in sources
Error: Duplicate tool name Source: Multiple tools with same name Why It Happens: Two MCP servers define same tool name Prevention: Use unique tool names, prefix with server name
Error: Invalid tool input Source: Input doesn't match Zod schema Why It Happens: Agent provided wrong data type Prevention: Use descriptive Zod schemas with .describe()
Error: Cannot access path Source: Restricted filesystem access Why It Happens: Path outside workingDirectory or no permissions Prevention: Set correct workingDirectory, check file permissions
Token Efficiency:
Errors prevented: 12 documented issues with exact solutions Key value: Structured outputs (v0.1.45+), session forking, canUseTool patterns, settingSources priority, MCP naming, error codes
Last verified: 2025-11-22 | Skill version: 2.0.0 | Changes: Added v0.1.45 structured outputs, plugins, hooks, new options. Removed tutorial/basic examples (~750 lines). Focused on knowledge gaps + error prevention + advanced patterns.
Other measured skills in the registry, with their headline benchmark lift.