fix(mcp): resolve access groups from the operation catalog

This commit is contained in:
Joshua Valluru 2026-10-05 13:17:26 -07:00
parent 2b13ca365e
commit 42dcf106f1
2 changed files with 23 additions and 1 deletions

View file

@ -3642,7 +3642,7 @@ class MCPRequestHandler:
requires_fresh_policy: bool = False,
) -> list[str]:
"""
Resolve MCP access groups to server IDs by querying BOTH the MCP server table (DB) AND config-loaded servers.
Resolve MCP access groups against the operation snapshot, or database and config outside an operation.
``requires_fresh_policy`` reads the writer and propagates a read fault instead of resolving to no servers.
"""
from litellm.proxy.proxy_server import prisma_client
@ -3653,6 +3653,10 @@ class MCPRequestHandler:
global_mcp_server_manager,
)
snapshot: Final = global_mcp_server_manager.catalog.current()
if snapshot is not None:
return list(MCPRequestHandler._get_config_server_ids_for_access_groups(snapshot.servers, access_groups))
# Use the new helper for config-loaded servers
server_ids: Final = MCPRequestHandler._get_config_server_ids_for_access_groups(
global_mcp_server_manager.config_mcp_servers, access_groups

View file

@ -18607,3 +18607,21 @@ async def test_catalog_revision_failure_preserves_state_and_recovers(monkeypatch
assert unavailable.value.detail == "MCP server configuration could not be refreshed"
assert manager.registry["catalog-server"].name == "initial"
assert (await manager.catalog.resolve("catalog-server")).name == "updated"
@pytest.mark.asyncio
@pytest.mark.parametrize("groups", [[], ["catalog-group"]])
async def test_access_group_resolution_uses_the_operation_catalog(monkeypatch, groups):
from litellm.proxy._experimental.mcp_server import mcp_server_manager
from litellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcp import MCPRequestHandler
row = _catalog_row().model_copy(update={"mcp_access_groups": groups})
_catalog_database(monkeypatch, AsyncMock(return_value=[row]))
manager = MCPServerManager()
monkeypatch.setattr(mcp_server_manager, "global_mcp_server_manager", manager)
stale = AsyncMock(return_value=set() if groups else {row.server_id})
monkeypatch.setattr(MCPRequestHandler, "_get_db_server_ids_for_access_groups", stale)
async with manager.catalog.operation():
allowed = await MCPRequestHandler._get_mcp_servers_from_access_groups(["catalog-group"])
assert set(allowed) == ({row.server_id} if groups else set())
stale.assert_not_awaited()