diff --git a/fastmcp_slim/fastmcp/cli/discovery.py b/fastmcp_slim/fastmcp/cli/discovery.py index ff3c616ff..fcc6a49d5 100644 --- a/fastmcp_slim/fastmcp/cli/discovery.py +++ b/fastmcp_slim/fastmcp/cli/discovery.py @@ -97,24 +97,33 @@ def _parse_mcp_servers( if not servers_dict: return [] - normalized = { - name: _normalize_server_entry(entry) - for name, entry in servers_dict.items() - if isinstance(entry, dict) - } + discovered: list[DiscoveredServer] = [] + for name, entry in servers_dict.items(): + if not isinstance(entry, dict): + continue - try: - config = MCPConfig.from_dict({"mcpServers": normalized}) - except Exception as exc: - logger.warning("Could not parse MCP servers from %s: %s", config_path, exc) - return [] + normalized = _normalize_server_entry(entry) + try: + config = MCPConfig.from_dict({"mcpServers": {name: normalized}}) + except Exception as exc: + logger.warning( + "Could not parse MCP server %r from %s: %s", + name, + config_path, + exc, + ) + continue - return [ - DiscoveredServer( - name=name, source=source, config=server, config_path=config_path + discovered.append( + DiscoveredServer( + name=name, + source=source, + config=config.mcpServers[name], + config_path=config_path, + ) ) - for name, server in config.mcpServers.items() - ] + + return discovered def _parse_mcp_config(path: Path, source: str) -> list[DiscoveredServer]: diff --git a/tests/cli/test_discovery.py b/tests/cli/test_discovery.py index 102bbf440..6318cc9f7 100644 --- a/tests/cli/test_discovery.py +++ b/tests/cli/test_discovery.py @@ -140,6 +140,30 @@ class TestParseMcpConfig: servers = _parse_mcp_config(path, "test") assert servers == [] + def test_invalid_server_does_not_hide_valid_servers( + self, tmp_path: Path, caplog: pytest.LogCaptureFixture + ): + path = tmp_path / "config.json" + _write_config( + path, + { + "mcpServers": { + "working": { + "command": "python", + "args": ["server.py"], + }, + "broken": { + "args": ["missing-command.py"], + }, + } + }, + ) + + servers = _parse_mcp_config(path, "test") + + assert [server.name for server in servers] == ["working"] + assert "broken" in caplog.text + def test_remote_server(self, tmp_path: Path): path = tmp_path / "config.json" _write_config(path, _REMOTE_CONFIG)