fix(ui): restore MCP catalog provider logos (#40781)

Resolves LIT-7390
This commit is contained in:
yuneng-jiang 2026-09-12 11:56:59 -07:00 • committed by GitHub
parent 347b642bdd
commit a73454b8fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 53 additions and 7 deletions

View file

@ -66,7 +66,7 @@
"name": "slack",
"title": "Slack",
"description": "Channel management, messaging, and Slack workspace integration",
"icon_url": "https://cdn.simpleicons.org/slack",
"icon_url": "/ui/assets/logos/slack.svg",
"category": "Communication",
"registry_url": null,
"transport": "stdio",
@ -249,7 +249,7 @@
"name": "exa",
"title": "Exa",
"description": "Fast, intelligent web search and web crawling",
"icon_url": "https://cdn.simpleicons.org/exa",
"icon_url": "/ui/assets/logos/exa_ai.png",
"category": "Search",
"registry_url": "https://registry.modelcontextprotocol.io/servers/ai.exa%2Fexa",
"transport": "http",
@ -262,7 +262,7 @@
"name": "tavily",
"title": "Tavily",
"description": "AI-optimized search engine for research and retrieval",
"icon_url": "https://cdn.simpleicons.org/tavily",
"icon_url": "/ui/assets/logos/tavily.png",
"category": "Search",
"registry_url": null,
"transport": "stdio",
@ -288,7 +288,7 @@
"name": "playwright",
"title": "Playwright",
"description": "Browser automation and testing with Playwright",
"icon_url": "https://cdn.simpleicons.org/playwright",
"icon_url": "https://raw.githubusercontent.com/microsoft/playwright/2f6148bcd1a96ec687d55ce08645fc6315b1514e/packages/recorder/public/playwright-logo.svg",
"category": "Web & Browser",
"registry_url": null,
"transport": "stdio",
@ -300,7 +300,7 @@
"name": "browserbase",
"title": "Browserbase",
"description": "Cloud browser automation and session management",
"icon_url": "https://cdn.simpleicons.org/browserbase",
"icon_url": "https://www.browserbase.com/favicon.svg",
"category": "Web & Browser",
"registry_url": null,
"transport": "stdio",
@ -315,7 +315,7 @@
"name": "aws",
"title": "AWS",
"description": "Interact with Amazon Web Services resources and APIs",
"icon_url": "https://cdn.simpleicons.org/amazonaws",
"icon_url": "/ui/assets/logos/aws.svg",
"category": "Cloud",
"registry_url": null,
"transport": "stdio",
@ -392,7 +392,7 @@
"name": "twilio",
"title": "Twilio",
"description": "Send SMS, make calls, and manage communication via Twilio",
"icon_url": "https://cdn.simpleicons.org/twilio",
"icon_url": "/ui/assets/logos/twilio.svg",
"category": "Communication",
"registry_url": null,
"transport": "stdio",

View file

@ -4,6 +4,11 @@ import { describe, it, expect, vi, beforeEach } from "vitest";
import MCPDiscovery from "./mcp_discovery";
import { fetchDiscoverableMCPServers } from "@/components/networking";
import type { DiscoverableMCPServer } from "@/components/mcp_tools/types";
import { renderWithProviders } from "../../../../../tests/test-utils";
import { setServerRootPath } from "@/lib/serverRootPath";
import { existsSync, readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
vi.mock("@/components/networking", () => ({
fetchDiscoverableMCPServers: vi.fn(),
@ -36,12 +41,53 @@ const defaultProps = {
describe("MCPDiscovery", () => {
beforeEach(() => {
vi.clearAllMocks();
setServerRootPath("/");
vi.mocked(fetchDiscoverableMCPServers).mockResolvedValue({
servers: [githubServer, slackServer],
categories: ["Developer Tools", "Communication"],
});
});
it.each(["", "/litellm"])("should render available catalog logos under the %s server root", async (root) => {
const testDirectory = dirname(fileURLToPath(import.meta.url));
const registry = JSON.parse(
readFileSync(resolve(testDirectory, "../../../../../../../litellm/proxy/mcp_registry.json"), "utf8"),
) as { servers: DiscoverableMCPServer[] };
const expectedLogos = [
["exa", "/ui/assets/logos/exa_ai.png"],
["tavily", "/ui/assets/logos/tavily.png"],
["slack", "/ui/assets/logos/slack.svg"],
["twilio", "/ui/assets/logos/twilio.svg"],
[
"playwright",
"https://raw.githubusercontent.com/microsoft/playwright/2f6148bcd1a96ec687d55ce08645fc6315b1514e/packages/recorder/public/playwright-logo.svg",
],
["browserbase", "https://www.browserbase.com/favicon.svg"],
["aws", "/ui/assets/logos/aws.svg"],
] as const;
setServerRootPath(root);
vi.mocked(fetchDiscoverableMCPServers).mockResolvedValue({
servers: expectedLogos.map(([name]) => {
const server = registry.servers.find((entry) => entry.name === name)!;
return server;
}),
categories: [],
});
renderWithProviders(<MCPDiscovery {...defaultProps} />);
for (const [name, source] of expectedLogos) {
const server = registry.servers.find((entry) => entry.name === name)!;
if (source.startsWith("/ui/")) {
expect(existsSync(resolve(testDirectory, "../../../../../public", source.slice(4)))).toBe(true);
}
expect(await screen.findByRole("img", { name: server.title })).toHaveAttribute(
"src",
source.startsWith("/ui/") ? `${root}${source}` : source,
);
}
});
// Each category name renders twice: once as a filter pill (a button) and once
// as the heading of its group. Only the heading is not a button.
const groupHeading = (category: string) => screen.getAllByText(category).filter((el) => el.tagName !== "BUTTON");