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 bf7f1a67431..e38e7b8cd9b 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 @@ -3,7 +3,7 @@ import { Modal, Tooltip, Form, Select, Input } from "antd"; import { InfoCircleOutlined } from "@ant-design/icons"; import { Button, TextInput } from "@tremor/react"; import { createMCPServer } from "../networking"; -import { AUTH_TYPE, OAUTH_FLOW, MCPServer, MCPServerCostInfo } from "./types"; +import { AUTH_TYPE, DiscoverableMCPServer, OAUTH_FLOW, MCPServer, MCPServerCostInfo } from "./types"; import OAuthFormFields from "./OAuthFormFields"; import MCPServerCostConfig from "./mcp_server_cost_config"; import MCPConnectionStatus from "./mcp_connection_status"; @@ -25,6 +25,8 @@ interface CreateMCPServerProps { isModalVisible: boolean; setModalVisible: (visible: boolean) => void; availableAccessGroups: string[]; + prefillData?: DiscoverableMCPServer | null; + onBackToDiscovery?: () => void; } const AUTH_TYPES_REQUIRING_AUTH_VALUE = [AUTH_TYPE.API_KEY, AUTH_TYPE.BEARER_TOKEN, AUTH_TYPE.BASIC]; @@ -38,6 +40,8 @@ const CreateMCPServer: React.FC = ({ isModalVisible, setModalVisible, availableAccessGroups, + prefillData, + onBackToDiscovery, }) => { const [form] = Form.useForm(); const [isLoading, setIsLoading] = useState(false); @@ -183,6 +187,39 @@ const CreateMCPServer: React.FC = ({ setPendingRestoredValues(null); }, [pendingRestoredValues, form, transportType]); + // Pre-fill form from discovery selection + React.useEffect(() => { + if (!isModalVisible || !prefillData) { + return; + } + // Sanitize server name: strip vendor prefix, replace hyphens with underscores + const sanitizedName = (prefillData.name || "") + .replace(/[^a-zA-Z0-9_]/g, "_") + .replace(/_+/g, "_") + .replace(/^_|_$/g, ""); + + const transport = prefillData.transport || ""; + setTransportType(transport); + + const prefillValues: Record = { + server_name: sanitizedName, + alias: sanitizedName, + description: prefillData.description || "", + transport: transport, + }; + + if (transport === "stdio") { + prefillValues.command = prefillData.command || ""; + prefillValues.args = prefillData.args || []; + } else if (prefillData.url) { + prefillValues.url = prefillData.url; + } + + form.setFieldsValue(prefillValues); + setFormValues(prefillValues); + setAliasManuallyEdited(false); + }, [isModalVisible, prefillData, form]); + const handleCreate = async (values: Record) => { setIsLoading(true); try { @@ -391,19 +428,29 @@ const CreateMCPServer: React.FC = ({ return ( - MCP Logo -

Add New MCP Server

+
+
+ MCP Logo +

Add New MCP Server

+
+ {onBackToDiscovery && ( + + )}
} open={isModalVisible}