SEP-2164:标准化资源不存在错误码
社区译文;来源: MCP 29affa6b
| 字段 | 值 |
|---|---|
| SEP | 2164 |
| 标题 | 标准化资源不存在错误码 |
| 状态 | 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 |
| Python | 0(通用) | 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 |
| Ruby | N/A(由实现者处理) | server.rb#L375-L379 |
| Swift | N/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 工作的客户端都已经会处理多个错误码,或以通用方式处理所有错误。
迁移路径
- SDK 应将资源不存在错误码更新为
-32602 - 在过渡期间,客户端 SHOULD 将
-32602和-32002都作为资源不存在处理 - 规范应将
-32602记录为规范错误码
安全影响
无。此变更只影响错误码值,不影响访问控制或数据暴露。