SEP-2164:标准化资源不存在错误码

SEP-2164:标准化资源不存在错误码

社区译文;来源: MCP 29affa6b

本 SEP 已达到 Final 状态,并作为已接受设计的历史记录保留。 定稿后对协议所做的更改不会反映在此处。权威要求请参阅当前规范 及其变更日志。
字段值
SEP2164
标题标准化资源不存在错误码
状态Final
类型标准跟踪
创建日期2026-01-28
作者Peter Alexander(@pja-ant)
发起人无(正在寻找发起人)
PR#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 对资源不存在的错误处理不同:

SDK当前错误码来源
TypeScript-32602(InvalidParams)mcp.ts#L561
Python0(通用)server.py#L790
C#-32002(自定义 RESOURCE_NOT_FOUND)McpServerImpl.cs#L289
Rust-32002(自定义 RESOURCE_NOT_FOUND)model.rs#L450
Java-32002(自定义 RESOURCE_NOT_FOUND)McpAsyncServer.java#L732
Go-32002(自定义 RESOURCE_NOT_FOUND)server.go#L786
Kotlin-32603(INTERNAL_ERROR)Server.kt#L618-L621
PHP-32002(自定义 RESOURCE_NOT_FOUND)Error.php#L37
RubyN/A(由实现者处理)server.rb#L375-L379
SwiftN/A(无内置处理器)N/A

这种不一致意味着客户端无法在不同实现之间可靠识别“资源不存在”情况。在 8 个内置资源处理的 SDK 中,使用了四种不同的错误码:-32002(C#、Rust、Java、Go、PHP)、-32602(TypeScript)、-32603(Kotlin)和 0(Python)。Ruby 和 Swift 将错误处理留给服务器实现者。需要区分“资源不存在”和其他错误的客户端必须处理所有这些变体。

规范

如果请求的资源不存在,服务器 MUST 返回错误码为 -32602(Invalid Params)的 JSON-RPC 错误:

{
  "jsonrpc": "2.0",
  "id": 2,
  "error": {
    "code": -32602,
    "message": "Resource not found",
    "data": {
      "uri": "file:///nonexistent.txt"
    }
  }
}

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 个 SDK 中只有 5 个使用 -32002),客户端目前无法依赖任何单一错误码。这意味着对客户端的实际影响很小:任何足够健壮、能够跨现有 SDK 工作的客户端都已经会处理多个错误码,或以通用方式处理所有错误。

迁移路径

  1. SDK 应将资源不存在错误码更新为 -32602
  2. 在过渡期间,客户端 SHOULD 将 -32602 和 -32002 都作为资源不存在处理
  3. 规范应将 -32602 记录为规范错误码

安全影响

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