Repository navigation
Agent Sdk
英文名:
agent-sdk· 领域:插件与扩展 · 返回功能索引
Claude Agent SDK 让你在自己的 TypeScript / Python 程序里使用 Claude Code:发一个任务,逐条收到 Claude 的思考、工具调用、工具结果和最终结果。SDK 在底层启动 claude 进程,用 stream-json(一行一个 JSON)和它通信。
本 fork 的 CLI 可以直接作为 SDK 的执行程序,只要把 pathToClaudeCodeExecutable 指过来。已用官方 TS SDK 0.3.303 和 Python SDK 验证,并补齐了 SDK 会发的几个控制请求(见下方「和官方的区别」)。
import { query } from '@anthropic-ai/claude-agent-sdk'
const run = query({
prompt: 'List the files here.',
options: {
pathToClaudeCodeExecutable: '/path/to/built-claude',
allowedTools: ['Bash(ls)'],
},
})
for await (const message of run) {
if (message.type === 'system') console.log('system', message.subtype, 'model=' + message.model)
if (message.type === 'assistant')
for (const block of message.message.content)
console.log('assistant', block.type, block.type === 'text' ? block.text : `${block.name} ${JSON.stringify(block.input)}`)
if (message.type === 'user') console.log('tool_result', JSON.stringify(message.message.content[0]?.content).slice(0, 60))
if (message.type === 'result') console.log('result', message.subtype, `$${message.total_cost_usd.toFixed(4)}`, message.result)
}实际运行输出(本 fork 的 binary,测试用假 API):
system init model=claude-opus-5-5
assistant tool_use Bash {"command":"ls","description":"list files"}
tool_result "api\nbuild\nnotes.md\nt.txt\ntodo.md\nu.txt\nv.txt\nweb"
assistant text FAKE_DONE
result success $0.0003 FAKE_DONE
消息依次是:会话初始化(system/init)→ Claude 决定调用工具(assistant 里的 tool_use)→ 工具结果(user 里的 tool_result)→ Claude 的回复 → 最终 result(含费用)。
本 fork 不发布自己的 SDK 包,直接用官方的 @anthropic-ai/claude-agent-sdk(TS)和 claude-agent-sdk(Python)。原因:
- 官方 SDK 只是启动 CLI 并收发 stream-json。把
pathToClaudeCodeExecutable(Python 是cli_path)指向本 fork 的 binary,消息、工具、权限回调、会话管理就都能用。 - fork 独有的功能要么靠设置或环境变量打开,要么是会话里模型自己调用的工具。官方 SDK 已有的
env、settings、plugins、extraArgs选项足以把它们传进去,不需要新的 API。 - 官方 SDK 的许可是 Anthropic 的商业条款(
© Anthropic PBC. All rights reserved),fork 它的代码再发布有风险,还要一直跟进官方版本。
只有一种情况值得另做一个包:你要在自己的前端渲染 Mods 界面,需要 ui_* 控制请求的客户端。协议见 mods-sdk-client.md。
| fork 功能 | SDK 选项(TS / Python) | 写法 |
|---|---|---|
| OpenAI / ChatGPT provider |
env / env
|
CLAUDE_CODE_USE_OPENAI: '1',再加 OPENAI_API_KEY 或 OPENAI_AUTH_TOKEN,可选 OPENAI_BASE_URL。也可以不传凭据,复用 ~/.codex/auth.json(先在终端 CLAUDE_CODE_USE_OPENAI=1 claude 里 /login 一次,ChatGPT 账号也行) |
| Daybreak 网络安全档位 |
settings / settings(JSON 字符串) |
{ daybreak: 'blue' },可选 blue / red / off
|
| SQLite FTS5 记忆检索 | settings |
{ memory: { sqlite: { enabled: true } } },会话多出 SearchMemory 工具 |
| Dynamic Workflow | settings |
{ enableWorkflows: true, workflowSizeGuideline: 'small' },关闭用 enableWorkflows: false
|
| Mods |
plugins / plugins
|
[{ type: 'local', path: '/abs/path/to/mod' }] |
| 独立会话通信 |
extraArgs / extra_args
|
{ name: 'sdk-worker' },其他会话可以用这个名字找到它 |
注意:TS SDK 的 env 会整个替换子进程环境,要写成 { ...process.env, CLAUDE_CODE_USE_OPENAI: '1' };Python SDK 的 env 是合并到当前环境上。
可运行的示例在 examples/agent-sdk/,都通过环境变量 CLAUDE_FORK_BIN 找到 binary:
cd examples/agent-sdk
bun add @anthropic-ai/claude-agent-sdk
CLAUDE_FORK_BIN=/path/to/built-claude bun openai-provider.mjs| 文件 | 演示 |
|---|---|
basic.mjs |
最小用法 |
openai-provider.mjs / openai_provider.py
|
OpenAI provider + Daybreak blue |
fork-settings.mjs |
用 settings 打开 SQLite 记忆和 Workflow,从 system/init 的工具列表确认 |
mods-plugin.mjs + hello-mod/
|
用 plugins 加载一个 Mod,它拒绝 Claude 读取 .env
|
实际运行输出(官方 TS SDK 0.3.310 / Python SDK 0.2.165,本 fork 重新构建的 binary,测试用假 API):
$ bun openai-provider.mjs # OPENAI_BASE_URL 指向假 Responses API
init model=gpt-5.6-sol
result success FAKE_OPENAI_DONE
# 假 API 收到的请求:{"model":"gpt-5.6-sol","access_programs":{"cyber":"daybreak_blue"}}
$ python3 openai_provider.py # 同上,Python SDK
init model=gpt-5.6-sol
result success FAKE_OPENAI_DONE
$ bun fork-settings.mjs
tools SearchMemory,Workflow # 去掉 settings 时只有 Workflow
$ bun mods-plugin.mjs
plugins hello-mod,agents-md
tool_result "<tool_use_error>hello-mod: .env files are off limits</tool_use_error>"
result success FAKE_DONE # 不加载 Mod 时,Read 会返回 .env 的内容
用 extraArgs: { name: 'sdk-worker' } 启动后,~/.claude/sessions/<pid>.json 里有 "name":"sdk-worker"、"entrypoint":"sdk-ts",同机其他会话可以按这个名字给它发消息。
任何语言都可以自己启动 CLI 并读写 JSON 行:
claude -p --input-format stream-json --output-format stream-json --verbosestdin 里除了用户消息,还可以发控制请求(control_request),例如初始化、切换模型、切换权限模式。依次发送 initialize、reload_skills、一个非法的 set_permission_mode 和一条用户消息,收到的回执:
{"request_id": "r1", "subtype": "success", "keys": ["capabilities", "commands", "agents", "output_style", "available_output_styles", "models", "account", "pid"]}
{"request_id": "r2", "subtype": "success", "keys": ["skills"]}
{"request_id": "r3", "subtype": "error", "error": "Cannot set permission mode: must be one of acceptEdits, auto, bypassPermissions, default, dontAsk, plan"}
result success FAKE_DONE
想让工具权限请求交给你的程序决定(SDK 的 canUseTool),加 --permission-prompt-tool stdio。
- 补齐 SDK 0.3 会调用的控制请求:
reload_skills、reload_output_styles、read_file(按 Read 工具的权限判断)、update_settings(只接受官方白名单内的设置)、mcp_read_resource(只读ui://)。 - 接受
string[]形式的systemPrompt(TS SDK 默认发送[""])。 -
set_model、set_permission_mode对非法值返回错误码,而不是静默接受。 - VS Code 插件面板用到的控制请求(
get_status、get_usage、background_tasks等)见 vscode-extension.md。 - 接受 SDK 0.3.303 会传的四个隐藏参数(之前会以
error: unknown option退出):-
--session-mirror(SDK 的sessionStore):每次写入本地 transcript 后输出一行{"type":"transcript_mirror","filePath":...,"entries":[...]}。 -
--resume-drops-turn <prompt uuid>(SDK 的resumeDropsTurn):配合--resume-session-at截断恢复时,检查被丢弃的部分只属于这一轮;混入了别的用户消息、排队消息或压缩摘要时,返回error_during_execution,错误以Resume rejected by --resume-drops-turn:开头。 -
--managed-settings <json>(SDK 的managedSettings):作为 policy 层,只保留限制型设置(permissions.deny/ask、各类 deny 列表、allowedMcpServers等允许清单、allowManaged*Only等锁);model、env、permissions.allow之类会被丢弃。本机已有管理员的 managed settings 时默认忽略它,除非管理员设置parentSettingsBehavior: "merge"。 -
--project-config-root <绝对路径>(SDK 的projectConfigRoot):项目设置、.mcp.json、.claude下的 commands / agents / skills / workflows / output-styles 和 hooks 的CLAUDE_PROJECT_DIR都从这个目录读,而不是工作目录;此时不能改 project 范围的 MCP 配置。
-
-
tools: ['Read', 'Glob']这类限定工具清单会被严格遵守,不再多出ListAgents、SendMessage。 - 后台子代理(Agent 工具)的消息会实时流给 SDK,带
parent_tool_use_id;同时输出task_updated(任务状态、结束时间等变化)和background_tasks_changed(后台任务清单变化),task_started也带subagent_type、is_backgrounded。 -
task_started/task_updated/task_progress/task_notification和background_tasks_changed的每项都带run_id(同一任务 id 重新运行会换新值),task_started也带spawn_depth。 - 后台子代理还在跑时,原回合的
result先暂存,等子代理的task_notification发出后再输出;之后处理通知的回合再输出第二个result,和官方一致。 -
stop_task对不存在或已结束的任务回成功(和官方一致),task_id不是字符串时回错误。 - 尚未实现:
set_mcp_permission_mode_override。另外后台子代理结束时,本 fork 的background_tasks_changed(空清单)比task_notification早一条,官方是之后;两者内容相同,只是先后不同。
想把 Mods 的界面画到自己的前端,见 mods-sdk-client.md。
输出来自实际运行(官方 @anthropic-ai/claude-agent-sdk 驱动本 fork 的 binary,模型回复由测试用假 API 生成)。下方「详细说明」保留各控制请求的字段规则、边界与验收记录。
以下内容自原 README 迁入,保持原文。
开发客户端协议时,从 src/entrypoints/sdk/controlTypes.ts 使用有限的 SDKControlUIRequest,并用 SDKControlUIResponseFor<Request> 关联回执。18 类客户端请求与 5 类引擎发给客户端的 responder 请求分别为 SDKControlUIClientRequest / SDKControlUILoopRequest。同名 Zod schema 从 controlSchemas.ts 导出;这些是仓库内部协议定义,不是额外的作者 $ capability。
下面的代码只构造并校验协议数据:
import type { SDKControlUIRenderRequest, SDKControlUIResponseFor } from './src/entrypoints/sdk/controlTypes.js'
import { SDKControlUIRenderRequestSchema } from './src/entrypoints/sdk/controlSchemas.js'
const request: SDKControlUIRenderRequest = {
subtype: 'ui_render', surface: 'desktop', component: 'ToolUse',
instance_id: 'tool-1', props: { input: { command: 'pwd' } }, on_screen: null,
}
const parsed = SDKControlUIRenderRequestSchema().parse(request)
type RenderResponse = SDKControlUIResponseFor<typeof request>绘制回执含 tree、props、rewritten 和 hooked,可带插件到 hash 的 client_modules 及 bench;客户端模块回执另含 entry、runtime、limits 和 files。树通过 handle 传递回调,通过路径传递 Client 模块。pane roster 的三个 nullable ID 和 focus 的 nullable element 都是必填字段;ui_message.data 必须存在,null 合法。输入校验与绘制、客户端资源及 hook 的运行时语义分别验收。
执行 make check-mods-control-types 做独立严格类型检查;make release-check 已包含此项。协议回归:
bun test --no-env-file ./src/entrypoints/sdk/controlSchemas.mods.test.ts ./src/entrypoints/sdk/controlSchemas.ssh.test.ts ./src/services/mods/remoteUiControl.test.ts协议定义覆盖其余远程控制及 system pane/scroll/focus 消息,当前 CLI 接通 ui_attach / ui_detach / ui_render / ui_press / ui_input / ui_select / ui_client_module / ui_client_press / ui_message / ui_client_fault 及 ui_invalidate 推送;Pane/scroll 的控制与推送见下文专项;元素 focus、prompt 控制和 focus 推送见下文新专项。18类客户端控制有运行入口,五类 responder 尚待完成;23类协议定义不代表23类功能均已验收。完整 UI/diff 继续单独验收。官方原生回执、字段限制与验证范围见SDK UI 协议专项。
mcp_set_servers 中的 stdio 配置应显式填写 args;没有命令行参数时也写 []:
{"type":"control_request","request_id":"mcp-1","request":{"subtype":"mcp_set_servers","servers":{"example":{"type":"stdio","command":"node","args":["/absolute/path/server.mjs"]}}}}
{"type":"control_request","request_id":"mcp-remove-1","request":{"subtype":"mcp_set_servers","servers":{}}}省略 args 时,在创建连接前返回 errors.example: "Spread syntax requires ...iterable not be null or undefined",与固定官方 2.1.292 一致。控制请求本身仍返回成功回执,并将服务器名称列入 added;调用方必须检查 errors。失败配置可通过后续空 servers 请求移除,移除回执的 removed 包含该名称。
本项验收覆盖不存在和存在的命令省略 args、完整控制回执、移除及退出。缺失可执行文件的系统错误路径文案仍与官方有差异;完整 MCP、Mods 及 SDK 生命周期继续单独验收。
查询当前服务器时发送:
{"type":"control_request","request_id":"mcp-status-1","request":{"subtype":"mcp_status"}}mcpServers[].source 是可选字符串,表示服务器定义来自何处:SDK 宿主注册的服务器为 sdk,插件提供的服务器为 plugin,普通配置返回其配置范围(如 user、project、local、dynamic)。scope 与 source 分开:插件和 SDK 服务器可以同属 dynamic 范围。读取来源应使用 source;服务器名称只是配置键,不能据其名称判定来源。兼容旧 CLI 未返回该字段的状态对象。
SDK 服务器连接成功后,serverInfo 来自 MCP initialize 响应的服务器实现信息,包含名称和版本;等待握手完成后再读取。source: "sdk" 表示定义来源,连接是否成功仍以 status 和实际握手结果为准。
MCP 服务器可在 initialize 响应的 result.instructions 中返回使用工具和资源的可选字符串。SDK 宿主也通过同一握手返回;等待连接完成后发送用户请求。非空指令通过 system-reminder 消息进入当前模型请求,SDK 与普通连接使用同一路径。字段位置见 MCP 的初始化规范。
指令默认最多保留 2048 个 UTF-16 单元。CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH 可设置正整数上限,支持前后空格和正号;非法值回退默认值。超长时附加 … [truncated],截断不会留下半个 Unicode 代理对。--debug-file 中会记录服务器名称、原始长度和上限。
这条上下文路径按固定官方 2.1.292 对照了 9 个 SDK、3 个 stdio 场景,包括缺省、空、超长、Unicode 边界及有效/无效上限;实际模型请求中的完整指令段和消息位置、状态/移除/结束回执及退出结果一致。本地 stream-json 的磁盘 transcript 仍会过滤此 attachment,恢复后的上下文尚未与官方对齐;上述对照只覆盖新会话的当前请求。磁盘持久化、恢复、重连后的指令变化及完整 MCP/Mods/UI 生命周期继续单独验收。
固定官方 2.1.292 的对照覆盖用户、动态和插件连接失败,以及 SDK 基本和完整 Implementation 元数据的成功握手;这些场景的完整状态、移除和退出回执相同。运行时 mod 注册服务器及完整 MCP/SDK 生命周期继续单独验收。
在 stream-json 会话中发送 set_model,并等待相同 request_id 的 control_response:
{"type":"control_request","request_id":"model-1","request":{"subtype":"set_model","model":"claude-sonnet-4-6"}}自定义模型先用最小 API 请求验证;验证成功才修改会话模型,同一进程的成功结果可复用。验证失败保留原模型,返回具体错误及可选 error_code:模型不在 availableModels 允许列表为 restricted_by_org,网络/可重试服务器失败为 check_failed,认证失败为 auth_failed,模型不存在为 catalog_unknown。PreModelSwitch hook 拒绝或要求确认时也会返回不带错误码的失败。普通 API 拒绝可以不带错误码,调用方应始终读取 error。错误码在类型定义和 schema 解析中保留。
API 验证的期限为 5 秒,超时会取消请求并返回 check_failed;晚到结果不会进入成功缓存。模型切换按接收顺序处理,等待验证期间仍可处理 interrupt 等控制消息。紧随 set_model 的用户消息在队列中等待验证完成,再使用实际生效的模型;未显式配置 effort 时使用该模型的默认值。验证失败时继续使用原模型。空模型名被拒绝;default 使用当前默认模型。通用配置见 Anthropic 的模型配置文档。
本项按固定官方 2.1.292 验收受控 API、缓存、错误回执、失败不改模型及等待期间的 interrupt 顺序。延迟校验后立即发消息的模型与 effort 已完成三方对照;普通 Sonnet 请求仍省略官方显式发送的 high,保留为请求形状差异。成功切换后的压缩状态来源见下节;远程 Mods 提示仍与官方不同。组织目录/授权覆盖、模型切换 Hook、system_prompt 和完整 SDK 生命周期仍需独立对齐与验收。
在 stream-json 会话中发送 set_permission_mode:
{"type":"control_request","request_id":"mode-1","request":{"subtype":"set_permission_mode","mode":"acceptEdits"}}切换与 Shift+Tab、/yolo 走同一闸门(bypass 策略与可用性、auto 闸门、plan 可用性)。失败时保留原模式,返回错误及 error_code,例如未知模式为 invalid_mode,bypass 被策略停用为 bypass_disabled,未以 bypass 启动为 bypass_not_launched,auto 设置不允许为 auto_mode_settings;完整取值见 src/entrypoints/sdk/controlTypes.ts。
canUseTool 回调返回 allow 时可省略 updatedInput,此时使用原始输入;格式错误的结果以说明预期格式的消息拒绝。
本页由 docs/features/agent-sdk.md 自动同步,请在仓库中修改。
- Agent SDK 与 stream-json 控制协议
- Agent Teams
- Agent 与后台任务
- 自动模式(Auto mode)
- 背景会话、daemon 与 agents 视图
- 自定义 UI / Branding 与 Status line
- 构建、发布与终端验收工具
- Channels
- Codex Apps
- 自动压缩窗口
- 调试日志
- /diff 视图
- Direct Connect
- Effort 档位
- 自主 Goal
- Hooks 事件、匹配与输出校验
- 快捷键与 Vim 模式
- MCP 配置与认证
- 记忆:auto memory 与 SQLite FTS5 检索
- 模型自动发现与 Gateway
- Mods 远程客户端(stream-json)
- Mods / Function Hooks
- Monitor 工具
- OpenAI / Codex provider
- 独立会话通信
- 权限规则、权限模式与 Safe mode
- 插件与 Marketplace
- Prompt context 与 Tool search
- 请求韧性:重试、回退模型与默认模型
- Bash 沙箱
- 定时任务:Cron、/loop 与 ScheduleWakeup
- 会话命令
- Skills
- SSH Remote
- 遥测与反馈
- 终端程序状态(OSC 7501)
- Terminal 工具
- 用量、成本与状态
- VS Code 插件
- Dynamic Workflow