Read CLI-scanned MCP config files as UTF-8 explicitly (#4690)

This commit is contained in:
Jeremiah Lowin 2026-07-28 08:12:17 -04:00 committed by GitHub
commit d6b9daecb1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 37 additions and 3 deletions

View file

@ -120,7 +120,7 @@ def _parse_mcp_servers(
def _parse_mcp_config(path: Path, source: str) -> list[DiscoveredServer]:
"""Parse an mcpServers-style JSON file into discovered servers."""
try:
text = path.read_text()
text = path.read_text(encoding="utf-8")
except OSError as exc:
logger.debug("Could not read %s: %s", path, exc)
return []
@ -158,7 +158,7 @@ def _scan_claude_code(start_dir: Path) -> list[DiscoveredServer]:
"""Scan ``~/.claude.json`` for global and project-scoped MCP servers."""
path = Path.home() / ".claude.json"
try:
text = path.read_text()
text = path.read_text(encoding="utf-8")
except OSError:
return []
@ -269,7 +269,7 @@ def _scan_goose() -> list[DiscoveredServer]:
path = config_dir / "config.yaml"
try:
text = path.read_text()
text = path.read_text(encoding="utf-8")
except OSError:
return []

View file

@ -148,6 +148,40 @@ class TestParseMcpConfig:
assert isinstance(servers[0].config, RemoteMCPServer)
assert servers[0].config.url == "http://localhost:8000/mcp"
def test_reads_as_utf8_explicitly(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
"""Regression test for GH-4689: config files must be read with an
explicit UTF-8 encoding, not the platform's preferred encoding
(e.g. cp949 on Windows with a non-UTF-8 locale), since that's what
every tool that writes these files emits."""
original_read_text = Path.read_text
def _tracking_read_text(self: Path, *args: Any, **kwargs: Any) -> str:
assert kwargs.get("encoding") == "utf-8", (
"path.read_text() must pass encoding='utf-8' explicitly"
)
return original_read_text(self, *args, **kwargs)
monkeypatch.setattr(Path, "read_text", _tracking_read_text)
path = tmp_path / "config.json"
path.write_bytes(
json.dumps(
{
"mcpServers": {
"demo": {
"command": "echo",
"args": ["hello — world"],
}
}
}
).encode("utf-8")
)
servers = _parse_mcp_config(path, "test")
assert len(servers) == 1
assert servers[0].name == "demo"
# ---------------------------------------------------------------------------
# Scanner: Claude Desktop