diff --git a/ui/litellm-dashboard/src/components/mcp_tools/create_mcp_server.tsx b/ui/litellm-dashboard/src/components/mcp_tools/create_mcp_server.tsx index 3a21a10be6..8c94837066 100644 --- a/ui/litellm-dashboard/src/components/mcp_tools/create_mcp_server.tsx +++ b/ui/litellm-dashboard/src/components/mcp_tools/create_mcp_server.tsx @@ -406,6 +406,7 @@ const CreateMCPServer: React.FC = ({ accessToken={accessToken} formValues={formValues} allowedTools={allowedTools} + existingAllowedTools={null} onAllowedToolsChange={setAllowedTools} /> diff --git a/ui/litellm-dashboard/src/components/mcp_tools/mcp_server_edit.tsx b/ui/litellm-dashboard/src/components/mcp_tools/mcp_server_edit.tsx index f8d9d8ac89..d9839b5881 100644 --- a/ui/litellm-dashboard/src/components/mcp_tools/mcp_server_edit.tsx +++ b/ui/litellm-dashboard/src/components/mcp_tools/mcp_server_edit.tsx @@ -5,6 +5,7 @@ import { MCPServer, MCPServerCostInfo } from "./types"; import { updateMCPServer, testMCPToolsListRequest } from "../networking"; import MCPServerCostConfig from "./mcp_server_cost_config"; import MCPPermissionManagement from "./MCPPermissionManagement"; +import MCPToolConfiguration from "./mcp_tool_configuration"; import { MinusCircleOutlined, PlusOutlined, InfoCircleOutlined } from "@ant-design/icons"; import { validateMCPServerUrl, validateMCPServerName } from "./utils"; import NotificationsManager from "../molecules/notifications_manager"; @@ -23,7 +24,8 @@ const MCPServerEdit: React.FC = ({ mcpServer, accessToken, o const [tools, setTools] = useState([]); const [isLoadingTools, setIsLoadingTools] = useState(false); const [searchValue, setSearchValue] = useState(""); - const [aliasManuallyEdited, setAliasManuallyEdited] = useState(false) + const [aliasManuallyEdited, setAliasManuallyEdited] = useState(false); + const [allowedTools, setAllowedTools] = useState([]); // Initialize cost config from existing server data useEffect(() => { @@ -32,6 +34,13 @@ const MCPServerEdit: React.FC = ({ mcpServer, accessToken, o } }, [mcpServer]); + // Initialize allowed tools from existing server data + useEffect(() => { + if (mcpServer.allowed_tools) { + setAllowedTools(mcpServer.allowed_tools); + } + }, [mcpServer]); + // Transform string array to object array for initial form values useEffect(() => { if (mcpServer.mcp_access_groups) { @@ -128,7 +137,7 @@ const MCPServerEdit: React.FC = ({ mcpServer, accessToken, o alias: values.alias, // Include permission management fields extra_headers: values.extra_headers || [], - allowed_tools: values.allowed_tools || [], + allowed_tools: allowedTools.length > 0 ? allowedTools : null, disallowed_tools: values.disallowed_tools || [], }; @@ -195,6 +204,24 @@ const MCPServerEdit: React.FC = ({ mcpServer, accessToken, o /> + {/* Tool Configuration Section */} +
+ +
+
Cancel 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 7442cd467b..1e31c55444 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 @@ -8,6 +8,7 @@ interface MCPToolConfigurationProps { accessToken: string | null formValues: Record allowedTools: string[] + existingAllowedTools: string[] | null onAllowedToolsChange: (tools: string[]) => void } @@ -15,6 +16,7 @@ const MCPToolConfiguration: React.FC = ({ accessToken, formValues, allowedTools, + existingAllowedTools, onAllowedToolsChange, }) => { const previousToolsLengthRef = useRef(0) @@ -25,19 +27,28 @@ const MCPToolConfiguration: React.FC = ({ enabled: true, }) - // Auto-select all tools when tools are first loaded + // Auto-select tools when tools are first loaded useEffect(() => { // Only auto-select if: // 1. We have tools // 2. Tools length changed (new tools loaded) // 3. No tools are currently selected (initial state) if (tools.length > 0 && tools.length !== previousToolsLengthRef.current && allowedTools.length === 0) { - const allToolNames = tools.map((tool) => tool.name) - onAllowedToolsChange(allToolNames) + if (existingAllowedTools && existingAllowedTools.length > 0) { + // If we have existing allowed tools, use those as the initial selection + // Filter to only include tools that are actually available from the server + const availableToolNames = tools.map((tool) => tool.name) + const validExistingTools = existingAllowedTools.filter(toolName => availableToolNames.includes(toolName)) + onAllowedToolsChange(validExistingTools) + } else { + // If no existing allowed tools, auto-select all tools (create mode) + const allToolNames = tools.map((tool) => tool.name) + onAllowedToolsChange(allToolNames) + } } // Update ref to track tools length (will be 0 when tools clear) previousToolsLengthRef.current = tools.length - }, [tools, allowedTools.length, onAllowedToolsChange]) + }, [tools, allowedTools.length, existingAllowedTools, onAllowedToolsChange]) const handleToolToggle = (toolName: string) => { if (allowedTools.includes(toolName)) {