From 34dc68a296466a9a025cbfc71d40a91d3384bf30 Mon Sep 17 00:00:00 2001 From: Christian-Sidak Date: Sun, 19 Apr 2026 06:35:57 +0000 Subject: [PATCH] test: add regression test for initialize hang on unexpected content-type (#2432) Add a test that verifies initialize() raises MCPError immediately when the server returns an unexpected Content-Type (e.g. text/plain) instead of hanging forever waiting for a response that never arrives. Fixes #2432 --- tests/client/test_notification_response.py | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/client/test_notification_response.py b/tests/client/test_notification_response.py index 69c8afeb8..afac24f88 100644 --- a/tests/client/test_notification_response.py +++ b/tests/client/test_notification_response.py @@ -71,6 +71,21 @@ async def handle_mcp_request(request: Request) -> Response: return Starlette(debug=True, routes=[Route("/mcp", handle_mcp_request, methods=["POST"])]) +def _create_plain_text_server_app() -> Starlette: + """Create a server that returns text/plain for all requests, including initialize. + + This reproduces the scenario from issue #2432 where a misconfigured server + returns an unexpected content type on the initialize call, causing the client + to hang forever. + """ + + async def handle_mcp_request(request: Request) -> Response: + # Always return text/plain — never a valid MCP response. + return Response(content="this is not json", status_code=200, media_type="text/plain") + + return Starlette(debug=True, routes=[Route("/mcp", handle_mcp_request, methods=["POST"])]) + + async def test_non_compliant_notification_response() -> None: """Verify the client ignores unexpected responses to notifications. @@ -116,6 +131,20 @@ async def test_unexpected_content_type_sends_jsonrpc_error() -> None: await session.list_tools() +async def test_initialize_does_not_hang_on_unexpected_content_type() -> None: + """Verify that initialize() raises MCPError immediately when server returns wrong content type. + + Regression test for issue #2432: when a misconfigured server returns a content type + other than application/json or text/event-stream in response to the initialize request, + the client must raise MCPError right away instead of hanging forever. + """ + async with httpx.AsyncClient(transport=httpx.ASGITransport(app=_create_plain_text_server_app())) as client: + async with streamable_http_client("http://localhost/mcp", http_client=client) as (read_stream, write_stream): + async with ClientSession(read_stream, write_stream) as session: # pragma: no branch + with pytest.raises(MCPError, match="Unexpected content type: text/plain"): # pragma: no branch + await session.initialize() + + def _create_http_error_app(error_status: int, *, error_on_notifications: bool = False) -> Starlette: """Create a server that returns an HTTP error for non-init requests."""