test(mcp): cover no-team admins' toolset access on LLM routes and drop a dead admin-check clause
Some checks are pending
LiteLLM Rust DB / db-queries (push) Waiting to run
LiteLLM Rust / rust-lint (push) Waiting to run
LiteLLM Rust / rust-test (push) Waiting to run
LiteLLM Rust / rust-wheel (push) Waiting to run

This commit is contained in:
mateo-berri 2026-10-28 23:13:01 -07:00
parent fb7583b528
commit 0d24446c6d
2 changed files with 18 additions and 7 deletions

View file

@ -306,11 +306,7 @@ def has_team_unbound_mcp_admin_view(user_api_key_auth: UserAPIKeyAuth | None) ->
return (
user_api_key_auth is not None
and user_api_key_has_admin_view(user_api_key_auth)
and (
is_mcp_admitted_user_subject(user_api_key_auth)
or not user_api_key_auth.team_id
or user_api_key_auth.team_id == UI_TEAM_ID
)
and (not user_api_key_auth.team_id or user_api_key_auth.team_id == UI_TEAM_ID)
)

View file

@ -21,7 +21,7 @@ from litellm.litellm_core_utils.litellm_logging import Logging
from litellm.proxy.mcp_server import operations as mcp_operations
from litellm.proxy.mcp_server.faults.list_outcomes import AggregateToolListing
from litellm.proxy.mcp_server.mcp_server_manager import ListedToolsCaller, MCPServerManager
from litellm.proxy._types import LitellmUserRoles, UserAPIKeyAuth
from litellm.proxy._types import UI_TEAM_ID, LitellmUserRoles, UserAPIKeyAuth
from litellm.proxy.utils import ProxyLogging
from litellm.responses import main as responses_main
from litellm.responses.mcp import litellm_proxy_mcp_handler as mcp_handler_module
@ -1519,6 +1519,7 @@ async def _tools_listing_kwargs_for_toolset_url(
team_toolset_id: str,
owner_role: LitellmUserRoles = LitellmUserRoles.INTERNAL_USER,
requested_toolsets: tuple[str, ...] = ("team-toolset",),
team_id: str | None = "team-1",
) -> dict[str, object]:
from litellm.proxy.mcp_server.ui_session_utils import granted_toolset_ids
from litellm.proxy._types import LiteLLM_ObjectPermissionTable
@ -1537,7 +1538,7 @@ async def _tools_listing_kwargs_for_toolset_url(
async def granted_through_team(context: UserAPIKeyAuth) -> frozenset[str]:
return await granted_toolset_ids(context, team_object_permission=team_permission, require_key_access=False)
team_key: Final = UserAPIKeyAuth(api_key="sk-team", team_id="team-1", user_role=owner_role)
team_key: Final = UserAPIKeyAuth(api_key="sk-team", team_id=team_id, user_role=owner_role)
await LiteLLM_Proxy_MCP_Handler._get_mcp_tools_from_manager(
user_api_key_auth=team_key,
mcp_tools_with_litellm_proxy=[
@ -1613,6 +1614,20 @@ async def test_a_denied_toolset_beside_a_granted_one_adds_nothing_to_the_scoped_
assert scoped.mcp_tool_permissions == {"srv-1": ["add"]}
@pytest.mark.asyncio
@pytest.mark.parametrize("team_id", [None, UI_TEAM_ID], ids=["no_team", "dashboard_session"])
async def test_an_admin_credential_without_a_team_keeps_a_toolset_no_grant_names(
monkeypatch: pytest.MonkeyPatch, team_id: str | None
):
kwargs: Final = await _tools_listing_kwargs_for_toolset_url(
monkeypatch, team_toolset_id="ts-other", owner_role=LitellmUserRoles.PROXY_ADMIN, team_id=team_id
)
scoped = kwargs["user_api_key_auth"].object_permission
assert scoped is not None
assert scoped.mcp_servers == ["srv-1"]
assert scoped.mcp_tool_permissions == {"srv-1": ["add"]}
@pytest.mark.asyncio
@pytest.mark.parametrize(
"toolset_lookup",