@@ -258,6 +258,57 @@ async def make_request(client_session: ClientSession):
258258 await ev_timeout .wait ()
259259
260260
261+ @pytest .mark .anyio
262+ async def test_response_id_non_canonical_numeric_string_no_match ():
263+ """Test that non-canonical numeric IDs don't collide with integer request IDs.
264+
265+ If a server returns ``"id": "01"``, it should not match a pending request with
266+ integer ID ``1``.
267+ """
268+ ev_timeout = anyio .Event ()
269+
270+ async with create_client_server_memory_streams () as (client_streams , server_streams ):
271+ client_read , client_write = client_streams
272+ server_read , server_write = server_streams
273+
274+ async def mock_server ():
275+ """Receive two requests and reply with a colliding non-canonical ID."""
276+ await server_read .receive () # request id 0
277+ await server_read .receive () # request id 1
278+
279+ response = JSONRPCResponse (
280+ jsonrpc = "2.0" ,
281+ id = "01" , # Non-canonical representation of 1
282+ result = {},
283+ )
284+ await server_write .send (SessionMessage (message = response ))
285+
286+ async def make_requests (client_session : ClientSession ):
287+ # First request consumes request ID 0 so the second request uses ID 1.
288+ await client_session .send_ping ()
289+
290+ try :
291+ await client_session .send_request (
292+ types .PingRequest (),
293+ types .EmptyResult ,
294+ request_read_timeout_seconds = 0.5 ,
295+ )
296+ pytest .fail ("Expected timeout" ) # pragma: no cover
297+ except MCPError as e :
298+ assert "Timed out" in str (e )
299+ ev_timeout .set ()
300+
301+ async with (
302+ anyio .create_task_group () as tg ,
303+ ClientSession (read_stream = client_read , write_stream = client_write ) as client_session ,
304+ ):
305+ tg .start_soon (mock_server )
306+ tg .start_soon (make_requests , client_session )
307+
308+ with anyio .fail_after (2 ): # pragma: no branch
309+ await ev_timeout .wait ()
310+
311+
261312@pytest .mark .anyio
262313async def test_connection_closed ():
263314 """Test that pending requests are cancelled when the connection is closed remotely."""
0 commit comments