fix: resolve ${VAR} env references in MCP client .mcp.json configs (#1609)

The MCP client passed raw "${VAR}" strings to child processes instead of
resolving them against process.env, breaking MCP servers that expect
resolved environment variable values.

Adds a resolveEnv() helper that interpolates ${VAR} patterns in env
config values before passing them to StdioClientTransport.

Closes #1599

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
TÂCHES 2026-03-20 10:39:15 -06:00 committed by GitHub
parent fc4cb836fe
commit ec55fe64f1

View file

@ -114,6 +114,22 @@ function getServerConfig(name: string): McpServerConfig | undefined {
return readConfigs().find((s) => s.name === name);
}
/** Resolve ${VAR} references in env values against process.env. */
function resolveEnv(env: Record<string, string>): Record<string, string> {
const resolved: Record<string, string> = {};
for (const [key, value] of Object.entries(env)) {
if (typeof value === "string") {
resolved[key] = value.replace(
/\$\{([^}]+)\}/g,
(_match, varName) => process.env[varName] ?? "",
);
} else {
resolved[key] = value;
}
}
return resolved;
}
async function getOrConnect(name: string, signal?: AbortSignal): Promise<Client> {
const existing = connections.get(name);
if (existing) return existing.client;
@ -128,7 +144,7 @@ async function getOrConnect(name: string, signal?: AbortSignal): Promise<Client>
transport = new StdioClientTransport({
command: config.command,
args: config.args,
env: config.env ? { ...process.env, ...config.env } as Record<string, string> : undefined,
env: config.env ? { ...process.env, ...resolveEnv(config.env) } as Record<string, string> : undefined,
cwd: config.cwd,
stderr: "pipe",
});