@@ -22,6 +22,64 @@ export type LoadedAgentDefinition = AgentDefinition & {
2222 */
2323export type LoadedAgents = Record < string , LoadedAgentDefinition >
2424
25+ /**
26+ * Resolves environment variable references in MCP server configs.
27+ * Values starting with `$` are treated as env var references (e.g., `'$NOTION_TOKEN'`).
28+ *
29+ * @param env - The env object from MCP config with possible $VAR_NAME references
30+ * @param agentId - The agent ID for error messages
31+ * @param mcpServerName - The MCP server name for error messages
32+ * @returns Resolved env object with all $VAR_NAME values replaced with actual values
33+ * @throws Error if a referenced environment variable is missing
34+ */
35+ export function resolveMcpEnv (
36+ env : Record < string , string > | undefined ,
37+ agentId : string ,
38+ mcpServerName : string ,
39+ ) : Record < string , string > {
40+ if ( ! env ) return { }
41+
42+ const resolved : Record < string , string > = { }
43+
44+ for ( const [ key , value ] of Object . entries ( env ) ) {
45+ if ( value . startsWith ( '$' ) ) {
46+ // $VAR_NAME reference - resolve from process.env
47+ const envVarName = value . slice ( 1 ) // Remove the leading $
48+ const envValue = process . env [ envVarName ]
49+
50+ if ( envValue === undefined ) {
51+ throw new Error (
52+ `Missing environment variable '${ envVarName } ' required by agent '${ agentId } ' in mcpServers.${ mcpServerName } .env.${ key } ` ,
53+ )
54+ }
55+
56+ resolved [ key ] = envValue
57+ } else {
58+ // Plain string value - use as-is
59+ resolved [ key ] = value
60+ }
61+ }
62+
63+ return resolved
64+ }
65+
66+ /**
67+ * Resolves all MCP server env references in an agent definition.
68+ * Mutates the mcpServers object to replace $VAR_NAME references with resolved values.
69+ *
70+ * @param agent - The agent definition to process
71+ * @throws Error if any referenced environment variable is missing
72+ */
73+ export function resolveAgentMcpEnv ( agent : AgentDefinition ) : void {
74+ if ( ! agent . mcpServers ) return
75+
76+ for ( const [ serverName , config ] of Object . entries ( agent . mcpServers ) ) {
77+ if ( 'command' in config && config . env ) {
78+ config . env = resolveMcpEnv ( config . env , agent . id , serverName )
79+ }
80+ }
81+ }
82+
2583/**
2684 * Validation error for an agent that failed validation.
2785 */
@@ -183,6 +241,18 @@ export async function loadLocalAgents({
183241 agentDefinition . handleSteps . toString ( )
184242 }
185243
244+ // Resolve $env references in MCP server configs
245+ try {
246+ resolveAgentMcpEnv ( processedAgentDefinition )
247+ } catch ( error ) {
248+ if ( verbose ) {
249+ console . error (
250+ error instanceof Error ? error . message : String ( error ) ,
251+ )
252+ }
253+ continue
254+ }
255+
186256 agents [ processedAgentDefinition . id ] = processedAgentDefinition
187257 } catch ( error ) {
188258 if ( verbose ) {
0 commit comments