From baa1fa4151d676531d21c6e9ceeb996b928db81f Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Sat, 21 Mar 2026 13:03:25 -0700 Subject: [PATCH] feat(ui): add Team (Owner) column to MCP servers table Shows the owning team alias resolved from team_id. Global servers (team_id=null) display "Global". Header includes info icon explaining that only servers from teams with mcp:read permission are visible. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../mcp_tools/mcp_server_columns.tsx | 27 ++++++++++++++++++- .../src/components/mcp_tools/mcp_servers.tsx | 14 +++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/ui/litellm-dashboard/src/components/mcp_tools/mcp_server_columns.tsx b/ui/litellm-dashboard/src/components/mcp_tools/mcp_server_columns.tsx index ea5ccf1c847..a86dc1c157e 100644 --- a/ui/litellm-dashboard/src/components/mcp_tools/mcp_server_columns.tsx +++ b/ui/litellm-dashboard/src/components/mcp_tools/mcp_server_columns.tsx @@ -5,7 +5,7 @@ import { Icon } from "@tremor/react"; import { PencilAltIcon, TrashIcon } from "@heroicons/react/outline"; import { getMaskedAndFullUrl } from "./utils"; import { Tooltip } from "antd"; -import { CheckOutlined } from "@ant-design/icons"; +import { CheckOutlined, InfoCircleOutlined } from "@ant-design/icons"; const HealthStatusBadge: React.FC<{ server: MCPServer; @@ -92,6 +92,7 @@ export const mcpServerColumns = ( onByokConnect?: (server: MCPServer) => void, onRecheckHealth?: (serverId: string) => void, recheckingServerIds?: Set, + teamAliasMap?: Map, ): ColumnDef[] => [ { accessorKey: "server_id", @@ -128,6 +129,30 @@ export const mcpServerColumns = ( ); }, }, + { + accessorKey: "team_id", + header: () => ( + + Team (Owner) + + + + + ), + enableSorting: true, + cell: ({ row }) => { + const tid = row.original.team_id; + if (!tid) { + return Global; + } + const alias = teamAliasMap?.get(tid); + return ( + + {alias || tid.slice(0, 8) + "..."} + + ); + }, + }, { accessorKey: "alias", header: "Alias", diff --git a/ui/litellm-dashboard/src/components/mcp_tools/mcp_servers.tsx b/ui/litellm-dashboard/src/components/mcp_tools/mcp_servers.tsx index 41bf5ce23ed..5d39812f66d 100644 --- a/ui/litellm-dashboard/src/components/mcp_tools/mcp_servers.tsx +++ b/ui/litellm-dashboard/src/components/mcp_tools/mcp_servers.tsx @@ -15,6 +15,7 @@ import MCPConnect from "./mcp_connect"; import { mcpServerColumns } from "./mcp_server_columns"; import { MCPServerView } from "./mcp_server_view"; import { DiscoverableMCPServer, MCPServer, MCPServerProps, Team } from "./types"; +import { useTeams } from "@/app/(dashboard)/hooks/teams/useTeams"; import MCPSemanticFilterSettings from "../Settings/AdminSettings/MCPSemanticFilterSettings/MCPSemanticFilterSettings"; import MCPNetworkSettings from "./MCPNetworkSettings"; import MCPDiscovery from "./mcp_discovery"; @@ -63,6 +64,16 @@ const MCPServers: React.FC = ({ accessToken, userRole, userID }) const [isDeletingServer, setIsDeletingServer] = useState(false); const [byokModalServer, setByokModalServer] = useState(null); const isInternalUser = userRole === "Internal User"; + const { data: allTeams } = useTeams(); + const teamAliasMap = React.useMemo(() => { + const map = new Map(); + if (allTeams) { + for (const t of allTeams) { + if (t.team_alias) map.set(t.team_id, t.team_alias); + } + } + return map; + }, [allTeams]); useEffect(() => { if (typeof window === "undefined") { @@ -171,8 +182,9 @@ const MCPServers: React.FC = ({ accessToken, userRole, userID }) (server: MCPServer) => setByokModalServer(server), recheckServerHealth, recheckingServerIds, + teamAliasMap, ), - [userRole, isLoadingHealth, recheckServerHealth, recheckingServerIds], + [userRole, isLoadingHealth, recheckServerHealth, recheckingServerIds, teamAliasMap], ); function handleDelete(server_id: string) {