@@ -166,3 +166,33 @@ async def test_manage_mcp_servers_lazy_behavior():
166166 finally :
167167 # Restore the original method
168168 MCPManager .start_servers = original_start_servers
169+
170+
171+ async def test_mcp_tools_not_duplicated ():
172+ """
173+ regression for https://github.com/prefecthq/marvin/issues/1142: MCP tools appear to be added twice.
174+
175+ The issue: Marvin pre-discovered MCP tools AND passed mcp_servers to pydantic-ai.
176+ In pydantic-ai's _prepare_request_parameters(), both were processed:
177+ - add_tool(ctx.deps.function_tools.values()) - Marvin's pre-discovered tools
178+ - add_mcp_server_tools(ctx.deps.mcp_servers) - pydantic-ai's native discovery
179+ This caused duplicate tool names sent to the LLM.
180+
181+ The fix: Remove Marvin's pre-discovery, let pydantic-ai handle MCP servers natively.
182+ """
183+ from pydantic_ai .mcp import MCPServerStdio
184+
185+ git_mcp_server = MCPServerStdio (command = "uvx" , args = ["mcp-server-git" ])
186+ agent = Agent (mcp_servers = [git_mcp_server ])
187+
188+ agent_tools = agent .get_tools ()
189+ tool_names = [getattr (tool , "__name__" , str (tool )) for tool in agent_tools ]
190+
191+ mcp_tool_names = ["git_log" , "git_status" , "git_diff" ]
192+ found_mcp_tools = [
193+ name for name in tool_names if any (mcp in name for mcp in mcp_tool_names )
194+ ]
195+
196+ assert len (found_mcp_tools ) == 0 , (
197+ f"Agent should not pre-discover MCP tools, found: { found_mcp_tools } "
198+ )
0 commit comments