query,以及控制 Claude 可以访问哪些工具。它还涵盖错误处理、工具注释和返回非文本内容(如图像)。
快速参考
| 如果您想… | 执行此操作 |
|---|---|
| 定义工具 | 使用 @tool(Python)或 tool()(TypeScript),包含名称、描述、架构和处理程序。请参阅创建自定义工具。 |
| 向 Claude 注册工具 | 在 create_sdk_mcp_server / createSdkMcpServer 中包装并传递给 query() 中的 mcpServers。请参阅调用自定义工具。 |
| 预先批准工具 | 添加到您的允许工具列表。请参阅配置允许的工具。 |
| 从 Claude 的上下文中删除内置工具 | 传递仅列出您想要的内置工具的 tools 数组。请参阅配置允许的工具。 |
| 让 Claude 并行调用工具 | 在没有副作用的工具上设置 readOnlyHint: true。请参阅添加工具注释。 |
| 处理错误而不停止循环 | 返回 isError: true 而不是抛出异常。请参阅处理错误。 |
| 返回图像或文件 | 在内容数组中使用 image 或 resource 块。请参阅返回图像和资源。 |
| 返回机器可读的 JSON 结果 | 在结果上设置 structuredContent。请参阅返回结构化数据。 |
| 扩展到许多工具 | 使用工具搜索按需加载工具。 |
创建自定义工具
工具由四个部分定义,作为参数传递给 TypeScript 中的tool() 助手或 Python 中的 @tool 装饰器:
- 名称: Claude 用来调用工具的唯一标识符。
- 描述: 工具的功能。Claude 读取此内容以决定何时调用它。
- 输入架构: Claude 必须提供的参数。在 TypeScript 中,这始终是 Zod 架构,处理程序的
args会自动从中获得类型。在 Python 中,这是一个将名称映射到类型的字典,如{"latitude": float},SDK 会为您将其转换为 JSON Schema。Python 装饰器还接受完整的 JSON Schema 字典,当您需要枚举、范围、可选字段或嵌套对象时。 - 处理程序: 当 Claude 调用工具时运行的异步函数。它接收验证的参数,必须返回一个对象,包含:
createSdkMcpServer(TypeScript)或 create_sdk_mcp_server(Python)将其包装在服务器中。服务器在应用程序内进程内运行,而不是作为单独的进程。
天气工具示例
此示例定义了一个get_temperature 工具并将其包装在 MCP 服务器中。它仅设置工具;要将其传递给 query 并运行它,请参阅下面的调用自定义工具。
tool() TypeScript 参考或 @tool Python 参考。
调用自定义工具
通过mcpServers 选项将您创建的 MCP 服务器传递给 query。mcpServers 中的键成为每个工具的完全限定名称中的 {server_name} 段:mcp__{server_name}__{tool_name}。在 allowedTools 中列出该名称,以便工具运行而无需权限提示。
这些代码片段重用上面示例中的 weatherServer 来询问 Claude 特定位置的天气。
添加更多工具
一个服务器在其tools 数组中列出的工具数量不限。如果有多个工具在一个服务器上,您可以在 allowedTools 中单独列出每个工具,或使用通配符 mcp__weather__* 来覆盖服务器公开的每个工具。
下面的示例向天气工具示例中的 weatherServer 添加第二个工具 get_precipitation_chance,并使用数组中的两个工具重建它。
添加工具注释
工具注释是描述工具行为方式的可选元数据。在 TypeScript 中作为tool() 助手的第五个参数传递,或在 Python 中通过 @tool 装饰器的 annotations 关键字参数传递。所有提示字段都是布尔值。
| 字段 | 默认值 | 含义 |
|---|---|---|
readOnlyHint | false | 工具不修改其环境。控制工具是否可以与其他只读工具并行调用。 |
destructiveHint | true | 工具可能执行破坏性更新。仅供参考。 |
idempotentHint | false | 使用相同参数的重复调用没有额外效果。仅供参考。 |
openWorldHint | true | 工具到达流程外的系统。仅供参考。 |
readOnlyHint: true 的工具如果处理程序这样做,仍然可以写入磁盘。保持注释与处理程序准确。
此示例向天气工具示例中的 get_temperature 工具添加 readOnlyHint。
ToolAnnotations。
控制工具访问
天气工具示例注册了一个服务器并在allowedTools 中列出了工具。本部分涵盖工具名称的构造方式以及当您有多个工具或想要限制内置工具时如何限制访问。
工具名称格式
当 MCP 工具暴露给 Claude 时,它们的名称遵循特定格式:- 模式:
mcp__{server_name}__{tool_name} - 示例:服务器
weather中名为get_temperature的工具变成mcp__weather__get_temperature
配置允许的工具
tools 选项和允许/不允许列表影响两个层:可用性(控制工具是否出现在 Claude 的上下文中)和权限(控制 Claude 尝试调用后是否批准调用)。tools 和裸名称 disallowedTools 条目改变可用性。allowedTools 和作用域 disallowedTools 规则仅改变权限。
| 选项 | 层 | 效果 |
|---|---|---|
tools: ["Read", "Grep"] | 可用性 | 仅列出的内置工具在 Claude 的上下文中。未列出的内置工具被删除。MCP 工具不受影响。 |
tools: [] | 可用性 | 所有内置工具都被删除。Claude 只能使用您的 MCP 工具。 |
| 允许的工具 | 权限 | 列出的工具运行而无需权限提示。未列出的工具保持可用;调用通过权限流进行。 |
| 不允许的工具 | 两者 | 裸工具名称(如 "Bash")将工具从 Claude 的上下文中删除,与从 tools 中省略它相同。作用域规则(如 "Bash(rm *)")将工具保留在上下文中,仅拒绝匹配的调用。 |
tools 中省略它或在 disallowedTools 中列出其裸名称(Python:disallowed_tools);两者都将工具保留在上下文之外,以便 Claude 永远不会尝试它。作用域 disallowedTools 规则会阻止匹配的调用但保留工具可见,因此 Claude 可能会浪费一个回合尝试它。有关完整的评估顺序,请参阅配置权限。
处理错误
您的处理程序报告错误的方式决定了代理循环是继续还是停止:| 发生的情况 | 结果 |
|---|---|
| 处理程序抛出未捕获的异常 | 代理循环停止。Claude 永远看不到错误,query 调用失败。 |
处理程序捕获错误并返回 isError: true(TS)/ "is_error": True(Python) | 代理循环继续。Claude 将错误视为数据,可以重试、尝试不同的工具或解释失败。 |
try/except(Python)或 try/catch(TypeScript)捕获,也作为错误结果返回。在这两种情况下,处理程序正常返回,代理循环继续。
返回图像和资源
工具结果中的content 数组接受 text、image 和 resource 块。您可以在同一响应中混合它们。
图像
图像块以 base64 编码的方式内联携带图像字节。没有 URL 字段。要返回位于 URL 的图像,在处理程序中获取它,读取响应字节,并在返回之前进行 base64 编码。结果作为视觉输入处理。| 字段 | 类型 | 注释 |
|---|---|---|
type | "image" | |
data | string | Base64 编码的字节。仅原始 base64,没有 data:image/...;base64, 前缀 |
mimeType | string | 必需。例如 image/png、image/jpeg、image/webp、image/gif |
资源
资源块嵌入由 URI 标识的内容片段。URI 是 Claude 引用的标签;实际内容位于块的text 或 blob 字段中。当您的工具生成稍后按名称寻址有意义的内容时使用此功能,例如生成的文件或来自外部系统的记录。
| 字段 | 类型 | 注释 |
|---|---|---|
type | "resource" | |
resource.uri | string | 内容的标识符。任何 URI 方案 |
resource.text | string | 内容,如果是文本。提供此项或 blob,不能两者都提供 |
resource.blob | string | 内容 base64 编码,如果是二进制 |
resource.mimeType | string | 可选 |
file:///tmp/report.md 是 Claude 可以稍后引用的标签;SDK 不从该路径读取。
CallToolResult 类型。有关完整定义,请参阅 MCP 规范。
返回结构化数据
structuredContent 是结果上的可选 JSON 对象,与 content 数组分开。使用它返回原始值,Claude 可以将其作为精确字段读取,而不是从文本字符串或图像中解析它们。
当设置 structuredContent 时,Claude 接收 JSON 加上来自 content 的任何图像或资源块。来自 content 的文本块不被转发,因为假设它们复制结构化数据。下面的示例将图表呈现为图像块,并从同一处理程序的 structuredContent 中返回其后面的数据点。
TypeScript
Python
@tool 装饰器仅从处理程序的返回字典转发 content 和 is_error。要从 Python 返回 structuredContent,请运行独立 MCP 服务器而不是进程内 SDK 服务器。示例:单位转换器
此工具在长度、温度和重量的单位之间转换值。用户可以询问”将 100 公里转换为英里”或”72°F 是多少摄氏度”,Claude 从请求中选择正确的单位类型和单位。 它演示了两种模式:- 枚举架构:
unit_type被限制为一组固定值。在 TypeScript 中,使用z.enum()。在 Python 中,字典架构不支持枚举,因此需要完整的 JSON Schema 字典。 - 不支持的输入处理: 当找不到转换对时,处理程序返回
isError: true,以便 Claude 可以告诉用户出了什么问题,而不是将失败视为正常结果。
query。此示例在循环中发送三个不同的提示,以显示同一工具处理不同的单位类型。对于每个响应,它检查 AssistantMessage 对象(包含 Claude 在该回合中进行的工具调用)并在打印最终 ResultMessage 文本之前打印每个 ToolUseBlock。这让您看到 Claude 何时使用工具与从其自己的知识中回答。
后续步骤
自定义工具在标准接口中包装异步函数。您可以在同一服务器中混合本页上的模式:单个服务器可以在彼此旁边保存数据库工具、API 网关工具和图像渲染器。 从这里:- 如果您的服务器增长到数十个工具,请参阅工具搜索以延迟加载它们,直到 Claude 需要它们。
- 要连接到外部 MCP 服务器(文件系统、GitHub、Slack)而不是构建自己的,请参阅连接 MCP 服务器。
- 要控制哪些工具自动运行与需要批准,请参阅配置权限。