claude-agent-sdk by jezweb/claude-skills
npx skills add https://github.com/jezweb/claude-skills --skill claude-agent-sdk包 : @anthropic-ai/claude-agent-sdk@0.2.12 破坏性变更 : v0.1.45 - 结构化输出 (2025年11月), v0.1.0 - 无默认系统提示, 需设置 settingSources
主要特性:
outputFormat 参数 - 使用 JSON 模式或 Zod 定义输出结构message.structured_outputstructured-outputs-2025-11-13示例:
import { query } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
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) {
// 保证匹配模式
const validated = schema.parse(message.structured_output);
console.log(`Sentiment: ${validated.sentiment}`);
}
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
Zod 兼容性 (v0.1.71+): SDK 同时支持 Zod v3.24.1+ 和 Zod v4.0.0+ 作为对等依赖。两种版本的导入方式均为 import { z } from "zod"。
plugins 数组 - 加载本地插件路径全部 12 个钩子事件:
| 钩子 | 触发时机 | 使用场景 |
|---|---|---|
PreToolUse | 工具执行前 | 验证、修改或阻止工具调用 |
PostToolUse | 工具执行后 | 记录结果、触发副作用 |
Notification | 代理通知 | 显示状态更新 |
UserPromptSubmit | 收到用户提示 | 预处理或验证输入 |
SubagentStart | 子代理启动 | 跟踪委托、记录上下文 |
SubagentStop | 子代理完成 | 汇总结果、清理 |
PreCompact | 上下文压缩前 | 在截断前保存状态 |
PermissionRequest | 需要权限时 | 自定义审批工作流 |
Stop | 代理停止时 | 清理、最终记录 |
SessionStart | 会话开始时 | 初始化状态 |
SessionEnd | 会话结束时 | 持久化状态、清理 |
Error | 发生错误时 | 自定义错误处理 |
钩子配置:
const response = query({
prompt: "...",
options: {
hooks: {
PreToolUse: async (input) => {
console.log(`Tool: ${input.toolName}`);
return { allow: true }; // 或 { allow: false, message: "..." }
},
PostToolUse: async (input) => {
await logToolUsage(input.toolName, input.result);
}
}
}
});
fallbackModel - 失败时自动回退模型maxThinkingTokens - 控制扩展思考预算strictMcpConfig - 严格的 MCP 配置验证continue - 使用新提示继续 (与 resume 不同)permissionMode: 'plan' - 用于规划工作流的新权限模式关键签名:
query(prompt: string | AsyncIterable<SDKUserMessage>, options?: Options)
-> AsyncGenerator<SDKMessage>
关键选项:
outputFormat - 结构化 JSON 模式验证 (v0.1.45+)settingSources - 文件系统设置加载 ('user'|'project'|'local')canUseTool - 自定义权限逻辑回调agents - 编程式子代理定义mcpServers - MCP 服务器配置permissionMode - 'default'|'acceptEdits'|'bypassPermissions'|'plan'betas - 启用 Beta 功能 (例如,1M 上下文窗口)sandbox - 安全执行的沙盒设置enableFileCheckpointing - 启用文件状态快照systemPrompt - 系统提示 (字符串或预设对象)启用 100 万令牌上下文窗口:
const response = query({
prompt: "Analyze this large codebase",
options: {
betas: ['context-1m-2025-08-07'], // 启用 1M 上下文
model: "claude-sonnet-4-5"
}
});
两种形式的 systemPrompt:
// 1. 简单字符串
systemPrompt: "You are a helpful coding assistant."
// 2. 带可选追加的预设 (保留 Claude Code 默认值)
systemPrompt: {
type: 'preset',
preset: 'claude_code',
append: "\n\nAdditional context: Focus on security."
}
使用预设形式 当你想要 Claude Code 的默认行为加上自定义附加内容时。
工具控制:
allowedTools - 白名单 (优先级更高)disallowedTools - 黑名单canUseTool - 自定义权限回调 (参见权限控制部分)内置工具: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, Task, NotebookEdit, BashOutput, KillBash, ListMcpResources, ReadMcpResource, AskUserQuestion
在代理执行期间启用用户交互:
const response = query({
prompt: "Review and refactor the codebase",
options: {
allowedTools: ["Read", "Write", "Edit", "AskUserQuestion"]
}
});
// 代理现在可以询问澄清问题
// 问题以 tool_call 形式出现在消息流中,名称为 "AskUserQuestion"
使用场景:
三种形式的工具配置:
// 1. 精确允许列表 (字符串数组)
tools: ["Read", "Write", "Grep"]
// 2. 禁用所有工具 (空数组)
tools: []
// 3. 带默认值的预设 (对象形式)
tools: { type: 'preset', preset: 'claude_code' }
注意: allowedTools 和 disallowedTools 仍然有效,但 tools 提供了更多灵活性。
服务器类型:
createSdkMcpServer() 和 tool() 定义工具定义:
tool(name: string, description: string, zodSchema, handler)
处理器返回:
{ content: [{ type: "text", text: "..." }], isError?: boolean }
const response = query({
prompt: "List files and analyze Git history",
options: {
mcpServers: {
// 文件系统服务器
"filesystem": {
command: "npx",
args: ["@modelcontextprotocol/server-filesystem"],
env: {
ALLOWED_PATHS: "/Users/developer/projects:/tmp"
}
},
// Git 操作服务器
"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"
]
}
});
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__<server-name>__<tool-name>
关键:
__) 作为分隔符allowedTools 数组中示例: mcp__weather-service__get_weather, mcp__filesystem__read_file
type AgentDefinition = {
description: string; // 何时使用此代理
prompt: string; // 代理的系统提示
tools?: string[]; // 允许的工具 (可选)
model?: 'sonnet' | 'opus' | 'haiku' | 'inherit'; // 模型 (可选)
skills?: string[]; // 要加载的技能 (v0.2.10+)
maxTurns?: number; // 停止前的最大轮次 (v0.2.10+)
}
字段详情:
haiku/sonnet/opus/inherit)用法:
agents: {
"security-checker": {
description: "安全审计和漏洞扫描",
prompt: "你负责安全检查。扫描密钥,验证 OWASP 合规性。",
tools: ["Read", "Grep", "Bash"],
model: "sonnet",
skills: ["security-best-practices"], // 加载特定技能
maxTurns: 10 // 限制为 10 轮
}
}
已知问题 : 当父代理停止时,子代理不会停止 (问题 #132)
当父代理停止时 (通过取消或错误),生成的子代理会继续作为孤立进程运行。这可能导致:
解决方法 : 在 Stop 钩子中实现清理:
const response = query({
prompt: "Deploy to production",
options: {
agents: {
"deployer": {
description: "处理部署",
prompt: "部署应用程序",
tools: ["Bash"]
}
},
hooks: {
Stop: async (input) => {
// 手动清理生成的进程
console.log("Parent stopped - cleaning up subagents");
// 实现进程跟踪和终止
}
}
}
});
增强跟踪 : 问题 #142 提议自动终止
选项:
resume: sessionId - 继续之前的会话forkSession: true - 从会话创建新分支continue: prompt - 使用新提示继续 (与 resume 不同)会话分叉模式 (独特能力):
// 在不修改原始会话的情况下探索替代方案
const forked = query({
prompt: "Try GraphQL instead of REST",
options: {
resume: sessionId,
forkSession: true // 创建新分支,原始会话保持不变
}
});
捕获会话 ID:
for await (const message of response) {
if (message.type === 'system' && message.subtype === 'init') {
sessionId = message.session_id; // 保存供后续恢复/分叉使用
}
}
更简单的多轮对话模式:
import {
unstable_v2_createSession,
unstable_v2_resumeSession,
unstable_v2_prompt
} from "@anthropic-ai/claude-agent-sdk";
// 创建新会话
const session = await unstable_v2_createSession({
model: "claude-sonnet-4-5",
workingDirectory: process.cwd(),
allowedTools: ["Read", "Grep", "Glob"]
});
// 发送提示并流式接收响应
const stream = unstable_v2_prompt(session, "Analyze the codebase structure");
for await (const message of stream) {
console.log(message);
}
// 在同一会话中继续对话
const stream2 = unstable_v2_prompt(session, "Now suggest improvements");
for await (const message of stream2) {
console.log(message);
}
// 恢复之前的会话
const resumedSession = await unstable_v2_resumeSession(session.sessionId);
注意: V2 API 处于预览状态 (unstable_ 前缀)。.receive() 方法在 v0.1.72 中更名为 .stream()。
权限模式:
type PermissionMode = "default" | "acceptEdits" | "bypassPermissions" | "plan";
default - 标准权限检查acceptEdits - 自动批准文件编辑bypassPermissions - 跳过所有检查 (仅在 CI/CD 中使用)plan - 规划模式 (v0.1.45+)const response = query({
prompt: "Deploy application to production",
options: {
permissionMode: "default",
canUseTool: async (toolName, input) => {
// 允许只读操作
if (['Read', 'Grep', 'Glob'].includes(toolName)) {
return { behavior: "allow" };
}
// 拒绝破坏性 bash 命令
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"
};
}
}
// 部署需要确认
if (input.command?.includes('deploy') || input.command?.includes('kubectl apply')) {
return {
behavior: "ask",
message: "Confirm deployment to production?"
};
}
// 默认允许
return { behavior: "allow" };
}
}
});
type CanUseToolCallback = (
toolName: string,
input: any
) => Promise<PermissionDecision>;
type PermissionDecision =
| { behavior: "allow" }
| { behavior: "deny"; message?: string }
| { behavior: "ask"; message?: string };
示例:
// 阻止所有文件写入
canUseTool: async (toolName, input) => {
if (toolName === 'Write' || toolName === 'Edit') {
return { behavior: "deny", message: "No file modifications allowed" };
}
return { behavior: "allow" };
}
// 对特定文件需要确认
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" };
}
// 记录所有工具使用情况
canUseTool: async (toolName, input) => {
console.log(`Tool requested: ${toolName}`, input);
await logToDatabase(toolName, input);
return { behavior: "allow" };
}
为 Bash 命令启用沙盒化执行:
const response = query({
prompt: "Run system diagnostics",
options: {
sandbox: {
enabled: true,
autoAllowBashIfSandboxed: true, // 在沙盒中自动批准 bash
excludedCommands: ["rm", "dd", "mkfs"], // 从不自动批准这些命令
allowUnsandboxedCommands: false // 拒绝无法沙盒化的命令
}
}
});
type SandboxSettings = {
enabled: boolean;
autoAllowBashIfSandboxed?: boolean; // 默认: false
excludedCommands?: string[];
allowUnsandboxedCommands?: boolean; // 默认: false
network?: NetworkSandboxSettings;
ignoreViolations?: SandboxIgnoreViolations;
};
type NetworkSandboxSettings = {
enabled: boolean;
proxyUrl?: string; // 网络请求的 HTTP 代理
};
关键选项:
enabled - 激活沙盒隔离autoAllowBashIfSandboxed - 对安全的 bash 命令跳过权限提示excludedCommands - 始终需要权限的命令allowUnsandboxedCommands - 允许无法沙盒化的命令 (有风险)network.proxyUrl - 通过代理路由网络以进行监控最佳实践: 在生产环境中处理不受信任输入的代理始终使用沙盒。
启用文件状态快照以实现回滚能力:
const response = query({
prompt: "Refactor the authentication module",
options: {
enableFileCheckpointing: true // 启用文件快照
}
});
// 稍后: 将文件更改回滚到特定点
for await (const message of response) {
if (message.type === 'user' && message.uuid) {
// 稍后可以回滚到此点
const userMessageUuid = message.uuid;
// 回滚 (在 Query 对象上调用)
await response.rewindFiles(userMessageUuid);
}
}
使用场景:
设置源:
type SettingSource = 'user' | 'project' | 'local';
user - ~/.claude/settings.json (全局)project - .claude/settings.json (团队共享)local - .claude/settings.local.json (gitignored 覆盖)默认: 不加载任何设置 (settingSources: [])
当加载多个源时,设置按以下顺序合并 (优先级从高到低):
query()) - 始终优先.claude/settings.local.json).claude/settings.json)~/.claude/settings.json)示例:
// .claude/settings.json
{
"allowedTools": ["Read", "Write", "Edit"]
}
// .claude/settings.local.json
{
"allowedTools": ["Read"] // 覆盖项目设置
}
// 编程方式
const response = query({
options: {
settingSources: ["project", "local"],
allowedTools: ["Read", "Grep"] // ← 这个优先
}
});
// 实际 allowedTools: ["Read", "Grep"]
最佳实践: 在 CI/CD 中使用 settingSources: ["project"] 以确保行为一致。
query() 函数返回一个具有以下方法的 Query 对象:
const q = query({ prompt: "..." });
// 异步迭代 (主要用法)
for await (const message of q) { ... }
// 运行时模型控制
await q.setModel("claude-opus-4-5"); // 在会话中途更改模型
await q.setMaxThinkingTokens(4096); // 设置思考预算
// 内省
const models = await q.supportedModels(); // 列出可用模型
const commands = await q.supportedCommands(); // 列出可用命令
const account = await q.accountInfo(); // 获取账户详情
// MCP 状态
const status = await q.mcpServerStatus(); // 检查 MCP 服务器状态
// 返回: { [serverName]: { status: 'connected' | 'failed', error?: string } }
// 文件操作 (需要 enableFileCheckpointing)
await q.rewindFiles(userMessageUuid); // 回滚到检查点
使用场景:
消息类型:
system - 会话初始化/完成 (包含 session_id)assistant - 代理响应tool_call - 工具执行请求tool_result - 工具执行结果error - 错误消息result - 最终结果 (v0.1.45+ 包含 structured_output)流式处理模式:
for await (const message of response) {
if (message.type === 'system' && message.subtype === 'init') {
sessionId = message.session_id; // 捕获供恢复/分叉使用
}
if (message.type === 'result' && message.structured_output) {
// 结构化输出可用 (v0.1.45+)
const validated = schema.parse(message.structured_output);
}
}
错误代码:
| 错误代码 | 原因 | 解决方案 |
|---|---|---|
CLI_NOT_FOUND | Claude Code 未安装 | 安装: npm install -g @anthropic-ai/claude-code |
AUTHENTICATION_FAILED | API 密钥无效 | 检查 ANTHROPIC_API_KEY 环境变量 |
RATE_LIMIT_EXCEEDED | 请求过多 | 实现带退避的重试机制 |
CONTEXT_LENGTH_EXCEEDED | 提示过长 | 使用会话压缩,减少上下文 |
PERMISSION_DENIED | 工具被阻止 | 检查 permissionMode、canUseTool |
TOOL_EXECUTION_FAILED | 工具错误 | 检查工具实现 |
SESSION_NOT_FOUND | 会话 ID 无效 | 验证会话 ID |
MCP_SERVER_FAILED | 服务器错误 | 检查服务器配置 |
此技能预防 14 个已记录的问题:
错误 : "Claude Code CLI not installed" 来源 : SDK 需要 Claude Code CLI 发生原因 : CLI 未全局安装 预防 : 使用 SDK 前安装: npm install -g @anthropic-ai/claude-code
错误 : "Invalid API key" 来源 : 缺少或错误的 ANTHROPIC_API_KEY 发生原因 : 环境变量未设置 预防 : 始终设置 export ANTHROPIC_API_KEY="sk-ant-..."
错误 : 工具执行被阻止 来源 : permissionMode 限制 发生原因 : 工具未被权限允许 预防 : 使用 allowedTools 或自定义 canUseTool 回调
错误 : "Prompt too long" 来源 : 输入超出模型上下文窗口 (问题 #138) 发生原因 : 大型代码库、长对话
⚠️ 关键行为 : 一旦会话达到上下文限制:
/compact 命令因相同错误而失败预防策略 :
// 1. 主动会话分叉 (在达到限制前创建检查点)
const checkpoint = query({
prompt: "Checkpoint current state",
options: {
resume: sessionId,
forkSession: true // 在达到限制前创建分支
}
});
// 2. 监控时间并主动轮换会话
const MAX_SESSION_TIME = 80 * 60 * 1000; // 80 分钟 (在 90 分钟崩溃前)
let sessionStartTime = Date.now();
function shouldRotateSession() {
return Date.now() - sessionStartTime > MAX_SESSION_TIME;
}
// 3. 在达到上下文限制前启动新会话
if (shouldRotateSession()) {
const summary = await getSummary(currentSession);
const newSession = query({
prompt: `Continue with context: ${summary}`
});
sessionStartTime = Date.now();
}
注意 : SDK 会自动压缩,但如果达到限制,会话将无法恢复
错误 : 工具无响应 来源 : 长时间运行的工具执行 发生原因 : 工具运行时间过长 (>5 分钟默认值) 预防 : 在工具实现中实现超时处理
错误 : "Invalid session ID" 来源 : 会话过期或无效 发生原因 : 会话 ID 不正确或太旧 预防 : 从 system 初始化消息中捕获 session_id
错误 : 服务器无响应 来源 : 服务器未运行或配置错误 发生原因 : 命令/URL 不正确,服务器崩溃 预防 : 独立测试 MCP 服务器,验证命令/URL
错误 : 无效的 AgentDefinition 来源 : 缺少必需字段 发生原因 : 缺少 description 或 prompt 预防 : 始终包含 description 和 prompt 字段
错误 : "Cannot read settings" 来源 : 设置文件不存在 发生原因 : settingSources 包含不存在的文件 预防 : 在包含到源中之前检查文件是否存在
错误 : 重复的工具名称 来源 : 多个工具使用相同名称 发生原因 : 两个 MCP 服务器定义了相同的工具名称 预防 : 使用唯一的工具名称,用服务器名称作为前缀
错误 : 无效的工具输入 来源 : 输入不匹配 Zod 模式 发生原因 : 代理提供了错误的数据类型 预防 : 使用带有 .describe() 的描述性 Zod 模式
错误 : 无法访问路径 来源 : 受限的文件系统访问 发生原因 : 路径在 workingDirectory 之外或无权限 预防 : 设置正确的 workingDirectory,检查文件权限
type 字段错误 : "Claude Code process exited with code 1" (隐晦,无上下文) 来源 : GitHub 问题 #131 发生原因 : 基于 URL 的 MCP 服务器需要显式的 type: "http" 或 type: "sse" 字段 预防 : 对于基于 URL 的 MCP 服务器始终指定传输类型
// ❌ 错误 - 缺少 type 字段 (导致隐晦的退出代码 1)
mcpServers: {
"my-server": {
url: "https://api.example.com/mcp"
}
}
// ✅ 正确 - 基于 URL 的服务器需要 type 字段
mcpServers: {
"my-server": {
url: "https://api.example.com/mcp",
type: "http" // 或用于 Server-Sent Events 的 "sse"
}
}
诊断线索 : 如果你看到 "process exited with code 1" 且没有其他上下文,请检查你的 MCP 服务器配置是否缺少 type 字段。
错误 : JSON 解析错误,代理挂起 来源 : GitHub 问题 #137 发生原因 : Unicode U+2028 (行分隔符) 和 U+2029 (段落分隔符) 在 JSON 中有效,但会破坏 JavaScript 解析 预防 : 在 MCP 工具结果中转义这些字符
// MCP 工具处理器 - 清理外部数据
tool("fetch_content", "Fetch text content", {}, async (args) => {
const content = await fetchExternalData();
// ✅ 清理 Unicode 行/段落分隔符
const sanitized = content
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029');
return {
content: [{ type: "text", text: sanitized }]
};
});
何时重要 : 可能包含这些字符的外部数据源 (API、网络抓取、用户输入)
令牌效率 :
预防的错误 : 14 个已记录问题及其确切解决方案 (包括 2 个社区发现的陷阱) 关键价值 : V2 会话 API、沙盒设置、文件检查点、查询方法、AskUserQuestion 工具、结构化输出 (v0.1.45+)、会话分叉、canUseTool 模式、完整的钩子系统 (12 个事件)、Zod v4 支持、子代理清理模式
最后验证 : 2026-01-20 | 技能版本 : 3.1.0 | 变更 : 添加了问题 #13 (MCP type 字段)、问题 #14 (Unicode U+2028/U+2029)、扩展了问题 #4 (会话破坏性)、添加了带有 Stop 钩子模式的子代理清理警告
每周安装
415
仓库
GitHub 星标
656
首次出现
2026年1月20日
安全审计
安装于
claude-code363
opencode279
gemini-cli274
cursor257
codex247
antigravity236
Package : @anthropic-ai/claude-agent-sdk@0.2.12 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:
import { query } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
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}`);
}
}
Zod Compatibility (v0.1.71+): SDK supports both Zod v3.24.1+ and Zod v4.0.0+ as peer dependencies. Import remains import { z } from "zod" for either version.
plugins array - Load local plugin pathsAll 12 Hook Events:
| Hook | When Fired | Use Case |
|---|---|---|
PreToolUse | Before tool execution | Validate, modify, or block tool calls |
PostToolUse | After tool execution | Log results, trigger side effects |
Notification | Agent notifications | Display status updates |
UserPromptSubmit | User prompt received | Pre-process or validate input |
SubagentStart | Subagent spawned |
Hook Configuration:
const response = query({
prompt: "...",
options: {
hooks: {
PreToolUse: async (input) => {
console.log(`Tool: ${input.toolName}`);
return { allow: true }; // or { allow: false, message: "..." }
},
PostToolUse: async (input) => {
await logToolUsage(input.toolName, input.result);
}
}
}
});
fallbackModel - 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:
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 callbackagents - Programmatic subagent definitionsmcpServers - MCP server configurationpermissionMode - 'default'|'acceptEdits'|'bypassPermissions'|'plan'betas - Enable beta features (e.g., 1M context window)sandbox - Sandbox settings for secure executionenableFileCheckpointing - Enable file state snapshotsEnable 1 million token context window:
const response = query({
prompt: "Analyze this large codebase",
options: {
betas: ['context-1m-2025-08-07'], // Enable 1M context
model: "claude-sonnet-4-5"
}
});
Two forms of systemPrompt:
// 1. Simple string
systemPrompt: "You are a helpful coding assistant."
// 2. Preset with optional append (preserves Claude Code defaults)
systemPrompt: {
type: 'preset',
preset: 'claude_code',
append: "\n\nAdditional context: Focus on security."
}
Use preset form when you want Claude Code's default behaviors plus custom additions.
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, AskUserQuestion
Enable user interaction during agent execution:
const response = query({
prompt: "Review and refactor the codebase",
options: {
allowedTools: ["Read", "Write", "Edit", "AskUserQuestion"]
}
});
// Agent can now ask clarifying questions
// Questions appear in message stream as tool_call with name "AskUserQuestion"
Use cases:
Three forms of tool configuration:
// 1. Exact allowlist (string array)
tools: ["Read", "Write", "Grep"]
// 2. Disable all tools (empty array)
tools: []
// 3. Preset with defaults (object form)
tools: { type: 'preset', preset: 'claude_code' }
Note: allowedTools and disallowedTools still work but tools provides more flexibility.
Server Types:
createSdkMcpServer() with tool() definitionsTool Definition:
tool(name: string, description: string, zodSchema, handler)
Handler Return:
{ content: [{ type: "text", text: "..." }], isError?: boolean }
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"
]
}
});
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"]
}
});
Format : mcp__<server-name>__<tool-name>
CRITICAL:
__) as separatorsallowedTools arrayExamples: mcp__weather-service__get_weather, mcp__filesystem__read_file
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)
skills?: string[]; // Skills to load (v0.2.10+)
maxTurns?: number; // Maximum turns before stopping (v0.2.10+)
}
Field Details:
haiku/sonnet/opus/inherit)Usage:
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",
skills: ["security-best-practices"], // Load specific skills
maxTurns: 10 // Limit to 10 turns
}
}
Known Issue : Subagents don't stop when parent agent stops (Issue #132)
When a parent agent is stopped (via cancellation or error), spawned subagents continue running as orphaned processes. This can lead to:
Workaround : Implement cleanup in Stop hooks:
const response = query({
prompt: "Deploy to production",
options: {
agents: {
"deployer": {
description: "Handle deployments",
prompt: "Deploy the application",
tools: ["Bash"]
}
},
hooks: {
Stop: async (input) => {
// Manual cleanup of spawned processes
console.log("Parent stopped - cleaning up subagents");
// Implement process tracking and termination
}
}
}
});
Enhancement Tracking : Issue #142 proposes auto-termination
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):
// 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:
for await (const message of response) {
if (message.type === 'system' && message.subtype === 'init') {
sessionId = message.session_id; // Save for later resume/fork
}
}
Simpler multi-turn conversation pattern:
import {
unstable_v2_createSession,
unstable_v2_resumeSession,
unstable_v2_prompt
} from "@anthropic-ai/claude-agent-sdk";
// Create a new session
const session = await unstable_v2_createSession({
model: "claude-sonnet-4-5",
workingDirectory: process.cwd(),
allowedTools: ["Read", "Grep", "Glob"]
});
// Send prompts and stream responses
const stream = unstable_v2_prompt(session, "Analyze the codebase structure");
for await (const message of stream) {
console.log(message);
}
// Continue conversation in same session
const stream2 = unstable_v2_prompt(session, "Now suggest improvements");
for await (const message of stream2) {
console.log(message);
}
// Resume a previous session
const resumedSession = await unstable_v2_resumeSession(session.sessionId);
Note: V2 APIs are in preview (unstable_ prefix). The .receive() method was renamed to .stream() in v0.1.72.
Permission Modes:
type 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+)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" };
}
}
});
type CanUseToolCallback = (
toolName: string,
input: any
) => Promise<PermissionDecision>;
type PermissionDecision =
| { behavior: "allow" }
| { behavior: "deny"; message?: string }
| { behavior: "ask"; message?: string };
Examples:
// 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" };
}
Enable sandboxed execution for Bash commands:
const response = query({
prompt: "Run system diagnostics",
options: {
sandbox: {
enabled: true,
autoAllowBashIfSandboxed: true, // Auto-approve bash in sandbox
excludedCommands: ["rm", "dd", "mkfs"], // Never auto-approve these
allowUnsandboxedCommands: false // Deny unsandboxable commands
}
}
});
type SandboxSettings = {
enabled: boolean;
autoAllowBashIfSandboxed?: boolean; // Default: false
excludedCommands?: string[];
allowUnsandboxedCommands?: boolean; // Default: false
network?: NetworkSandboxSettings;
ignoreViolations?: SandboxIgnoreViolations;
};
type NetworkSandboxSettings = {
enabled: boolean;
proxyUrl?: string; // HTTP proxy for network requests
};
Key Options:
enabled - Activate sandbox isolationautoAllowBashIfSandboxed - Skip permission prompts for safe bash commandsexcludedCommands - Commands that always require permissionallowUnsandboxedCommands - Allow commands that can't be sandboxed (risky)network.proxyUrl - Route network through proxy for monitoringBest Practice: Always use sandbox in production agents handling untrusted input.
Enable file state snapshots for rollback capability:
const response = query({
prompt: "Refactor the authentication module",
options: {
enableFileCheckpointing: true // Enable file snapshots
}
});
// Later: rewind file changes to a specific point
for await (const message of response) {
if (message.type === 'user' && message.uuid) {
// Can rewind to this point later
const userMessageUuid = message.uuid;
// To rewind (call on Query object)
await response.rewindFiles(userMessageUuid);
}
}
Use cases:
Setting Sources:
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: [])
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:
// .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.
The query() function returns a Query object with these methods:
const q = query({ prompt: "..." });
// Async iteration (primary usage)
for await (const message of q) { ... }
// Runtime model control
await q.setModel("claude-opus-4-5"); // Change model mid-session
await q.setMaxThinkingTokens(4096); // Set thinking budget
// Introspection
const models = await q.supportedModels(); // List available models
const commands = await q.supportedCommands(); // List available commands
const account = await q.accountInfo(); // Get account details
// MCP status
const status = await q.mcpServerStatus(); // Check MCP server status
// Returns: { [serverName]: { status: 'connected' | 'failed', error?: string } }
// File operations (requires enableFileCheckpointing)
await q.rewindFiles(userMessageUuid); // Rewind to checkpoint
Use cases:
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:
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 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 |
This skill prevents 14 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 (Issue #138) Why It Happens : Large codebase, long conversations
⚠️ Critical Behavior : Once a session hits context limit:
/compact command fails with same errorPrevention Strategies :
// 1. Proactive session forking (create checkpoints before hitting limit)
const checkpoint = query({
prompt: "Checkpoint current state",
options: {
resume: sessionId,
forkSession: true // Create branch before hitting limit
}
});
// 2. Monitor time and rotate sessions proactively
const MAX_SESSION_TIME = 80 * 60 * 1000; // 80 minutes (before 90-min crash)
let sessionStartTime = Date.now();
function shouldRotateSession() {
return Date.now() - sessionStartTime > MAX_SESSION_TIME;
}
// 3. Start new sessions before hitting context limits
if (shouldRotateSession()) {
const summary = await getSummary(currentSession);
const newSession = query({
prompt: `Continue with context: ${summary}`
});
sessionStartTime = Date.now();
}
Note : SDK auto-compacts, but if limit is reached, session becomes unrecoverable
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
type FieldError : "Claude Code process exited with code 1" (cryptic, no context) Source : GitHub Issue #131 Why It Happens : URL-based MCP servers require explicit type: "http" or type: "sse" field Prevention : Always specify transport type for URL-based MCP servers
// ❌ Wrong - missing type field (causes cryptic exit code 1)
mcpServers: {
"my-server": {
url: "https://api.example.com/mcp"
}
}
// ✅ Correct - type field required for URL-based servers
mcpServers: {
"my-server": {
url: "https://api.example.com/mcp",
type: "http" // or "sse" for Server-Sent Events
}
}
Diagnostic Clue : If you see "process exited with code 1" with no other context, check your MCP server configuration for missing type fields.
Error : JSON parse error, agent hangs Source : GitHub Issue #137 Why It Happens : Unicode U+2028 (line separator) and U+2029 (paragraph separator) are valid in JSON but break JavaScript parsing Prevention : Escape these characters in MCP tool results
// MCP tool handler - sanitize external data
tool("fetch_content", "Fetch text content", {}, async (args) => {
const content = await fetchExternalData();
// ✅ Sanitize Unicode line/paragraph separators
const sanitized = content
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029');
return {
content: [{ type: "text", text: sanitized }]
};
});
When This Matters : External data sources (APIs, web scraping, user input) that may contain these characters
Related : MCP Python SDK Issue #1356
Token Efficiency :
Errors prevented : 14 documented issues with exact solutions (including 2 community-sourced gotchas) Key value : V2 Session APIs, Sandbox Settings, File Checkpointing, Query methods, AskUserQuestion tool, structured outputs (v0.1.45+), session forking, canUseTool patterns, complete hooks system (12 events), Zod v4 support, subagent cleanup patterns
Last verified : 2026-01-20 | Skill version : 3.1.0 | Changes : Added Issue #13 (MCP type field), Issue #14 (Unicode U+2028/U+2029), expanded Issue #4 (session-breaking), added subagent cleanup warning with Stop hook pattern
Weekly Installs
415
Repository
GitHub Stars
656
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubFailSocketPassSnykWarn
Installed on
claude-code363
opencode279
gemini-cli274
cursor257
codex247
antigravity236
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
138,300 周安装
save-thread技能:会话保存与交接摘要工具(兼容性说明)
320 周安装
Canvas Design - AI设计哲学与视觉表达工具,自动生成专业级视觉艺术作品
320 周安装
Codex Subagent 子代理技能:创建自主代理卸载上下文密集型任务,优化AI工作流
320 周安装
Snowflake原生Streamlit应用开发指南:部署、运行时与安全模型详解
320 周安装
agent-browser:专为AI智能体设计的Rust无头浏览器自动化CLI工具
321 周安装
Preline主题生成器 - 一键生成美观UI主题CSS文件,支持深色模式
321 周安装
| Track delegation, log context |
SubagentStop | Subagent completed | Aggregate results, cleanup |
PreCompact | Before context compaction | Save state before truncation |
PermissionRequest | Permission needed | Custom approval workflows |
Stop | Agent stopping | Cleanup, final logging |
SessionStart | Session begins | Initialize state |
SessionEnd | Session ends | Persist state, cleanup |
Error | Error occurred | Custom error handling |
systemPrompt - System prompt (string or preset object)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 |