From c3ea8f74808f751cfe680952e6a0bf4ace679b69 Mon Sep 17 00:00:00 2001 From: KingsleyOWO Date: Fri, 22 May 2026 17:57:01 +0800 Subject: [PATCH] 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 --- backend/open_webui/utils/mcp/client.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/utils/mcp/client.py b/backend/open_webui/utils/mcp/client.py index a4691750db..37a1a7245a 100644 --- a/backend/open_webui/utils/mcp/client.py +++ b/backend/open_webui/utils/mcp/client.py @@ -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: