44
55import json
66import os
7+ import re
78
89import click
910from rich .console import Console
@@ -157,7 +158,6 @@ def add(server_name, force=False, alias=None):
157158 install_args = selected_method .get ("args" , install_args )
158159 package_name = selected_method .get ("package" , package_name )
159160 env_vars = selected_method .get ("env" , env_vars )
160- required_args = server_metadata .get ("required_args" , required_args )
161161
162162 console .print (f"\n [green]Using [bold]{ installation_method } [/] installation method[/]" )
163163
@@ -175,7 +175,9 @@ def add(server_name, force=False, alias=None):
175175 # Get all available arguments from the server metadata
176176 all_arguments = server_metadata .get ("arguments" , {})
177177
178- # Process environment variables to store in config
178+ required_args = {}
179+ # Process variables to store in config
180+ processed_variables = {}
179181 processed_env = {}
180182
181183 # First, prompt for all defined arguments even if they're not in env_vars
@@ -196,6 +198,7 @@ def add(server_name, force=False, alias=None):
196198
197199 # Add required indicator
198200 if is_required :
201+ required_args [arg_name ] = arg_info
199202 prompt_text += " (required)"
200203 else :
201204 prompt_text += " (optional, press Enter to skip)"
@@ -216,13 +219,12 @@ def add(server_name, force=False, alias=None):
216219 )
217220 if user_value != env_value :
218221 # User provided a different value
219- processed_env [arg_name ] = user_value
222+ processed_variables [arg_name ] = user_value
220223 else :
221- # User kept the environment value
222- processed_env [arg_name ] = f"${{ { arg_name } }}"
224+ # User use environment value
225+ processed_variables [arg_name ] = env_value
223226 except click .Abort :
224- # Keep environment reference on abort
225- processed_env [arg_name ] = f"${{{ arg_name } }}"
227+ pass
226228 else :
227229 # No environment value
228230 try :
@@ -234,7 +236,7 @@ def add(server_name, force=False, alias=None):
234236 or "key" in arg_name .lower ()
235237 or "secret" in arg_name .lower (),
236238 )
237- processed_env [arg_name ] = user_value
239+ processed_variables [arg_name ] = user_value
238240 else :
239241 # Optional argument can be skipped
240242 user_value = click .prompt (
@@ -247,43 +249,36 @@ def add(server_name, force=False, alias=None):
247249 )
248250 # Only add non-empty values to the environment
249251 if user_value and user_value .strip ():
250- processed_env [arg_name ] = user_value
252+ processed_variables [arg_name ] = user_value
251253 # Explicitly don't add anything if the user leaves it blank
252254 except click .Abort :
253255 if is_required :
254256 console .print (f"[yellow]Warning: Required argument { arg_name } not provided.[/]" )
255- # Store as environment reference even if missing
256- processed_env [arg_name ] = f"${{{ arg_name } }}"
257257
258258 # Resume progress display
259259 progress = Progress (SpinnerColumn (), TextColumn ("[bold green]{task.description}[/]" ), console = console )
260260 progress .start ()
261261 progress .add_task (f"Configuring { server_name } ..." , total = None )
262262
263- # Now process any remaining environment variables from the installation method
263+ # Now process the replacement of environment variables
264264 for key , value in env_vars .items ():
265- # Skip if we already processed this key
266- if key in processed_env :
267- continue
265+ processed_env [key ] = value
268266
269267 if isinstance (value , str ) and value .startswith ("${" ) and value .endswith ("}" ):
270- env_var_name = value [2 :- 1 ] # Extract variable name from ${NAME}
271- is_required = env_var_name in required_args
272-
273268 # For required arguments, prompt the user if not in environment
274- env_value = os .environ .get (env_var_name , "" )
269+ env_value = os .environ .get (key , "" )
275270
276- if not env_value and is_required :
271+ if not env_value and key in required_args and key not in processed_variables :
277272 progress .stop ()
278- console .print (f"[yellow]Warning:[/] Required argument { env_var_name } is not set in environment" )
273+ console .print (f"[yellow]Warning:[/] Required argument { key } is not set in environment" )
279274
280275 # Prompt for the value
281- arg_info = required_args .get (env_var_name , {})
276+ arg_info = required_args .get (key , {})
282277 description = arg_info .get ("description" , "" )
283278 try :
284279 user_value = click .prompt (
285- f"Enter value for { env_var_name } ({ description } )" ,
286- hide_input = "token" in env_var_name .lower () or "key" in env_var_name .lower (),
280+ f"Enter value for { key } ({ description } )" ,
281+ hide_input = "token" in key .lower () or "key" in key .lower (),
287282 )
288283 processed_env [key ] = user_value
289284 except click .Abort :
@@ -298,19 +293,33 @@ def add(server_name, force=False, alias=None):
298293 progress .add_task (f"Configuring { server_name } ..." , total = None )
299294 else :
300295 # Store reference to environment variable
301- processed_env [key ] = value
296+ processed_env [key ] = processed_variables . get ( key , env_value )
302297 else :
303298 processed_env [key ] = value
304299
300+ # replace arguments with values
301+ processed_args = []
302+ for arg in install_args :
303+ matched = re .match (r"\$\{(.*?)\}" , arg )
304+ if matched :
305+ original , key = matched .group (0 ), matched .group (1 )
306+ if key not in processed_variables :
307+ # not required, remove the argument from args
308+ continue
309+ replaced_arg = arg .replace (original , processed_variables .get (key , arg ))
310+ processed_args .append (replaced_arg )
311+ else :
312+ processed_args .append (arg )
313+
305314 # Get actual MCP execution command, args, and env from the selected installation method
306315 # This ensures we use the actual server command information instead of placeholders
307316 if selected_method :
308317 mcp_command = selected_method .get ("command" , install_command )
309- mcp_args = selected_method . get ( "args" , install_args )
318+ mcp_args = processed_args
310319 # Env vars are already processed above
311320 else :
312321 mcp_command = install_command
313- mcp_args = install_args
322+ mcp_args = processed_args
314323
315324 # Create server configuration using ServerConfig
316325 server_config = ServerConfig (
@@ -319,7 +328,7 @@ def add(server_name, force=False, alias=None):
319328 description = description ,
320329 command = mcp_command , # Use the actual MCP server command
321330 args = mcp_args , # Use the actual MCP server arguments
322- env_vars = processed_env ,
331+ env = processed_env ,
323332 # Use the simplified installation method
324333 installation = installation_method ,
325334 )
0 commit comments