@@ -41,6 +41,7 @@ def is_process_running(pid):
4141 except Exception :
4242 return False
4343
44+
4445def is_port_listening (host , port ) -> bool :
4546 """
4647 Check if the specified (host, port) is being listened on.
@@ -133,10 +134,18 @@ def start_router(verbose):
133134 return
134135
135136 # get router config
136- config = ConfigManager ().get_router_config ()
137+ config_manager = ConfigManager ()
138+ config = config_manager .get_router_config ()
137139 host = config ["host" ]
138140 port = config ["port" ]
139141
142+ # Check if we have an API key, if not, create one
143+ share_config = config_manager .read_share_config ()
144+ if share_config .get ("api_key" ) is None :
145+ api_key = secrets .token_urlsafe (32 )
146+ config_manager .save_share_config (api_key = api_key )
147+ console .print ("[bold green]Created API key for router authentication[/]" )
148+
140149 # prepare uvicorn command
141150 uvicorn_cmd = [
142151 sys .executable ,
@@ -185,9 +194,29 @@ def start_router(verbose):
185194 pid = process .pid
186195 write_pid_file (pid )
187196
197+ # Display router started information
188198 console .print (f"[bold green]MCPRouter started[/] at http://{ host } :{ port } (PID: { pid } )" )
189199 console .print (f"Log file: { log_file } " )
190- console .print ("Use 'mcpm router off' to stop the router." )
200+
201+ # Display connection instructions
202+ console .print ("\n [bold cyan]Connection Information:[/]" )
203+
204+ # Get API key if available
205+ api_key = config_manager .read_share_config ().get ("api_key" )
206+
207+ # Show URL with or without authentication based on API key availability
208+ if api_key :
209+ # Show authenticated URL
210+ console .print (f"SSE Server URL: [green]http://{ host } :{ port } /sse?s={ api_key } [/]" )
211+ console .print ("\n [bold cyan]To use a specific profile with authentication:[/]" )
212+ console .print (f"[green]http://{ host } :{ port } /sse?s={ api_key } &profile=<profile_name>[/]" )
213+ else :
214+ # Show URL without authentication
215+ console .print (f"SSE Server URL: [green]http://{ host } :{ port } /sse[/]" )
216+ console .print ("\n [bold cyan]To use a specific profile:[/]" )
217+ console .print (f"[green]http://{ host } :{ port } /sse?profile=<profile_name>[/]" )
218+
219+ console .print ("\n [yellow]Use 'mcpm router off' to stop the router.[/]" )
191220
192221 except Exception as e :
193222 console .print (f"[bold red]Error:[/] Failed to start MCPRouter: { e } " )
@@ -197,17 +226,22 @@ def start_router(verbose):
197226@click .option ("-H" , "--host" , type = str , help = "Host to bind the SSE server to" )
198227@click .option ("-p" , "--port" , type = int , help = "Port to bind the SSE server to" )
199228@click .option ("-a" , "--address" , type = str , help = "Remote address to share the router" )
229+ @click .option (
230+ "--auth/--no-auth" , default = True , is_flag = True , help = "Enable/disable API key authentication (default: enabled)"
231+ )
200232@click .help_option ("-h" , "--help" )
201- def set_router_config (host , port , address ):
233+ def set_router_config (host , port , address , auth ):
202234 """Set MCPRouter global configuration.
203235
204236 Example:
205237 mcpm router set -H localhost -p 8888
206238 mcpm router set --host 127.0.0.1 --port 9000
239+ mcpm router set --no-auth # disable authentication
240+ mcpm router set --auth # enable authentication
207241 """
208- if not host and not port and not address :
242+ if not host and not port and not address and auth is None :
209243 console .print (
210- "[yellow]No changes were made. Please specify at least one option (--host, --port, or --address)[/]"
244+ "[yellow]No changes were made. Please specify at least one option (--host, --port, --address, --auth/--no-auth )[/]"
211245 )
212246 return
213247
@@ -220,7 +254,32 @@ def set_router_config(host, port, address):
220254 port = port or current_config ["port" ]
221255 share_address = address or current_config ["share_address" ]
222256
223- # save config
257+ # Handle authentication setting
258+ share_config = config_manager .read_share_config ()
259+ current_api_key = share_config .get ("api_key" )
260+
261+ if auth :
262+ # Enable authentication
263+ if current_api_key is None :
264+ # Generate a new API key if authentication is enabled but no key exists
265+ api_key = secrets .token_urlsafe (32 )
266+ config_manager .save_share_config (
267+ share_url = share_config .get ("url" ), share_pid = share_config .get ("pid" ), api_key = api_key
268+ )
269+ console .print ("[bold green]API key authentication enabled.[/] Generated new API key." )
270+ else :
271+ console .print ("[bold green]API key authentication enabled.[/] Using existing API key." )
272+ else :
273+ # Disable authentication by clearing the API key
274+ if current_api_key is not None :
275+ config_manager .save_share_config (
276+ share_url = share_config .get ("url" ), share_pid = share_config .get ("pid" ), api_key = None
277+ )
278+ console .print ("[bold yellow]API key authentication disabled.[/]" )
279+ else :
280+ console .print ("[bold yellow]API key authentication was already disabled.[/]" )
281+
282+ # save router config
224283 if config_manager .save_router_config (host , port , share_address ):
225284 console .print (
226285 f"[bold green]Router configuration updated:[/] host={ host } , port={ port } , share_address={ share_address } "
0 commit comments