From f325f9589284856fca81176984301fbe31f910ba Mon Sep 17 00:00:00 2001 From: Navin Pai Date: Fri, 11 Jul 2025 14:24:23 +0530 Subject: [PATCH 1/3] Add support for passing `connect_timeout` and `client_session_timeout_seconds` to `MCPServerAdapter` --- crewai_tools/adapters/mcp_adapter.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crewai_tools/adapters/mcp_adapter.py b/crewai_tools/adapters/mcp_adapter.py index db4c15a2..938e9b6d 100644 --- a/crewai_tools/adapters/mcp_adapter.py +++ b/crewai_tools/adapters/mcp_adapter.py @@ -2,9 +2,11 @@ import logging from typing import TYPE_CHECKING, Any +from datetime import timedelta from crewai.tools import BaseTool from crewai_tools.adapters.tool_collection import ToolCollection + """ MCPServer for CrewAI. @@ -70,6 +72,8 @@ def __init__( self, serverparams: StdioServerParameters | dict[str, Any], *tool_names: str, + connect_timeout: int = 30, + client_session_timeout_seconds: float | timedelta | None = 5, ): """Initialize the MCP Server @@ -78,6 +82,8 @@ def __init__( `StdioServerParameters` or a `dict` respectively for STDIO and SSE. *tool_names: Optional names of tools to filter. If provided, only tools with matching names will be available. + connect_timeout: Timeout for connecting to the MCP server (default: 30 seconds). + client_session_timeout_seconds: Timeout for client sessions (default: 5 seconds). """ @@ -106,7 +112,12 @@ def __init__( try: self._serverparams = serverparams - self._adapter = MCPAdapt(self._serverparams, CrewAIAdapter()) + self._adapter = MCPAdapt( + self._serverparams, + CrewAIAdapter(), + connect_timeout=connect_timeout, + client_session_timeout_seconds=client_session_timeout_seconds, + ) self.start() except Exception as e: From 0aed4188dc8a20f9ae1c62a18b07881adfcdefa7 Mon Sep 17 00:00:00 2001 From: Navin Pai Date: Fri, 11 Jul 2025 14:49:51 +0530 Subject: [PATCH 2/3] [MINOR] Adding tests to check passing of timeout parameters --- tests/adapters/mcp_adapter_test.py | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/adapters/mcp_adapter_test.py b/tests/adapters/mcp_adapter_test.py index d0dc8868..009c11fd 100644 --- a/tests/adapters/mcp_adapter_test.py +++ b/tests/adapters/mcp_adapter_test.py @@ -1,6 +1,7 @@ from textwrap import dedent import pytest +from datetime import timedelta from mcp import StdioServerParameters from crewai_tools import MCPServerAdapter @@ -187,3 +188,50 @@ def test_filter_with_only_nonexistent_tools(echo_server_script): # Should return an empty tool collection assert isinstance(tools, ToolCollection) assert len(tools) == 0 + + +def test_timeout_parameters_are_set(echo_server_script): + """Test that connect_timeout and client_session_timeout_seconds are properly set.""" + from datetime import timedelta + + serverparams = StdioServerParameters( + command="uv", args=["run", "python", "-c", echo_server_script] + ) + + # Test with custom timeout values + connect_timeout = 45 + client_session_timeout_seconds = 10.5 + + try: + mcp_server_adapter = MCPServerAdapter( + serverparams, + connect_timeout=connect_timeout, + client_session_timeout_seconds=client_session_timeout_seconds, + ) + + # Verify the timeout parameters are set on the adapter + assert mcp_server_adapter._adapter.connect_timeout == connect_timeout + assert ( + mcp_server_adapter._adapter.client_session_timeout_seconds + == client_session_timeout_seconds + ) + + # Test with timedelta for client_session_timeout_seconds + client_session_timeout_timedelta = timedelta(seconds=15) + mcp_server_adapter_timedelta = MCPServerAdapter( + serverparams, + connect_timeout=60, + client_session_timeout_seconds=client_session_timeout_timedelta, + ) + + assert mcp_server_adapter_timedelta._adapter.connect_timeout == 60 + assert ( + mcp_server_adapter_timedelta._adapter.client_session_timeout_seconds + == client_session_timeout_timedelta + ) + + finally: + if "mcp_server_adapter" in locals(): + mcp_server_adapter.stop() + if "mcp_server_adapter_timedelta" in locals(): + mcp_server_adapter_timedelta.stop() From be0e27b820778249900584f5a1a6cae22c24b617 Mon Sep 17 00:00:00 2001 From: Navin Pai Date: Fri, 11 Jul 2025 15:28:33 +0530 Subject: [PATCH 3/3] [MINOR] Remove inline import --- crewai_tools/adapters/mcp_adapter.py | 3 ++- tests/adapters/mcp_adapter_test.py | 22 +++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/crewai_tools/adapters/mcp_adapter.py b/crewai_tools/adapters/mcp_adapter.py index 938e9b6d..7433fe33 100644 --- a/crewai_tools/adapters/mcp_adapter.py +++ b/crewai_tools/adapters/mcp_adapter.py @@ -1,10 +1,11 @@ from __future__ import annotations import logging -from typing import TYPE_CHECKING, Any from datetime import timedelta +from typing import TYPE_CHECKING, Any from crewai.tools import BaseTool + from crewai_tools.adapters.tool_collection import ToolCollection """ diff --git a/tests/adapters/mcp_adapter_test.py b/tests/adapters/mcp_adapter_test.py index 009c11fd..23cfe290 100644 --- a/tests/adapters/mcp_adapter_test.py +++ b/tests/adapters/mcp_adapter_test.py @@ -1,12 +1,13 @@ +from datetime import timedelta from textwrap import dedent import pytest -from datetime import timedelta from mcp import StdioServerParameters from crewai_tools import MCPServerAdapter from crewai_tools.adapters.tool_collection import ToolCollection + @pytest.fixture def echo_server_script(): return dedent( @@ -84,7 +85,8 @@ def test_context_manager_syntax(echo_server_script): assert tools[0].name == "echo_tool" assert tools[1].name == "calc_tool" assert tools[0].run(text="hello") == "Echo: hello" - assert tools[1].run(a=5, b=3) == '8' + assert tools[1].run(a=5, b=3) == "8" + def test_context_manager_syntax_sse(echo_sse_server): sse_serverparams = echo_sse_server @@ -93,7 +95,8 @@ def test_context_manager_syntax_sse(echo_sse_server): assert tools[0].name == "echo_tool" assert tools[1].name == "calc_tool" assert tools[0].run(text="hello") == "Echo: hello" - assert tools[1].run(a=5, b=3) == '8' + assert tools[1].run(a=5, b=3) == "8" + def test_try_finally_syntax(echo_server_script): serverparams = StdioServerParameters( @@ -106,10 +109,11 @@ def test_try_finally_syntax(echo_server_script): assert tools[0].name == "echo_tool" assert tools[1].name == "calc_tool" assert tools[0].run(text="hello") == "Echo: hello" - assert tools[1].run(a=5, b=3) == '8' + assert tools[1].run(a=5, b=3) == "8" finally: mcp_server_adapter.stop() + def test_try_finally_syntax_sse(echo_sse_server): sse_serverparams = echo_sse_server mcp_server_adapter = MCPServerAdapter(sse_serverparams) @@ -119,10 +123,11 @@ def test_try_finally_syntax_sse(echo_sse_server): assert tools[0].name == "echo_tool" assert tools[1].name == "calc_tool" assert tools[0].run(text="hello") == "Echo: hello" - assert tools[1].run(a=5, b=3) == '8' + assert tools[1].run(a=5, b=3) == "8" finally: mcp_server_adapter.stop() + def test_context_manager_with_filtered_tools(echo_server_script): serverparams = StdioServerParameters( command="uv", args=["run", "python", "-c", echo_server_script] @@ -139,6 +144,7 @@ def test_context_manager_with_filtered_tools(echo_server_script): with pytest.raises(KeyError): _ = tools["calc_tool"] + def test_context_manager_sse_with_filtered_tools(echo_sse_server): sse_serverparams = echo_sse_server # Only select the calc_tool @@ -146,13 +152,14 @@ def test_context_manager_sse_with_filtered_tools(echo_sse_server): assert isinstance(tools, ToolCollection) assert len(tools) == 1 assert tools[0].name == "calc_tool" - assert tools[0].run(a=10, b=5) == '15' + assert tools[0].run(a=10, b=5) == "15" # Check that echo_tool is not present with pytest.raises(IndexError): _ = tools[1] with pytest.raises(KeyError): _ = tools["echo_tool"] + def test_try_finally_with_filtered_tools(echo_server_script): serverparams = StdioServerParameters( command="uv", args=["run", "python", "-c", echo_server_script] @@ -169,6 +176,7 @@ def test_try_finally_with_filtered_tools(echo_server_script): finally: mcp_server_adapter.stop() + def test_filter_with_nonexistent_tool(echo_server_script): serverparams = StdioServerParameters( command="uv", args=["run", "python", "-c", echo_server_script] @@ -179,6 +187,7 @@ def test_filter_with_nonexistent_tool(echo_server_script): assert len(tools) == 1 assert tools[0].name == "echo_tool" + def test_filter_with_only_nonexistent_tools(echo_server_script): serverparams = StdioServerParameters( command="uv", args=["run", "python", "-c", echo_server_script] @@ -192,7 +201,6 @@ def test_filter_with_only_nonexistent_tools(echo_server_script): def test_timeout_parameters_are_set(echo_server_script): """Test that connect_timeout and client_session_timeout_seconds are properly set.""" - from datetime import timedelta serverparams = StdioServerParameters( command="uv", args=["run", "python", "-c", echo_server_script]