Fix JSON-RPC error response ID matching#1720
Merged
felixweinberger merged 3 commits intomainfrom Dec 10, 2025
Merged
Conversation
When an MCP server returns a JSON-RPC response with a string ID (e.g., "id": "0") but the client sent an integer ID (e.g., "id": 0), the response would fail to match the pending request, causing a timeout. This fix normalizes response IDs to integers before lookup, matching the TypeScript SDK approach: https://github.com/modelcontextprotocol/typescript-sdk/blob/a606fb17909ea454e83aab14c73f14ea45c04448/src/shared/protocol.ts#L861
97466ea to
67447c4
Compare
felixweinberger
previously approved these changes
Dec 10, 2025
Contributor
felixweinberger
left a comment
There was a problem hiding this comment.
Seems reasonable and matches the approach we take in the Typescript SDK. Might be worth adding that warning log though when we hit the unexpected case.
src/mcp/shared/session.py
Outdated
| try: | ||
| return int(response_id) | ||
| except ValueError: | ||
| pass |
Contributor
There was a problem hiding this comment.
Should we log a warning for the exception here?
If we hit this it means the assumption of integer RequestIds is violated right? Seems worth bubbling that up. Not sure if that's sufficiently obvious from wherever else this surfaces.
Contributor
There was a problem hiding this comment.
Something like this maybe?
logger.warning(
f"Response ID {response_id!r} cannot be normalized to match pending requests"
)
felixweinberger
previously approved these changes
Dec 10, 2025
Log a warning when a string response ID cannot be converted to an integer, as this means the response will never match any pending request (since the client always sends integer IDs).
ba82151 to
e76efbd
Compare
felixweinberger
approved these changes
Dec 10, 2025
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.
Motivation and Context
When an MCP server returns a JSON-RPC response with the request ID as a string (e.g.,
"id": "0") but the client sent the request with an integer ID (e.g.,"id": 0), the response fails to match the pending request. This causes the client to timeout waiting for a response that was already received but couldn't be correlated.The root cause is in
src/mcp/shared/session.py:256-260where the client stores pending requests using an integer counter:When a response arrives, the lookup
self._response_streams.pop(response_id, None)fails silently ifresponse_idis"0"(string) because Python dict lookups are type-sensitive (0 != "0").This is valid per the JSON-RPC spec and the SDK's own type definition at
src/mcp/types.py:40:How Has This Been Tested?
Added three new unit tests in
tests/shared/test_session.py:test_response_id_type_mismatch_string_to_int- success responses with string IDs match integer request IDstest_error_response_id_type_mismatch_string_to_int- error responses with string IDs match integer request IDstest_response_id_non_numeric_string_no_match- non-numeric string IDs (like"abc") don't incorrectly matchBreaking Changes
None. This is a backwards-compatible fix that makes the client more tolerant of server responses.
Types of changes
Bug fix (non-breaking change which fixes an issue)
New feature (non-breaking change which adds functionality)
Breaking change (fix or feature that would cause existing functionality to change)
Documentation update
Checklist
I have read the MCP Documentation
My code follows the repository's style guidelines
New and existing tests pass locally
I have added appropriate error handling
I have added or updated documentation as needed
Additional context
The fix adds a
_pop_response_stream()helper method that:First tries an exact match lookup
If the ID is a string, tries converting to int and looks up again
If the ID is an int, tries converting to string and looks up again
This handles the common case where servers echo back IDs in a different but semantically equivalent format.