@@ -262,7 +262,7 @@ def __init__(
262262 tool_result_resolver = tool_result_resolver ,
263263 )
264264 self .url = url
265- self .headers = headers
265+ self ._headers = headers or {}
266266 self ._timeout = timeout
267267 self ._sse_read_timeout = sse_read_timeout
268268 self ._allowed_tools = set (allowed_tools ) if allowed_tools else None
@@ -278,6 +278,37 @@ def __init__(
278278 # Fall back to URL-based detection for backward compatibility
279279 self ._use_streamable_http = self ._should_use_streamable_http (url )
280280
281+ self ._http_client : httpx .AsyncClient | None = None
282+
283+ @property
284+ def headers (self ) -> dict [str , Any ]:
285+ return self ._headers
286+
287+ @headers .setter
288+ def headers (self , headers : dict [str , Any ]) -> None :
289+ self ._headers = headers
290+ if self ._http_client is not None :
291+ self ._http_client .headers = headers
292+
293+ def _create_http_client (
294+ self ,
295+ headers : dict [str , Any ] | None = None ,
296+ timeout : httpx .Timeout | None = None ,
297+ auth : httpx .Auth | None = None ,
298+ ) -> httpx .AsyncClient :
299+ # ported from mcp.shared._httpx_utils.create_mcp_http_client
300+ kwargs : dict [str , Any ] = {
301+ "follow_redirects" : True ,
302+ "timeout" : timeout
303+ if timeout is not None
304+ else httpx .Timeout (self ._timeout , read = self ._sse_read_timeout ),
305+ "headers" : headers if headers is not None else self ._headers ,
306+ }
307+ if auth is not None :
308+ kwargs ["auth" ] = auth
309+ self ._http_client = httpx .AsyncClient (** kwargs )
310+ return self ._http_client
311+
281312 def _should_use_streamable_http (self , url : str ) -> bool :
282313 """
283314 Determine transport type based on URL path (for backward compatibility).
@@ -306,10 +337,7 @@ def client_streams(
306337
307338 @asynccontextmanager
308339 async def _streamable_http_with_client (): # type: ignore[no-untyped-def]
309- async with httpx .AsyncClient (
310- headers = self .headers or {},
311- timeout = httpx .Timeout (self ._timeout , read = self ._sse_read_timeout ),
312- ) as http_client :
340+ async with self ._create_http_client () as http_client :
313341 async with streamable_http_client (
314342 url = self .url , http_client = http_client
315343 ) as streams :
@@ -319,9 +347,10 @@ async def _streamable_http_with_client(): # type: ignore[no-untyped-def]
319347 else :
320348 return sse_client ( # type: ignore[no-any-return]
321349 url = self .url ,
322- headers = self .headers ,
350+ headers = self ._headers ,
323351 timeout = self ._timeout ,
324352 sse_read_timeout = self ._sse_read_timeout ,
353+ httpx_client_factory = self ._create_http_client ,
325354 )
326355
327356 async def list_tools (self ) -> list [MCPTool ]:
0 commit comments