11local Error = require (" mcphub.utils.errors" )
22local Job = require (" plenary.job" )
33local State = require (" mcphub.state" )
4+ local config = require (" mcphub.config" )
45local config_manager = require (" mcphub.utils.config_manager" )
56local constants = require (" mcphub.utils.constants" )
67local curl = require (" plenary.curl" )
@@ -63,7 +64,7 @@ function MCPHub:new(opts)
6364end
6465
6566--- Resolve context (workspace vs global) for the current directory
66- --- @return table | nil Context information or nil on error
67+ --- @return MCPHub.JobContext | nil Context information or nil on error
6768function MCPHub :resolve_context ()
6869 if not State .config .workspace .enabled then
6970 return self :_resolve_global_context ()
@@ -73,7 +74,7 @@ function MCPHub:resolve_context()
7374end
7475
7576--- Resolve workspace-specific context
76- --- @return table | nil Workspace context or nil to fall back to global
77+ --- @return MCPHub.JobContext | nil Workspace context or nil to fall back to global
7778function MCPHub :_resolve_workspace_context ()
7879 local workspace_utils = require (" mcphub.utils.workspace" )
7980 local current_dir = vim .fn .getcwd ()
@@ -133,7 +134,7 @@ function MCPHub:_resolve_workspace_context()
133134end
134135
135136--- Resolve global context (original behavior)
136- --- @return table Global context
137+ --- @return MCPHub.JobContext Global context
137138function MCPHub :_resolve_global_context ()
138139 return {
139140 port = self .setup_opts .port ,
@@ -144,11 +145,61 @@ function MCPHub:_resolve_global_context()
144145 }
145146end
146147
148+ --- Resolve global environment variables
149+ --- @param context MCPHub.JobContext Hub context (workspace info , port , etc. )
150+ --- @return table Resolved global environment variables
151+ function MCPHub :_resolve_global_env (context )
152+ local global_env_config = config .global_env
153+ local resolved_global_env = {}
154+
155+ -- Handle function type
156+ if type (global_env_config ) == " function" then
157+ local success , result = pcall (global_env_config , context )
158+ if not success then
159+ vim .notify (" global_env function failed: " .. result , vim .log .levels .WARN )
160+ return {}
161+ end
162+ if type (result ) ~= " table" then
163+ vim .notify (" global_env function must return a table" , vim .log .levels .WARN )
164+ return {}
165+ end
166+ global_env_config = result
167+ elseif type (global_env_config ) ~= " table" then
168+ if global_env_config ~= nil then
169+ vim .notify (" global_env must be table or function" , vim .log .levels .WARN )
170+ end
171+ return {}
172+ end
173+
174+ -- Process mixed array/hash format
175+ for key , value in pairs (global_env_config ) do
176+ if type (key ) == " number" then
177+ -- Array-style entry: just the env var name
178+ if type (value ) == " string" then
179+ local env_value = os.getenv (value )
180+ if env_value then
181+ resolved_global_env [value ] = env_value
182+ end
183+ end
184+ else
185+ -- Hash-style entry: key = value
186+ if type (value ) == " string" then
187+ resolved_global_env [key ] = value
188+ end
189+ end
190+ end
191+
192+ return resolved_global_env
193+ end
194+
147195--- Start server with resolved context
148- --- @param context table Context information from resolve_context
196+ --- @param context MCPHub.JobContext Context information from resolve_context
149197function MCPHub :_start_server_with_context (context )
150198 self .is_owner = true
151199
200+ -- Resolve global environment variables
201+ local resolved_global_env = self :_resolve_global_env (context )
202+
152203 -- Build command args with config files
153204 local args = utils .clean_args ({
154205 self .cmdArgs ,
@@ -170,6 +221,23 @@ function MCPHub:_start_server_with_context(context)
170221 " --watch" ,
171222 })
172223
224+ -- Prepare job environment with global env
225+ local job_env = {}
226+ if next (resolved_global_env ) then
227+ -- Serialize global env for mcp-hub
228+ local success , json_env = pcall (vim .fn .json_encode , resolved_global_env )
229+ if success then
230+ job_env .MCP_HUB_ENV = json_env
231+ log .debug (" Passing global environment variables to mcp-hub: " .. vim .inspect ({
232+ count = vim .tbl_count (resolved_global_env ),
233+ keys = vim .tbl_keys (resolved_global_env ),
234+ }))
235+ else
236+ vim .notify (" Failed to serialize global_env: " .. json_env , vim .log .levels .WARN )
237+ end
238+ end
239+ job_env = vim .tbl_extend (" force" , vim .fn .environ (), job_env or {})
240+
173241 log .debug (" Starting server with context" .. vim .inspect ({
174242 port = context .port ,
175243 cwd = context .cwd ,
@@ -182,6 +250,7 @@ function MCPHub:_start_server_with_context(context)
182250 command = self .cmd ,
183251 args = args ,
184252 cwd = context .cwd , -- Set working directory
253+ env = job_env , -- Pass environment variables
185254 hide = true ,
186255 on_stderr = vim .schedule_wrap (function (_ , data )
187256 if data then
0 commit comments