- 状态(Status): Final
- 类型(Type): Standards Track
- 创建(Created): 2026-01-28
- 作者(Author(s)): Peter Alexander (@pja-ant)
- 担保人(Sponsor): None (seeking sponsor)
- PR: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2164
摘要
当前的 MCP 规范推荐-32002 作为”资源未找到”的错误码。然而,-32002 落在 JSON-RPC “服务器错误”范围(-32000 到 -32099)内,该范围保留给实现自定义的错误,而非协议层语义。此外,各 SDK 实现并不一致——6 个官方 SDK 中只有 4 个使用 -32002,而 TypeScript SDK 使用 -32602、Python SDK 使用 0。
本 SEP 统一采用 -32602(Invalid Params,无效参数),即此场景下正确的 JSON-RPC 错误码,并使规范与 JSON-RPC 标准对齐。
动机
当前各 SDK 实现对”资源未找到”的错误处理各不相同:
这种不一致意味着客户端无法在各实现之间可靠地检测”资源未找到”的情况。在 8 个具有内置资源处理的 SDK 中,使用了四种不同的错误码:
-32002(C#、Rust、Java、Go、PHP)、-32602(TypeScript)、-32603(Kotlin)和 0(Python)。Ruby 和 Swift 将错误处理留给服务器实现者。需要将”资源未找到”与其他错误区分开的客户端必须处理所有变体。
规范
如果所请求的资源不存在,服务器**必须(MUST)**返回一个错误码为-32602(Invalid Params)的 JSON-RPC 错误:
data 字段**应当(SHOULD)**包含未找到的 uri。
服务器**不得(MUST NOT)**为不存在的资源返回空的 contents 数组。空数组是有歧义的——它可能意味着资源存在但没有内容,也可能意味着资源根本不存在。
理由
为何选择 -32602(Invalid Params)?
-32602 是 JSON-RPC 中表示无效参数的标准错误码。不存在的 URI 在语义上是一个无效参数——客户端提供了一个不对应任何资源的 URI。这与 TypeScript SDK 的既有行为一致,并避免了在 JSON-RPC 保留范围之外引入自定义错误码。
为何不用自定义错误码?
若干 SDK 使用-32002(RESOURCE_NOT_FOUND),但:
- 依据 JSON-RPC 规范,
-32000到-32099范围内的自定义码”保留给实现自定义的服务器错误”,而非协议层语义 - 添加一个协议定义的自定义码要求所有客户端都更新以识别它
-32602已经具有正确的含义,且被 JSON-RPC 库普遍理解
向后兼容性
这改变的是所规定的内容——当前规范推荐-32002,而本 SEP 将其改为 -32602。然而,由于当前的推荐在各 SDK 间并未被一致遵循(10 个中只有 5 个使用 -32002),客户端今天无法依赖任何单一的错误码。这意味着对客户端的实际影响很小——任何健壮到能跨既有 SDK 工作的客户端,都已经处理多种错误码或对所有错误一概处理。
迁移路径
- SDK 应将其”资源未找到”错误码更新为
-32602 - 在过渡期间,客户端**应当(SHOULD)**将
-32602和-32002都作为”资源未找到”处理 - 规范应将
-32602记录为规范的(canonical)错误码