diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 1926bb9bf15..6e79a0289c1 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -13401,7 +13401,11 @@ async def dynamic_mcp_route(mcp_server_name: str, request: Request): "/{mcp_server_name}/health", methods=["GET", "HEAD"], ) -async def dynamic_mcp_health_route(mcp_server_name: str, request: Request): +async def dynamic_mcp_health_route( + mcp_server_name: str, + request: Request, + user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), +): """Handle health check passthrough for MCP servers like /github_mcp/health""" from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( global_mcp_server_manager, diff --git a/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_health_route.py b/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_health_route.py index f5d163b5a71..4e7b998b0c3 100644 --- a/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_health_route.py +++ b/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_health_route.py @@ -188,6 +188,38 @@ class TestDynamicMcpHealthRoute: assert exc_info.value.status_code == 502 assert "connection refused" in exc_info.value.detail + @pytest.mark.asyncio + async def test_health_route_head_method(self): + """HEAD requests are forwarded; response body should be empty.""" + try: + from litellm.proxy.proxy_server import dynamic_mcp_health_route + except ImportError: + pytest.skip("proxy_server not available") + + mcp_server = _make_server() + if mcp_server is None: + pytest.skip("MCP types not available") + + upstream_response = MagicMock() + upstream_response.content = b"" + upstream_response.status_code = 200 + upstream_response.headers = {"content-type": "application/json"} + + mock_http_client = AsyncMock() + mock_http_client.get = AsyncMock(return_value=upstream_response) + + with ( + patch(_MCP_MANAGER_PATH) as mock_manager, + patch(_IP_UTILS_PATH) as mock_ip_utils, + patch(_HTTP_CLIENT_PATH, return_value=mock_http_client), + ): + mock_ip_utils.get_mcp_client_ip.return_value = "127.0.0.1" + mock_manager.get_mcp_server_by_name.return_value = mcp_server + + response = await dynamic_mcp_health_route("my_mcp", _make_request()) + + assert response.status_code == 200 + @pytest.mark.asyncio async def test_health_route_forwards_upstream_status_code(self): """Non-200 status codes from the upstream server are forwarded as-is."""