Initial commit
This commit is contained in:
595
SKILL.md
Normal file
595
SKILL.md
Normal file
@@ -0,0 +1,595 @@
|
||||
---
|
||||
name: claude-agent-sdk
|
||||
description: |
|
||||
Build autonomous AI agents with Claude Agent SDK. Structured outputs (v0.1.45, Nov 2025) guarantee JSON schema validation, plugins system, hooks for event-driven workflows. Use when: building coding agents with validated JSON responses, SRE systems, security auditors, or troubleshooting CLI not found, structured output validation, session forking errors.
|
||||
license: MIT
|
||||
metadata:
|
||||
version: 2.0.0
|
||||
last_verified: 2025-11-22
|
||||
package_version: 0.1.50
|
||||
token_savings: ~70%
|
||||
errors_prevented: 12
|
||||
breaking_changes: v0.1.45 - Structured outputs (Nov 2025), v0.1.0 - No default system prompt, settingSources required
|
||||
keywords:
|
||||
- claude agent sdk
|
||||
- "@anthropic-ai/claude-agent-sdk"
|
||||
- structured outputs
|
||||
- json schema validation
|
||||
- outputFormat
|
||||
- query()
|
||||
- createSdkMcpServer
|
||||
- AgentDefinition
|
||||
- tool()
|
||||
- claude subagents
|
||||
- mcp servers
|
||||
- autonomous agents
|
||||
- plugins system
|
||||
- hooks system
|
||||
- session management
|
||||
- session forking
|
||||
- permissionMode
|
||||
- canUseTool
|
||||
- multi-agent orchestration
|
||||
- settingSources
|
||||
- CLI not found
|
||||
- context length exceeded
|
||||
- structured output validation
|
||||
- zod schema
|
||||
---
|
||||
|
||||
# Claude Agent SDK - Structured Outputs & Error Prevention Guide
|
||||
|
||||
**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
|
||||
|
||||
---
|
||||
|
||||
## What's New in v0.1.45+ (Nov 2025)
|
||||
|
||||
**Major Features:**
|
||||
|
||||
### 1. Structured Outputs (v0.1.45, Nov 14, 2025)
|
||||
- **JSON schema validation** - Guarantees responses match exact schemas
|
||||
- **`outputFormat` parameter** - Define output structure with JSON schema or Zod
|
||||
- **Access validated results** - Via `message.structured_output`
|
||||
- **Beta header required**: `structured-outputs-2025-11-13`
|
||||
- **Type safety** - Full TypeScript inference with Zod schemas
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
import { 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}`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Plugins System (v0.1.27)
|
||||
- **`plugins` array** - Load local plugin paths
|
||||
- **Custom plugin support** - Extend agent capabilities
|
||||
|
||||
### 3. Hooks System (v0.1.0+)
|
||||
- **Event-driven callbacks** - PreToolUse, PostToolUse, Notification, UserPromptSubmit
|
||||
- **Session event hooks** - Monitor and control agent behavior
|
||||
|
||||
### 4. Additional Options
|
||||
- **`fallbackModel`** - Automatic model fallback on failures
|
||||
- **`maxThinkingTokens`** - Control extended thinking budget
|
||||
- **`strictMcpConfig`** - Strict MCP configuration validation
|
||||
- **`continue`** - 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
|
||||
|
||||
---
|
||||
|
||||
## The Complete Claude Agent SDK Reference
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Core Query API](#core-query-api)
|
||||
2. [Tool Integration](#tool-integration-built-in--custom)
|
||||
3. [MCP Servers](#mcp-servers-model-context-protocol)
|
||||
4. [Subagent Orchestration](#subagent-orchestration)
|
||||
5. [Session Management](#session-management)
|
||||
6. [Permission Control](#permission-control)
|
||||
7. [Filesystem Settings](#filesystem-settings)
|
||||
8. [Message Types & Streaming](#message-types--streaming)
|
||||
9. [Error Handling](#error-handling)
|
||||
10. [Known Issues](#known-issues-prevention)
|
||||
|
||||
---
|
||||
|
||||
## Core Query API
|
||||
|
||||
**Key signature:**
|
||||
```typescript
|
||||
query(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 callback
|
||||
- `agents` - Programmatic subagent definitions
|
||||
- `mcpServers` - MCP server configuration
|
||||
- `permissionMode` - 'default'|'acceptEdits'|'bypassPermissions'|'plan'
|
||||
|
||||
---
|
||||
|
||||
## Tool Integration (Built-in + Custom)
|
||||
|
||||
**Tool Control:**
|
||||
- `allowedTools` - Whitelist (takes precedence)
|
||||
- `disallowedTools` - Blacklist
|
||||
- `canUseTool` - Custom permission callback (see Permission Control section)
|
||||
|
||||
**Built-in Tools:** Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, Task, NotebookEdit, BashOutput, KillBash, ListMcpResources, ReadMcpResource
|
||||
|
||||
---
|
||||
|
||||
## MCP Servers (Model Context Protocol)
|
||||
|
||||
**Server Types:**
|
||||
- **In-process** - `createSdkMcpServer()` with `tool()` definitions
|
||||
- **External** - stdio, HTTP, SSE transport
|
||||
|
||||
**Tool Definition:**
|
||||
```typescript
|
||||
tool(name: string, description: string, zodSchema, handler)
|
||||
```
|
||||
|
||||
**Handler Return:**
|
||||
```typescript
|
||||
{ content: [{ type: "text", text: "..." }], isError?: boolean }
|
||||
```
|
||||
|
||||
### External MCP Servers (stdio)
|
||||
|
||||
```typescript
|
||||
const 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"
|
||||
]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### External MCP Servers (HTTP/SSE)
|
||||
|
||||
```typescript
|
||||
const 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"]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### MCP Tool Naming Convention
|
||||
|
||||
**Format**: `mcp__<server-name>__<tool-name>`
|
||||
|
||||
**CRITICAL:**
|
||||
- Server name and tool name MUST match configuration
|
||||
- Use double underscores (`__`) as separators
|
||||
- Include in `allowedTools` array
|
||||
|
||||
**Examples:** `mcp__weather-service__get_weather`, `mcp__filesystem__read_file`
|
||||
|
||||
---
|
||||
|
||||
## Subagent Orchestration
|
||||
|
||||
### AgentDefinition Type
|
||||
|
||||
```typescript
|
||||
type 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:**
|
||||
|
||||
- **description**: When to use agent (used by main agent for delegation)
|
||||
- **prompt**: System prompt (defines role, inherits main context)
|
||||
- **tools**: Allowed tools (if omitted, inherits from main agent)
|
||||
- **model**: Model override (`haiku`/`sonnet`/`opus`/`inherit`)
|
||||
|
||||
**Usage:**
|
||||
```typescript
|
||||
agents: {
|
||||
"security-checker": {
|
||||
description: "Security audits and vulnerability scanning",
|
||||
prompt: "You check security. Scan for secrets, verify OWASP compliance.",
|
||||
tools: ["Read", "Grep", "Bash"],
|
||||
model: "sonnet"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Session Management
|
||||
|
||||
**Options:**
|
||||
- `resume: sessionId` - Continue previous session
|
||||
- `forkSession: true` - Create new branch from session
|
||||
- `continue: 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:**
|
||||
```typescript
|
||||
for await (const message of response) {
|
||||
if (message.type === 'system' && message.subtype === 'init') {
|
||||
sessionId = message.session_id; // Save for later resume/fork
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Permission Control
|
||||
|
||||
**Permission Modes:**
|
||||
```typescript
|
||||
type PermissionMode = "default" | "acceptEdits" | "bypassPermissions" | "plan";
|
||||
```
|
||||
|
||||
- `default` - Standard permission checks
|
||||
- `acceptEdits` - Auto-approve file edits
|
||||
- `bypassPermissions` - Skip ALL checks (use in CI/CD only)
|
||||
- `plan` - Planning mode (v0.1.45+)
|
||||
|
||||
### Custom Permission Logic
|
||||
|
||||
```typescript
|
||||
const 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" };
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### canUseTool Callback
|
||||
|
||||
```typescript
|
||||
type 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" };
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Filesystem Settings
|
||||
|
||||
**Setting Sources:**
|
||||
```typescript
|
||||
type 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: []`)
|
||||
|
||||
### Settings Priority
|
||||
|
||||
When multiple sources loaded, settings merge in this order (highest priority first):
|
||||
|
||||
1. **Programmatic options** (passed to `query()`) - Always win
|
||||
2. **Local settings** (`.claude/settings.local.json`)
|
||||
3. **Project settings** (`.claude/settings.json`)
|
||||
4. **User settings** (`~/.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 & Streaming
|
||||
|
||||
**Message Types:**
|
||||
- `system` - Session init/completion (includes `session_id`)
|
||||
- `assistant` - Agent responses
|
||||
- `tool_call` - Tool execution requests
|
||||
- `tool_result` - Tool execution results
|
||||
- `error` - Error messages
|
||||
- `result` - Final result (includes `structured_output` for v0.1.45+)
|
||||
|
||||
**Streaming Pattern:**
|
||||
```typescript
|
||||
for 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 Handling
|
||||
|
||||
**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 |
|
||||
|
||||
---
|
||||
|
||||
## Known Issues Prevention
|
||||
|
||||
This skill prevents **12** documented issues:
|
||||
|
||||
### Issue #1: CLI Not Found Error
|
||||
**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`
|
||||
|
||||
### Issue #2: Authentication Failed
|
||||
**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-..."`
|
||||
|
||||
### Issue #3: Permission Denied Errors
|
||||
**Error**: Tool execution blocked
|
||||
**Source**: `permissionMode` restrictions
|
||||
**Why It Happens**: Tool not allowed by permissions
|
||||
**Prevention**: Use `allowedTools` or custom `canUseTool` callback
|
||||
|
||||
### Issue #4: Context Length Exceeded
|
||||
**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
|
||||
|
||||
### Issue #5: Tool Execution Timeout
|
||||
**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
|
||||
|
||||
### Issue #6: Session Not Found
|
||||
**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
|
||||
|
||||
### Issue #7: MCP Server Connection Failed
|
||||
**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
|
||||
|
||||
### Issue #8: Subagent Definition Errors
|
||||
**Error**: Invalid AgentDefinition
|
||||
**Source**: Missing required fields
|
||||
**Why It Happens**: `description` or `prompt` missing
|
||||
**Prevention**: Always include `description` and `prompt` fields
|
||||
|
||||
### Issue #9: Settings File Not Found
|
||||
**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
|
||||
|
||||
### Issue #10: Tool Name Collision
|
||||
**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
|
||||
|
||||
### Issue #11: Zod Schema Validation Error
|
||||
**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()`
|
||||
|
||||
### Issue #12: Filesystem Permission Denied
|
||||
**Error**: Cannot access path
|
||||
**Source**: Restricted filesystem access
|
||||
**Why It Happens**: Path outside `workingDirectory` or no permissions
|
||||
**Prevention**: Set correct `workingDirectory`, check file permissions
|
||||
|
||||
---
|
||||
|
||||
## Official Documentation
|
||||
|
||||
- **Agent SDK Overview**: https://platform.claude.com/docs/en/api/agent-sdk/overview
|
||||
- **TypeScript API**: https://platform.claude.com/docs/en/api/agent-sdk/typescript
|
||||
- **Structured Outputs**: https://platform.claude.com/docs/en/agent-sdk/structured-outputs
|
||||
- **GitHub (TypeScript)**: https://github.com/anthropics/claude-agent-sdk-typescript
|
||||
- **CHANGELOG**: https://github.com/anthropics/claude-agent-sdk-typescript/blob/main/CHANGELOG.md
|
||||
|
||||
---
|
||||
|
||||
**Token Efficiency**:
|
||||
- **Without skill**: ~12,000 tokens (MCP setup, permission patterns, session forking, structured outputs, error handling)
|
||||
- **With skill**: ~3,600 tokens (focused on v0.1.45+ features + error prevention + advanced patterns)
|
||||
- **Savings**: ~70% (~8,400 tokens)
|
||||
|
||||
**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.
|
||||
Reference in New Issue
Block a user