From 7fb71d70be09b5a11d31ce625316d45be5aefdbc Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 5 Mar 2026 01:09:16 +0000 Subject: [PATCH] Fix MCP server search in playground - Added showSearch prop to enable search input in MCP server selector - Added filterOption to search across server name, alias, server_id, and description - Search is case-insensitive and filters in real-time - Added test to verify search input appears when dropdown opens - Updated tsconfig.json with Next.js auto-configuration (jsx: react-jsx) Fixes issue where MCP server search was not working in the playground. Co-authored-by: Ishaan Jaff --- .../playground/chat_ui/ChatUI.test.tsx | 39 +++++++++++++++++++ .../components/playground/chat_ui/ChatUI.tsx | 18 +++++++++ ui/litellm-dashboard/tsconfig.json | 2 +- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/ui/litellm-dashboard/src/components/playground/chat_ui/ChatUI.test.tsx b/ui/litellm-dashboard/src/components/playground/chat_ui/ChatUI.test.tsx index e00f27c39f4..330ea4dee32 100644 --- a/ui/litellm-dashboard/src/components/playground/chat_ui/ChatUI.test.tsx +++ b/ui/litellm-dashboard/src/components/playground/chat_ui/ChatUI.test.tsx @@ -373,4 +373,43 @@ describe("ChatUI", () => { const customProxyInput = screen.getByPlaceholderText("Optional: Enter custom proxy URL (e.g., http://localhost:5000)"); expect(customProxyInput).toHaveValue(testProxyUrl); }); + + it("should enable search functionality for MCP server selector", async () => { + render( + + ); + + await waitFor(() => { + expect(screen.getByText("Test Key")).toBeInTheDocument(); + }); + + const mcpServersText = screen.queryByText("MCP Servers"); + expect(mcpServersText).toBeInTheDocument(); + + if (mcpServersText) { + const selectContainer = mcpServersText.parentElement?.nextElementSibling; + const selectElement = selectContainer?.querySelector(".ant-select-selector"); + expect(selectElement).toBeInTheDocument(); + + if (selectElement) { + fireEvent.mouseDown(selectElement); + + await waitFor(() => { + const allServersOption = screen.queryByText("All MCP Servers"); + if (allServersOption) { + expect(allServersOption).toBeInTheDocument(); + } + }); + + const searchInput = document.querySelector(".ant-select-selection-search-input"); + expect(searchInput).toBeInTheDocument(); + } + } + }); }); diff --git a/ui/litellm-dashboard/src/components/playground/chat_ui/ChatUI.tsx b/ui/litellm-dashboard/src/components/playground/chat_ui/ChatUI.tsx index df04eece289..3272e9b589a 100644 --- a/ui/litellm-dashboard/src/components/playground/chat_ui/ChatUI.tsx +++ b/ui/litellm-dashboard/src/components/playground/chat_ui/ChatUI.tsx @@ -1636,9 +1636,27 @@ const ChatUI: React.FC = ({ loading={isLoadingMCPServers} className="mb-2" allowClear + showSearch optionLabelProp="label" disabled={!MCP_SUPPORTED_ENDPOINTS.has(endpointType as EndpointType)} maxTagCount={endpointType === EndpointType.MCP ? 1 : "responsive"} + filterOption={(input, option) => { + if (option?.value === "__all__") { + return "All MCP Servers".toLowerCase().includes(input.toLowerCase()); + } + const server = mcpServers.find((s) => s.server_id === option?.value); + if (!server) return false; + const searchText = [ + server.server_name, + server.alias, + server.server_id, + server.description, + ] + .filter(Boolean) + .join(" ") + .toLowerCase(); + return searchText.includes(input.toLowerCase()); + }} > {/* All MCP Servers option - hidden for MCP direct mode */} {endpointType !== EndpointType.MCP && ( diff --git a/ui/litellm-dashboard/tsconfig.json b/ui/litellm-dashboard/tsconfig.json index 5b0352feb98..d24bdd340f7 100644 --- a/ui/litellm-dashboard/tsconfig.json +++ b/ui/litellm-dashboard/tsconfig.json @@ -14,7 +14,7 @@ "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve", + "jsx": "react-jsx", "incremental": true, "plugins": [ {