Wrapper for MCP tools with timeout handling.
| 58 | |
| 59 | |
| 60 | class MCPTool(Tool): |
| 61 | """Wrapper for MCP tools with timeout handling.""" |
| 62 | |
| 63 | def __init__( |
| 64 | self, |
| 65 | name: str, |
| 66 | description: str, |
| 67 | parameters: dict[str, Any], |
| 68 | session: ClientSession, |
| 69 | execute_timeout: float | None = None, |
| 70 | ): |
| 71 | self._name = name |
| 72 | self._description = description |
| 73 | self._parameters = parameters |
| 74 | self._session = session |
| 75 | self._execute_timeout = execute_timeout |
| 76 | |
| 77 | @property |
| 78 | def name(self) -> str: |
| 79 | return self._name |
| 80 | |
| 81 | @property |
| 82 | def description(self) -> str: |
| 83 | return self._description |
| 84 | |
| 85 | @property |
| 86 | def parameters(self) -> dict[str, Any]: |
| 87 | return self._parameters |
| 88 | |
| 89 | async def execute(self, **kwargs) -> ToolResult: |
| 90 | """Execute MCP tool via the session with timeout protection.""" |
| 91 | timeout = self._execute_timeout or _default_timeout_config.execute_timeout |
| 92 | |
| 93 | try: |
| 94 | # Wrap call_tool with timeout |
| 95 | async with asyncio.timeout(timeout): |
| 96 | result = await self._session.call_tool(self._name, arguments=kwargs) |
| 97 | |
| 98 | # MCP tool results are a list of content items |
| 99 | content_parts = [] |
| 100 | for item in result.content: |
| 101 | if hasattr(item, "text"): |
| 102 | content_parts.append(item.text) |
| 103 | else: |
| 104 | content_parts.append(str(item)) |
| 105 | |
| 106 | content_str = "\n".join(content_parts) |
| 107 | |
| 108 | is_error = result.isError if hasattr(result, "isError") else False |
| 109 | |
| 110 | return ToolResult(success=not is_error, content=content_str, error=None if not is_error else "Tool returned error") |
| 111 | |
| 112 | except TimeoutError: |
| 113 | return ToolResult( |
| 114 | success=False, |
| 115 | content="", |
| 116 | error=f"MCP tool execution timed out after {timeout}s. The remote server may be slow or unresponsive.", |
| 117 | ) |