From 6b7d7e2eb8745103b0bf4a513515b972a27f5885 Mon Sep 17 00:00:00 2001 From: muskliu <862259098@qq.com> Date: Sun, 22 Feb 2026 00:39:53 +0800 Subject: [PATCH] fix(mcp): add 30s timeout to MCP tool calls to prevent agent hangs --- nanobot/agent/tools/mcp.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/nanobot/agent/tools/mcp.py b/nanobot/agent/tools/mcp.py index ad352bf..a5e619a 100644 --- a/nanobot/agent/tools/mcp.py +++ b/nanobot/agent/tools/mcp.py @@ -1,11 +1,15 @@ """MCP client: connects to MCP servers and wraps their tools as native nanobot tools.""" +import asyncio from contextlib import AsyncExitStack from typing import Any import httpx from loguru import logger +# Timeout for individual MCP tool calls (seconds). +MCP_TOOL_TIMEOUT = 30 + from nanobot.agent.tools.base import Tool from nanobot.agent.tools.registry import ToolRegistry @@ -34,7 +38,14 @@ class MCPToolWrapper(Tool): async def execute(self, **kwargs: Any) -> str: from mcp import types - result = await self._session.call_tool(self._original_name, arguments=kwargs) + try: + result = await asyncio.wait_for( + self._session.call_tool(self._original_name, arguments=kwargs), + timeout=MCP_TOOL_TIMEOUT, + ) + except asyncio.TimeoutError: + logger.warning("MCP tool '{}' timed out after {}s", self._name, MCP_TOOL_TIMEOUT) + return f"(MCP tool call timed out after {MCP_TOOL_TIMEOUT}s)" parts = [] for block in result.content: if isinstance(block, types.TextContent):