modelcontextprotocol / modelcontextprotocol/python-sdk
MCPServer handlers should raise exceptions, not return error objects
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 24.3k
- 派生
- 4k
- 平均合并
- 1 天 1 小时
- 30 天内合并 PR
- 31
描述
Problem
The current error handling across the two server layers is inconsistent and confusing for users. As noted by Marcelo, the experience should be more like Starlette's raise HTTPException pattern.
Current behavior
MCPServer (high-level) tool handlers:
- Raising any exception → caught by
Tool.run(), re-wrapped asToolError, then caught by_handle_call_tool()→CallToolResult(isError=True)(a JSON-RPC success response) - Raising
MCPError→ re-raised past_handle_call_tool()→ becomes a JSON-RPC error response - Returning
CallToolResult(isError=True)directly → also works - Resource/prompt handlers have no
try/exceptat the MCPServer layer — exceptions propagate to the low-level server
Low-level server handlers:
_handle_request()catchesMCPError→ sends its.erroras a JSON-RPC error- Any other
Exception→ErrorData(code=0, message=str(err))→ JSON-RPC error with non-standard code
Users need to understand the difference between ToolError, MCPError, CallToolResult(isError=True), and plain exceptions — each produces different behavior depending on which layer catches it.
Desired behavior
- MCPServer users should raise exceptions to signal errors — the framework converts them to the appropriate protocol response. No need to construct and return error result objects.
- Low-level server users should return
ErrorDataexplicitly when they want to control the JSON-RPC error response, since they operate at the protocol level. - Unhandled exceptions at either layer should be caught gracefully by the framework and returned as a well-formed JSON-RPC error, without leaking internal details to the client.
Related issues
- #1742 — Introduce typed error classes with metadata (covers error taxonomy but not the raise-vs-return layering)
- #698 — Tool.run should not reveal exception value to the client (security concern with current behavior)
- #396 — Inconsistent Exception Handling in
@app.call_tool(older, narrower scope) - #1788 — Extensible pattern for protocol flow-control exceptions
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 src/mcp/server/mcpserver/server.py 中的 _handle_call_tool() 和 src/mcp/server/lowlevel/server.py 中的 _handle_request() 开始,比较它们的异常路径和响应构造方式。当高层处理器可以通过抛出异常来发出错误信号,低层处理器可以显式返回 ErrorData,并且任一层的未处理异常都能生成格式正确的 JSON-RPC 错误而不泄露内部细节时,这项工作就完成了。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- api, backend-api-design
- Issue 类型
- 重构
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100