From 4e19ecbf7bda84eea42da83ec57f4b1ec1c18b95 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sat, 6 Sep 2025 07:52:45 +0000 Subject: [PATCH] Fix: Add connect_timeout parameter to get_mcp_tools method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add Optional import to crew_base.py for type annotation - Modify get_mcp_tools to accept connect_timeout parameter with 30s default - Pass connect_timeout to MCPServerAdapter constructor - Update existing test to verify default timeout is passed - Add test for custom timeout values - Add test for backward compatibility Fixes issue #3463 where @CrewBase users couldn't configure MCP server connection timeouts Co-Authored-By: João --- src/crewai/project/crew_base.py | 6 ++-- tests/test_project.py | 51 ++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/crewai/project/crew_base.py b/src/crewai/project/crew_base.py index e1602acf0..6bd035279 100644 --- a/src/crewai/project/crew_base.py +++ b/src/crewai/project/crew_base.py @@ -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) diff --git a/tests/test_project.py b/tests/test_project.py index 70b69bb8a..97057c3e1 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -284,4 +284,53 @@ 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_custom_timeout(): + with patch("embedchain.client.Client.setup"): + from crewai_tools import MCPServerAdapter + from crewai_tools.adapters.mcp_adapter import ToolCollection + + @CrewBase + class CrewWithCustomTimeout(InternalCrew): + mcp_server_params = {"host": "localhost", "port": 8000} + + @agent + def test_agent(self): + return Agent( + config=self.agents_config["researcher"], + tools=self.get_mcp_tools("simple_tool", connect_timeout=60), + ) + + mock = Mock(spec=MCPServerAdapter) + mock.tools = ToolCollection([simple_tool]) + with patch("crewai_tools.MCPServerAdapter", return_value=mock) as adapter_mock: + crew = CrewWithCustomTimeout() + assert crew.test_agent().tools == [simple_tool] + + adapter_mock.assert_called_once_with({"host": "localhost", "port": 8000}, connect_timeout=60) + + +def test_internal_crew_with_mcp_backward_compatibility(): + with patch("embedchain.client.Client.setup"): + from crewai_tools import MCPServerAdapter + from crewai_tools.adapters.mcp_adapter import ToolCollection + + @CrewBase + class CrewWithoutTimeout(InternalCrew): + mcp_server_params = {"host": "localhost", "port": 8000} + + @agent + def test_agent(self): + return Agent( + config=self.agents_config["researcher"], + tools=self.get_mcp_tools("simple_tool"), + ) + + mock = Mock(spec=MCPServerAdapter) + mock.tools = ToolCollection([simple_tool]) + with patch("crewai_tools.MCPServerAdapter", return_value=mock) as adapter_mock: + crew = CrewWithoutTimeout() + assert crew.test_agent().tools == [simple_tool] + + adapter_mock.assert_called_once_with({"host": "localhost", "port": 8000}, connect_timeout=30)