- 人工智能
- AI Agent
- 工具调用
【免费下载链接】specification
Specification and documentation for the Model Context Protocol
导读
本文深度解读 Model Context Protocol(MCP)官方提案 SEP-1303:当工具的输入参数无法通过业务校验(如日期格式错误、值超出范围)时,服务端应将其作为isError: true的 Tool Execution Error 返回,而非 JSON-RPC 协议级错误。这一变更的核心价值在于:错误信息会进入大语言模型(LLM)的上下文窗口,使模型能够基于错误反馈自动修正参数并重试,从而显著提升任务完成率、降低人工干预。读完本文,你将理解两类错误机制的边界划分、SEP-1303 的具体修改内容,以及如何在 MCP Server 实现中落地这一行为。
背景:为什么校验错误必须对模型可见
MCP 中tools/call的错误报告存在两种机制:
- Protocol Errors(协议错误):以标准 JSON-RPC 错误响应返回(如
-32602 Invalid params),由 MCP Client 在应用层捕获。 - Tool Execution Errors(工具执行错误):放在
tools/call的 result 中,以isError: true标记,随正常 JSON-RPC 响应一起返回。
关键区别在于:只有 Tool Execution Errors 会被转发回模型。LLM 依靠上下文窗口中的错误反馈来学习并纠正下一次调用;协议错误被 Client 拦截后,模型根本看不到错误内容,只能盲目重试,反复失败。
SEP-1303 正是为解决这一信息断层而提出,其最终目标(Status: Final,2025-08-05 创建,Issue #1303)是把工具参数校验失败统一归入 Tool Execution Errors,让错误信息进入模型的上下文窗口。
问题场景:一个航班订票工具的校验困境
提案给出了一个极具代表性的例子:航班订票工具使用zod对出发日期做业务校验:
departureDate: z.string() .regex(/^\d{2}\/\d{2}\/\d{4}$/, "date must be in dd/mm/yyyy format") .superRefine((dateStr, ctx) => { const date = parseDateFr(dateStr); if (date.getTime() < Date.now()) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "Dates must be in the future. Current date is " + formatDateFr(new Date()), }); } return true; }) .describe("Departure date in dd/mm/yyyy format");这里存在一个根本性的表达能力缺口:工具的 inputSchema(JSON Schema)只能描述正则层面的语法约束,无法表达"日期必须晚于今天"这类运行时业务规则。因此,即便模型给出的日期语法完全合法、通过了 JSON Schema 校验,仍然可能在语义上不合法(例如过去日期)。
当这种业务校验失败被当作 Protocol Error 返回时,会产生连锁问题:
- 模型收不到"日期被拒的原因";
- 模型反复提交同样类型的错误参数(提案举例:某些客户端在用户只提供日/月或相对日期时,会一致地发送 2024 年日期,并在毫无反馈的情况下把同一个
tools/call重试 3 次); - 本可以自我纠正的任务最终失败;
- 用户被迫手动介入,体验受损。
提案的收益:让模型"看得见"错误
将输入校验错误转为 Tool Execution Error 后,收益是直接的:
- 更高的任务完成率:模型能在无需人工干预的情况下自我纠正校验错误;
- 更好的用户体验:失败减少、任务完成更快;
- 充分利用模型能力:现代 LLM 擅长理解错误消息并据此调整行为;
- 减少 API 调用:模型在第一次错误反馈后就自我修正,显著降低盲目重试次数。
规范变更:消除两类错误的边界歧义
当前行为(SEP 提出时的规范状态)
SEP-1303 指出,当时的 工具错误处理规范 给出的指引存在歧义:
- "Invalid arguments" 应作为 Protocol Error;
- "Invalid input data" 应作为 Tool Execution Error。
从 2025-06-18 版规范(docs/specification/2025-06-18/server/tools.mdx)可以看到,当时 Protocol Errors 明确包含Invalid arguments,而 Tool Execution Errors 包含Invalid input data。这两个类别语义重叠、边界模糊,导致不同实现各自为政,有价值的错误反馈常常丢失。
提案的修改
SEP-1303 提出两项明确修改:
- 从 Protocol Errors 中移除 "invalid arguments" 类别;
- 所有工具参数校验失败统一归入 Tool Execution Errors,即将
invalid arguments与invalid input data合并为新的input validation errors类别。
提案给出的规范文本更新如下:
## Error Handling Tools use two error reporting mechanisms: 1. **Protocol Errors**: Standard JSON-RPC errors for issues like: - Unknown tools - Server errors 2. **Tool Execution Errors**: Reported in tool results with `isError: true`: - API failures - Input validation errors - Business logic errors行为对比:协议错误 vs 工具执行错误
修改前(Protocol Error,模型不可见)
// Model submits past date request: { ... method: "tools/call", params: { name: "book_flight", arguments: { departureDate: "12/12/2024" // Past date } } } // Server returns Protocol Error response: { ... error: { code: -32602, message: "Invalid params" } } // Model retries blindly with another past date // This cycle repeats until failure修改后(Tool Execution Error,模型可见)
// Model submits past date request: { ... method: "tools/call", params: { name: "book_flight", arguments: { departureDate: "12/12/2024" // Past date } } } // Server returns Tool Execution Error (visible to model) response: { ... "result": { "content": [ { "type": "text", "text": "Dates must be in the future. Current date is 08/08/2025" } ], "isError": true } } // Model understands the error and corrects itself request: { method: "tools/call", params: { name: "book_flight", arguments: { departureDate: "12/12/2025" // Future date } } }前后对比清晰地展示了核心差异:修改后,模型看到的是"Dates must be in the future. Current date is 08/08/2025"这条可操作的、语义化的错误消息,而非一条冷冰冰的-32602 Invalid params,从而能够一步到位地修正为正确日期。
规范落地:从 2025-06-18 到 2026-07-28 的演进验证
SEP-1303 的修改最终被纳入后续正式规范。在 2026-07-28 版工具规范 中,错误处理章节已按 SEP 精神重写:
Protocol Errors被明确限定为"模型不太可能自行修复的、请求结构本身的问题":
- 未知工具(Unknown tool);
- 畸形请求(不满足 CallToolRequest schema 的请求);
- 服务器错误。 其返回形式仍是标准 JSON-RPC 错误,例如
-32602 Unknown tool: invalid_tool_name。
Tool Execution Errors被明确界定为"包含模型可用来自我纠正并重试的可操作反馈":
- API 失败;
- 输入校验错误(如日期格式错误、值超出范围)——即 SEP-1303 新增合并的
input validation errors类别; - 业务逻辑错误。 返回形式为
result中携带isError: true,如:
{ "jsonrpc": "2.0", "id": 4, "result": { "resultType": "complete", "content": [ { "type": "text", "text": "Invalid departure date: must be in the future. Current date is 08/08/2025." } ], "isError": true } }同时,规范明确了客户端义务的强弱梯度:客户端MAY将协议错误提供给模型(但成功恢复的可能性较低);客户端SHOULD将工具执行错误提供给模型以支持自我纠正。
Schema 层面的约束
从 schema/2026-07-28/schema.ts 中CallToolResult.isError字段的注释可以看到与 SEP-1303 完全一致的表述:工具产生的任何错误都应放在 result 对象内并以isError: true标记,而不是作为 MCP 协议级错误响应返回——否则 LLM 将无法看到错误发生并自我纠正;而"找不到工具""服务器不支持工具调用"等异常情况才应作为 MCP 错误响应返回。
向后兼容性:澄清而非破坏
SEP-1303 明确声明该变更向后兼容:
- 不改变协议结构本身;
- 只是澄清既有模糊行为;
- 保留所有现有错误类型与格式;
- 在不破坏现有实现的前提下改善行为。
采用澄清后行为的 Server,将为模型提供更好的自我恢复能力,同时继续兼容所有现有 Client。
实现建议:Server 端如何落地
结合 SEP 与 安全考量章节 的要求,Server 实现者在落地时应注意:
- 在工具函数内部捕获业务校验失败,将其转换为
result.content中的文本描述,并设置isError: true; - 错误消息要"可操作":明确说明失败原因与当前有效条件(例如"日期必须晚于今天,当前日期是 08/08/2025"),让模型无需猜测即可修正;
- 仅对真正属于请求结构的问题(未知工具、JSON-RPC 参数畸形)才返回协议级错误(
-32602等); - 服务端必须校验所有工具输入(Security Considerations 中 Server 的 MUST 项),校验失败走 Tool Execution Error 通道正是这一要求的自然延伸;
- 在 HTTP 传输场景下,畸形请求(如缺少协议字段)会以
400 Bad Request返回并伴随-32602(见 basic/index.mdx),这与工具业务校验失败属于完全不同的层级,不应混淆。
总结
SEP-1303 是一个"小而关键"的规范澄清:通过把工具输入校验错误从协议错误迁移到 Tool Execution Error,它让 LLM 获得了自我纠错所需的上下文反馈,直接改善了 MCP 生态中 Agent 任务的完成率与用户体验。该提案现已落地于 2026-07-28 版规范与 schema 注释中,是 MCP Server 开发者应当严格遵循的错误处理基线。
- 人工智能
- AI Agent
- 工具调用
【免费下载链接】specification
Specification and documentation for the Model Context Protocol
相关推荐
深入解析 Angular 错误 NG01101:Wrong Async Validator Return Type(异步校验器返回值类型错误)
深入解析 Angular 错误 NG01101:Wrong Async Validator Return Type(异步校验器返回值类型错误) 导读 NG011
前端Web框架CANN opbase 错误码 EZ0007 全解:Invalid_Input_Dtype 输入数据类型校验错误
CANN opbase 错误码 EZ0007 全解:Invalid_Input_Dtype 输入数据类型校验错误 导读 EZ0007(Invalid_Input
人工智能算子库CANNAscendFay 数字人框架配置完整指南:改对两个文件,一次跑通
Fay 数字人框架配置完整指南:改对两个文件,一次跑通 你在 system.conf 里填了 API 密钥,重启后数字人还是不回话?别急着怀疑密钥本身。先弄清
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考