From 1e83c8c05172f2400585022aa4b45da7d7fc321d Mon Sep 17 00:00:00 2001 From: eviaaaaa <2278596667@qq.com> Date: Thu, 9 Apr 2026 18:44:04 +0800 Subject: [PATCH] Fix: align MCP tool call timeout and handle empty content (#13899) ### What problem does this PR solve? Resolves #12105 This PR fixes two MCP tool call issues in `common/mcp_tool_call_conn.py`. First, the timeout passed to `tool_call(..., timeout=...)` was only applied to the outer `future.result(...)` wait, but was not forwarded to the internal MCP request. As a result, callers could pass a longer timeout while the actual MCP request still failed after the default internal timeout. Second, the MCP tool call result handling assumed `result.content[0]` always existed. If an MCP server returned an empty content list, this could raise an exception unexpectedly. This PR fixes both issues by: - forwarding the external `timeout` value to the internal MCP request timeout - returning a clear message when the MCP server returns empty content instead of indexing into an empty list ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) - [ ] New Feature (non-breaking change which adds functionality) - [ ] Documentation Update - [ ] Refactoring - [ ] Performance Improvement - [ ] Other (please describe) --- common/mcp_tool_call_conn.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/common/mcp_tool_call_conn.py b/common/mcp_tool_call_conn.py index 9033c79c4a..95e3581bb0 100644 --- a/common/mcp_tool_call_conn.py +++ b/common/mcp_tool_call_conn.py @@ -182,6 +182,8 @@ class MCPToolCallSession(ToolCallSession): return f"MCP server error: {result.content}" # For now, we only support text content + if not result.content: + return "MCP server returned empty content." if isinstance(result.content[0], TextContent): return result.content[0].text else: @@ -214,7 +216,10 @@ class MCPToolCallSession(ToolCallSession): if self._close: return "Error: Session is closed" - future = asyncio.run_coroutine_threadsafe(self._call_mcp_tool(name, arguments), self._event_loop) + future = asyncio.run_coroutine_threadsafe( + self._call_mcp_tool(name, arguments, request_timeout=timeout), + self._event_loop, + ) try: return future.result(timeout=timeout) except FuturesTimeoutError: