Skip to content

Commit 953d0de

Browse files
refactor: Address API design improvements in StreamableHTTP client
This commit addresses two API design concerns: 1. Remove private module usage in examples: Examples no longer import from the private mcp.shared._httpx_utils module. Instead, they create httpx clients directly using the public httpx library. 2. Rename httpx_client parameter to http_client: The 'httpx_client' parameter name was redundant since the type annotation already specifies it's an httpx.AsyncClient. Renaming to 'http_client' provides a cleaner, more concise API. Changes: - Updated oauth_client.py and simple-auth-client examples to use public APIs - Renamed httpx_client to http_client in function signatures - Updated all internal callers and tests - Updated deprecated streamablehttp_client wrapper function
1 parent 93f2cf4 commit 953d0de

File tree

7 files changed

+22
-22
lines changed

7 files changed

+22
-22
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,12 +2256,12 @@ cd to the `examples/snippets` directory and run:
22562256
import asyncio
22572257
from urllib.parse import parse_qs, urlparse
22582258

2259+
import httpx
22592260
from pydantic import AnyUrl
22602261

22612262
from mcp import ClientSession
22622263
from mcp.client.auth import OAuthClientProvider, TokenStorage
22632264
from mcp.client.streamable_http import streamable_http_client
2264-
from mcp.shared._httpx_utils import create_mcp_http_client
22652265
from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, OAuthToken
22662266

22672267

@@ -2315,8 +2315,8 @@ async def main():
23152315
callback_handler=handle_callback,
23162316
)
23172317

2318-
async with create_mcp_http_client(auth=oauth_auth) as custom_client:
2319-
async with streamable_http_client("http://localhost:8001/mcp", httpx_client=custom_client) as (read, write, _):
2318+
async with httpx.AsyncClient(auth=oauth_auth, follow_redirects=True) as custom_client:
2319+
async with streamable_http_client("http://localhost:8001/mcp", http_client=custom_client) as (read, write, _):
23202320
async with ClientSession(read, write) as session:
23212321
await session.initialize()
23222322

examples/clients/simple-auth-client/mcp_simple_auth_client/main.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
from typing import Any
1616
from urllib.parse import parse_qs, urlparse
1717

18+
import httpx
1819
from mcp.client.auth import OAuthClientProvider, TokenStorage
1920
from mcp.client.session import ClientSession
2021
from mcp.client.sse import sse_client
2122
from mcp.client.streamable_http import streamable_http_client
22-
from mcp.shared._httpx_utils import create_mcp_http_client
2323
from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, OAuthToken
2424

2525

@@ -205,10 +205,10 @@ async def _default_redirect_handler(authorization_url: str) -> None:
205205
await self._run_session(read_stream, write_stream, None)
206206
else:
207207
print("📡 Opening StreamableHTTP transport connection with auth...")
208-
async with create_mcp_http_client(auth=oauth_auth) as custom_client:
208+
async with httpx.AsyncClient(auth=oauth_auth, follow_redirects=True) as custom_client:
209209
async with streamable_http_client(
210210
url=self.server_url,
211-
httpx_client=custom_client,
211+
http_client=custom_client,
212212
) as (read_stream, write_stream, get_session_id):
213213
await self._run_session(read_stream, write_stream, get_session_id)
214214

examples/snippets/clients/oauth_client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
import asyncio
1111
from urllib.parse import parse_qs, urlparse
1212

13+
import httpx
1314
from pydantic import AnyUrl
1415

1516
from mcp import ClientSession
1617
from mcp.client.auth import OAuthClientProvider, TokenStorage
1718
from mcp.client.streamable_http import streamable_http_client
18-
from mcp.shared._httpx_utils import create_mcp_http_client
1919
from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, OAuthToken
2020

2121

@@ -69,8 +69,8 @@ async def main():
6969
callback_handler=handle_callback,
7070
)
7171

72-
async with create_mcp_http_client(auth=oauth_auth) as custom_client:
73-
async with streamable_http_client("http://localhost:8001/mcp", httpx_client=custom_client) as (read, write, _):
72+
async with httpx.AsyncClient(auth=oauth_auth, follow_redirects=True) as custom_client:
73+
async with streamable_http_client("http://localhost:8001/mcp", http_client=custom_client) as (read, write, _):
7474
async with ClientSession(read, write) as session:
7575
await session.initialize()
7676

src/mcp/client/session_group.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ async def _establish_session(
263263

264264
client = streamable_http_client(
265265
url=server_params.url,
266-
httpx_client=httpx_client,
266+
http_client=httpx_client,
267267
terminate_on_close=server_params.terminate_on_close,
268268
)
269269
read, write, _ = await session_stack.enter_async_context(client)

src/mcp/client/streamable_http.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ def get_session_id(self) -> str | None:
452452
async def streamable_http_client(
453453
url: str,
454454
*,
455-
httpx_client: httpx.AsyncClient | None = None,
455+
http_client: httpx.AsyncClient | None = None,
456456
terminate_on_close: bool = True,
457457
) -> AsyncGenerator[
458458
tuple[
@@ -467,7 +467,7 @@ async def streamable_http_client(
467467
468468
Args:
469469
url: The MCP server endpoint URL.
470-
httpx_client: Optional pre-configured httpx.AsyncClient. If None, a default
470+
http_client: Optional pre-configured httpx.AsyncClient. If None, a default
471471
client with recommended MCP timeouts will be created. To configure headers,
472472
authentication, or other HTTP settings, create an httpx.AsyncClient and pass it here.
473473
terminate_on_close: If True, send a DELETE request to terminate the session
@@ -486,8 +486,8 @@ async def streamable_http_client(
486486
write_stream, write_stream_reader = anyio.create_memory_object_stream[SessionMessage](0)
487487

488488
# Determine if we need to create and manage the client
489-
client_provided = httpx_client is not None
490-
client = httpx_client
489+
client_provided = http_client is not None
490+
client = http_client
491491

492492
if client is None:
493493
# Create default client with recommended MCP timeouts
@@ -579,7 +579,7 @@ async def streamablehttp_client(
579579
async with client:
580580
async with streamable_http_client(
581581
url,
582-
httpx_client=client,
582+
http_client=client,
583583
terminate_on_close=terminate_on_close,
584584
) as streams:
585585
yield streams

tests/client/test_session_group.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,13 +347,13 @@ async def test_establish_session_parameterized(
347347
elif client_type_name == "streamablehttp":
348348
assert isinstance(server_params_instance, StreamableHttpParameters)
349349
# Verify streamable_http_client was called with url, httpx_client, and terminate_on_close
350-
# The httpx_client is created by the real create_mcp_http_client
350+
# The http_client is created by the real create_mcp_http_client
351351
import httpx
352352

353353
call_args = mock_specific_client_func.call_args
354354
assert call_args.kwargs["url"] == server_params_instance.url
355355
assert call_args.kwargs["terminate_on_close"] == server_params_instance.terminate_on_close
356-
assert isinstance(call_args.kwargs["httpx_client"], httpx.AsyncClient)
356+
assert isinstance(call_args.kwargs["http_client"], httpx.AsyncClient)
357357

358358
mock_client_cm_instance.__aenter__.assert_awaited_once()
359359

tests/shared/test_streamable_http.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ async def test_streamable_http_client_session_termination(basic_server: None, ba
10201020
headers[MCP_SESSION_ID_HEADER] = captured_session_id
10211021

10221022
async with create_mcp_http_client(headers=headers) as httpx_client:
1023-
async with streamable_http_client(f"{basic_server_url}/mcp", httpx_client=httpx_client) as (
1023+
async with streamable_http_client(f"{basic_server_url}/mcp", http_client=httpx_client) as (
10241024
read_stream,
10251025
write_stream,
10261026
_,
@@ -1087,7 +1087,7 @@ async def mock_delete(self: httpx.AsyncClient, *args: Any, **kwargs: Any) -> htt
10871087
headers[MCP_SESSION_ID_HEADER] = captured_session_id
10881088

10891089
async with create_mcp_http_client(headers=headers) as httpx_client:
1090-
async with streamable_http_client(f"{basic_server_url}/mcp", httpx_client=httpx_client) as (
1090+
async with streamable_http_client(f"{basic_server_url}/mcp", http_client=httpx_client) as (
10911091
read_stream,
10921092
write_stream,
10931093
_,
@@ -1187,7 +1187,7 @@ async def run_tool():
11871187
headers[MCP_PROTOCOL_VERSION_HEADER] = captured_protocol_version
11881188

11891189
async with create_mcp_http_client(headers=headers) as httpx_client:
1190-
async with streamable_http_client(f"{server_url}/mcp", httpx_client=httpx_client) as (
1190+
async with streamable_http_client(f"{server_url}/mcp", http_client=httpx_client) as (
11911191
read_stream,
11921192
write_stream,
11931193
_,
@@ -1399,7 +1399,7 @@ async def test_streamablehttp_request_context_propagation(context_aware_server:
13991399
}
14001400

14011401
async with create_mcp_http_client(headers=custom_headers) as httpx_client:
1402-
async with streamable_http_client(f"{basic_server_url}/mcp", httpx_client=httpx_client) as (
1402+
async with streamable_http_client(f"{basic_server_url}/mcp", http_client=httpx_client) as (
14031403
read_stream,
14041404
write_stream,
14051405
_,
@@ -1437,7 +1437,7 @@ async def test_streamablehttp_request_context_isolation(context_aware_server: No
14371437
}
14381438

14391439
async with create_mcp_http_client(headers=headers) as httpx_client:
1440-
async with streamable_http_client(f"{basic_server_url}/mcp", httpx_client=httpx_client) as (
1440+
async with streamable_http_client(f"{basic_server_url}/mcp", http_client=httpx_client) as (
14411441
read_stream,
14421442
write_stream,
14431443
_,

0 commit comments

Comments
 (0)