diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py
index 98464d3a127..5d5a25e7cd6 100644
--- a/litellm/proxy/_types.py
+++ b/litellm/proxy/_types.py
@@ -4239,6 +4239,8 @@ class TeamAccessGroupModelGrant(LiteLLMPydanticObjectBase):
access_group_id: str
access_group_name: str
models: tuple[str, ...]
+ mcp_server_ids: tuple[str, ...] = ()
+ agent_ids: tuple[str, ...] = ()
class TeamInfoResponseObjectTeamTable(LiteLLM_TeamTable):
diff --git a/litellm/proxy/management_endpoints/team_endpoints.py b/litellm/proxy/management_endpoints/team_endpoints.py
index 714cf252e69..72cdc75c29e 100644
--- a/litellm/proxy/management_endpoints/team_endpoints.py
+++ b/litellm/proxy/management_endpoints/team_endpoints.py
@@ -4318,6 +4318,8 @@ async def _resolve_team_access_group_resources(
access_group_id=group.access_group_id,
access_group_name=group.access_group_name,
models=tuple(group.access_model_names or ()),
+ mcp_server_ids=tuple(group.access_mcp_server_ids or ()),
+ agent_ids=tuple(group.access_agent_ids or ()),
)
for group in resolved_groups
),
diff --git a/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py
index 088e82b370f..166fcb2863c 100644
--- a/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py
+++ b/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py
@@ -9897,11 +9897,11 @@ class TestResolveTeamAccessGroupResources:
assert resolved.access_group_mcp_server_ids == ["mcp-1"]
assert resolved.access_group_agent_ids == ["agent-1"]
assert [
- (d.access_group_id, d.access_group_name, d.models)
+ (d.access_group_id, d.access_group_name, d.models, d.mcp_server_ids, d.agent_ids)
for d in (resolved.access_group_details or [])
] == [
- ("ag-1", "shared-models", ("gpt-4", "claude-3")),
- ("ag-2", "extra-models", ("claude-3", "gemini")),
+ ("ag-1", "shared-models", ("gpt-4", "claude-3"), ("mcp-1",), ()),
+ ("ag-2", "extra-models", ("claude-3", "gemini"), (), ("agent-1",)),
]
@pytest.mark.asyncio
diff --git a/ui/litellm-dashboard/src/components/object_permissions_view.tsx b/ui/litellm-dashboard/src/components/object_permissions_view.tsx
index 011791fa18d..e90645a9e9f 100644
--- a/ui/litellm-dashboard/src/components/object_permissions_view.tsx
+++ b/ui/litellm-dashboard/src/components/object_permissions_view.tsx
@@ -3,9 +3,12 @@ import VectorStorePermissions from "./permissions/VectorStorePermissions";
import MCPServerPermissions from "./permissions/MCPServerPermissions";
import AgentPermissions from "./permissions/AgentPermissions";
import type { ObjectPermission } from "./object_permission_types";
+import type { InheritedGrant } from "./permissions/inheritedGrants";
interface ObjectPermissionsViewProps {
objectPermission?: ObjectPermission | null;
+ inheritedMcpServers?: InheritedGrant[];
+ inheritedAgents?: InheritedGrant[];
variant?: "card" | "inline";
className?: string;
accessToken?: string | null;
@@ -13,6 +16,8 @@ interface ObjectPermissionsViewProps {
export function ObjectPermissionsView({
objectPermission,
+ inheritedMcpServers = [],
+ inheritedAgents = [],
variant = "card",
className = "",
accessToken,
@@ -34,9 +39,15 @@ export function ObjectPermissionsView({
mcpAccessGroups={mcpAccessGroups}
mcpToolPermissions={mcpToolPermissions}
mcpToolsets={mcpToolsets}
+ inheritedMcpServers={inheritedMcpServers}
+ accessToken={accessToken}
+ />
+
Search tools
{searchTools.length === 0 ? ( diff --git a/ui/litellm-dashboard/src/components/permissions/AgentPermissions.test.tsx b/ui/litellm-dashboard/src/components/permissions/AgentPermissions.test.tsx new file mode 100644 index 00000000000..01c7b60b8a5 --- /dev/null +++ b/ui/litellm-dashboard/src/components/permissions/AgentPermissions.test.tsx @@ -0,0 +1,71 @@ +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import AgentPermissions from "./AgentPermissions"; +import * as networking from "../networking"; + +vi.mock("../networking"); + +describe("AgentPermissions", () => { + const accessToken = "test-token"; + const agentId = "90337622-756e-4f25-98f0-01fc8174aa24"; + + beforeEach(() => { + vi.clearAllMocks(); + }); + + it("lists agents inherited from access groups, counts them, and names the groups on hover", async () => { + const user = userEvent.setup(); + vi.mocked(networking.getAgentsList).mockResolvedValue({ + agents: [{ agent_id: agentId, agent_name: "support_agent" }], + }); + + render( +