@@ -75,7 +75,7 @@ def server_url(server_port: int) -> str:
7575 return f"http://127.0.0.1:{ server_port } "
7676
7777
78- def start_server_process (port : int ) -> subprocess .Popen [str ]:
78+ def start_server_process (port : int , json_response : bool | None = None ) -> subprocess .Popen [str ]:
7979 """Start server in a separate process."""
8080 # Create a temporary script to run the server
8181 import os
@@ -114,7 +114,7 @@ def run_server_with_logging(port: int) -> None:
114114 # Create session manager
115115 session_manager = StreamableHTTPSessionManager(
116116 app=app,
117- json_response=False ,
117+ json_response={ json_response } ,
118118 stateless=True, # Use stateless mode to trigger the race condition
119119 )
120120
@@ -248,3 +248,30 @@ async def test_race_condition_invalid_content_type(server_port: int):
248248 process .wait ()
249249 # Check server logs for race condition errors
250250 check_server_logs_for_errors (process , "test_race_condition_invalid_content_type" )
251+
252+
253+ @pytest .mark .anyio
254+ async def test_race_condition_message_router_async_for (server_port : int ):
255+ """
256+ Uses json_response=True to trigger the `if self.is_json_response_enabled` branch,
257+ which reproduces the ClosedResourceError when message_router is suspended
258+ in async for loop while transport cleanup closes streams concurrently.
259+ """
260+ process = start_server_process (server_port , json_response = True )
261+
262+ try :
263+ # use standard mcp client to send requests
264+ from mcp .client .session import ClientSession
265+ from mcp .client .streamable_http import streamablehttp_client
266+
267+ for _ in range (1 ):
268+ async with streamablehttp_client (f"http://127.0.0.1:{ server_port } " ) as (read_stream , write_stream , _ ):
269+ async with ClientSession (read_stream , write_stream ) as session :
270+ await session .initialize ()
271+
272+
273+ finally :
274+ process .terminate ()
275+ process .wait ()
276+ # Check server logs for race condition errors in message router
277+ check_server_logs_for_errors (process , "test_race_condition_message_router_async_for" )
0 commit comments