fix: propagate McpError as JSON-RPC error response in lowlevel server#3096
Open
nankingjing wants to merge 1 commit into
Open
fix: propagate McpError as JSON-RPC error response in lowlevel server#3096nankingjing wants to merge 1 commit into
nankingjing wants to merge 1 commit into
Conversation
When a tool handler raises McpError, the call_tool decorator handler caught it via the generic `except Exception` block and wrapped it as CallToolResult(isError=True), dropping the structured error code on the wire. The UrlElicitationRequiredError subclass already had a re-raise bypass for exactly this reason, but the parent McpError class did not. Broaden the re-raise guard from UrlElicitationRequiredError to McpError so any McpError propagates to _handle_request, which converts it to a JSON-RPC error response preserving the original error code, message, and data. This subsumes the existing UrlElicitationRequiredError bypass since it is a subclass of McpError. Github-Issue:modelcontextprotocol#2770 Reported-by:mengyunxie
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2770
Motivation and Context
When a tool handler registered via the lowlevel server's
@server.call_tool()decorator raisesMcpError, the handler catches it via the genericexcept Exceptionblock and wraps it asCallToolResult(isError=True). This drops the structured error code on the wire, so clients cannot distinguish error types without parsing the message string.The
UrlElicitationRequiredErrorsubclass already has a re-raise bypass for exactly this reason, but the parentMcpErrorclass does not. (The v2 high-level API onmainalready handles this correctly.)How Has This Been Tested?
McpErrorraised in a lowlevel tool handler reaches the client as a JSON-RPC error with the original code, message, and data preserved (it fails without this change), plus a companion test asserting non-McpErrorexceptions still returnCallToolResult(isError=True).Breaking Changes
Tool handlers that deliberately raise
McpErrornow produce a JSON-RPC error response (the documented behavior for the error, matchingUrlElicitationRequiredErrorand the v2 API) instead of anisError: trueresult. Handlers that raise other exceptions are unaffected.Types of changes
Checklist
Additional context
This scopes the fix to the lowlevel server per the issue's proposed fix. #2772 covers related ground but also changes FastMCP
Tool.run()behavior; this PR is the minimal lowlevel-only change with regression tests at the lowlevel layer, in case the maintainers prefer to take that separately.