From 4653773376c26d5c37bdcda1964cbc0a2bb4e4b9 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 20 May 2026 18:12:42 +0000 Subject: [PATCH] fix(mcp): match alias/server_name in _resolve_mcp_server_for_tool_call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The registry lookup in _resolve_mcp_server_for_tool_call previously only compared candidate.name against the provided server_name, but tool name prefixes can be derived from a server's alias or server_name (see get_server_prefix). When the tool→server mapping is empty/stale (cold start, dynamic tools), the lookup would fail for alias-configured servers even though get_mcp_server_by_name (used by the REST path) matches alias, server_name, and name. Match the same priority of identifiers in both the registry pass and the unprefixed fallback so the MCP protocol call_tool path is consistent with the REST path. Co-authored-by: Yassin Kortam --- .../mcp_server/mcp_server_manager.py | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py b/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py index 7ee7658fe9c..6eb76ea3f64 100644 --- a/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py +++ b/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py @@ -2828,20 +2828,30 @@ class MCPServerManager: prefixed_tool_name = add_server_prefix_to_name(name, server_name) mcp_server = self._get_mcp_server_from_tool_name(prefixed_tool_name) resolved_by_server_name_only = False + normalized_server_name = normalize_server_name(server_name) + + def _candidate_matches_server_name(candidate: MCPServer) -> bool: + for identifier in ( + candidate.alias, + candidate.server_name, + candidate.name, + ): + if identifier and normalize_server_name(identifier) == ( + normalized_server_name + ): + return True + return False + if mcp_server is None: for candidate in self.get_registry().values(): - if normalize_server_name(candidate.name) == normalize_server_name( - server_name - ): + if _candidate_matches_server_name(candidate): mcp_server = candidate resolved_by_server_name_only = True break if mcp_server is None: fallback = self._get_mcp_server_from_tool_name(name) if fallback is not None and ( - not server_name - or normalize_server_name(fallback.name) - == normalize_server_name(server_name) + not server_name or _candidate_matches_server_name(fallback) ): mcp_server = fallback if mcp_server is None: