modelcontextprotocol / modelcontextprotocol/python-sdk

MCPServer handlers should raise exceptions, not return error objects

未關閉
#2,153 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

enhancement v2
主要語言
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 as ToolError, 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/except at the MCPServer layer — exceptions propagate to the low-level server

Low-level server handlers:

  • _handle_request() catches MCPError → sends its .error as a JSON-RPC error
  • Any other ExceptionErrorData(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
  1. 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.
  2. Low-level server users should return ErrorData explicitly when they want to control the JSON-RPC error response, since they operate at the protocol level.
  3. 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

AI Disclaimer

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 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

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。