diff --git a/litellm/proxy/management_endpoints/mcp_management_endpoints.py b/litellm/proxy/management_endpoints/mcp_management_endpoints.py index 8fc1b48fd22..710aa0b1162 100644 --- a/litellm/proxy/management_endpoints/mcp_management_endpoints.py +++ b/litellm/proxy/management_endpoints/mcp_management_endpoints.py @@ -15,6 +15,7 @@ Endpoints here: """ +import functools import importlib import json import os @@ -1370,6 +1371,7 @@ if MCP_AVAILABLE: "openapi_registry.json", ) + @functools.lru_cache(maxsize=1) def _load_openapi_registry() -> Dict[str, Any]: try: with open(_OPENAPI_REGISTRY_PATH, "r") as f: diff --git a/ui/litellm-dashboard/src/components/mcp_tools/OpenAPIQuickPicker.tsx b/ui/litellm-dashboard/src/components/mcp_tools/OpenAPIQuickPicker.tsx index 973427bf058..2959ed25e57 100644 --- a/ui/litellm-dashboard/src/components/mcp_tools/OpenAPIQuickPicker.tsx +++ b/ui/litellm-dashboard/src/components/mcp_tools/OpenAPIQuickPicker.tsx @@ -13,7 +13,7 @@ export interface OpenAPIRegistryEntry { description: string; icon_url: string; spec_url: string; - oauth: { + oauth?: { authorization_url: string; token_url: string; pkce: boolean; diff --git a/ui/litellm-dashboard/src/components/mcp_tools/mcp_tool_configuration.tsx b/ui/litellm-dashboard/src/components/mcp_tools/mcp_tool_configuration.tsx index c6bf39828e4..1a7c58fe10e 100644 --- a/ui/litellm-dashboard/src/components/mcp_tools/mcp_tool_configuration.tsx +++ b/ui/litellm-dashboard/src/components/mcp_tools/mcp_tool_configuration.tsx @@ -152,6 +152,7 @@ const MCPToolConfiguration: React.FC = ({ const previousToolsRef = useRef([]); const [toolSearchTerm, setToolSearchTerm] = useState(""); const hasInitializedRef = useRef(false); + const previousSuggestedToolNamesRef = useRef(""); const [expandedTools, setExpandedTools] = useState>(new Set()); const { tools, isLoadingTools, toolsError, canFetchTools } = useTestMCPConnection({ @@ -223,6 +224,15 @@ const MCPToolConfiguration: React.FC = ({ const previousToolNames = previousToolsRef.current.map((tool) => tool.name).sort().join(","); const toolsListChanged = currentToolNames !== previousToolNames; + // Reset initialization when a new preset is selected (suggestedTools fingerprint changes) + const currentSuggestedNames = suggestedTools.map((t) => t.name).sort().join(","); + if (currentSuggestedNames !== previousSuggestedToolNamesRef.current) { + previousSuggestedToolNamesRef.current = currentSuggestedNames; + if (currentSuggestedNames !== "") { + hasInitializedRef.current = false; + } + } + if (tools.length > 0 && toolsListChanged) { const availableToolNames = tools.map((tool) => tool.name);