From 64815da52cc7610886fbdb2545caba0ec080fde2 Mon Sep 17 00:00:00 2001 From: Sayan Sisodiya Date: Sat, 11 Apr 2026 18:59:20 -0700 Subject: [PATCH] Fix MCP resolution for split flat names --- .../codex-mcp/src/mcp_connection_manager.rs | 19 +++++++++++-------- .../src/mcp_connection_manager_tests.rs | 13 +++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/codex-rs/codex-mcp/src/mcp_connection_manager.rs b/codex-rs/codex-mcp/src/mcp_connection_manager.rs index 97e8e30ad8..54838b6ea4 100644 --- a/codex-rs/codex-mcp/src/mcp_connection_manager.rs +++ b/codex-rs/codex-mcp/src/mcp_connection_manager.rs @@ -1200,15 +1200,18 @@ impl McpConnectionManager { pub async fn resolve_tool_info(&self, tool_name: &ToolName) -> Option { let all_tools = self.list_all_tools().await; - if tool_name.namespace.is_some() { - let tools_by_name = all_tools - .into_values() - .map(|tool| (tool.callable_tool_name(), tool)) - .collect::>(); - tools_by_name.get(tool_name).cloned() - } else { - all_tools.get(&tool_name.name).cloned() + let tools_by_name = all_tools + .into_values() + .map(|tool| (tool.callable_tool_name(), tool)) + .collect::>(); + + if let Some(tool) = tools_by_name.get(tool_name) { + return Some(tool.clone()); } + + tools_by_name + .into_iter() + .find_map(|(name, tool)| (name.display() == tool_name.name).then_some(tool)) } pub async fn notify_sandbox_state_change(&self, sandbox_state: &SandboxState) -> Result<()> { diff --git a/codex-rs/codex-mcp/src/mcp_connection_manager_tests.rs b/codex-rs/codex-mcp/src/mcp_connection_manager_tests.rs index 427fc9308d..f093918211 100644 --- a/codex-rs/codex-mcp/src/mcp_connection_manager_tests.rs +++ b/codex-rs/codex-mcp/src/mcp_connection_manager_tests.rs @@ -674,6 +674,10 @@ async fn resolve_tool_info_accepts_plain_and_namespaced_tool_names() { .resolve_tool_info(&ToolName::namespaced("mcp__rmcp__", "echo")) .await .expect("split MCP tool namespace and name should resolve"); + let split_with_flat_name = manager + .resolve_tool_info(&ToolName::namespaced("mcp__rmcp__", "mcp__rmcp__echo")) + .await + .expect("split namespace with flat qualified MCP tool name should resolve"); let expected = ("rmcp", "mcp__rmcp__", "echo", "echo"); assert_eq!( @@ -694,6 +698,15 @@ async fn resolve_tool_info_accepts_plain_and_namespaced_tool_names() { ), expected ); + assert_eq!( + ( + split_with_flat_name.server_name.as_str(), + split_with_flat_name.callable_namespace.as_str(), + split_with_flat_name.callable_name.as_str(), + split_with_flat_name.tool.name.as_ref(), + ), + expected + ); } #[tokio::test]