66from crewai_tools import MCPServerAdapter
77from crewai_tools .adapters .tool_collection import ToolCollection
88
9+
910@pytest .fixture
1011def 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
3334def 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
7677def 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
8890def 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
97100def 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
112118def 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+
125132def 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+
141149def 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+
155164def 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
171183def 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+
181194def 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