From 32c3204f4e4f348998f19bcfec77b7b0a0539d1c Mon Sep 17 00:00:00 2001 From: Lance Hsu Date: Wed, 15 Apr 2026 16:11:26 +0800 Subject: [PATCH] test(mcp): mock MCP registry in semantic filter e2e test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hook now validates MCP tool prefixes against the live server registry (via `known_server_prefixes`). Without a mock, `get_registry()` returns an empty dict, `known_prefixes` is empty, and all tools are classified as non-MCP — the hook early-returns None and the e2e assertion fails. Register 10 fake MCP servers matching the tool prefixes (`gmail`, `calendar`, `files`, etc.) via monkeypatch so the hyphen-prefixed tool names pass the registry check and actually exercise the semantic filter. --- .../test_semantic_tool_filter_e2e.py | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/tests/mcp_tests/test_semantic_tool_filter_e2e.py b/tests/mcp_tests/test_semantic_tool_filter_e2e.py index c619f0f6d46..7826f9b3c43 100644 --- a/tests/mcp_tests/test_semantic_tool_filter_e2e.py +++ b/tests/mcp_tests/test_semantic_tool_filter_e2e.py @@ -5,6 +5,7 @@ End-to-end test for MCP Semantic Tool Filtering import asyncio import os import sys +import types from unittest.mock import Mock import pytest @@ -25,19 +26,45 @@ except ImportError: @pytest.mark.asyncio @pytest.mark.skipif( not SEMANTIC_ROUTER_AVAILABLE, - reason="semantic-router not installed. Install the `litellm[semantic-router]` extra." + reason="semantic-router not installed. Install the `litellm[semantic-router]` extra.", ) @pytest.mark.skipif( not os.environ.get("OPENAI_API_KEY"), reason="OPENAI_API_KEY not set in environment" ) -async def test_e2e_semantic_filter(): +async def test_e2e_semantic_filter(monkeypatch): """E2E: Load router/filter and verify hook filters tools.""" from litellm import Router + from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( + global_mcp_server_manager, + ) from litellm.proxy.hooks.mcp_semantic_filter import SemanticToolFilterHook from litellm.proxy._experimental.mcp_server.semantic_tool_filter import ( SemanticMCPToolFilter, ) + # Register fake MCP servers for each hyphen-prefix used in the tool + # names below, so the hook's registry-based classifier treats them as + # MCP tools. Without this the tools fall into `non_mcp_tools` and the + # hook early-returns before the semantic filter runs. + fake_registry = { + prefix: types.SimpleNamespace(alias=None, server_name=prefix, server_id=prefix) + for prefix in ( + "gmail", + "calendar", + "files", + "web", + "slack", + "docs", + "db", + "api", + "tasks", + "notes", + ) + } + monkeypatch.setattr( + global_mcp_server_manager, "get_registry", lambda: fake_registry + ) + # Create router and filter router = Router( model_list=[