fix(mcp): add 30s timeout to MCP tool calls to prevent agent hangs

This commit is contained in:
muskliu
2026-02-22 00:39:53 +08:00
parent edc671a8a3
commit 6b7d7e2eb8

View File

@@ -1,11 +1,15 @@
"""MCP client: connects to MCP servers and wraps their tools as native nanobot tools.""" """MCP client: connects to MCP servers and wraps their tools as native nanobot tools."""
import asyncio
from contextlib import AsyncExitStack from contextlib import AsyncExitStack
from typing import Any from typing import Any
import httpx import httpx
from loguru import logger 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.base import Tool
from nanobot.agent.tools.registry import ToolRegistry from nanobot.agent.tools.registry import ToolRegistry
@@ -34,7 +38,14 @@ class MCPToolWrapper(Tool):
async def execute(self, **kwargs: Any) -> str: async def execute(self, **kwargs: Any) -> str:
from mcp import types 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 = [] parts = []
for block in result.content: for block in result.content:
if isinstance(block, types.TextContent): if isinstance(block, types.TextContent):