proto(mcp): allow editing env vars after server creation

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).
This commit is contained in:
Claude 2026-05-21 03:05:48 +00:00
parent 5d57c6bfa3
commit 0e478ed03c
No known key found for this signature in database

View file

@ -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<MCPServerEditProps> = ({
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<MCPServerEditProps> = ({
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<MCPServerEditProps> = ({
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<MCPServerEditProps> = ({
</>
)}
{/* PROTOTYPE: Environment variables (global vs per-user) */}
<div className="mt-6">
<EnvVarsSection />
</div>
{/* Permission Management / Access Control Section */}
<div className="mt-6">
<MCPPermissionManagement