@@ -254,7 +254,7 @@ def test_sync_handler_uses_result_reporter(self):
254254 from_host = "claude-desktop" ,
255255 to_host = "cursor" ,
256256 servers = None ,
257- pattern = None ,
257+
258258 dry_run = False ,
259259 auto_approve = True ,
260260 no_backup = True ,
@@ -461,7 +461,7 @@ def test_list_servers_reads_from_host_config(self):
461461 args = Namespace (
462462 env_manager = mock_env_manager ,
463463 host = "claude-desktop" ,
464- pattern = None ,
464+
465465 json = False ,
466466 )
467467
@@ -510,7 +510,7 @@ def test_list_servers_shows_third_party_servers(self):
510510 Risk: Missing 3rd party servers in output
511511 """
512512 from hatch .cli .cli_mcp import handle_mcp_list_servers
513- from hatch .mcp_host_config import MCPServerConfig
513+ from hatch .mcp_host_config import MCPHostType , MCPServerConfig
514514 from hatch .mcp_host_config .models import HostConfiguration
515515
516516 # Create mock env_manager with NO packages (empty environment)
@@ -520,8 +520,7 @@ def test_list_servers_shows_third_party_servers(self):
520520
521521 args = Namespace (
522522 env_manager = mock_env_manager ,
523- host = "claude-desktop" ,
524- pattern = None ,
523+ host = None , # No filter - show all hosts
525524 json = False ,
526525 )
527526
@@ -531,6 +530,7 @@ def test_list_servers_shows_third_party_servers(self):
531530 })
532531
533532 with patch ('hatch.cli.cli_mcp.MCPHostRegistry' ) as mock_registry :
533+ mock_registry .detect_available_hosts .return_value = [MCPHostType .CLAUDE_DESKTOP ]
534534 mock_strategy = MagicMock ()
535535 mock_strategy .read_configuration .return_value = mock_host_config
536536 mock_strategy .get_config_path .return_value = MagicMock (exists = lambda : True )
@@ -565,7 +565,7 @@ def test_list_servers_without_host_shows_all_hosts(self):
565565 args = Namespace (
566566 env_manager = mock_env_manager ,
567567 host = None , # No host filter - show ALL hosts
568- pattern = None ,
568+
569569 json = False ,
570570 )
571571
@@ -613,13 +613,13 @@ def get_strategy_side_effect(host_type):
613613 assert "claude-desktop" in output or "Host" in output , \
614614 "Host column should be present when showing all hosts"
615615
616- def test_list_servers_pattern_filter (self ):
617- """--pattern flag should filter servers by regex on server name .
616+ def test_list_servers_host_filter_pattern (self ):
617+ """--host flag should filter by host name using regex pattern .
618618
619- Reference: R02 §2.5 - "--pattern filters by server name ( regex) "
619+ Reference: R10 §3.2 - "--host accepts regex patterns "
620620 """
621621 from hatch .cli .cli_mcp import handle_mcp_list_servers
622- from hatch .mcp_host_config import MCPServerConfig
622+ from hatch .mcp_host_config import MCPHostType , MCPServerConfig
623623 from hatch .mcp_host_config .models import HostConfiguration
624624
625625 mock_env_manager = MagicMock ()
@@ -628,22 +628,35 @@ def test_list_servers_pattern_filter(self):
628628
629629 args = Namespace (
630630 env_manager = mock_env_manager ,
631- host = "claude-desktop" ,
632- pattern = "weather.*" , # Regex pattern
631+ host = "claude.*" , # Regex pattern
633632 json = False ,
634633 )
635634
636- mock_host_config = HostConfiguration (servers = {
635+ claude_config = HostConfiguration (servers = {
637636 "weather-server" : MCPServerConfig (name = "weather-server" , command = "python" , args = []),
638- "weather-api" : MCPServerConfig (name = "weather-api" , command = "python" , args = []),
639- "fetch-server" : MCPServerConfig (name = "fetch-server" , command = "node" , args = []), # Should NOT match
637+ })
638+ cursor_config = HostConfiguration (servers = {
639+ "fetch-server" : MCPServerConfig (name = "fetch-server" , command = "node" , args = []),
640640 })
641641
642642 with patch ('hatch.cli.cli_mcp.MCPHostRegistry' ) as mock_registry :
643- mock_strategy = MagicMock ()
644- mock_strategy .read_configuration .return_value = mock_host_config
645- mock_strategy .get_config_path .return_value = MagicMock (exists = lambda : True )
646- mock_registry .get_strategy .return_value = mock_strategy
643+ mock_registry .detect_available_hosts .return_value = [
644+ MCPHostType .CLAUDE_DESKTOP ,
645+ MCPHostType .CURSOR ,
646+ ]
647+
648+ def get_strategy_side_effect (host_type ):
649+ mock_strategy = MagicMock ()
650+ mock_strategy .get_config_path .return_value = MagicMock (exists = lambda : True )
651+ if host_type == MCPHostType .CLAUDE_DESKTOP :
652+ mock_strategy .read_configuration .return_value = claude_config
653+ elif host_type == MCPHostType .CURSOR :
654+ mock_strategy .read_configuration .return_value = cursor_config
655+ else :
656+ mock_strategy .read_configuration .return_value = HostConfiguration (servers = {})
657+ return mock_strategy
658+
659+ mock_registry .get_strategy .side_effect = get_strategy_side_effect
647660
648661 with patch ('hatch.mcp_host_config.strategies' ):
649662 captured_output = io .StringIO ()
@@ -652,21 +665,20 @@ def test_list_servers_pattern_filter(self):
652665
653666 output = captured_output .getvalue ()
654667
655- # Matching servers should appear
656- assert "weather-server" in output , "weather-server should match pattern"
657- assert "weather-api" in output , "weather-api should match pattern"
668+ # Server from claude-desktop should appear (matches pattern)
669+ assert "weather-server" in output , "weather-server should appear (host matches pattern)"
658670
659- # Non-matching server should NOT appear
671+ # Server from cursor should NOT appear (doesn't match pattern)
660672 assert "fetch-server" not in output , \
661- "fetch-server should NOT appear (doesn't match pattern )"
673+ "fetch-server should NOT appear (cursor doesn't match 'claude.*' )"
662674
663675 def test_list_servers_json_output_host_centric (self ):
664676 """JSON output should include host-centric data structure.
665677
666- Reference: R02 §8.1 - JSON output format for mcp list servers
678+ Reference: R10 §3.2 - JSON output format for mcp list servers
667679 """
668680 from hatch .cli .cli_mcp import handle_mcp_list_servers
669- from hatch .mcp_host_config import MCPServerConfig
681+ from hatch .mcp_host_config import MCPHostType , MCPServerConfig
670682 from hatch .mcp_host_config .models import HostConfiguration
671683 import json
672684
@@ -684,8 +696,7 @@ def test_list_servers_json_output_host_centric(self):
684696
685697 args = Namespace (
686698 env_manager = mock_env_manager ,
687- host = "claude-desktop" ,
688- pattern = None ,
699+ host = None , # No filter - show all hosts
689700 json = True , # JSON output
690701 )
691702
@@ -695,6 +706,7 @@ def test_list_servers_json_output_host_centric(self):
695706 })
696707
697708 with patch ('hatch.cli.cli_mcp.MCPHostRegistry' ) as mock_registry :
709+ mock_registry .detect_available_hosts .return_value = [MCPHostType .CLAUDE_DESKTOP ]
698710 mock_strategy = MagicMock ()
699711 mock_strategy .read_configuration .return_value = mock_host_config
700712 mock_strategy .get_config_path .return_value = MagicMock (exists = lambda : True )
@@ -710,22 +722,23 @@ def test_list_servers_json_output_host_centric(self):
710722 # Parse JSON output
711723 data = json .loads (output )
712724
713- # Verify structure
714- assert "host" in data , "JSON should include host field"
715- assert "servers" in data , "JSON should include servers array"
716- assert data ["host" ] == "claude-desktop"
725+ # Verify structure per R10 §8
726+ assert "rows" in data , "JSON should include rows array"
717727
718- # Verify both servers present with hatch_managed field
719- server_names = [s ["name " ] for s in data ["servers " ]]
728+ # Verify both servers present with correct fields
729+ server_names = [s ["server " ] for s in data ["rows " ]]
720730 assert "managed-server" in server_names
721731 assert "unmanaged-server" in server_names
722732
723- # Verify hatch_managed status
724- for server in data ["servers" ]:
725- if server ["name" ] == "managed-server" :
726- assert server ["hatch_managed" ] == True
727- elif server ["name" ] == "unmanaged-server" :
728- assert server ["hatch_managed" ] == False
733+ # Verify hatch_managed status and host field
734+ for row in data ["rows" ]:
735+ assert "host" in row , "Each row should have host field"
736+ assert "hatch_managed" in row , "Each row should have hatch_managed field"
737+ if row ["server" ] == "managed-server" :
738+ assert row ["hatch_managed" ] == True
739+ assert row ["environment" ] == "default"
740+ elif row ["server" ] == "unmanaged-server" :
741+ assert row ["hatch_managed" ] == False
729742
730743
731744class TestMCPListHostsHostCentric :
0 commit comments