33import logging
44from typing import Any
55
6- import httpx
6+ import httpx2
77import pytest
88from mcp_types import (
99 INVALID_PARAMS ,
@@ -125,10 +125,10 @@ async def test_the_default_streamable_http_app_answers_a_real_hostname_with_421(
125125 caplog : pytest .LogCaptureFixture ,
126126) -> None :
127127 """tutorial003: one 421, three spellings. The page presents all three as the same event."""
128- transport = httpx .ASGITransport (app = tutorial003 .app )
128+ transport = httpx2 .ASGITransport (app = tutorial003 .app )
129129 async with tutorial003 .mcp .session_manager .run ():
130130 # What curl (or the reverse proxy's access log) shows: the status and the plain-text body.
131- async with httpx .AsyncClient (transport = transport , base_url = "http://mcp.example.com" ) as raw :
131+ async with httpx2 .AsyncClient (transport = transport , base_url = "http://mcp.example.com" ) as raw :
132132 with caplog .at_level (logging .WARNING , logger = "mcp.server.transport_security" ):
133133 response = await raw .post ("/mcp" , json = INITIALIZE , headers = MCP_HEADERS )
134134 assert (response .status_code , response .text ) == (421 , "Invalid Host header" )
@@ -137,7 +137,7 @@ async def test_the_default_streamable_http_app_answers_a_real_hostname_with_421(
137137 # What the server operator finds by grepping the server log.
138138 assert "Invalid Host header: mcp.example.com" in caplog .messages
139139 # What the python `Client` raises instead: the generic stand-in, wrapped by the task group.
140- async with httpx .AsyncClient (transport = transport ) as http_client :
140+ async with httpx2 .AsyncClient (transport = transport ) as http_client :
141141 client = Client (streamable_http_client ("http://mcp.example.com/mcp" , http_client = http_client ))
142142 with pytest .raises (Exception ) as exc_info : # pragma: no branch
143143 await client .__aenter__ () # the connection attempt itself is what fails
@@ -147,9 +147,9 @@ async def test_the_default_streamable_http_app_answers_a_real_hostname_with_421(
147147
148148async def test_an_allowlisted_hostname_connects_and_calls_a_tool () -> None :
149149 """tutorial004: `transport_security=` names the deployed hostname, and the same client connects."""
150- transport = httpx .ASGITransport (app = tutorial004 .app )
150+ transport = httpx2 .ASGITransport (app = tutorial004 .app )
151151 async with tutorial004 .mcp .session_manager .run ():
152- async with httpx .AsyncClient (transport = transport ) as http_client :
152+ async with httpx2 .AsyncClient (transport = transport ) as http_client :
153153 allowed = streamable_http_client ("http://mcp.example.com/mcp" , http_client = http_client )
154154 async with Client (allowed ) as c : # pragma: no branch
155155 assert c .protocol_version == "2026-07-28"
@@ -159,8 +159,8 @@ async def test_an_allowlisted_hostname_connects_and_calls_a_tool() -> None:
159159
160160async def test_a_mounted_app_without_a_lifespan_fails_on_the_first_request () -> None :
161161 """tutorial005: Starlette never runs a mounted sub-app's lifespan, so nothing starts the manager."""
162- transport = httpx .ASGITransport (app = tutorial005 .app )
163- async with httpx .AsyncClient (transport = transport , base_url = "http://127.0.0.1:8000" ) as http :
162+ transport = httpx2 .ASGITransport (app = tutorial005 .app )
163+ async with httpx2 .AsyncClient (transport = transport , base_url = "http://127.0.0.1:8000" ) as http :
164164 with pytest .raises (RuntimeError , match = r"Task group is not initialized\. Make sure to use run\(\)\." ):
165165 await http .post ("/mcp" )
166166
@@ -170,7 +170,7 @@ async def test_a_session_id_the_server_never_issued_gets_a_404_session_not_found
170170 mcp = MCPServer ("Weather" )
171171 app = mcp .streamable_http_app ()
172172 async with mcp .session_manager .run ():
173- async with httpx .AsyncClient (transport = httpx .ASGITransport (app = app ), base_url = "http://127.0.0.1:8000" ) as h :
173+ async with httpx2 .AsyncClient (transport = httpx2 .ASGITransport (app = app ), base_url = "http://127.0.0.1:8000" ) as h :
174174 response = await h .post (
175175 "/mcp" ,
176176 json = {"jsonrpc" : "2.0" , "id" : 1 , "method" : "tools/list" , "params" : {}},
@@ -243,9 +243,9 @@ async def test_a_legacy_ctx_elicit_without_a_callback_says_elicitation_not_suppo
243243
244244async def test_ctx_elicit_over_stateless_http_has_no_back_channel () -> None :
245245 """tutorial008: `stateless_http=True` leaves the server no channel to send `elicitation/create`."""
246- transport = httpx .ASGITransport (app = tutorial008 .app )
246+ transport = httpx2 .ASGITransport (app = tutorial008 .app )
247247 async with tutorial008 .mcp .session_manager .run ():
248- async with httpx .AsyncClient (transport = transport ) as http_client :
248+ async with httpx2 .AsyncClient (transport = transport ) as http_client :
249249 stateless = streamable_http_client ("http://127.0.0.1:8000/mcp" , http_client = http_client )
250250 async with Client (stateless ) as c : # pragma: no branch
251251 with pytest .raises (MCPError ) as exc_info : # pragma: no branch
0 commit comments