Skip to main content

摘要

当前的 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 工作的客户端,都已经处理多种错误码或对所有错误一概处理。

迁移路径

  1. SDK 应将其”资源未找到”错误码更新为 -32602
  2. 在过渡期间,客户端**应当(SHOULD)**将 -32602-32002 都作为”资源未找到”处理
  3. 规范应将 -32602 记录为规范的(canonical)错误码

安全影响

无。此变更仅影响错误码的值,不影响访问控制或数据暴露。