11"""Profile share command."""
22
33import asyncio
4+ import logging
45import secrets
56
67import click
1011from mcpm .fastmcp_integration .proxy import create_mcpm_proxy
1112from mcpm .profile .profile_config import ProfileConfigManager
1213from mcpm .utils .config import DEFAULT_SHARE_ADDRESS , DEFAULT_PORT
14+ from mcpm .utils .logging_config import setup_dependency_logging , ensure_dependency_logging_suppressed , get_uvicorn_log_level
1315
1416console = Console ()
1517profile_config_manager = ProfileConfigManager ()
18+ logger = logging .getLogger (__name__ )
1619
1720
1821async def find_available_port (preferred_port , max_attempts = 10 ):
@@ -47,7 +50,8 @@ async def share_profile_fastmcp(profile_servers, profile_name, port, address, ht
4750 config_manager .save_auth_config (api_key )
4851 console .print (f"[green]Generated new API key:[/] [cyan]{ api_key } [/]" )
4952 try :
50- console .print (f"[cyan]Creating FastMCP proxy for profile '{ profile_name } '...[/]" )
53+ server_count = len (profile_servers )
54+ logger .debug (f"Creating FastMCP proxy for profile '{ profile_name } ' with { server_count } server(s)" )
5155
5256 # Create FastMCP proxy for profile servers (HTTP mode - disable auth)
5357 proxy = await create_mcpm_proxy (
@@ -58,30 +62,36 @@ async def share_profile_fastmcp(profile_servers, profile_name, port, address, ht
5862 api_key = api_key ,
5963 )
6064
61- server_count = len (profile_servers )
62- console .print (f"[green]FastMCP proxy created with { server_count } server(s)[/]" )
65+ logger .debug (f"FastMCP proxy created with { server_count } server(s)" )
66+
67+ # Set up dependency logging for FastMCP/MCP libraries
68+ setup_dependency_logging ()
69+
70+ # Re-suppress library logging after FastMCP initialization
71+ ensure_dependency_logging_suppressed ()
6372
6473 # Use default port if none specified, then find available port
6574 preferred_port = port or DEFAULT_PORT
6675 actual_port = await find_available_port (preferred_port )
6776 if actual_port != preferred_port :
68- console . print (f"[yellow] Port { preferred_port } is busy, using port { actual_port } instead[/] " )
77+ logger . debug (f"Port { preferred_port } is busy, using port { actual_port } instead" )
6978
70- console . print (f"[cyan] Starting streamable HTTP server on port { actual_port } ...[/] " )
79+ logger . debug (f"Starting HTTP server on port { actual_port } " )
7180
7281 # Start the FastMCP proxy as a streamable HTTP server in a background task
73- server_task = asyncio .create_task (proxy .run_http_async (host = "127.0.0.1" , port = actual_port ))
82+ server_task = asyncio .create_task (proxy .run_http_async (host = "127.0.0.1" , port = actual_port , uvicorn_config = { "log_level" : get_uvicorn_log_level ()} ))
7483
7584 # Wait a moment for server to start
7685 await asyncio .sleep (2 )
7786
78- console . print (f"[green] FastMCP proxy running on port { actual_port } [/] " )
87+ logger . debug (f"FastMCP proxy running on port { actual_port } " )
7988
8089 # Create tunnel to make it publicly accessible
8190 if not address :
8291 address = DEFAULT_SHARE_ADDRESS
8392
8493 remote_host , remote_port = address .split (":" )
94+ logger .debug (f"Creating tunnel from localhost:{ actual_port } to { remote_host } :{ remote_port } " )
8595
8696 # Generate a random share token
8797 share_token = secrets .token_urlsafe (32 )
@@ -96,26 +106,25 @@ async def share_profile_fastmcp(profile_servers, profile_name, port, address, ht
96106 share_server_tls_certificate = None ,
97107 )
98108
99- console .print ("[cyan]Creating secure tunnel...[/]" )
100109 public_url = tunnel .start_tunnel ()
101110
102111 if public_url :
103- console .print (f"[bold green]Profile '{ profile_name } ' is now publicly accessible![/]" )
104- console .print (f"[cyan]Public URL:[/] { public_url } " )
112+ # Display critical information only
113+ http_url = f"{ public_url } /mcp/"
114+ console .print (f"[bold green]Profile '{ profile_name } ' is now shared at:[/]" )
115+ console .print (f"[cyan]{ http_url } [/]" )
116+
105117 if not no_auth and api_key :
106118 console .print (f"[bold green]API Key:[/] [cyan]{ api_key } [/]" )
107- console .print (f"[dim]Provide this key in the 'Authorization' header as a Bearer token.[/]" )
108119 else :
109120 console .print ("[bold red]Warning:[/] Anyone with the URL can access your servers." )
110- console .print ()
111- console .print ("[bold]Connection URL:[/]" )
112- console .print (f" • HTTP: [cyan]{ public_url } /mcp/[/]" )
113- console .print ()
114- console .print ("[bold]Available servers in this profile:[/]" )
121+
122+ # Show available servers
123+ console .print (f"[bold green]Shared servers:[/]" )
115124 for server_config in profile_servers :
116- console .print (f" • { server_config .name } " )
117- console . print ()
118- console .print ("[dim]Press Ctrl+C to stop sharing... [/]" )
125+ console .print (f" • [cyan] { server_config .name } [/] " )
126+
127+ console .print ("[dim]Press Ctrl+C to stop sharing[/]" )
119128
120129 # Keep running until interrupted
121130 try :
@@ -127,6 +136,7 @@ async def share_profile_fastmcp(profile_servers, profile_name, port, address, ht
127136 tunnel .kill ()
128137 else :
129138 console .print ("[red]Failed to create tunnel[/]" )
139+ logger .error ("Failed to create tunnel" )
130140 server_task .cancel ()
131141 # Wait for cancellation to complete
132142 await asyncio .gather (server_task , return_exceptions = True )
@@ -135,10 +145,11 @@ async def share_profile_fastmcp(profile_servers, profile_name, port, address, ht
135145 return 0
136146
137147 except KeyboardInterrupt :
138- console .print ("\n [yellow]Stopping profile sharing ...[/]" )
148+ console .print ("\n [yellow]Stopping...[/]" )
139149 return 130
140150 except Exception as e :
141- console .print (f"[red]Error sharing profile: { e } [/]" )
151+ console .print (f"[red]Error: { e } [/]" )
152+ logger .exception ("Detailed error information" )
142153 return 1
143154
144155
0 commit comments