Skip to content

Commit df24dff

Browse files
committed
feat: support environment variables reference in mcp env config
1 parent e2d649d commit df24dff

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

src/services/mcp/McpHub.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
} from "../../shared/mcp"
3131
import { fileExistsAtPath } from "../../utils/fs"
3232
import { arePathsEqual } from "../../utils/path"
33+
import { injectEnv } from "../../utils/config"
3334

3435
export type McpConnection = {
3536
server: McpServer
@@ -452,7 +453,7 @@ export class McpHub {
452453
args: config.args,
453454
cwd: config.cwd,
454455
env: {
455-
...config.env,
456+
...(config.env ? await injectEnv(config.env) : {}),
456457
...(process.env.PATH ? { PATH: process.env.PATH } : {}),
457458
},
458459
stderr: "pipe",

src/utils/config.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Deeply injects environment variables into a configuration object/string/json
3+
*
4+
* Uses VSCode env:name pattern: https://code.visualstudio.com/docs/reference/variables-reference#_environment-variables
5+
*
6+
* Does not mutate original object
7+
*/
8+
export async function injectEnv(config: string | Record<PropertyKey, any>, notFoundValue: any = "") {
9+
// Use simple regex replace for now, will see if object traversal and recursion is needed here (e.g: for non-serializable objects)
10+
11+
const isObject = typeof config === "object"
12+
let _config: string = isObject ? JSON.stringify(config) : config
13+
14+
_config = _config.replace(/\$\{env:([\w\.]+)\}/g, (_, name) => {
15+
if (!process.env[name]) console.warn(`[injectEnv] env variable ${name} referenced but not found in process.env`)
16+
17+
return process.env[name] || notFoundValue
18+
})
19+
20+
return isObject ? JSON.parse(_config) : _config
21+
}

0 commit comments

Comments
 (0)