fix: make MCPClient.connect() initialize timeout configurable via env var

Add MCP_INITIALIZE_TIMEOUT environment variable to override the hardcoded
  10s session.initialize() timeout in MCPClient.connect(). Raise default to
  60s to accommodate cold-start handshake times observed against real MCP
  servers exposing many tools.

  Fixes: #25001
This commit is contained in:
KingsleyOWO 2026-05-22 17:57:01 +08:00 • committed by GitHub
parent 42783881e9
commit c3ea8f7480
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,5 +1,6 @@
import asyncio
import logging
import os
from contextlib import AsyncExitStack
from typing import Optional
@ -14,6 +15,12 @@ from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, OAu
from open_webui.env import AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL, AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER
# Timeout (in seconds) for the MCP session.initialize() handshake.
# The handshake performs a list-tools round-trip and can take tens of
# seconds on cold-start servers or servers exposing many tools. Override
# via the MCP_INITIALIZE_TIMEOUT environment variable.
MCP_INITIALIZE_TIMEOUT = float(os.environ.get("MCP_INITIALIZE_TIMEOUT", "60"))
def _build_httpx_client(headers=None, timeout=None, auth=None, verify=True):
"""Create an httpx AsyncClient for MCP transport.
@ -69,7 +76,7 @@ class MCPClient:
self._session_context = ClientSession(read_stream, write_stream) # pylint: disable=W0201
self.session = await exit_stack.enter_async_context(self._session_context)
with anyio.fail_after(10):
with anyio.fail_after(MCP_INITIALIZE_TIMEOUT):
await self.session.initialize()
self.exit_stack = exit_stack.pop_all()
except Exception as e: