通过 SDK 内置的进程内 MCP 服务器定义自定义工具,让 Claude 可以调用你的函数、访问数据库、调用外部 API 或执行领域特定操作。无需启动独立进程。

核心机制

工具定义四要素:

  • name:唯一标识符,Claude 用它调用工具
  • description:工具功能描述,Claude 据此决定何时调用
  • input schema:Python 用 dict 或 JSON Schema,TypeScript 用 Zod schema
  • handler:异步处理函数,接收验证后的参数,返回结果对象

工具命名格式:注册到 MCP 服务器后,工具名变为 mcp__<server_name>__<tool_name>。

handler 返回值结构:

{
    "content": [{"type": "text", "text": "结果文本"}],  # 必须
    "is_error": True,   # 可选,标记工具失败(Agent 循环继续)
    "structuredContent": {...}  # 可选,机器可读的结构化数据(Python 不支持)
}

错误处理原则:handler 抛出未捕获异常会终止整个 Agent 循环;返回 is_error: True 则 Claude 看到错误信息并可调整策略,循环继续。

关键细节

from claude_agent_sdk import tool, create_sdk_mcp_server, query, ClaudeAgentOptions
 
@tool(
    "get_temperature",
    "Get the current temperature at a location",
    {"latitude": float, "longitude": float},
)
async def get_temperature(args):
    # 调用外部 API...
    return {"content": [{"type": "text", "text": f"Temperature: 72°F"}]}
 
weather_server = create_sdk_mcp_server(
    name="weather",
    version="1.0.0",
    tools=[get_temperature],
)
 
async for message in query(
    prompt="What's the temperature in San Francisco?",
    options=ClaudeAgentOptions(
        mcp_servers={"weather": weather_server},
        allowed_tools=["mcp__weather__get_temperature"],
    ),
):
    ...

工具注解(Annotations):

  • readOnlyHint: True - 无副作用,允许并发执行
  • destructiveHint: True - 可能有破坏性操作(仅信息性)
  • idempotentHint: True - 重复调用无额外效果(仅信息性)

返回图片:content 中使用 type: "image",data 字段为 base64 编码(不含 data URI 前缀)。

工具可用性控制:

  • tools: ["Read", "Grep"] - 只让 Claude 看到这些内置工具(从上下文移除其他)
  • allowed_tools - 预批准工具(工具仍在上下文中,只是无需审批)
  • disallowed_tools - 阻止工具调用(工具仍在上下文中,Claude 可能尝试后被拒绝)

与其他概念的关联

  • mcp - 连接外部 MCP 服务器(vs 进程内自定义工具)
  • tool-search - 工具数量多时按需加载
  • permissions - 工具权限控制

实践要点

  • 工具数量多时(>10 个),考虑使用 tool-search 按需加载,避免占满上下文
  • Python 的 dict schema 不支持 enum,需要 enum 约束时使用完整 JSON Schema dict
  • 可选参数:TypeScript 用 .default(),Python 在 schema 中省略该字段并在 handler 中用 args.get() 读取
  • 通配符 mcp__weather__* 可一次预批准服务器的所有工具