From 76d8d2995127bc51ff4ec6aab41c13a4637a69ee Mon Sep 17 00:00:00 2001 From: Prithvi1994 Date: Sun, 26 Apr 2026 00:33:16 +0000 Subject: [PATCH] fix(proxy): reject suffix remainders containing any separator, not just configured one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Greptile review on #26533: the guard `MCP_TOOL_PREFIX_SEPARATOR not in rest` only checked for the configured separator (default `-`). When the suffix separator is `-` and the remainder is `extra_tool`, the guard passes because `extra_tool` contains no `-` — but `_` is also a valid MCP separator. Fix: check for both `_` and `-` in the remainder, since a unique-ID segment should contain no separator at all. --- .../_experimental/mcp_server/semantic_tool_filter.py | 11 ++++++++--- .../mcp_server/test_semantic_tool_filter.py | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/litellm/proxy/_experimental/mcp_server/semantic_tool_filter.py b/litellm/proxy/_experimental/mcp_server/semantic_tool_filter.py index b6f6c7a87a0..a41678a6412 100644 --- a/litellm/proxy/_experimental/mcp_server/semantic_tool_filter.py +++ b/litellm/proxy/_experimental/mcp_server/semantic_tool_filter.py @@ -245,8 +245,8 @@ class SemanticMCPToolFilter: ``fc_web_search-firecrawl_scrape`` does match ``fc_web_search-firecrawl_scrape_a1b2c3d4`` but does not match ``fc_web_search-firecrawl_scrape_extra_tool`` (the part after the - canonical must be a single unique-ID segment, not another - ```` pair). + canonical contains a separator, indicating it's another + namespaced tool, not a unique-ID suffix). Both prefix and suffix matching are gated on ``canonical`` itself containing ``MCP_TOOL_PREFIX_SEPARATOR``. Server-registered MCP @@ -288,7 +288,12 @@ class SemanticMCPToolFilter: # namespaced tool, not a unique-ID suffix. if remainder and remainder[0] in ("_", "-"): rest = remainder[1:] - if MCP_TOOL_PREFIX_SEPARATOR not in rest: + # A unique-ID segment contains no separator at all (it's a + # short hex or alphanumeric string). Reject remainders that + # contain either underscore or dash, since both are valid + # separators in MCP tool names regardless of the configured + # MCP_TOOL_PREFIX_SEPARATOR. + if "_" not in rest and "-" not in rest: return True return False diff --git a/tests/test_litellm/proxy/_experimental/mcp_server/test_semantic_tool_filter.py b/tests/test_litellm/proxy/_experimental/mcp_server/test_semantic_tool_filter.py index 4b02988a4dc..1b21210bd3f 100644 --- a/tests/test_litellm/proxy/_experimental/mcp_server/test_semantic_tool_filter.py +++ b/tests/test_litellm/proxy/_experimental/mcp_server/test_semantic_tool_filter.py @@ -681,8 +681,8 @@ class TestGetToolsByNames: """ ``svc-search-extra_tool`` must NOT match canonical ``svc-search`` because the remainder after the separator (``extra_tool``) itself - contains ``MCP_TOOL_PREFIX_SEPARATOR`` (``-``), indicating it is - another namespaced tool, not a unique-ID suffix. + contains a separator character (``_``), indicating it is another + namespaced tool, not a unique-ID suffix. """ filter_instance = self._make_filter() available_tools = [