modelcontextprotocol / modelcontextprotocol/python-sdk

MCPServer handlers should raise exceptions, not return error objects

Offen
#2,153 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

enhancement v2
Vorherrschende Sprache
Python
Sterne
24.3k
Forks
4k
Ø Merge
1 T. 1 Std.
Gemergte PRs (30 T.)
31

Beschreibung

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

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit _handle_call_tool() in src/mcp/server/mcpserver/server.py und _handle_request() in src/mcp/server/lowlevel/server.py und vergleiche deren Pfade für Ausnahmen und die Erstellung der Antworten. Die Arbeit ist abgeschlossen, wenn Handler auf hoher Ebene Fehler durch das Auslösen von Ausnahmen signalisieren können, Handler auf niedriger Ebene explizit ErrorData zurückgeben können und nicht behandelte Ausnahmen auf beiden Ebenen wohlgeformte JSON-RPC-Fehler erzeugen, ohne interne Details offenzulegen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
api, backend-api-design
Issue-Typ
Refactoring
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.