diff --git a/ui/litellm-dashboard/src/components/mcp_tools/MCPLogoSelector.test.tsx b/ui/litellm-dashboard/src/components/mcp_tools/MCPLogoSelector.test.tsx
new file mode 100644
index 00000000000..94b9058b372
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/mcp_tools/MCPLogoSelector.test.tsx
@@ -0,0 +1,55 @@
+import React from "react";
+import { render, screen, fireEvent } from "@testing-library/react";
+import { describe, it, expect, vi, beforeEach } from "vitest";
+import userEvent from "@testing-library/user-event";
+import MCPLogoSelector from "./MCPLogoSelector";
+
+describe("MCPLogoSelector", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ it("should render the logo grid and custom URL input", () => {
+ render();
+ expect(screen.getByPlaceholderText(/paste a custom logo URL/i)).toBeInTheDocument();
+ });
+
+ it("should show a preview when a value is provided", () => {
+ render();
+ expect(screen.getByAltText("Selected logo")).toBeInTheDocument();
+ });
+
+ it("should not show a preview when no value is provided", () => {
+ render();
+ expect(screen.queryByAltText("Selected logo")).not.toBeInTheDocument();
+ });
+
+ it("should call onChange with undefined when the clear button is clicked", async () => {
+ const onChange = vi.fn();
+ const user = userEvent.setup();
+ render();
+
+ await user.click(screen.getByRole("button", { name: /✕/ }));
+ expect(onChange).toHaveBeenCalledWith(undefined);
+ });
+
+ it("should call onChange with the logo URL when a grid logo is clicked", async () => {
+ const onChange = vi.fn();
+ const user = userEvent.setup();
+ render();
+
+ const githubButton = screen.getByRole("button", { name: /GitHub/i });
+ await user.click(githubButton);
+ expect(onChange).toHaveBeenCalledWith("/ui/assets/logos/github.svg");
+ });
+
+ it("should deselect a logo when clicking the already-selected logo", async () => {
+ const onChange = vi.fn();
+ const user = userEvent.setup();
+ render();
+
+ const githubButton = screen.getByRole("button", { name: /GitHub/i });
+ await user.click(githubButton);
+ expect(onChange).toHaveBeenCalledWith(undefined);
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/mcp_tools/MCPStandardsSettings.test.tsx b/ui/litellm-dashboard/src/components/mcp_tools/MCPStandardsSettings.test.tsx
new file mode 100644
index 00000000000..4f20b7cda79
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/mcp_tools/MCPStandardsSettings.test.tsx
@@ -0,0 +1,62 @@
+import { describe, it, expect } from "vitest";
+import { FIELD_GROUPS, MCP_REQUIRED_FIELD_DEFS, SETTINGS_KEY } from "./MCPStandardsSettings";
+import { MCPServer } from "./types";
+
+const makeServer = (overrides: Partial = {}): MCPServer => ({
+ server_id: "s1",
+ created_at: "2024-01-01",
+ created_by: "user",
+ updated_at: "2024-01-01",
+ updated_by: "user",
+ ...overrides,
+});
+
+describe("FIELD_GROUPS", () => {
+ it("should contain four groups", () => {
+ expect(FIELD_GROUPS).toHaveLength(4);
+ expect(FIELD_GROUPS.map((g) => g.label)).toEqual([
+ "Documentation",
+ "Source",
+ "Connection",
+ "Security",
+ ]);
+ });
+});
+
+describe("MCP_REQUIRED_FIELD_DEFS", () => {
+ it("should flatten all fields from groups", () => {
+ const totalFields = FIELD_GROUPS.reduce((sum, g) => sum + g.fields.length, 0);
+ expect(MCP_REQUIRED_FIELD_DEFS).toHaveLength(totalFields);
+ });
+});
+
+describe("field check functions", () => {
+ const findCheck = (key: string) =>
+ MCP_REQUIRED_FIELD_DEFS.find((f) => f.key === key)!.check;
+
+ it("should pass description check when description is present", () => {
+ expect(findCheck("description")(makeServer({ description: "A service" }))).toBe(true);
+ });
+
+ it("should fail description check when description is empty", () => {
+ expect(findCheck("description")(makeServer({ description: " " }))).toBe(false);
+ });
+
+ it("should pass auth check when auth_type is not none", () => {
+ expect(findCheck("auth_type")(makeServer({ auth_type: "oauth2" }))).toBe(true);
+ });
+
+ it("should fail auth check when auth_type is none", () => {
+ expect(findCheck("auth_type")(makeServer({ auth_type: "none" }))).toBe(false);
+ });
+
+ it("should fail auth check when auth_type is missing", () => {
+ expect(findCheck("auth_type")(makeServer())).toBe(false);
+ });
+});
+
+describe("SETTINGS_KEY", () => {
+ it("should equal mcp_required_fields", () => {
+ expect(SETTINGS_KEY).toBe("mcp_required_fields");
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/mcp_tools/mcp_connection_status.test.tsx b/ui/litellm-dashboard/src/components/mcp_tools/mcp_connection_status.test.tsx
new file mode 100644
index 00000000000..8cd9d0e4ca9
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/mcp_tools/mcp_connection_status.test.tsx
@@ -0,0 +1,87 @@
+import React from "react";
+import { render, screen } from "@testing-library/react";
+import { describe, it, expect, vi, beforeEach } from "vitest";
+import userEvent from "@testing-library/user-event";
+import MCPConnectionStatus from "./mcp_connection_status";
+
+describe("MCPConnectionStatus", () => {
+ const defaultProps = {
+ formValues: { url: "https://example.com/mcp" },
+ tools: [] as any[],
+ isLoadingTools: false,
+ toolsError: null,
+ toolsErrorStackTrace: null,
+ canFetchTools: false,
+ fetchTools: vi.fn(),
+ };
+
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ it("should render nothing when canFetchTools is false and no URL is set", () => {
+ const { container } = render(
+
+ );
+ expect(container.firstChild).toBeNull();
+ });
+
+ it("should show 'Complete required fields' message when URL is set but canFetchTools is false", () => {
+ render();
+ expect(screen.getByText(/Complete required fields to test connection/i)).toBeInTheDocument();
+ });
+
+ it("should show 'Connection successful' when tools are loaded", () => {
+ render(
+
+ );
+ expect(screen.getByText("Connection successful")).toBeInTheDocument();
+ expect(screen.getByText("Connected")).toBeInTheDocument();
+ });
+
+ it("should show loading state when isLoadingTools is true", () => {
+ render(
+
+ );
+ expect(screen.getByText(/Testing connection to MCP server/i)).toBeInTheDocument();
+ expect(screen.getByText("Connecting...")).toBeInTheDocument();
+ });
+
+ it("should show error state with retry button when toolsError is set", async () => {
+ const fetchTools = vi.fn();
+ const user = userEvent.setup();
+ render(
+
+ );
+
+ expect(screen.getByText("Connection Failed")).toBeInTheDocument();
+ expect(screen.getByText("Connection refused")).toBeInTheDocument();
+
+ await user.click(screen.getByRole("button", { name: /retry/i }));
+ expect(fetchTools).toHaveBeenCalled();
+ });
+
+ it("should show 'No tools found' when connection succeeds but no tools returned", () => {
+ render(
+
+ );
+ expect(screen.getByText(/No tools found for this MCP server/i)).toBeInTheDocument();
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/mcp_tools/types.test.tsx b/ui/litellm-dashboard/src/components/mcp_tools/types.test.tsx
new file mode 100644
index 00000000000..155abe27ae2
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/mcp_tools/types.test.tsx
@@ -0,0 +1,59 @@
+import { describe, it, expect } from "vitest";
+import { AUTH_TYPE, OAUTH_FLOW, TRANSPORT, handleTransport, handleAuth } from "./types";
+
+describe("handleTransport", () => {
+ it("should default to SSE when transport is null", () => {
+ expect(handleTransport(null)).toBe(TRANSPORT.SSE);
+ });
+
+ it("should default to SSE when transport is undefined", () => {
+ expect(handleTransport(undefined)).toBe(TRANSPORT.SSE);
+ });
+
+ it("should return openapi when specPath is present and transport is not stdio", () => {
+ expect(handleTransport("http", "/spec.yaml")).toBe(TRANSPORT.OPENAPI);
+ });
+
+ it("should keep stdio even when specPath is present", () => {
+ expect(handleTransport(TRANSPORT.STDIO, "/spec.yaml")).toBe(TRANSPORT.STDIO);
+ });
+
+ it("should return the transport as-is when no specPath", () => {
+ expect(handleTransport("http")).toBe("http");
+ });
+});
+
+describe("handleAuth", () => {
+ it("should default to NONE when authType is null", () => {
+ expect(handleAuth(null)).toBe(AUTH_TYPE.NONE);
+ });
+
+ it("should default to NONE when authType is undefined", () => {
+ expect(handleAuth(undefined)).toBe(AUTH_TYPE.NONE);
+ });
+
+ it("should return the provided auth type", () => {
+ expect(handleAuth(AUTH_TYPE.OAUTH2)).toBe("oauth2");
+ });
+});
+
+describe("constants", () => {
+ it("should define all expected auth types", () => {
+ expect(AUTH_TYPE.NONE).toBe("none");
+ expect(AUTH_TYPE.API_KEY).toBe("api_key");
+ expect(AUTH_TYPE.BEARER_TOKEN).toBe("bearer_token");
+ expect(AUTH_TYPE.OAUTH2).toBe("oauth2");
+ });
+
+ it("should define all expected transport types", () => {
+ expect(TRANSPORT.SSE).toBe("sse");
+ expect(TRANSPORT.HTTP).toBe("http");
+ expect(TRANSPORT.STDIO).toBe("stdio");
+ expect(TRANSPORT.OPENAPI).toBe("openapi");
+ });
+
+ it("should define OAuth flow types", () => {
+ expect(OAUTH_FLOW.INTERACTIVE).toBe("interactive");
+ expect(OAUTH_FLOW.M2M).toBe("m2m");
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/mcp_tools/utils.test.tsx b/ui/litellm-dashboard/src/components/mcp_tools/utils.test.tsx
new file mode 100644
index 00000000000..a35b56b47bd
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/mcp_tools/utils.test.tsx
@@ -0,0 +1,75 @@
+import { describe, it, expect } from "vitest";
+import {
+ extractMCPToken,
+ maskUrl,
+ getMaskedAndFullUrl,
+ validateMCPServerUrl,
+ validateMCPServerName,
+} from "./utils";
+
+describe("extractMCPToken", () => {
+ it("should extract token after /mcp/", () => {
+ const result = extractMCPToken("https://example.com/mcp/abc123");
+ expect(result).toEqual({ token: "abc123", baseUrl: "https://example.com/mcp/" });
+ });
+
+ it("should return null token when URL has no /mcp/ segment", () => {
+ const result = extractMCPToken("https://example.com/api/v1");
+ expect(result).toEqual({ token: null, baseUrl: "https://example.com/api/v1" });
+ });
+
+ it("should return null token when nothing follows /mcp/", () => {
+ const result = extractMCPToken("https://example.com/mcp/");
+ expect(result).toEqual({ token: null, baseUrl: "https://example.com/mcp/" });
+ });
+});
+
+describe("maskUrl", () => {
+ it("should replace the token with ellipsis", () => {
+ expect(maskUrl("https://example.com/mcp/secret-token")).toBe("https://example.com/mcp/...");
+ });
+
+ it("should return the original URL when there is no token", () => {
+ expect(maskUrl("https://example.com/api")).toBe("https://example.com/api");
+ });
+});
+
+describe("getMaskedAndFullUrl", () => {
+ it("should return hasToken true when a token exists", () => {
+ const result = getMaskedAndFullUrl("https://example.com/mcp/tok");
+ expect(result).toEqual({ maskedUrl: "https://example.com/mcp/...", hasToken: true });
+ });
+
+ it("should return hasToken false when no token exists", () => {
+ const result = getMaskedAndFullUrl("https://example.com/api");
+ expect(result).toEqual({ maskedUrl: "https://example.com/api", hasToken: false });
+ });
+});
+
+describe("validateMCPServerUrl", () => {
+ it("should resolve for a valid HTTP URL", async () => {
+ await expect(validateMCPServerUrl("https://example.com/path")).resolves.toBeUndefined();
+ });
+
+ it("should resolve for an empty string", async () => {
+ await expect(validateMCPServerUrl("")).resolves.toBeUndefined();
+ });
+
+ it("should reject for an invalid URL", async () => {
+ await expect(validateMCPServerUrl("not-a-url")).rejects.toBeDefined();
+ });
+});
+
+describe("validateMCPServerName", () => {
+ it("should resolve for a valid underscore name", async () => {
+ await expect(validateMCPServerName("my_server")).resolves.toBeUndefined();
+ });
+
+ it("should reject names containing hyphens", async () => {
+ await expect(validateMCPServerName("my-server")).rejects.toBeDefined();
+ });
+
+ it("should reject names containing spaces", async () => {
+ await expect(validateMCPServerName("my server")).rejects.toBeDefined();
+ });
+});