99from mcp .client .streamable_http import streamablehttp_client
1010from mcp .shared .auth import OAuthClientInformationFull , OAuthClientMetadata , OAuthToken
1111import httpx
12- from open_webui .env import AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL
12+ from open_webui .env import AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL , AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER
1313
1414
15- def create_insecure_httpx_client (headers = None , timeout = None , auth = None ):
16- """Create an httpx AsyncClient with SSL verification disabled.
15+ def _build_httpx_client (headers = None , timeout = None , auth = None , verify = True ):
16+ """Create an httpx AsyncClient for MCP transport.
17+
18+ Falls back to AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER when the caller
19+ (i.e. the MCP SDK) does not supply an explicit timeout.
1720
18- Note: verify=False must be passed at construction time because httpx
21+ Note: verify must be passed at construction time because httpx
1922 configures the SSL context during __init__. Setting client.verify = False
2023 after construction does not affect the underlying transport's SSL context.
2124 """
2225 kwargs = {
2326 'follow_redirects' : True ,
24- 'verify' : False ,
27+ 'verify' : verify ,
2528 }
2629 if timeout is not None :
2730 kwargs ['timeout' ] = timeout
31+ elif AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER is not None :
32+ kwargs ['timeout' ] = float (AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER )
2833 if headers is not None :
2934 kwargs ['headers' ] = headers
3035 if auth is not None :
3136 kwargs ['auth' ] = auth
3237 return httpx .AsyncClient (** kwargs )
3338
3439
40+ def create_httpx_client (headers = None , timeout = None , auth = None ):
41+ return _build_httpx_client (headers = headers , timeout = timeout , auth = auth , verify = True )
42+
43+
44+ def create_insecure_httpx_client (headers = None , timeout = None , auth = None ):
45+ return _build_httpx_client (headers = headers , timeout = timeout , auth = auth , verify = False )
46+
47+
3548class MCPClient :
3649 def __init__ (self ):
3750 self .session : Optional [ClientSession ] = None
@@ -40,14 +53,11 @@ def __init__(self):
4053 async def connect (self , url : str , headers : Optional [dict ] = None ):
4154 async with AsyncExitStack () as exit_stack :
4255 try :
43- if AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL :
44- self ._streams_context = streamablehttp_client (url , headers = headers )
45- else :
46- self ._streams_context = streamablehttp_client (
47- url ,
48- headers = headers ,
49- httpx_client_factory = create_insecure_httpx_client ,
50- )
56+ self ._streams_context = streamablehttp_client (
57+ url ,
58+ headers = headers ,
59+ httpx_client_factory = create_httpx_client if AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL else create_insecure_httpx_client ,
60+ )
5161
5262 transport = await exit_stack .enter_async_context (self ._streams_context )
5363 read_stream , write_stream , _ = transport
0 commit comments