Skip to content

Commit 27e60df

Browse files
author
RN
committed
test(tools): Verify ImportError on missing mcp dependency
Adds a unit test to ensure that MCPServerAdapter raises an ImportError when its required `mcp` package is not available. This test uses `pytest` and `monkeypatch` to simulate the missing dependency. It verifies the fix from the previous commit and prevents regressions where the application might crash in non-interactive environments.
1 parent b939f77 commit 27e60df

File tree

1 file changed

+48
-21
lines changed

1 file changed

+48
-21
lines changed

tests/adapters/mcp_adapter_test.py

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,49 +6,50 @@
66
from crewai_tools import MCPServerAdapter
77
from crewai_tools.adapters.tool_collection import ToolCollection
88

9+
910
@pytest.fixture
1011
def echo_server_script():
1112
return dedent(
12-
'''
13+
"""
1314
from mcp.server.fastmcp import FastMCP
1415
1516
mcp = FastMCP("Echo Server")
1617
1718
@mcp.tool()
1819
def echo_tool(text: str) -> str:
19-
"""Echo the input text"""
20+
\"\"\"Echo the input text\"\"\"
2021
return f"Echo: {text}"
2122
2223
@mcp.tool()
2324
def calc_tool(a: int, b: int) -> int:
24-
"""Calculate a + b"""
25+
\"\"\"Calculate a + b\"\"\"
2526
return a + b
2627
2728
mcp.run()
28-
'''
29+
"""
2930
)
3031

3132

3233
@pytest.fixture
3334
def echo_server_sse_script():
3435
return dedent(
35-
'''
36+
"""
3637
from mcp.server.fastmcp import FastMCP
3738
3839
mcp = FastMCP("Echo Server", host="127.0.0.1", port=8000)
3940
4041
@mcp.tool()
4142
def echo_tool(text: str) -> str:
42-
"""Echo the input text"""
43+
\"\"\"Echo the input text\"\"\"
4344
return f"Echo: {text}"
4445
4546
@mcp.tool()
4647
def calc_tool(a: int, b: int) -> int:
47-
"""Calculate a + b"""
48+
\"\"\"Calculate a + b\"\"\"
4849
return a + b
4950
5051
mcp.run("sse")
51-
'''
52+
"""
5253
)
5354

5455

@@ -75,15 +76,16 @@ def echo_sse_server(echo_server_sse_script):
7576

7677
def test_context_manager_syntax(echo_server_script):
7778
serverparams = StdioServerParameters(
78-
command="uv", args=["run", "python", "-c", echo_server_script]
79+
command="python", args=["-c", echo_server_script]
7980
)
8081
with MCPServerAdapter(serverparams) as tools:
8182
assert isinstance(tools, ToolCollection)
8283
assert len(tools) == 2
8384
assert tools[0].name == "echo_tool"
8485
assert tools[1].name == "calc_tool"
8586
assert tools[0].run(text="hello") == "Echo: hello"
86-
assert tools[1].run(a=5, b=3) == '8'
87+
assert tools[1].run(a=5, b=3) == "8"
88+
8789

8890
def test_context_manager_syntax_sse(echo_sse_server):
8991
sse_serverparams = echo_sse_server
@@ -92,22 +94,26 @@ def test_context_manager_syntax_sse(echo_sse_server):
9294
assert tools[0].name == "echo_tool"
9395
assert tools[1].name == "calc_tool"
9496
assert tools[0].run(text="hello") == "Echo: hello"
95-
assert tools[1].run(a=5, b=3) == '8'
97+
assert tools[1].run(a=5, b=3) == "8"
98+
9699

97100
def test_try_finally_syntax(echo_server_script):
98101
serverparams = StdioServerParameters(
99-
command="uv", args=["run", "python", "-c", echo_server_script]
102+
command="python", args=["-c", echo_server_script]
100103
)
104+
mcp_server_adapter = None # Define before try block
101105
try:
102106
mcp_server_adapter = MCPServerAdapter(serverparams)
103107
tools = mcp_server_adapter.tools
104108
assert len(tools) == 2
105109
assert tools[0].name == "echo_tool"
106110
assert tools[1].name == "calc_tool"
107111
assert tools[0].run(text="hello") == "Echo: hello"
108-
assert tools[1].run(a=5, b=3) == '8'
112+
assert tools[1].run(a=5, b=3) == "8"
109113
finally:
110-
mcp_server_adapter.stop()
114+
if mcp_server_adapter:
115+
mcp_server_adapter.stop()
116+
111117

112118
def test_try_finally_syntax_sse(echo_sse_server):
113119
sse_serverparams = echo_sse_server
@@ -118,13 +124,14 @@ def test_try_finally_syntax_sse(echo_sse_server):
118124
assert tools[0].name == "echo_tool"
119125
assert tools[1].name == "calc_tool"
120126
assert tools[0].run(text="hello") == "Echo: hello"
121-
assert tools[1].run(a=5, b=3) == '8'
127+
assert tools[1].run(a=5, b=3) == "8"
122128
finally:
123129
mcp_server_adapter.stop()
124130

131+
125132
def test_context_manager_with_filtered_tools(echo_server_script):
126133
serverparams = StdioServerParameters(
127-
command="uv", args=["run", "python", "-c", echo_server_script]
134+
command="python", args=["-c", echo_server_script]
128135
)
129136
# Only select the echo_tool
130137
with MCPServerAdapter(serverparams, "echo_tool") as tools:
@@ -138,24 +145,27 @@ def test_context_manager_with_filtered_tools(echo_server_script):
138145
with pytest.raises(KeyError):
139146
_ = tools["calc_tool"]
140147

148+
141149
def test_context_manager_sse_with_filtered_tools(echo_sse_server):
142150
sse_serverparams = echo_sse_server
143151
# Only select the calc_tool
144152
with MCPServerAdapter(sse_serverparams, "calc_tool") as tools:
145153
assert isinstance(tools, ToolCollection)
146154
assert len(tools) == 1
147155
assert tools[0].name == "calc_tool"
148-
assert tools[0].run(a=10, b=5) == '15'
156+
assert tools[0].run(a=10, b=5) == "15"
149157
# Check that echo_tool is not present
150158
with pytest.raises(IndexError):
151159
_ = tools[1]
152160
with pytest.raises(KeyError):
153161
_ = tools["echo_tool"]
154162

163+
155164
def test_try_finally_with_filtered_tools(echo_server_script):
156165
serverparams = StdioServerParameters(
157-
command="uv", args=["run", "python", "-c", echo_server_script]
166+
command="python", args=["-c", echo_server_script]
158167
)
168+
mcp_server_adapter = None # Define before try block
159169
try:
160170
# Select both tools but in reverse order
161171
mcp_server_adapter = MCPServerAdapter(serverparams, "calc_tool", "echo_tool")
@@ -166,24 +176,41 @@ def test_try_finally_with_filtered_tools(echo_server_script):
166176
assert tools[0].name == "calc_tool"
167177
assert tools[1].name == "echo_tool"
168178
finally:
169-
mcp_server_adapter.stop()
179+
if mcp_server_adapter:
180+
mcp_server_adapter.stop()
181+
170182

171183
def test_filter_with_nonexistent_tool(echo_server_script):
172184
serverparams = StdioServerParameters(
173-
command="uv", args=["run", "python", "-c", echo_server_script]
185+
command="python", args=["-c", echo_server_script]
174186
)
175187
# Include a tool that doesn't exist
176188
with MCPServerAdapter(serverparams, "echo_tool", "nonexistent_tool") as tools:
177189
# Only echo_tool should be in the result
178190
assert len(tools) == 1
179191
assert tools[0].name == "echo_tool"
180192

193+
181194
def test_filter_with_only_nonexistent_tools(echo_server_script):
182195
serverparams = StdioServerParameters(
183-
command="uv", args=["run", "python", "-c", echo_server_script]
196+
command="python", args=["-c", echo_server_script]
184197
)
185198
# All requested tools don't exist
186199
with MCPServerAdapter(serverparams, "nonexistent1", "nonexistent2") as tools:
187200
# Should return an empty tool collection
188201
assert isinstance(tools, ToolCollection)
189202
assert len(tools) == 0
203+
204+
205+
def test_adapter_raises_import_error_if_mcp_is_missing(monkeypatch):
206+
"""
207+
Tests that MCPServerAdapter raises ImportError if the mcp package is not available.
208+
"""
209+
# 1. Simulate the condition where 'mcp' is not installed by setting the
210+
# MCP_AVAILABLE flag to False in the adapter's module.
211+
monkeypatch.setattr("crewai_tools.adapters.mcp_adapter.MCP_AVAILABLE", False)
212+
213+
# 2. Assert that instantiating the adapter under this condition raises an
214+
# ImportError with our specific error message.
215+
with pytest.raises(ImportError, match="`mcp` package not found"):
216+
MCPServerAdapter(serverparams={})

0 commit comments

Comments
 (0)