指南
处理权限
在 Claude Agent SDK 中控制工具使用和权限
SDK 权限
SDK 权限
Claude Agent SDK 提供强大的权限控制功能,允许您管理 Claude 在应用程序中如何使用工具。
本指南涵盖如何使用 canUseTool 回调、钩子和 settings.json 权限规则来实现权限系统。有关完整的 API 文档,请参阅 TypeScript SDK 参考。
概述
概述
Claude Agent SDK 提供四种互补的方式来控制工具使用:
- 权限模式 - 影响所有工具的全局权限行为设置
- canUseTool 回调 - 用于其他规则未涵盖情况的运行时权限处理程序
- 钩子 - 通过自定义逻辑对每个工具执行进行细粒度控制
- 权限规则 (settings.json) - 具有集成 bash 命令解析的声明式允许/拒绝规则
每种方法的用例:
- 权限模式 - 设置整体权限行为(规划、自动接受编辑、绕过检查)
canUseTool- 对未涵盖情况的动态批准,提示用户获取权限- 钩子 - 对所有工具执行的程序化控制
- 权限规则 - 具有智能 bash 命令解析的静态策略
权限流程图
权限流程图
%%{init: {"theme": "base", "themeVariables": {"edgeLabelBackground": "#F0F0EB", "lineColor": "#91918D"}, "flowchart": {"edgeLabelMarginX": 12, "edgeLabelMarginY": 8}}}%%
flowchart TD
Start([工具请求]) --> PreHook(PreToolUse 钩子)
PreHook -->| 允许 | Execute(执行工具)
PreHook -->| 拒绝 | Denied(已拒绝)
PreHook -->| 询问 | Callback(canUseTool 回调)
PreHook -->| 继续 | Deny(检查拒绝规则)
Deny -->| 匹配 | Denied
Deny -->| 无匹配 | Allow(检查允许规则)
Allow -->| 匹配 | Execute
Allow -->| 无匹配 | Ask(检查询问规则)
Ask -->| 匹配 | Callback
Ask -->| 无匹配 | Mode{权限模式?}
Mode -->| bypassPermissions | Execute
Mode -->| 其他模式 | Callback
Callback -->| 允许 | Execute
Callback -->| 拒绝 | Denied
Denied --> DeniedResponse([反馈给代理])
Execute --> PostHook(PostToolUse 钩子)
PostHook --> Done([工具响应])
style Start fill:#F0F0EB,stroke:#D9D8D5,color:#191919
style Denied fill:#BF4D43,color:#fff
style DeniedResponse fill:#BF4D43,color:#fff
style Execute fill:#DAAF91,color:#191919
style Done fill:#DAAF91,color:#191919
classDef hookClass fill:#CC785C,color:#fff
class PreHook,PostHook hookClass
classDef ruleClass fill:#EBDBBC,color:#191919
class Deny,Allow,Ask ruleClass
classDef modeClass fill:#A8DAEF,color:#191919
class Mode modeClass
classDef callbackClass fill:#D4A27F,color:#191919
class Callback callbackClass处理顺序: PreToolUse 钩子 → 拒绝规则 → 允许规则 → 询问规则 → 权限模式检查 → canUseTool 回调 → PostToolUse 钩子
权限模式
权限模式
权限模式提供对 Claude 如何使用工具的全局控制。您可以在调用 query() 时设置权限模式,或在流式会话期间动态更改它。
可用模式
可用模式
SDK 支持四种权限模式,每种都有不同的行为:
| 模式 | 描述 | 工具行为 |
|---|---|---|
default | 标准权限行为 | 应用正常权限检查 |
plan | 规划模式 - 无执行 | Claude 只能使用只读工具;在执行前呈现计划 (SDK 中当前不支持) |
acceptEdits | 自动接受文件编辑 | 文件编辑和文件系统操作自动获得批准 |
bypassPermissions | 绕过所有权限检查 | 所有工具无需权限提示即可运行(谨慎使用) |
设置权限模式
设置权限模式
您可以通过两种方式设置权限模式:
1. 初始配置
在创建查询时设置模式:
import { query } from "@anthropic-ai/claude-agent-sdk";
const result = await query({
prompt: "帮我重构这段代码",
options: {
permissionMode: 'default' // 标准权限模式
}
});2. 动态模式更改(仅流式)
在流式会话期间更改模式:
import { query } from "@anthropic-ai/claude-agent-sdk";
// 为流式输入创建异步生成器
async function* streamInput() {
yield {
type: 'user',
message: {
role: 'user',
content: "让我们从默认权限开始"
}
};
// 稍后在对话中...
yield {
type: 'user',
message: {
role: 'user',
content: "现在让我们加快开发速度"
}
};
}
const q = query({
prompt: streamInput(),
options: {
permissionMode: 'default' // 以默认模式开始
}
});
// 动态更改模式
await q.setPermissionMode('acceptEdits');
// 处理消息
for await (const message of q) {
console.log(message);
}特定模式行为
特定模式行为
接受编辑模式 (acceptEdits)
在接受编辑模式下:
- 所有文件编辑自动获得批准
- 文件系统操作(mkdir、touch、rm 等)自动批准
- 其他工具仍需要正常权限
- 当您信任 Claude 的编辑时加快开发速度
- 适用于快速原型制作和迭代
自动批准的操作:
- 文件编辑(Edit、Write 工具)
- Bash 文件系统命令(mkdir、touch、rm、mv、cp)
- 文件创建和删除
绕过权限模式 (bypassPermissions)
在绕过权限模式下:
- 所有工具使用都自动获得批准
- 不出现权限提示
- 钩子仍然执行(仍可阻止操作)
- 极其谨慎使用 - Claude 拥有完整系统访问权限
- 仅建议在受控环境中使用
权限流程中的模式优先级
权限流程中的模式优先级
权限模式在权限流程的特定点进行评估:
- 钩子首先执行 - 可以允许、拒绝、询问或继续
- 检查拒绝规则 - 无论模式如何都阻止工具
- 检查允许规则 - 如果匹配则允许工具
- 检查询问规则 - 如果匹配则提示权限
- 评估权限模式:
bypassPermissions模式 - 如果激活,允许所有剩余工具- 其他模式 - 延迟到
canUseTool回调
canUseTool回调 - 处理剩余情况
这意味着:
- 钩子始终可以控制工具使用,即使在
bypassPermissions模式下 - 显式拒绝规则覆盖所有权限模式
- 询问规则在权限模式之前评估
bypassPermissions模式覆盖未匹配工具的canUseTool回调
最佳实践
最佳实践
- 使用默认模式 进行受控执行和正常权限检查
- 使用 acceptEdits 模式 处理隔离文件或目录时
- 避免 bypassPermissions 在生产环境或有敏感数据的系统上
- 结合模式与钩子 进行细粒度控制
- 根据任务进度和信心动态切换模式
模式进展示例:
// 以默认模式开始进行受控执行
permissionMode: 'default'
// 切换到 acceptEdits 进行快速迭代
await q.setPermissionMode('acceptEdits')canUseTool
canUseTool
canUseTool 回调在调用 query 函数时作为选项传递。它接收工具名称和输入参数,必须返回一个决定 - 允许或拒绝。
canUseTool 在 Claude Code 向用户显示权限提示时触发,例如钩子和权限规则不涵盖它且不在 acceptEdits 模式下。
以下是一个完整示例,展示如何实现交互式工具批准:
import { query } from "@anthropic-ai/claude-agent-sdk";
async function promptForToolApproval(toolName: string, input: any) {
console.log("\n🔧 工具请求:");
console.log(` 工具: ${toolName}`);
// 显示工具参数
if (input && Object.keys(input).length > 0) {
console.log(" 参数:");
for (const [key, value] of Object.entries(input)) {
let displayValue = value;
if (typeof value === 'string' && value.length > 100) {
displayValue = value.substring(0, 100) + "...";
} else if (typeof value === 'object') {
displayValue = JSON.stringify(value, null, 2);
}
console.log(` ${key}: ${displayValue}`);
}
}
// 获取用户批准(用您的 UI 逻辑替换)
const approved = await getUserApproval();
if (approved) {
console.log(" ✅ 已批准\n");
return {
behavior: "allow",
updatedInput: input
};
} else {
console.log(" ❌ 已拒绝\n");
return {
behavior: "deny",
message: "用户拒绝了此工具的权限"
};
}
}
// 使用权限回调
const result = await query({
prompt: "帮我分析这个代码库",
options: {
canUseTool: async (toolName, input) => {
return promptForToolApproval(toolName, input);
}
}
});相关资源
相关资源