Skip to content

Commit e0f7807

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 80a48bf commit e0f7807

File tree

7 files changed

+20
-20
lines changed

7 files changed

+20
-20
lines changed

README.md

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

2373+
import httpx
23732374
from pydantic import AnyUrl
23742375

23752376
from mcp import ClientSession
23762377
from mcp.client.auth import OAuthClientProvider, TokenStorage
23772378
from mcp.client.streamable_http import streamable_http_client
2378-
from mcp.shared._httpx_utils import create_mcp_http_client
23792379
from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, OAuthToken
23802380

23812381

@@ -2429,8 +2429,8 @@ async def main():
24292429
callback_handler=handle_callback,
24302430
)
24312431

2432-
async with create_mcp_http_client(auth=oauth_auth) as custom_client:
2433-
async with streamable_http_client("http://localhost:8001/mcp", httpx_client=custom_client) as (read, write, _):
2432+
async with httpx.AsyncClient(auth=oauth_auth, follow_redirects=True) as custom_client:
2433+
async with streamable_http_client("http://localhost:8001/mcp", http_client=custom_client) as (read, write, _):
24342434
async with ClientSession(read, write) as session:
24352435
await session.initialize()
24362436

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

@@ -212,10 +212,10 @@ async def _default_redirect_handler(authorization_url: str) -> None:
212212
await self._run_session(read_stream, write_stream, None)
213213
else:
214214
print("📡 Opening StreamableHTTP transport connection with auth...")
215-
async with create_mcp_http_client(auth=oauth_auth) as custom_client:
215+
async with httpx.AsyncClient(auth=oauth_auth, follow_redirects=True) as custom_client:
216216
async with streamable_http_client(
217217
url=self.server_url,
218-
httpx_client=custom_client,
218+
http_client=custom_client,
219219
) as (read_stream, write_stream, get_session_id):
220220
await self._run_session(read_stream, write_stream, get_session_id)
221221

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
@@ -322,7 +322,7 @@ async def _establish_session(
322322

323323
client = streamable_http_client(
324324
url=server_params.url,
325-
httpx_client=httpx_client,
325+
http_client=httpx_client,
326326
terminate_on_close=server_params.terminate_on_close,
327327
)
328328
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
@@ -570,7 +570,7 @@ def get_session_id(self) -> str | None:
570570
async def streamable_http_client(
571571
url: str,
572572
*,
573-
httpx_client: httpx.AsyncClient | None = None,
573+
http_client: httpx.AsyncClient | None = None,
574574
terminate_on_close: bool = True,
575575
) -> AsyncGenerator[
576576
tuple[
@@ -585,7 +585,7 @@ async def streamable_http_client(
585585
586586
Args:
587587
url: The MCP server endpoint URL.
588-
httpx_client: Optional pre-configured httpx.AsyncClient. If None, a default
588+
http_client: Optional pre-configured httpx.AsyncClient. If None, a default
589589
client with recommended MCP timeouts will be created. To configure headers,
590590
authentication, or other HTTP settings, create an httpx.AsyncClient and pass it here.
591591
terminate_on_close: If True, send a DELETE request to terminate the session
@@ -604,8 +604,8 @@ async def streamable_http_client(
604604
write_stream, write_stream_reader = anyio.create_memory_object_stream[SessionMessage](0)
605605

606606
# Determine if we need to create and manage the client
607-
client_provided = httpx_client is not None
608-
client = httpx_client
607+
client_provided = http_client is not None
608+
client = http_client
609609

610610
if client is None:
611611
# Create default client with recommended MCP timeouts
@@ -697,7 +697,7 @@ async def streamablehttp_client(
697697
async with client:
698698
async with streamable_http_client(
699699
url,
700-
httpx_client=client,
700+
http_client=client,
701701
terminate_on_close=terminate_on_close,
702702
) as streams:
703703
yield streams

tests/client/test_session_group.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,13 +355,13 @@ async def test_establish_session_parameterized(
355355
elif client_type_name == "streamablehttp": # pragma: no branch
356356
assert isinstance(server_params_instance, StreamableHttpParameters)
357357
# Verify streamable_http_client was called with url, httpx_client, and terminate_on_close
358-
# The httpx_client is created by the real create_mcp_http_client
358+
# The http_client is created by the real create_mcp_http_client
359359
import httpx
360360

361361
call_args = mock_specific_client_func.call_args
362362
assert call_args.kwargs["url"] == server_params_instance.url
363363
assert call_args.kwargs["terminate_on_close"] == server_params_instance.terminate_on_close
364-
assert isinstance(call_args.kwargs["httpx_client"], httpx.AsyncClient)
364+
assert isinstance(call_args.kwargs["http_client"], httpx.AsyncClient)
365365

366366
mock_client_cm_instance.__aenter__.assert_awaited_once()
367367

tests/shared/test_streamable_http.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,7 +1329,7 @@ async def run_tool():
13291329
headers[MCP_PROTOCOL_VERSION_HEADER] = captured_protocol_version
13301330

13311331
async with create_mcp_http_client(headers=headers) as httpx_client:
1332-
async with streamable_http_client(f"{server_url}/mcp", httpx_client=httpx_client) as (
1332+
async with streamable_http_client(f"{server_url}/mcp", http_client=httpx_client) as (
13331333
read_stream,
13341334
write_stream,
13351335
_,
@@ -1542,7 +1542,7 @@ async def test_streamablehttp_request_context_propagation(context_aware_server:
15421542
}
15431543

15441544
async with create_mcp_http_client(headers=custom_headers) as httpx_client:
1545-
async with streamable_http_client(f"{basic_server_url}/mcp", httpx_client=httpx_client) as (
1545+
async with streamable_http_client(f"{basic_server_url}/mcp", http_client=httpx_client) as (
15461546
read_stream,
15471547
write_stream,
15481548
_,
@@ -1580,7 +1580,7 @@ async def test_streamablehttp_request_context_isolation(context_aware_server: No
15801580
}
15811581

15821582
async with create_mcp_http_client(headers=headers) as httpx_client:
1583-
async with streamable_http_client(f"{basic_server_url}/mcp", httpx_client=httpx_client) as (
1583+
async with streamable_http_client(f"{basic_server_url}/mcp", http_client=httpx_client) as (
15841584
read_stream,
15851585
write_stream,
15861586
_,

0 commit comments

Comments
 (0)