From 0e478ed03c818e0d3acdd5276c7043e52f0e379a Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 21 May 2026 03:05:48 +0000 Subject: [PATCH] proto(mcp): allow editing env vars after server creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the same EnvVarsSection to the existing Edit Settings flow (MCPServerEdit). On mount, pre-fills the form from localStorage keyed by the server's current alias; on save, persists the updated definitions back (re-keyed under the new alias if it was renamed). No backend wiring — same mock pattern as the create flow. Verified via temporary scaffold (now removed): - Mounts MCPServerEdit against a stub server with 3 seeded defs - Form renders all 3 rows pre-filled - Add/remove/change-scope work - Save persists the new defs to localStorage even though the API call fails in the verify harness (persistence runs before updateMCPServer). --- .../components/mcp_tools/mcp_server_edit.tsx | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) 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 4eb7920d099..c76f09dfd47 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 @@ -9,6 +9,13 @@ import MCPPermissionManagement from "./MCPPermissionManagement"; import MCPToolConfiguration from "./mcp_tool_configuration"; import StdioConfiguration from "./StdioConfiguration"; import MCPLogoSelector from "./MCPLogoSelector"; +import EnvVarsSection from "./mock/EnvVarsSection"; +import { + getEnvVarDefinitions, + setEnvVarDefinitions, + notifyEnvVarsChanged, + EnvVarDefinition, +} from "./mock/mockMcpEnvVars"; import { validateMCPServerUrl, validateMCPServerName, @@ -200,6 +207,14 @@ const MCPServerEdit: React.FC = ({ return mcpServer.transport; }, [mcpServer]); + // PROTOTYPE: existing env-var definitions for this server, loaded from + // localStorage by alias and folded into the form's initialValues below so + // antd's Form.List picks them up at mount time. + const initialEnvVars = React.useMemo(() => { + const aliasKey = mcpServer.alias || mcpServer.server_name || ""; + return aliasKey ? getEnvVarDefinitions(aliasKey) : []; + }, [mcpServer.alias, mcpServer.server_name]); + const initialValues = React.useMemo( () => ({ ...mcpServer, @@ -210,8 +225,9 @@ const MCPServerEdit: React.FC = ({ token_validation_json: mcpServer.token_validation ? JSON.stringify(mcpServer.token_validation, null, 2) : undefined, + mock_env_vars: initialEnvVars, }), - [mcpServer, effectiveTransport, initialStaticHeaders, initialEnvJson], + [mcpServer, effectiveTransport, initialStaticHeaders, initialEnvJson, initialEnvVars], ); // Initialize cost config from existing server data @@ -401,9 +417,31 @@ const MCPServerEdit: React.FC = ({ available_on_public_internet: availableOnPublicInternetRaw, delegate_auth_to_upstream: delegateAuthToUpstreamRaw, token_validation_json: rawTokenValidationJson, + mock_env_vars: mockEnvVarsRaw, ...restValues } = values; + // PROTOTYPE: persist updated env-var definitions to localStorage under + // the current alias. If the alias was renamed in this edit, we also + // copy the previously-saved defs to the new alias so the link survives. + const cleanedEnvVars: EnvVarDefinition[] = Array.isArray(mockEnvVarsRaw) + ? mockEnvVarsRaw + .filter((row: any) => row && row.name && String(row.name).trim() !== "") + .map((row: any) => ({ + name: String(row.name).trim(), + value: row.scope === "per_user" ? "" : (row.value ?? ""), + scope: row.scope === "per_user" ? "per_user" : "global", + })) + : []; + const newAlias = + (restValues.alias && String(restValues.alias).trim()) || + (restValues.server_name && String(restValues.server_name).trim()) || + ""; + if (newAlias) { + setEnvVarDefinitions(newAlias, cleanedEnvVars); + notifyEnvVarsChanged(); + } + const accessGroups = (restValues.mcp_access_groups || []).map((g: any) => typeof g === "string" ? g : g.name || String(g), ); @@ -1089,6 +1127,11 @@ const MCPServerEdit: React.FC = ({ )} + {/* PROTOTYPE: Environment variables (global vs per-user) */} +
+ +
+ {/* Permission Management / Access Control Section */}