Compare commits

...

1 Commits

Author SHA1 Message Date
Devin AI
7c70cb493c Fix: Add connect_timeout parameter to get_mcp_tools method
- Add Optional[int] connect_timeout parameter with default value of 30 seconds
- Pass connect_timeout to MCPServerAdapter constructor to prevent timeouts
- Add comprehensive tests for timeout functionality
- Maintain backward compatibility with existing code
- Fixes issue #3326 where get_mcp_tools hits timeout with multiple MCP servers

Co-Authored-By: João <joao@crewai.com>
2025-08-15 18:38:10 +00:00
2 changed files with 34 additions and 4 deletions

View File

@@ -1,7 +1,7 @@
import inspect
import logging
from pathlib import Path
from typing import Any, Callable, Dict, TypeVar, cast, List
from typing import Any, Callable, Dict, TypeVar, cast, List, Optional
from crewai.tools import BaseTool
import yaml
@@ -86,7 +86,7 @@ def CrewBase(cls: T) -> T:
import types
return types.MethodType(_close_mcp_server, self)
def get_mcp_tools(self, *tool_names: list[str]) -> List[BaseTool]:
def get_mcp_tools(self, *tool_names: list[str], connect_timeout: Optional[int] = 30) -> List[BaseTool]:
if not self.mcp_server_params:
return []
@@ -94,7 +94,7 @@ def CrewBase(cls: T) -> T:
adapter = getattr(self, '_mcp_server_adapter', None)
if not adapter:
self._mcp_server_adapter = MCPServerAdapter(self.mcp_server_params)
self._mcp_server_adapter = MCPServerAdapter(self.mcp_server_params, connect_timeout=connect_timeout)
return self._mcp_server_adapter.tools.filter_by_names(tool_names or None)

View File

@@ -270,4 +270,34 @@ def test_internal_crew_with_mcp():
assert crew.reporting_analyst().tools == [simple_tool, another_simple_tool]
assert crew.researcher().tools == [simple_tool]
adapter_mock.assert_called_once_with({"host": "localhost", "port": 8000})
adapter_mock.assert_called_once_with({"host": "localhost", "port": 8000}, connect_timeout=30)
def test_internal_crew_with_mcp_connect_timeout():
from crewai_tools import MCPServerAdapter
from crewai_tools.adapters.mcp_adapter import ToolCollection
@CrewBase
class TestCrewWithMCP:
mcp_server_params = {"host": "localhost", "port": 8000}
agents_config = None
tasks_config = None
mock = Mock(spec=MCPServerAdapter)
mock.tools = ToolCollection([simple_tool, another_simple_tool])
with patch("crewai_tools.MCPServerAdapter", return_value=mock) as adapter_mock:
crew1 = TestCrewWithMCP()
crew1.get_mcp_tools()
adapter_mock.assert_called_with({"host": "localhost", "port": 8000}, connect_timeout=30)
adapter_mock.reset_mock()
crew2 = TestCrewWithMCP()
crew2.get_mcp_tools(connect_timeout=60)
adapter_mock.assert_called_with({"host": "localhost", "port": 8000}, connect_timeout=60)
adapter_mock.reset_mock()
crew3 = TestCrewWithMCP()
crew3.get_mcp_tools("simple_tool", connect_timeout=45)
adapter_mock.assert_called_with({"host": "localhost", "port": 8000}, connect_timeout=45)