From c99ac0124cf41571d37f5ef3b84213012573cd94 Mon Sep 17 00:00:00 2001 From: user <70670632+stuxf@users.noreply.github.com> Date: Sun, 10 May 2026 03:40:20 +0000 Subject: [PATCH] chore(mcp): use INTERNAL_REQUEST for documented internal-caller path in _get_allowed_mcp_servers The function's docstring at server.py:862-864 documents that when both client_ip is None and the auth context is empty, the call is internal (admin debug, registry maintenance) and IP filtering is intentionally skipped. After the previous commit made filter_server_ids_by_ip_with_info fail closed on None, that documented path silently returned an empty allowed-server list instead of bypassing the filter. Pass INTERNAL_REQUEST when both fall-throughs return None so the documented internal-caller behaviour matches the new wrapper contract. External request handlers that pass None unintentionally still hit the fail-closed path the previous commit added. --- .../proxy/_experimental/mcp_server/server.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/litellm/proxy/_experimental/mcp_server/server.py b/litellm/proxy/_experimental/mcp_server/server.py index 276a6e8a3bb..910e8025853 100644 --- a/litellm/proxy/_experimental/mcp_server/server.py +++ b/litellm/proxy/_experimental/mcp_server/server.py @@ -863,14 +863,24 @@ if MCP_AVAILABLE: This is intentional for internal callers but may indicate a bug if called from a request handler without proper context setup. """ - # Use explicit client_ip if provided, otherwise try auth context - if client_ip is None: - client_ip = _get_client_ip_from_context() - if client_ip is None: + # Use explicit client_ip if provided, otherwise try auth context. + # If neither is available the call is treated as internal (admin + # debug, registry maintenance, background work) and uses + # INTERNAL_REQUEST to bypass IP gating explicitly. The wrapper + # otherwise fails closed on None. + from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( + INTERNAL_REQUEST, + ) + + gate_arg: Union[str, "_InternalRequest", None] = client_ip + if gate_arg is None: + gate_arg = _get_client_ip_from_context() + if gate_arg is None: verbose_logger.debug( "MCP _get_allowed_mcp_servers called without client_ip and no auth context. " "IP filtering will be skipped. This is expected for internal calls." ) + gate_arg = INTERNAL_REQUEST allowed_mcp_server_ids = ( await global_mcp_server_manager.get_allowed_mcp_servers(user_api_key_auth) @@ -879,7 +889,7 @@ if MCP_AVAILABLE: allowed_mcp_server_ids, _ip_blocked, ) = global_mcp_server_manager.filter_server_ids_by_ip_with_info( - allowed_mcp_server_ids, client_ip + allowed_mcp_server_ids, gate_arg ) verbose_logger.debug( "MCP IP filter: client_ip=%s, allowed_server_ids=%s",