From bc2e0d223b42a8f4a881d6faf0e6375d04362569 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 20 May 2026 19:44:41 +0000 Subject: [PATCH] fix(mcp): retry tool-server lookup with prefixed name in REST mismatch check When the REST /mcp-rest/tools/call path sends a raw tool name plus requested_server_id, _get_mcp_server_from_tool_name(name) can return None if the mapping only stores the prefixed form. That bypassed the tool_server_mismatch 403 guard and let the call fall through to trusting requested_server. Retry the lookup with every known prefix of the requested server so the mismatch check fires whenever the tool is actually registered. Co-authored-by: Yassin Kortam --- litellm/proxy/_experimental/mcp_server/server.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/litellm/proxy/_experimental/mcp_server/server.py b/litellm/proxy/_experimental/mcp_server/server.py index a9a15d1af6c..5676aaf0d22 100644 --- a/litellm/proxy/_experimental/mcp_server/server.py +++ b/litellm/proxy/_experimental/mcp_server/server.py @@ -2096,6 +2096,20 @@ if MCP_AVAILABLE: # short ID (LITELLM_USE_SHORT_MCP_TOOL_PREFIX) that doesn't match the # server's display name directly. mcp_server = global_mcp_server_manager._get_mcp_server_from_tool_name(name) + if mcp_server is None and requested_server is not None: + # REST callers may pass the raw tool name (no prefix) plus a + # ``requested_server_id``. The mapping might only contain the + # prefixed form, so retry the lookup with every known prefix of + # the requested server before treating the tool as unresolved — + # otherwise the tool_server_mismatch guard below is silently + # bypassed. + for known_prefix in iter_known_server_prefixes(requested_server): + candidate = global_mcp_server_manager._get_mcp_server_from_tool_name( + add_server_prefix_to_name(name, known_prefix) + ) + if candidate is not None: + mcp_server = candidate + break if mcp_server is not None: server_name = mcp_server.name