diff --git a/ui/litellm-dashboard/e2e_tests/tests/mcp/mcpServers.spec.ts b/ui/litellm-dashboard/e2e_tests/tests/mcp/mcpServers.spec.ts index 2dccf0f3953..7c4a7cb0568 100644 --- a/ui/litellm-dashboard/e2e_tests/tests/mcp/mcpServers.spec.ts +++ b/ui/litellm-dashboard/e2e_tests/tests/mcp/mcpServers.spec.ts @@ -54,9 +54,7 @@ test.describe("MCP Servers", () => { // the MCP servers grid so the form modal's `server_name` input — which // still holds the timestamped value during its close animation — can't // satisfy the assertion before the server actually lands in the list. - await expect(page.getByText("MCP Server created successfully").first()) - .toBeVisible({ timeout: 15_000 }); - await expect(page.getByTestId("mcp-servers-grid").getByText(uniqueName).first()) - .toBeVisible({ timeout: 10_000 }); + await expect(page.getByText("MCP Server created successfully").first()).toBeVisible({ timeout: 15_000 }); + await expect(page.getByTestId("mcp-servers-grid").getByText(uniqueName).first()).toBeVisible({ timeout: 10_000 }); }); }); diff --git a/ui/litellm-dashboard/eslint-suppressions.json b/ui/litellm-dashboard/eslint-suppressions.json index 1110403446c..d0a0a8f66f5 100644 --- a/ui/litellm-dashboard/eslint-suppressions.json +++ b/ui/litellm-dashboard/eslint-suppressions.json @@ -1307,6 +1307,11 @@ "count": 1 } }, + "src/components/mcp_tools/UserEnvVarsModal.tsx": { + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, "src/components/mcp_tools/create_mcp_server.tsx": { "no-restricted-imports": { "count": 1 @@ -1377,7 +1382,7 @@ "count": 1 }, "react-hooks/set-state-in-effect": { - "count": 2 + "count": 4 } }, "src/components/mcp_tools/mcp_tool_configuration.tsx": { @@ -1504,7 +1509,7 @@ "count": 23 }, "no-restricted-syntax": { - "count": 270 + "count": 274 } }, "src/components/object_permissions_view.tsx": { diff --git a/ui/litellm-dashboard/src/components/mcp_tools/EnvVarsSection.tsx b/ui/litellm-dashboard/src/components/mcp_tools/EnvVarsSection.tsx index 5599f7091df..4a694d71585 100644 --- a/ui/litellm-dashboard/src/components/mcp_tools/EnvVarsSection.tsx +++ b/ui/litellm-dashboard/src/components/mcp_tools/EnvVarsSection.tsx @@ -1,10 +1,6 @@ import React from "react"; import { Form, Input, Select, Button, Tooltip, Typography } from "antd"; -import { - InfoCircleOutlined, - MinusCircleOutlined, - PlusOutlined, -} from "@ant-design/icons"; +import { InfoCircleOutlined, MinusCircleOutlined, PlusOutlined } from "@ant-design/icons"; const { Text } = Typography; @@ -33,12 +29,12 @@ const EnvVarsSection: React.FC = () => { - Define variables you can interpolate in Static Headers or - Authentication using {"${VAR_NAME}"}.
+ Define variables you can interpolate in Static Headers or Authentication using{" "} + {"${VAR_NAME}"}.
Instance: admin-defined value used for every user.
- Per-user: each user supplies their own value (e.g. personal - credentials) via the MCP Gateway dashboard. + Per-user: each user supplies their own value (e.g. personal credentials) via the MCP Gateway + dashboard. } > @@ -46,8 +42,7 @@ const EnvVarsSection: React.FC = () => {
- Reference these in Static Headers or Authentication as{" "} - {"${VAR_NAME}"}. For example:{" "} + Reference these in Static Headers or Authentication as {"${VAR_NAME}"}. For example:{" "} {"${DB_PROTOCOL}://${CORP_USERNAME}:${CORP_PASSWORD}@${DB_HOSTNAME}"} @@ -79,10 +74,7 @@ const EnvVarsSection: React.FC = () => { }, ]} > - +
@@ -96,10 +88,7 @@ const EnvVarsSection: React.FC = () => { > + remove(name)} diff --git a/ui/litellm-dashboard/src/components/mcp_tools/MCPServerCard.tsx b/ui/litellm-dashboard/src/components/mcp_tools/MCPServerCard.tsx index 017e8f0d51a..064a9481325 100644 --- a/ui/litellm-dashboard/src/components/mcp_tools/MCPServerCard.tsx +++ b/ui/litellm-dashboard/src/components/mcp_tools/MCPServerCard.tsx @@ -53,18 +53,14 @@ const MCPServerCard: FC = ({ // Logo is sourced exclusively from the admin-set `mcp_info.logo_url`. const candidateLogo = server.mcp_info?.logo_url ?? undefined; const [failedLogoUrl, setFailedLogoUrl] = useState(null); - const logoUrl = - candidateLogo && failedLogoUrl !== candidateLogo ? candidateLogo : undefined; + const logoUrl = candidateLogo && failedLogoUrl !== candidateLogo ? candidateLogo : undefined; const transport = server.transport || "http"; - const displayTransport = - server.spec_path && transport !== "stdio" ? "openapi" : transport; + const displayTransport = server.spec_path && transport !== "stdio" ? "openapi" : transport; const authType = server.auth_type || "none"; const status = server.status || "unknown"; const healthTone = HEALTH_TONE[status] ?? HEALTH_TONE.unknown; const isPublic = server.available_on_public_internet; - const accessGroups = (server.mcp_access_groups ?? []).filter( - (g): g is string => typeof g === "string", - ); + const accessGroups = (server.mcp_access_groups ?? []).filter((g): g is string => typeof g === "string"); const missing = missingUserFields ?? []; const needsAttention = missing.length > 0; @@ -82,8 +78,9 @@ const MCPServerCard: FC = ({ let subtitle = ""; let subtitleTooltip = ""; if (transport === "stdio") { - const parts = [server.command, ...(server.args ?? [])] - .filter((p): p is string => typeof p === "string" && p.length > 0); + const parts = [server.command, ...(server.args ?? [])].filter( + (p): p is string => typeof p === "string" && p.length > 0, + ); subtitle = parts.join(" "); subtitleTooltip = subtitle; } else if (server.spec_path) { @@ -156,28 +153,19 @@ const MCPServerCard: FC = ({
)}
-
+
{name}
{alias && {alias}} {alias && ·} - - {server.server_id.slice(0, 7)} - + {server.server_id.slice(0, 7)}
{menuItems.length > 0 && ( - +