如果你同时用 MCP 和 Claude Messages API,有一个命名差异迟早会坑到你。它很小、很容易忽略,而且出问题时没有任何报错。搞清楚 MCP 的工具定义格式——以及它和 Claude API 格式的区别——能帮你省掉排查幽灵 schema 错误的时间。
三个字段,就这些
MCP 的工具定义正好三个字段:
name— 工具的标识符,client 请求调用工具时使用description— 工具做什么,帮助 AI 模型选择正确的工具(可选但强烈推荐)inputSchema— 一个标准 JSON Schema,定义工具的输入参数
这就是全部接口面。没有指向端点的 handler 字段。没有定义返回值的 outputSchema。没有 parameters 简写。Server 在内部实现执行逻辑——定义只描述接口。
命名陷阱:inputSchema vs input_schema
坑就在这里。MCP 用 camelCase:inputSchema。Claude Messages API 用 snake_case:input_schema。同一个概念,不同的大小写。
为什么?MCP 遵循 JSON-RPC 约定(camelCase),Claude API 有自己的命名约定(snake_case)。两边对字段内容都用标准 JSON Schema——区别纯粹在字段名。
这很要命,因为从一个系统复制工具定义到另一个系统时,如果不改字段名,会产生一个静默失败的定义。Schema 内容完全一样、完全合法,但键名对目标系统来说是错的。
定义里没有的东西
三个常见误解:
-
没有
outputSchema— 只定义了输入。工具返回什么由 server 的实现决定,定义不做约束。MCP 和 Claude API 的工具定义里都没有输出 schema。 -
没有
handler— 定义描述的是工具接受什么,不是在哪里或怎么执行。实现细节留在 server 端。 -
属性没有
optional标记 — 可选性由 JSON Schema 的required数组控制。列在required里的是必填项,其余的默认可选。JSON Schema 里没有逐属性的optional: true注解。
完整示例
一个创建 GitHub issue 的工具,title 必填,body 和 labels 可选:
{
"name": "create_issue",
"description": "Creates a new GitHub issue in the specified repository",
"inputSchema": {
"type": "object",
"properties": {
"title": { "type": "string" },
"body": { "type": "string" },
"labels": { "type": "array", "items": { "type": "string" } }
},
"required": ["title"]
}
}
注意:inputSchema(camelCase),因为这是 MCP。在 Claude API 里,同样的 schema 内容放在 input_schema(snake_case)下面。两个系统都支持完整的 JSON Schema,包括嵌套对象——两边都没有嵌套限制。
一句话总结: MCP 工具定义有三个字段(name、description、inputSchema 用 camelCase)——snake_case 的 input_schema 属于 Claude API,搞混它们是最常见的集成错误。