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 0db1f4c14cd..7a65422ade0 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
@@ -21,7 +21,7 @@ export const mcpServerColumns = (
cell: ({ row }) => (
onView(row.original.server_id)}
- className="font-mono text-blue-500 bg-blue-50 hover:bg-blue-100 text-xs font-normal px-2 py-0.5 text-left w-full truncate whitespace-nowrap cursor-pointer max-w-[15ch]"
+ className="font-mono text-blue-600 bg-blue-50 hover:bg-blue-100 text-xs font-medium px-2 py-0.5 rounded-md border border-blue-200 text-left truncate whitespace-nowrap cursor-pointer max-w-[15ch] transition-colors"
>
{row.original.server_id.slice(0, 7)}...
@@ -56,16 +56,39 @@ export const mcpServerColumns = (
cell: ({ row }) => {
const transport = row.original.transport || "http";
const specPath = row.original.spec_path;
- // If server has spec_path, display as "OPENAPI" instead of the raw transport type
const displayTransport = specPath && transport !== "stdio" ? "OPENAPI" : transport;
- return {displayTransport.toUpperCase()} ;
+ const label = displayTransport.toUpperCase();
+ const colorClass =
+ label === "HTTP" ? "bg-blue-50 text-blue-700 border-blue-200" :
+ label === "SSE" ? "bg-purple-50 text-purple-700 border-purple-200" :
+ label === "STDIO" ? "bg-amber-50 text-amber-700 border-amber-200" :
+ label === "OPENAPI" ? "bg-teal-50 text-teal-700 border-teal-200" :
+ "bg-gray-50 text-gray-700 border-gray-200";
+ return (
+
+ {label}
+
+ );
},
},
{
accessorKey: "auth_type",
header: "Auth Type",
enableSorting: true,
- cell: ({ getValue }) => {(getValue() as string) || "none"} ,
+ cell: ({ getValue }) => {
+ const authType = (getValue() as string) || "none";
+ const colorClass =
+ authType === "oauth2" ? "bg-indigo-50 text-indigo-700 border-indigo-200" :
+ authType === "bearer_token" ? "bg-sky-50 text-sky-700 border-sky-200" :
+ authType === "api_key" ? "bg-emerald-50 text-emerald-700 border-emerald-200" :
+ authType === "basic" ? "bg-orange-50 text-orange-700 border-orange-200" :
+ "bg-gray-50 text-gray-500 border-gray-200";
+ return (
+
+ {authType}
+
+ );
+ },
},
{
id: "health_status",
@@ -76,38 +99,34 @@ export const mcpServerColumns = (
const lastCheck = server.last_health_check;
const error = server.health_check_error;
- // Show loading spinner if health check is in progress
if (isLoadingHealth) {
return (
-
+
+
+ Checking
+
);
}
const getStatusColor = (status: string) => {
switch (status) {
case "healthy":
- return "text-green-500 bg-green-50 hover:bg-green-100";
+ return "text-green-700 bg-green-50 border border-green-200";
case "unhealthy":
- return "text-red-500 bg-red-50 hover:bg-red-100";
+ return "text-red-700 bg-red-50 border border-red-200";
default:
- return "text-gray-500 bg-gray-50 hover:bg-gray-100";
+ return "text-gray-600 bg-gray-50 border border-gray-200";
}
};
const getStatusIcon = (status: string) => {
switch (status) {
case "healthy":
- return "●";
+ return "✓";
case "unhealthy":
- return "●";
+ return "✗";
default:
- return "●";
+ return "?";
}
};
@@ -127,12 +146,12 @@ export const mcpServerColumns = (
return (
-
- {getStatusIcon(status)}
+ {getStatusIcon(status)}
{status.charAt(0).toUpperCase() + status.slice(1)}
-
+
);
},
@@ -143,19 +162,23 @@ export const mcpServerColumns = (
cell: ({ row }) => {
const groups = row.original.mcp_access_groups;
if (Array.isArray(groups) && groups.length > 0) {
- // If string array
if (typeof groups[0] === "string") {
const joined = groups.join(", ");
return (
-
- {joined.length > 30 ? `${joined.slice(0, 30)}...` : joined}
-
+
+
+ {groups[0]}
+
+ {groups.length > 1 && (
+ +{groups.length - 1}
+ )}
+
);
}
}
- return None ;
+ return — ;
},
},
{
@@ -164,33 +187,47 @@ export const mcpServerColumns = (
cell: ({ row }) => {
const isPublic = row.original.available_on_public_internet;
return isPublic ? (
- All networks
+
+
+ Public
+
) : (
- Internal only
+
+
+ Internal
+
);
},
},
{
- header: "Created At",
+ header: "Created",
accessorKey: "created_at",
enableSorting: true,
sortingFn: "datetime",
cell: ({ row }) => {
const server = row.original;
+ if (!server.created_at) return — ;
+ const date = new Date(server.created_at);
return (
- {server.created_at ? new Date(server.created_at).toLocaleDateString() : "-"}
+
+ {date.toLocaleDateString()}
+
);
},
},
{
- header: "Updated At",
+ header: "Updated",
accessorKey: "updated_at",
enableSorting: true,
sortingFn: "datetime",
cell: ({ row }) => {
const server = row.original;
+ if (!server.updated_at) return — ;
+ const date = new Date(server.updated_at);
return (
- {server.updated_at ? new Date(server.updated_at).toLocaleDateString() : "-"}
+
+ {date.toLocaleDateString()}
+
);
},
},
diff --git a/ui/litellm-dashboard/src/components/mcp_tools/mcp_servers.test.tsx b/ui/litellm-dashboard/src/components/mcp_tools/mcp_servers.test.tsx
index 173b623a2ff..8385fc7ac70 100644
--- a/ui/litellm-dashboard/src/components/mcp_tools/mcp_servers.test.tsx
+++ b/ui/litellm-dashboard/src/components/mcp_tools/mcp_servers.test.tsx
@@ -305,8 +305,8 @@ describe("MCPServers", () => {
expect(screen.getByText("Team B Server")).toBeInTheDocument();
expect(screen.getByText("Team A Server 2")).toBeInTheDocument();
- // Find the team select dropdown by looking for the "Current Team:" label
- const teamLabel = screen.getByText("Current Team:");
+ // Find the team select dropdown by looking for the "Team" label
+ const teamLabel = screen.getByText("Team");
const teamSelectContainer = teamLabel.closest("div")?.querySelector(".ant-select");
expect(teamSelectContainer).toBeTruthy();
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 f48649d6653..f985d3d5fb5 100644
--- a/ui/litellm-dashboard/src/components/mcp_tools/mcp_servers.tsx
+++ b/ui/litellm-dashboard/src/components/mcp_tools/mcp_servers.tsx
@@ -48,17 +48,6 @@ const MCPServers: React.FC = ({ accessToken, userRole, userID })
});
}, [mcpServers, healthStatuses]);
- // Log allowed_tools from fetched servers
- React.useEffect(() => {
- if (mcpServers) {
- console.log("MCP Servers fetched:", mcpServers);
- mcpServers.forEach((server) => {
- console.log(`Server: ${server.server_name || server.server_id}`);
- console.log(` allowed_tools:`, server.allowed_tools);
- });
- }
- }, [mcpServers]);
-
// state
const [serverIdToDelete, setServerToDelete] = useState(null);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
@@ -257,34 +246,28 @@ const MCPServers: React.FC = ({ accessToken, userRole, userID })
confirmLoading={isDeletingServer}
>
-
Are you sure you want to delete this MCP Server? This action cannot be undone.
+
This action is permanent and cannot be undone. All associated configurations will be removed.
{serverToDelete && (
-
-
- Server Information
-
-
+
+
{serverToDelete.server_name && (
- Server Name}>
- {serverToDelete.server_name}
+ Name}>
+ {serverToDelete.server_name}
)}
- {serverToDelete.alias && (
- Alias}>
- {serverToDelete.alias}
-
- )}
- Server ID}>
-
+ ID}>
+
{serverToDelete.server_id}
- URL}>
-
- {serverToDelete.url}
-
-
+ {serverToDelete.url && (
+ URL}>
+
+ {serverToDelete.url}
+
+
+ )}
)}
@@ -353,50 +336,38 @@ const MCPServers: React.FC = ({ accessToken, userRole, userID })
-
-
-
Current Team:
-
+
+
+
Team
+
-
-
-
{isInternalUser ? "All Available Servers" : "All Servers"}
-
+ {isInternalUser ? "All Available Servers" : "All Servers"}
-
+ Personal
{uniqueTeams.map((team) => (
-
-
-
{team.team_alias || team.team_id}
-
+ {team.team_alias || team.team_id}
))}
-
- Access Group:
+
+
+
+
+ Access Group
-
+
-
+
-
+ All Access Groups
{uniqueMcpAccessGroups.map((group) => (
-
+ {group}
))}
@@ -411,8 +382,8 @@ const MCPServers: React.FC = ({ accessToken, userRole, userID })
renderSubComponent={() =>
}
getRowCanExpand={() => false}
isLoading={isLoadingServers}
- noDataMessage="No MCP servers configured"
- loadingMessage="🚅 Loading MCP servers..."
+ noDataMessage="No MCP servers configured. Click '+ Add New MCP Server' to get started."
+ loadingMessage="Loading MCP servers..."
enableSorting={true}
/>