fix: route hyphenated mcp tools

This commit is contained in:
Krrish Dholakia 2026-06-22 18:36:54 -07:00
parent 7ae84c2b84
commit 0463a74905
4 changed files with 52 additions and 10 deletions

View file

@ -3852,7 +3852,9 @@ class MCPServerManager:
(
original_tool_name,
server_name_from_prefix,
) = split_server_prefix_from_name(tool_name)
) = split_server_prefix_from_name(
tool_name, known_server_prefixes=set(prefix_to_server.keys())
)
normalised_prefix = normalize_server_name(server_name_from_prefix)
matched_server = prefix_to_server.get(normalised_prefix)
if matched_server is not None and (

View file

@ -2688,8 +2688,15 @@ if MCP_AVAILABLE:
# translate it back to the original prefixed name before any routing.
name = _resolve_display_name_to_original(name, allowed_mcp_servers)
# Remove prefix from tool name for logging and processing
original_tool_name, server_name = split_server_prefix_from_name(name)
allowed_server_prefixes = {
normalize_server_name(prefix)
for server in allowed_mcp_servers
for prefix in iter_known_server_prefixes(server)
if prefix
}
original_tool_name, server_name = split_server_prefix_from_name(
name, known_server_prefixes=allowed_server_prefixes
)
requested_server: Optional[MCPServer] = None
if requested_server_id:

View file

@ -323,8 +323,18 @@ def iter_known_server_prefixes(server: Any) -> Iterator[str]:
yield from _emit(server_id)
def split_server_prefix_from_name(prefixed_name: str) -> Tuple[str, str]:
def split_server_prefix_from_name(
prefixed_name: str,
known_server_prefixes: Optional[Set[str]] = None,
) -> Tuple[str, str]:
"""Return the unprefixed name plus the server name used as prefix."""
if known_server_prefixes:
for prefix in sorted(known_server_prefixes, key=len, reverse=True):
normalized_prefix = normalize_server_name(prefix)
separator = f"{normalized_prefix}{MCP_TOOL_PREFIX_SEPARATOR}"
if prefixed_name.startswith(separator):
return prefixed_name[len(separator) :], normalized_prefix
if MCP_TOOL_PREFIX_SEPARATOR in prefixed_name:
parts = prefixed_name.split(MCP_TOOL_PREFIX_SEPARATOR, 1)
if len(parts) == 2:
@ -360,8 +370,12 @@ def is_tool_name_prefixed(
return False
if known_server_prefixes is not None:
candidate_prefix = tool_name.split(MCP_TOOL_PREFIX_SEPARATOR, 1)[0]
return normalize_server_name(candidate_prefix) in known_server_prefixes
return any(
tool_name.startswith(
f"{normalize_server_name(prefix)}{MCP_TOOL_PREFIX_SEPARATOR}"
)
for prefix in known_server_prefixes
)
# Legacy fallback – separator present somewhere in the name.
return True

View file

@ -4,9 +4,10 @@ Tests for is_tool_name_prefixed with known_server_prefixes parameter.
Verifies fix for https://github.com/BerriAI/litellm/issues/25081
"""
import pytest
from litellm.proxy._experimental.mcp_server.utils import is_tool_name_prefixed
from litellm.proxy._experimental.mcp_server.utils import (
is_tool_name_prefixed,
split_server_prefix_from_name,
)
# ---------------------------------------------------------------------------
@ -36,7 +37,7 @@ class TestLegacyBehaviour:
class TestWithKnownPrefixes:
"""When known_server_prefixes is supplied, only real prefixes match."""
PREFIXES = {"myserver", "weather_api", "code_tools"}
PREFIXES = {"myserver", "weather_api", "code_tools", "deepwiki-mcp"}
def test_known_prefix_returns_true(self):
assert (
@ -82,3 +83,21 @@ class TestWithKnownPrefixes:
)
is True
)
def test_hyphenated_server_prefix_returns_true(self):
assert (
is_tool_name_prefixed(
"deepwiki-mcp-read_wiki_structure",
known_server_prefixes=self.PREFIXES,
)
is True
)
def test_hyphenated_server_prefix_split_uses_longest_known_prefix(self):
tool_name, server_name = split_server_prefix_from_name(
"deepwiki-mcp-read_wiki_structure",
known_server_prefixes=self.PREFIXES,
)
assert tool_name == "read_wiki_structure"
assert server_name == "deepwiki-mcp"