mirror of
https://github.com/langflow-ai/langflow.git
synced 2026-07-24 18:31:48 +08:00
fix(mcp): make run_tool wait_for timeout configurable, raise floor to… (#12996)
fix(mcp): make run_tool wait_for timeout configurable, raise floor to 180s
The hardcoded `timeout=30.0` on `asyncio.wait_for(session.call_tool(...))`
in both `MCPSseClient.run_tool` and `MCPStreamableHttpClient.run_tool` was
truncating in-flight tool calls whose servers needed longer than 30s to
respond — most visibly large MCP composers whose tool responses include
sizeable catalogs.
Failure mode:
LLM → AgentExecutor → run_tool (1 call from the LLM)
├── attempt 1: get_session (probe ..._1 fails → swap ..._2)
│ → call_tool → 30s wait_for fires, TimeoutError raised
│ (server is still working — response ignored on arrival)
└── attempt 2: get_session (probe ..._2 fails → swap ..._3)
→ call_tool → 30s wait_for fires again
→ util.py dedup ("Repeated TimeoutError, not retrying")
→ ValueError("Maximum retries exceeded ...")
← AgentExecutor surfaces error → flow fails
The retry loop's TimeoutError dedup correctly stops looping once it sees
the same error twice, but every call against a slow server hit the same
ceiling and never had a chance to succeed. The session swaps between
attempts also produced excess HTTP churn against the server.
Both `run_tool` methods now resolve the timeout from
`get_settings_service().settings.mcp_server_timeout` (already used for
connection setup at lines 1617 / 1887, env: `LANGFLOW_MCP_SERVER_TIMEOUT`)
with a `max(setting, 180.0)` floor so default deployments don't end up
*shorter* than the previous hardcoded 30s — the Pydantic default for
`mcp_server_timeout` is 20.
Touched:
src/lfx/src/lfx/base/mcp/util.py
- L1677, L1689 (stdio run_tool)
- L1960, L1972 (streamable HTTP run_tool)
Unchanged on purpose:
- L1217, L1381 session-creation `timeout=30.0` (separate concern).
- L1060 `_validate_session_connectivity` 3.0s probe (separate
concern; addressed in follow-up if probe thrash persists).
Tuning:
- LANGFLOW_MCP_SERVER_TIMEOUT now governs both connection setup and
tool-call wait_for. The 180s floor clamps low values; raise the env
var above 180 to take effect.
Repro / verification:
- Trace run that previously failed at 67.08s with "Maximum retries
exceeded with repeated TimeoutError errors" against
`mcp-guardium_get_service_info` (47KB response payload) now
completes on attempt 1.
Co-authored-by: MANSURA HABIBA <MANSURAH@ie.ibm.com>
This commit is contained in:
@ -1672,6 +1672,9 @@ class MCPStdioClient:
|
||||
param_hash = uuid.uuid4().hex[:8]
|
||||
self._session_context = f"default_{param_hash}"
|
||||
|
||||
# Tool-call timeout: env LANGFLOW_MCP_SERVER_TIMEOUT (via settings), with a 180s
|
||||
# floor so default deployments aren't shorter than the previous hardcoded 30s.
|
||||
timeout = max(get_settings_service().settings.mcp_server_timeout, 180.0)
|
||||
max_retries = 2
|
||||
last_error_type = None
|
||||
|
||||
@ -1683,7 +1686,7 @@ class MCPStdioClient:
|
||||
|
||||
result = await asyncio.wait_for(
|
||||
session.call_tool(tool_name, arguments=arguments),
|
||||
timeout=30.0, # 30 second timeout
|
||||
timeout=timeout,
|
||||
)
|
||||
except Exception as e:
|
||||
current_error_type = type(e).__name__
|
||||
@ -1952,6 +1955,9 @@ class MCPStreamableHttpClient:
|
||||
param_hash = uuid.uuid4().hex[:8]
|
||||
self._session_context = f"default_http_{param_hash}"
|
||||
|
||||
# Tool-call timeout: env LANGFLOW_MCP_SERVER_TIMEOUT (via settings), with a 180s
|
||||
# floor so default deployments aren't shorter than the previous hardcoded 30s.
|
||||
timeout = max(get_settings_service().settings.mcp_server_timeout, 180.0)
|
||||
max_retries = 2
|
||||
last_error_type = None
|
||||
|
||||
@ -1963,7 +1969,7 @@ class MCPStreamableHttpClient:
|
||||
|
||||
result = await asyncio.wait_for(
|
||||
session.call_tool(tool_name, arguments=arguments),
|
||||
timeout=30.0, # 30 second timeout
|
||||
timeout=timeout,
|
||||
)
|
||||
except Exception as e:
|
||||
current_error_type = type(e).__name__
|
||||
|
||||
Reference in New Issue
Block a user