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..915b1a55234 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 @@ -10,6 +10,7 @@ vi.mock("../networking", () => ({ fetchMCPServers: vi.fn(), fetchMCPServerHealth: vi.fn(), deleteMCPServer: vi.fn(), + createMCPServer: vi.fn(), getProxyBaseUrl: vi.fn().mockReturnValue("http://localhost:4000"), fetchMCPClientIp: vi.fn().mockResolvedValue(null), getGeneralSettingsCall: vi.fn().mockResolvedValue([]), @@ -348,4 +349,74 @@ describe("MCPServers", () => { // Team B server should not be visible expect(screen.queryByText("Team B Server")).not.toBeInTheDocument(); }); + + it("should refetch servers after creating a new MCP server", async () => { + const mockServers = [ + { + server_id: "server-1", + server_name: "Existing Server", + alias: "existing-server", + url: "https://example.com/mcp", + transport: "http", + auth_type: "none", + created_at: "2024-01-01T00:00:00Z", + created_by: "user-1", + updated_at: "2024-01-01T00:00:00Z", + updated_by: "user-1", + teams: [], + mcp_access_groups: [], + }, + ]; + + const newServer = { + server_id: "server-new", + server_name: "New Server", + alias: "new-server", + url: "https://new-example.com/mcp", + transport: "http", + auth_type: "none", + created_at: "2024-01-02T00:00:00Z", + created_by: "user-1", + updated_at: "2024-01-02T00:00:00Z", + updated_by: "user-1", + teams: [], + mcp_access_groups: [], + }; + + vi.mocked(networking.fetchMCPServers).mockResolvedValue(mockServers); + vi.mocked(networking.fetchMCPServerHealth).mockResolvedValue([]); + + const queryClient = createQueryClient(); + render( + + + , + ); + + await waitFor(() => { + expect(screen.getByText("Existing Server")).toBeInTheDocument(); + }); + + const initialCallCount = vi.mocked(networking.fetchMCPServers).mock.calls.length; + + vi.mocked(networking.fetchMCPServers).mockResolvedValue([...mockServers, newServer]); + + const mcpServersComponent = screen.getByText("MCP Servers").closest("div")?.parentElement; + expect(mcpServersComponent).toBeTruthy(); + + await act(async () => { + queryClient.invalidateQueries({ queryKey: ["mcpServers"] }); + }); + + await waitFor(() => { + expect(vi.mocked(networking.fetchMCPServers).mock.calls.length).toBeGreaterThan(initialCallCount); + }); + + await waitFor(() => { + expect(screen.getByText("New Server")).toBeInTheDocument(); + }); + + expect(screen.getByText("Existing Server")).toBeInTheDocument(); + expect(screen.getByText("New Server")).toBeInTheDocument(); + }); }); 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..5012dde3fe8 100644 --- a/ui/litellm-dashboard/src/components/mcp_tools/mcp_servers.tsx +++ b/ui/litellm-dashboard/src/components/mcp_tools/mcp_servers.tsx @@ -213,6 +213,7 @@ const MCPServers: React.FC = ({ accessToken, userRole, userID }) const handleCreateSuccess = (newMcpServer: MCPServer) => { setFilteredServers((prev) => [...prev, newMcpServer]); setModalVisible(false); + refetch(); }; // Memoize the selected server to prevent unnecessary re-renders