Skip to content

fix: propagate MCPError from tool handlers as JSON-RPC error#2842

Closed
shiwenbin1617 wants to merge 1 commit into
modelcontextprotocol:mainfrom
shiwenbin1617:fix/mcp-error-propagation-in-tool-handler
Closed

fix: propagate MCPError from tool handlers as JSON-RPC error#2842
shiwenbin1617 wants to merge 1 commit into
modelcontextprotocol:mainfrom
shiwenbin1617:fix/mcp-error-propagation-in-tool-handler

Conversation

@shiwenbin1617

Copy link
Copy Markdown

Fixes #2770

Root cause

tools/base.py only re-raised UrlElicitationRequiredError; any other MCPError raised inside a tool function fell through to the bare except Exception clause, got wrapped into ToolError, and surfaced as CallToolResult(isError=True) instead of a structured JSON-RPC error response.

Fix

Broaden the guard from except UrlElicitationRequiredError to except MCPError. Since UrlElicitationRequiredError is a subclass of MCPError, the existing behaviour for that case is unchanged.

Changes

  • src/mcp/server/mcpserver/tools/base.py: widen re-raise guard (1 line)
  • tests/server/mcpserver/test_url_elicitation_error_throw.py: regression test covering the plain MCPError propagation path

Testing

uv run --frozen pytest tests/server/mcpserver/test_url_elicitation_error_throw.py tests/interaction/mcpserver/test_tools.py
# 438 passed

Previously, only UrlElicitationRequiredError was re-raised; any other
MCPError raised inside a tool function was caught by the bare
'except Exception' clause and wrapped into a ToolError, which then
surfaced as a CallToolResult(isError=True) instead of a structured
JSON-RPC error response.

Since UrlElicitationRequiredError is a subclass of MCPError,
broadening the guard to 'except MCPError' covers all cases including
the original one.

Fixes modelcontextprotocol#2770
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

McpError raised in tool handlers is swallowed as isError:true instead of propagating as JSON-RPC error

1 participant