基于 Claude Code v2.1.88 源码分析,源码路径:
src/
工具系统的核心类型定义在 src/Tool.ts,每个工具必须实现 Tool 接口。该接口采用泛型设计,支持类型安全的输入/输出和进度报告。
type Tool<
Input extends AnyObject = AnyObject, // Zod schema 约束的输入类型
Output = unknown, // 工具执行输出类型
P extends ToolProgressData = ToolProgressData // 进度事件类型
>| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
name |
string |
是 | 工具唯一标识符,如 Bash、Edit |
aliases |
string[] |
否 | 向后兼容的别名(重命名后旧名称仍可用) |
inputSchema |
z.ZodType |
是 | Zod schema,用于输入验证 |
inputJSONSchema |
ToolInputJSONSchema |
否 | MCP 工具直接指定 JSON Schema 格式 |
outputSchema |
z.ZodType |
否 | 输出类型 schema |
maxResultSizeChars |
number |
是 | 结果超过此阈值则持久化到磁盘,返回预览 |
searchHint |
string |
否 | ToolSearch 关键词匹配短语(3-10词) |
shouldDefer |
boolean |
否 | 是否延迟加载(需要 ToolSearch 先发现才能调用) |
alwaysLoad |
boolean |
否 | 始终加载,不参与延迟机制 |
isMcp |
boolean |
否 | 标记为 MCP 工具 |
isLsp |
boolean |
否 | 标记为 LSP 工具 |
strict |
boolean |
否 | 启用严格模式,API 更严格遵循工具参数 schema |
mcpInfo |
{serverName, toolName} |
否 | MCP 工具的服务器和工具原始名称 |
执行相关:
// 核心调用方法
call(
args: z.infer<Input>,
context: ToolUseContext,
canUseTool: CanUseToolFn,
parentMessage: AssistantMessage,
onProgress?: ToolCallProgress<P>,
): Promise<ToolResult<Output>>
// 输入验证(schema 验证后的业务逻辑验证)
validateInput?(
input: z.infer<Input>,
context: ToolUseContext,
): Promise<ValidationResult>
// 权限检查(tool-specific 逻辑)
checkPermissions(
input: z.infer<Input>,
context: ToolUseContext,
): Promise<PermissionResult>行为标记方法:
isEnabled(): boolean // 工具是否启用
isConcurrencySafe(input): boolean // 是否可以并发执行(只读工具返回 true)
isReadOnly(input): boolean // 是否只读操作
isDestructive?(input): boolean // 是否不可逆操作(delete、overwrite)
interruptBehavior?(): 'cancel' | 'block' // 用户中断时的行为
isSearchOrReadCommand?(input): {isSearch, isRead, isList} // UI 折叠标记UI 渲染方法:
renderToolUseMessage(input, options): React.ReactNode // 渲染调用消息
renderToolResultMessage?(content, progress, options): React.ReactNode // 渲染结果
renderToolUseProgressMessage?(progress, options): React.ReactNode // 渲染进度
renderToolUseRejectedMessage?(input, options): React.ReactNode // 拒绝消息
renderToolUseErrorMessage?(result, options): React.ReactNode // 错误消息
renderGroupedToolUse?(toolUses, options): React.ReactNode | null // 分组渲染工具结果类型:
type ToolResult<T> = {
data: T
newMessages?: (UserMessage | AssistantMessage | AttachmentMessage | SystemMessage)[]
contextModifier?: (context: ToolUseContext) => ToolUseContext // 仅非并发安全工具有效
mcpMeta?: {
_meta?: Record<string, unknown>
structuredContent?: Record<string, unknown>
}
}所有工具通过 buildTool() 工厂函数构建,提供安全的默认值:
const TOOL_DEFAULTS = {
isEnabled: () => true,
isConcurrencySafe: () => false, // 保守默认:不安全
isReadOnly: () => false, // 保守默认:假设写操作
isDestructive: () => false,
checkPermissions: () => Promise.resolve({ behavior: 'allow', updatedInput }),
toAutoClassifierInput: () => '', // 默认跳过分类器
userFacingName: () => name,
}buildTool 的类型签名使用了精心设计的泛型推导:BuiltTool<D> 在类型层面精确镜像 {...TOOL_DEFAULTS, ...def} 的运行时语义,确保 60+ 个工具的类型检查一致性。
权限上下文是 DeepImmutable 类型,不可变设计确保安全性。
type ToolPermissionContext = DeepImmutable<{
mode: PermissionMode
additionalWorkingDirectories: Map<string, AdditionalWorkingDirectory>
alwaysAllowRules: ToolPermissionRulesBySource
alwaysDenyRules: ToolPermissionRulesBySource
alwaysAskRules: ToolPermissionRulesBySource
isBypassPermissionsModeAvailable: boolean
isAutoModeAvailable?: boolean
strippedDangerousRules?: ToolPermissionRulesBySource
shouldAvoidPermissionPrompts?: boolean // 后台 agent 无 UI 时自动拒绝
awaitAutomatedChecksBeforeDialog?: boolean // coordinator workers 先等自动检查
prePlanMode?: PermissionMode // plan mode 进入前的模式,退出时恢复
}>// 外部模式(用户可配置)
type ExternalPermissionMode =
| 'default' // 默认:每次询问用户
| 'acceptEdits' // 自动接受编辑,其他仍询问
| 'bypassPermissions' // 跳过所有权限检查(dangerously-skip-permissions)
| 'dontAsk' // 不询问,不允许的操作直接拒绝
| 'plan' // Plan mode:只允许只读操作
// 内部模式(系统使用)
type InternalPermissionMode = ExternalPermissionMode
| 'auto' // 自动模式(基于分类器判断)
| 'bubble' // 冒泡模式(子 agent 向上传递权限请求)type PermissionRuleSource =
| 'userSettings' // ~/.claude/settings.json
| 'projectSettings' // .claude/settings.json (项目级)
| 'localSettings' // .claude/settings.local.json
| 'flagSettings' // Feature flag 配置
| 'policySettings' // 企业策略
| 'cliArg' // CLI 参数
| 'session' // 会话内临时授权工具注册在 src/tools.ts,采用函数式组装模式:
getAllBaseTools() -- 获取所有内置工具(尊重 feature flag)
|
v
getTools(permCtx) -- 过滤 deny 规则 + isEnabled() 检查
|
v
assembleToolPool(permCtx, mcpTools) -- 合并内置工具和 MCP 工具
|
v
getMergedTools(permCtx, mcpTools) -- 简单合并(用于 token 计算)
核心工具始终注册,条件工具通过 feature flag 或环境变量控制:
function getAllBaseTools(): Tools {
return [
// 核心工具 - 始终可用
AgentTool, TaskOutputTool, BashTool,
FileReadTool, FileEditTool, FileWriteTool,
NotebookEditTool, WebFetchTool, TodoWriteTool,
WebSearchTool, TaskStopTool, AskUserQuestionTool,
SkillTool, EnterPlanModeTool, ExitPlanModeV2Tool, BriefTool,
// 条件搜索工具(有嵌入搜索时不注册)
...(hasEmbeddedSearchTools() ? [] : [GlobTool, GrepTool]),
// Feature-gated 工具
...(isWorktreeModeEnabled() ? [EnterWorktreeTool, ExitWorktreeTool] : []),
...(isToolSearchEnabledOptimistic() ? [ToolSearchTool] : []),
...(isTodoV2Enabled() ? [TaskCreateTool, TaskGetTool, ...] : []),
// 内部/实验性工具
...(process.env.USER_TYPE === 'ant' ? [ConfigTool, TungstenTool] : []),
...(feature('KAIROS') ? [SleepTool, SendUserFileTool, ...] : []),
...(feature('AGENT_TRIGGERS') ? cronTools : []),
// 仅测试
...(process.env.NODE_ENV === 'test' ? [TestingPermissionTool] : []),
]
}原始工具池
|-- filterToolsByDenyRules() 过滤 blanket deny 规则
|-- REPL 模式过滤 隐藏被 REPL 包装的原始工具
|-- isEnabled() 检查 过滤禁用的工具
|-- SIMPLE 模式 只保留 Bash + Read + Edit
v
最终工具集
filterToolsByDenyRules 使用与运行时权限检查相同的匹配器,确保 MCP 服务器前缀规则(如 mcp__server)在模型看到工具之前就将其过滤掉。
function assembleToolPool(permCtx, mcpTools): Tools {
const builtInTools = getTools(permCtx)
const allowedMcpTools = filterToolsByDenyRules(mcpTools, permCtx)
// 分区排序:内置工具作为连续前缀,确保 prompt cache 稳定性
// 服务器的 cache breakpoint 在最后一个内置工具之后
const byName = (a, b) => a.name.localeCompare(b.name)
return uniqBy(
[...builtInTools].sort(byName).concat(allowedMcpTools.sort(byName)),
'name', // 按名称去重,内置工具优先
)
}// 按名称或别名查找
function findToolByName(tools: Tools, name: string): Tool | undefined {
return tools.find(t => toolMatchesName(t, name))
}
function toolMatchesName(tool, name): boolean {
return tool.name === name || (tool.aliases?.includes(name) ?? false)
}模型输出 tool_use block
|
v
┌──────────────────┐
│ StreamingToolExecutor.addTool()
│ 或 toolOrchestration.runTools()
└────────┬─────────┘
|
v
┌──────────────────┐
│ runToolUse() │ -- toolExecution.ts
└────────┬─────────┘
|
1. 查找工具定义
2. 检查 abort signal
|
v
┌──────────────────────────────┐
│ checkPermissionsAndCallTool() │
└────────┬─────────────────────┘
|
3. Zod schema 验证(inputSchema.safeParse)
4. tool.validateInput() 业务验证
5. tool.backfillObservableInput() 填充派生字段
|
v
┌──────────────────────────────┐
│ PreToolUse Hooks │ -- 并行执行
│ - 可返回 allow/deny/ask │
│ - 可修改 input │
│ - 可阻止继续执行 │
└────────┬─────────────────────┘
|
v
┌──────────────────────────────┐
│ resolveHookPermissionDecision│
│ Hook allow + deny/ask规则? │──> 规则优先
│ Hook deny? │──> 直接拒绝
│ Hook ask / 无决定? │──> 正常权限流
└────────┬─────────────────────┘
|
v
┌──────────────────────────────┐
│ canUseTool() │ -- 交互式权限对话框
│ 或 checkRuleBasedPermissions│
└────────┬─────────────────────┘
|
┌─────┴─────┐
│ │
allow deny
│ │
v v
┌────────┐ 返回错误消息
│tool.call│
└───┬────┘
|
v
┌──────────────────────────────┐
│ PostToolUse Hooks │
│ - 可修改 MCP 工具输出 │
│ - 可注入附加上下文 │
│ - 可阻止后续执行 │
└────────┬─────────────────────┘
|
v
结果序列化 → mapToolResultToToolResultBlockParam
结果大小检查 → processToolResultBlock(超限则持久化到磁盘)
resolveHookPermissionDecision 中关键不变量:Hook 的 allow 不会绕过 settings.json 的 deny/ask 规则。
async function resolveHookPermissionDecision(hookResult, tool, input, ...):
if hookResult.behavior === 'allow':
// deny/ask 规则仍然生效
ruleCheck = await checkRuleBasedPermissions(tool, input, context)
if ruleCheck === null:
return hookResult // 无规则阻止,hook 生效
if ruleCheck.behavior === 'deny':
return ruleCheck // deny 规则覆盖 hook
if ruleCheck.behavior === 'ask':
return canUseTool(...) // ask 规则要求用户确认
if hookResult.behavior === 'deny':
return hookResult // hook 拒绝直接生效
// 无 hook 决策或 'ask' → 正常权限流
return canUseTool(...)StreamingToolExecutor(src/services/tools/StreamingToolExecutor.ts)是新版执行器,支持工具在流式解析过程中立即开始执行:
class StreamingToolExecutor {
private tools: TrackedTool[] = []
private hasErrored = false
private siblingAbortController: AbortController // 兄弟工具错误时终止
// 工具流入即加入队列
addTool(block: ToolUseBlock, assistantMessage: AssistantMessage): void
// 并发控制
private canExecuteTool(isConcurrencySafe: boolean): boolean {
const executing = this.tools.filter(t => t.status === 'executing')
return executing.length === 0 ||
(isConcurrencySafe && executing.every(t => t.isConcurrencySafe))
}
}并发策略:
- 并发安全工具(
isConcurrencySafe = true):可以与其他并发安全工具并行执行 - 非并发安全工具(
isConcurrencySafe = false):必须独占执行
工具状态机:queued → executing → completed → yielded
错误传播:当一个 Bash 工具出错时,siblingAbortController 会终止所有兄弟子进程,但不会终止父级 query 控制器。
src/services/tools/toolOrchestration.ts 提供传统的批处理执行:
function partitionToolCalls(toolUseMessages, context): Batch[] {
// 将工具调用分区为:
// 1. 多个连续的并发安全工具 → 一个并发批次
// 2. 单个非并发安全工具 → 一个串行批次
}
async function* runTools(toolUses, assistants, canUseTool, context) {
for (const { isConcurrencySafe, blocks } of partitionToolCalls(...)) {
if (isConcurrencySafe) {
yield* runToolsConcurrently(blocks, ...) // 并行,最大并发 10
} else {
yield* runToolsSerially(blocks, ...) // 串行
}
}
}最大并发度通过环境变量 CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY 控制,默认 10。
位置:src/tools/BashTool/
BashTool 是最复杂的工具,包含 18 个子模块,涵盖安全、权限、沙箱等多个层面。
输入 schema:
z.object({
command: z.string(),
timeout: z.number().optional(),
description: z.string().optional(),
run_in_background: z.boolean().optional(),
dangerouslyDisableSandbox: z.boolean().optional(),
})安全子系统:
| 模块 | 职责 |
|---|---|
bashPermissions.ts |
命令级权限匹配(前缀、精确、通配符规则) |
bashSecurity.ts |
AST 解析安全检查 |
modeValidation.ts |
权限模式验证(plan mode 下的只读约束) |
pathValidation.ts |
路径约束检查 |
readOnlyValidation.ts |
只读模式下的命令验证 |
sedValidation.ts |
sed 编辑命令特殊处理 |
shouldUseSandbox.ts |
沙箱决策逻辑 |
commandSemantics.ts |
命令语义分析(判断命令类型) |
destructiveCommandWarning.ts |
危险命令警告 |
沙箱机制:
function shouldUseSandbox(input: {command?, dangerouslyDisableSandbox?}): boolean {
if (!SandboxManager.isSandboxingEnabled()) return false
if (input.dangerouslyDisableSandbox && SandboxManager.areUnsandboxedCommandsAllowed())
return false
if (!input.command) return false
if (containsExcludedCommand(input.command)) return false // 用户排除列表
return true
}沙箱排除命令匹配支持三种模式:
- 前缀匹配:
docker:*→ 匹配所有 docker 开头的命令 - 精确匹配:
git status→ 只匹配该精确命令 - 通配符匹配:
git *→ 匹配 git 任意子命令
环境变量剥离(BINARY_HIJACK_VARS)和包装命令剥离(timeout、nice 等)确保 FOO=bar timeout 30 bazel run 仍能匹配 bazel:*。
命令分类(用于 UI 折叠):
- 搜索命令:
find、grep、rg、ag、ack、locate、which - 读取命令:
cat、head、tail、wc、stat、jq、awk、cut - 列表命令:
ls、tree、du - 语义中性命令:
echo、printf、true、false、:(不影响管道的搜索/读取语义)
并发安全判断:BashTool 的 isConcurrencySafe 基于命令语义分析,只读命令返回 true。
后台执行:run_in_background: true 时命令在后台 shell 任务中执行,2 秒后显示进度提示。在 assistant 模式下,阻塞式 bash 在主 agent 中运行 15 秒后自动后台化。
位置:src/tools/FileEditTool/
FileEditTool 实现基于字符串替换的精确编辑模型。
输入 schema:
z.object({
file_path: z.string(),
old_string: z.string(), // 要替换的文本
new_string: z.string(), // 替换后的文本
replace_all: z.boolean().optional().default(false),
})验证层(validateInput)执行了严格的多重检查:
- 团队内存秘密检查:
checkTeamMemSecrets阻止向团队内存文件写入秘密 - 空操作检查:
old_string === new_string时拒绝 - deny 规则检查:
matchingRuleForInput匹配路径级 deny 规则 - UNC 路径安全:跳过 UNC 路径的文件系统操作,防止 NTLM 凭据泄露
- 文件大小限制:最大 1 GiB
- 编码检测:支持 UTF-8 和 UTF-16LE
- 文件存在性检查:不存在 + 空
old_string= 新文件创建 - Jupyter notebook 重定向:
.ipynb文件引导使用NotebookEditTool - 读取时间戳校验:必须先 Read 再 Edit,且文件在 Read 后未被修改
- 唯一性检查:多处匹配时必须
replace_all: true或提供更多上下文 - Settings 文件特殊验证:防止无效的 Claude 配置文件修改
执行流程(call):
1. 扩展路径 → expandPath()
2. 发现技能目录 → discoverSkillDirsForPaths()
3. 诊断追踪器通知 → diagnosticTracker.beforeFileEdited()
4. 确保父目录存在 + 文件历史备份
5. ─── 原子性临界区 ───
a. 同步读取文件 → readFileSyncWithMetadata()
b. 陈旧性检查(时间戳 + 内容比对)
c. findActualString()(引号归一化匹配)
d. preserveQuoteStyle()(保持弯引号风格)
e. getPatchForEdit()(生成 patch)
f. writeTextContent()(写入磁盘,保持编码和换行风格)
─── 临界区结束 ───
6. LSP 通知 → didChange + didSave
7. VSCode 通知 → diff view
8. 更新 readFileState 时间戳(使后续写入的陈旧性检查生效)
9. 分析日志
关键设计:临界区内避免异步操作,防止并发编辑交错。
位置:src/tools/AgentTool/,包含 20+ 子模块。
AgentTool 是 Claude Code 多 agent 架构的核心,支持多种子 agent 模式。
输入 schema:
z.object({
description: z.string(), // 3-5 词任务描述
prompt: z.string(), // 任务详细提示
subagent_type: z.string().optional(), // 专用 agent 类型
model: z.enum(['sonnet', 'opus', 'haiku']).optional(), // 模型覆盖
run_in_background: z.boolean().optional(), // 后台运行
// 多 agent 参数
name: z.string().optional(), // agent 名称(可通过 SendMessage 寻址)
team_name: z.string().optional(), // 团队名称
mode: PermissionMode.optional(), // 权限模式
isolation: z.enum(['worktree', 'remote']).optional(), // 隔离模式
cwd: z.string().optional(), // 工作目录覆盖
})内置 Agent 类型:
| Agent | 文件 | 用途 |
|---|---|---|
general_purpose |
generalPurposeAgent.ts |
通用子 agent(默认) |
explore |
exploreAgent.ts |
代码探索 |
plan |
planAgent.ts |
规划 agent |
verification |
verificationAgent.ts |
验证 agent |
claude_code_guide |
claudeCodeGuideAgent.ts |
Claude Code 使用指南 |
隔离模式:
- worktree:创建临时 git worktree,agent 在隔离的仓库副本上工作
- remote(仅内部):在远程 CCR 环境中启动 agent
执行分支:
AgentTool.call()
|
├── fork subagent (feature gate)
│ └── buildForkedMessages() → 共享父级消息上下文
│
├── 同步执行
│ └── runAgent() → query() → 返回完整结果
│
├── 后台执行 (run_in_background: true)
│ └── registerAsyncAgent() → runAsyncAgentLifecycle()
│ → 完成后通知主线程
│
└── 远程执行 (isolation: 'remote')
└── teleportToRemote() → registerRemoteAgentTask()
子 agent 工具限制(constants/tools.ts):
// 所有 agent 禁止的工具
ALL_AGENT_DISALLOWED_TOOLS = {
TaskOutputTool, ExitPlanModeTool, EnterPlanModeTool,
AgentTool (非内部用户), AskUserQuestionTool, TaskStopTool,
WorkflowTool
}
// 异步 agent 允许的工具白名单
ASYNC_AGENT_ALLOWED_TOOLS = {
FileReadTool, WebSearchTool, TodoWriteTool, GrepTool, GlobTool,
BashTool, FileEditTool, FileWriteTool, NotebookEditTool,
SkillTool, ToolSearchTool, EnterWorktreeTool, ExitWorktreeTool
}
// Coordinator 模式仅允许的工具
COORDINATOR_MODE_ALLOWED_TOOLS = {
AgentTool, TaskStopTool, SendMessageTool, SyntheticOutputTool
}runAgent 核心流程(runAgent.ts):
1. 创建子 agent 上下文 → createSubagentContext()
2. 组装工具池 → assembleToolPool()(含 MCP 工具)
3. 注册 frontmatter hooks
4. 构建系统提示 → getSystemPrompt() + enhanceSystemPromptWithEnvDetails()
5. 执行 query loop → query()(与主循环相同的 API 调用)
6. 记录 sidechain transcript
7. 清理:kill shell tasks、清理 hooks
位置:src/tools/MCPTool/
MCPTool 是 MCP (Model Context Protocol) 工具的桥接层。其独特之处在于 MCPTool.ts 定义的是一个模板对象,实际字段在 mcpClient.ts 中被运行时覆盖。
模板定义:
const MCPTool = buildTool({
isMcp: true,
name: 'mcp', // 运行时覆盖为 mcp__server__tool
maxResultSizeChars: 100_000,
// 以下方法全部在 mcpClient.ts 中被覆盖
async description() { return DESCRIPTION },
async prompt() { return PROMPT },
async call() { return { data: '' } },
userFacingName: () => 'mcp',
// 权限采用 passthrough 模式
async checkPermissions(): Promise<PermissionResult> {
return { behavior: 'passthrough', message: 'MCPTool requires permission.' }
},
})MCP 工具注册流程:
MCP 服务器连接 → fetchToolsForClient()
|
v
为每个远程工具创建 MCPTool 的克隆
|-- name: mcp__<serverName>__<toolName>(归一化)
|-- description: 从 MCP 服务器获取
|-- inputJSONSchema: 从 MCP 服务器获取
|-- call: 代理到 MCP 客户端的 callTool
|-- mcpInfo: { serverName, toolName }
v
注入 appState.mcp.tools → assembleToolPool 合并
权限特殊处理:MCPTool 返回 behavior: 'passthrough',意味着不做 tool-specific 权限判断,完全交给通用权限系统处理。
UI 折叠(classifyForCollapse.ts):根据 MCP 工具的语义对 UI 显示进行分类折叠。
┌─────────────────────────────┐
│ 1. Zod Schema 验证 │ -- 输入格式检查
└────────────┬────────────────┘
│ 通过
┌────────────v────────────────┐
│ 2. tool.validateInput() │ -- 业务逻辑验证
└────────────┬────────────────┘
│ 通过
┌────────────v────────────────┐
│ 3. PreToolUse Hooks │ -- 可 allow/deny/ask
└────────────┬────────────────┘
│
┌────────────v────────────────┐
│ 4. tool.checkPermissions() │ -- 工具特定权限
│ (BashTool: 多层检查) │
│ (FileEdit: 路径检查) │
│ (MCPTool: passthrough) │
└────────────┬────────────────┘
│
┌────────────v────────────────┐
│ 5. checkRuleBasedPermissions │ -- settings.json 规则
│ alwaysAllow > alwaysDeny │
│ > alwaysAsk 规则匹配 │
└────────────┬────────────────┘
│ 无规则匹配
┌────────────v────────────────┐
│ 6. 权限模式决策 │
│ default → 询问用户 │
│ acceptEdits → 编辑自动通过 │
│ bypassPermissions → 全通过 │
│ dontAsk → 拒绝 │
│ plan → 仅只读工具通过 │
│ auto → 分类器判断 │
└─────────────────────────────┘
BashTool 的权限检查是最复杂的,涉及多个子系统:
// bashPermissions.ts 中的权限匹配
type ShellPermissionRule =
| { type: 'prefix'; prefix: string } // "git:*" → 匹配 git 开头的命令
| { type: 'exact'; command: string } // "git status" → 精确匹配
| { type: 'wildcard'; pattern: string } // "git *" → 通配符匹配BashTool 权限检查顺序:
- 权限模式检查(
checkPermissionMode) - 路径约束检查(
checkPathConstraints) - 只读约束检查(
checkReadOnlyConstraints) - sed 编辑约束检查(
checkSedConstraints) - 命令级权限规则匹配
- AST 安全分析(
parseForSecurity) - 分类器检查(auto 模式下的推测性并行检查)
// settings.json 中的权限配置
{
"permissions": {
"allow": [
"Bash(git *)", // 允许所有 git 命令
"Bash(npm test)", // 允许 npm test
"Edit(src/**/*.ts)", // 允许编辑 src 下的 TypeScript 文件
"mcp__memory" // 允许 memory MCP 服务器的所有工具
],
"deny": [
"Bash(rm -rf *)", // 禁止危险删除
"mcp__dangerous_server" // 禁止整个 MCP 服务器
]
}
}type PermissionResult =
| { behavior: 'allow'; updatedInput?: Record<string, unknown>; decisionReason?: ... }
| { behavior: 'deny'; message: string; decisionReason?: ... }
| { behavior: 'ask'; message?: string; updatedInput?: ...; forceDecision?: ... }
| { behavior: 'passthrough'; message: string } // MCP 工具使用权限决策来源追踪(用于遥测):
type PermissionDecisionReason =
| { type: 'rule'; rule: PermissionRule; source: string }
| { type: 'hook'; hookName: string; hookSource?: string }
| { type: 'mode'; mode: PermissionMode }
| { type: 'classifier'; ... }
| { type: 'permissionPromptTool'; toolResult?: unknown }
| { type: 'sandboxOverride' }
| { type: 'workingDir' }
| { type: 'safetyCheck' }
| { type: 'other' }| 工具名称 | 文件 | 并发安全 | 只读 | 说明 |
|---|---|---|---|---|
Bash |
BashTool/ |
视命令 | 视命令 | Shell 命令执行,支持沙箱 |
Edit |
FileEditTool/ |
否 | 否 | 字符串替换式文件编辑 |
Read |
FileReadTool/ |
是 | 是 | 文件读取(含图片、PDF、Notebook) |
Write |
FileWriteTool/ |
否 | 否 | 完整文件写入 |
Glob |
GlobTool/ |
是 | 是 | 文件模式匹配搜索 |
Grep |
GrepTool/ |
是 | 是 | 基于 ripgrep 的内容搜索 |
NotebookEdit |
NotebookEditTool/ |
否 | 否 | Jupyter Notebook 编辑 |
WebFetch |
WebFetchTool/ |
是 | 是 | URL 内容获取与摘要 |
WebSearch |
WebSearchTool/ |
是 | 是 | 网络搜索 |
Agent |
AgentTool/ |
否 | 否 | 子 agent 生成(同步/异步/远程) |
TaskOutput |
TaskOutputTool/ |
- | - | 异步任务输出 |
TaskStop |
TaskStopTool/ |
- | - | 终止后台任务 |
AskUserQuestion |
AskUserQuestionTool/ |
- | - | 向用户提问 |
TodoWrite |
TodoWriteTool/ |
否 | 否 | 待办事项管理 |
Skill |
SkillTool/ |
否 | - | 技能调用 |
Brief |
BriefTool/ |
- | - | 简报生成 |
SendMessage |
SendMessageTool/ |
- | - | 向其他 agent 发送消息 |
ToolSearch |
ToolSearchTool/ |
是 | 是 | 延迟工具发现 |
| 工具名称 | 文件 | 说明 |
|---|---|---|
EnterPlanMode |
EnterPlanModeTool/ |
进入 plan 模式 |
ExitPlanModeV2 |
ExitPlanModeTool/ |
退出 plan 模式 |
| 工具名称 | 文件 | 说明 |
|---|---|---|
EnterWorktree |
EnterWorktreeTool/ |
创建并进入 git worktree |
ExitWorktree |
ExitWorktreeTool/ |
退出并可选删除 worktree |
| 工具名称 | 文件 | 说明 |
|---|---|---|
TaskCreate |
TaskCreateTool/ |
创建任务 |
TaskGet |
TaskGetTool/ |
获取任务详情 |
TaskUpdate |
TaskUpdateTool/ |
更新任务状态 |
TaskList |
TaskListTool/ |
列出任务 |
| 工具名称 | 文件 | 说明 |
|---|---|---|
mcp__* |
MCPTool/ |
MCP 工具桥接(动态注册) |
ListMcpResources |
ListMcpResourcesTool/ |
列出 MCP 资源 |
ReadMcpResource |
ReadMcpResourceTool/ |
读取 MCP 资源 |
| 工具名称 | 文件 | 说明 |
|---|---|---|
TeamCreate |
TeamCreateTool/ |
创建 agent 团队 |
TeamDelete |
TeamDeleteTool/ |
删除 agent 团队 |
ListPeers |
ListPeersTool/ |
列出对等 agent |
| 工具名称 | Feature Gate | 说明 |
|---|---|---|
Config |
USER_TYPE=ant |
配置管理 |
Tungsten |
USER_TYPE=ant |
虚拟终端 |
REPL |
USER_TYPE=ant |
REPL 模式(包装原始工具) |
PowerShell |
Windows | Windows PowerShell 执行 |
LSP |
ENABLE_LSP_TOOL |
语言服务器协议工具 |
Sleep |
PROACTIVE/KAIROS |
等待工具 |
CronCreate/Delete/List |
AGENT_TRIGGERS |
定时任务管理 |
RemoteTrigger |
AGENT_TRIGGERS_REMOTE |
远程触发器 |
Monitor |
MONITOR_TOOL |
监控工具 |
WebBrowser |
WEB_BROWSER_TOOL |
浏览器自动化 |
Snip |
HISTORY_SNIP |
历史修剪 |
Workflow |
WORKFLOW_SCRIPTS |
工作流脚本 |
SuggestBackgroundPR |
USER_TYPE=ant |
后台 PR 建议 |
SendUserFile |
KAIROS |
发送文件给用户 |
PushNotification |
KAIROS |
推送通知 |
SubscribePR |
KAIROS_GITHUB_WEBHOOKS |
PR 订阅 |
CtxInspect |
CONTEXT_COLLAPSE |
上下文检查 |
TerminalCapture |
TERMINAL_PANEL |
终端面板捕获 |
OverflowTest |
OVERFLOW_TEST_TOOL |
溢出测试 |
| 工具名称 | 说明 |
|---|---|
SyntheticOutput |
合成输出(不在常规工具池中) |
VerifyPlanExecution |
计划执行验证(CLAUDE_CODE_VERIFY_PLAN=true) |
TestingPermission |
测试专用权限工具(NODE_ENV=test) |
McpAuth |
MCP 认证工具 |
-
Fail-Closed 安全设计:
buildTool默认值假设工具不安全(非并发、可写),只有显式标记为安全的工具才能获得并发执行和跳过权限检查。 -
多层权限纵深防御:Zod 验证 → 业务验证 → PreToolUse hooks → 工具特定权限 → 规则匹配 → 模式决策 → 用户确认。Hook 的 allow 不会绕过 deny/ask 规则。
-
不可变权限上下文:
ToolPermissionContext使用DeepImmutable确保权限状态在传播过程中不被意外修改。 -
流式执行优化:
StreamingToolExecutor支持工具在 API 响应流式解析时就开始执行,减少端到端延迟。兄弟工具错误通过独立的siblingAbortController传播,不影响 query 级别的 abort。 -
MCP 桥接模式:MCPTool 使用模板对象 + 运行时属性覆盖,将外部 MCP 工具无缝集成到内部工具系统,共享权限和执行基础设施。
-
子 agent 工具隔离:通过
ALL_AGENT_DISALLOWED_TOOLS、ASYNC_AGENT_ALLOWED_TOOLS、COORDINATOR_MODE_ALLOWED_TOOLS三个集合精确控制不同 agent 角色可用的工具,防止递归和权限逃逸。 -
Prompt Cache 稳定性:
assembleToolPool通过分区排序(内置工具作为连续前缀)确保工具顺序不受 MCP 工具注册时序影响,维护 API prompt cache 的命中率。