@@ -253,13 +253,15 @@ def handle_mcp_list_servers(args: Namespace) -> int:
253253 args: Parsed command-line arguments containing:
254254 - env_manager: HatchEnvironmentManager instance
255255 - env: Optional environment name (uses current if not specified)
256+ - host: Optional host filter
256257
257258 Returns:
258259 int: EXIT_SUCCESS (0) on success, EXIT_ERROR (1) on failure
259260 """
260261 try :
261262 env_manager : HatchEnvironmentManager = args .env_manager
262263 env_name : Optional [str ] = getattr (args , 'env' , None )
264+ host_filter : Optional [str ] = getattr (args , 'host' , None )
263265
264266 env_name = env_name or env_manager .get_current_environment ()
265267
@@ -268,84 +270,65 @@ def handle_mcp_list_servers(args: Namespace) -> int:
268270 return EXIT_ERROR
269271
270272 packages = env_manager .list_packages (env_name )
271- mcp_packages = []
273+
274+ # Collect server data: (server_name, host, is_hatch_managed, env_name, version)
275+ server_rows = []
272276
273277 for package in packages :
274- # Check if package has host configuration tracking (indicating MCP server)
278+ package_name = package ["name" ]
279+ version = package .get ("version" , "-" )
275280 configured_hosts = package .get ("configured_hosts" , {})
281+
276282 if configured_hosts :
277- # Use the tracked server configuration from any host
278- first_host = next (iter (configured_hosts .values ()))
279- server_config_data = first_host .get ("server_config" , {})
280-
281- # Create a simple server config object
282- class SimpleServerConfig :
283- def __init__ (self , data ):
284- self .name = data .get ("name" , package ["name" ])
285- self .command = data .get ("command" , "unknown" )
286- self .args = data .get ("args" , [])
287-
288- server_config = SimpleServerConfig (server_config_data )
289- mcp_packages .append (
290- {"package" : package , "server_config" : server_config }
291- )
283+ for host_name in configured_hosts .keys ():
284+ # Apply host filter if specified
285+ if host_filter and host_name != host_filter :
286+ continue
287+ server_rows .append ((package_name , host_name , True , env_name , version ))
292288 else :
293- # Try the original method as fallback
294- try :
295- server_config = get_package_mcp_server_config (
296- env_manager , env_name , package ["name" ]
297- )
298- mcp_packages .append (
299- {"package" : package , "server_config" : server_config }
300- )
301- except :
302- # Package doesn't have MCP server or method failed
303- continue
289+ # Package not deployed to any host yet
290+ if not host_filter : # Only show if no host filter
291+ server_rows .append ((package_name , "-" , True , env_name , version ))
304292
305- if not mcp_packages :
306- print (f"No MCP servers configured in environment '{ env_name } '" )
293+ if not server_rows :
294+ if host_filter :
295+ print (f"No MCP servers on host '{ host_filter } '" )
296+ else :
297+ print (f"No MCP servers in environment '{ env_name } '" )
307298 return EXIT_SUCCESS
308299
309- print (f"MCP servers in environment '{ env_name } ':" )
310- print (f"{ 'Server Name' :<20} { 'Package' :<20} { 'Version' :<10} { 'Command' } " )
311- print ("-" * 80 )
312-
313- for item in mcp_packages :
314- package = item ["package" ]
315- server_config = item ["server_config" ]
316-
317- server_name = server_config .name
318- package_name = package ["name" ]
319- version = package .get ("version" , "unknown" )
320- command = f"{ server_config .command } { ' ' .join (server_config .args )} "
321-
322- print (f"{ server_name :<20} { package_name :<20} { version :<10} { command } " )
300+ # Display header based on filter
301+ if host_filter :
302+ print (f"MCP servers on { host_filter } :" )
303+ columns = [
304+ ColumnDef (name = "Server Name" , width = 20 ),
305+ ColumnDef (name = "Hatch" , width = 8 ),
306+ ColumnDef (name = "Environment" , width = 15 ),
307+ ColumnDef (name = "Version" , width = 10 ),
308+ ]
309+ else :
310+ print ("MCP servers (all hosts):" )
311+ columns = [
312+ ColumnDef (name = "Server Name" , width = 20 ),
313+ ColumnDef (name = "Host" , width = 18 ),
314+ ColumnDef (name = "Hatch" , width = 8 ),
315+ ColumnDef (name = "Environment" , width = 15 ),
316+ ColumnDef (name = "Version" , width = 10 ),
317+ ]
318+
319+ formatter = TableFormatter (columns )
323320
324- # Display host configuration tracking information
325- configured_hosts = package .get ("configured_hosts" , {})
326- if configured_hosts :
327- print (f"{ '' :>20} Configured on hosts:" )
328- for hostname , host_config in configured_hosts .items ():
329- config_path = host_config .get ("config_path" , "unknown" )
330- last_synced = host_config .get ("last_synced" , "unknown" )
331- # Format the timestamp for better readability
332- if last_synced != "unknown" :
333- try :
334- from datetime import datetime
335-
336- dt = datetime .fromisoformat (
337- last_synced .replace ("Z" , "+00:00" )
338- )
339- last_synced = dt .strftime ("%Y-%m-%d %H:%M:%S" )
340- except :
341- pass # Keep original format if parsing fails
342- print (
343- f"{ '' :>22} - { hostname } : { config_path } (synced: { last_synced } )"
344- )
321+ for server_name , host , is_hatch , env , version in server_rows :
322+ hatch_status = "✅" if is_hatch else "❌"
323+ env_display = env if is_hatch else "-"
324+ version_display = version if is_hatch else "-"
325+
326+ if host_filter :
327+ formatter .add_row ([server_name , hatch_status , env_display , version_display ])
345328 else :
346- print (f"{ '' :>20} No host configurations tracked" )
347- print () # Add blank line between servers
329+ formatter .add_row ([server_name , host , hatch_status , env_display , version_display ])
348330
331+ print (formatter .render ())
349332 return EXIT_SUCCESS
350333 except Exception as e :
351334 print (f"Error listing servers: { e } " )
0 commit comments