teach ClaudeCodeOptions.mcp_servers to accept a filepath (#114)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run

`claude`'s `--mcp-config` takes either a JSON file or string, so support
this in `ClaudeCodeOptions`
```
  --mcp-config <file or string>    Load MCP servers from a JSON file or string
```

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: Sam Fu <shunfu@users.noreply.github.com>
This commit is contained in:
Sam Fu 2025-08-06 14:13:59 -07:00 committed by GitHub
parent 9fc830028e
commit f233df1852
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 84 additions and 4 deletions

View file

@ -130,9 +130,17 @@ class SubprocessCLITransport(Transport):
cmd.extend(["--add-dir", str(directory)])
if self._options.mcp_servers:
cmd.extend(
["--mcp-config", json.dumps({"mcpServers": self._options.mcp_servers})]
)
if isinstance(self._options.mcp_servers, dict):
# Dict format: serialize to JSON
cmd.extend(
[
"--mcp-config",
json.dumps({"mcpServers": self._options.mcp_servers}),
]
)
else:
# String or Path format: pass directly as file path or JSON string
cmd.extend(["--mcp-config", str(self._options.mcp_servers)])
# Add extra args for future CLI flags
for flag, value in self._options.extra_args.items():

View file

@ -117,7 +117,7 @@ class ClaudeCodeOptions:
max_thinking_tokens: int = 8000
system_prompt: str | None = None
append_system_prompt: str | None = None
mcp_servers: dict[str, McpServerConfig] = field(default_factory=dict)
mcp_servers: dict[str, McpServerConfig] | str | Path = field(default_factory=dict)
permission_mode: PermissionMode | None = None
continue_conversation: bool = False
resume: str | None = None

View file

@ -227,3 +227,75 @@ class TestSubprocessCLITransport:
boolean_idx = cmd.index("--boolean-flag")
# Either it's the last element or the next element is another flag
assert boolean_idx == len(cmd) - 1 or cmd[boolean_idx + 1].startswith("--")
def test_build_command_with_mcp_servers(self):
"""Test building CLI command with mcp_servers option."""
import json
mcp_servers = {
"test-server": {
"type": "stdio",
"command": "/path/to/server",
"args": ["--option", "value"],
}
}
transport = SubprocessCLITransport(
prompt="test",
options=ClaudeCodeOptions(mcp_servers=mcp_servers),
cli_path="/usr/bin/claude",
)
cmd = transport._build_command()
# Find the --mcp-config flag and its value
assert "--mcp-config" in cmd
mcp_idx = cmd.index("--mcp-config")
mcp_config_value = cmd[mcp_idx + 1]
# Parse the JSON and verify structure
config = json.loads(mcp_config_value)
assert "mcpServers" in config
assert config["mcpServers"] == mcp_servers
def test_build_command_with_mcp_servers_as_file_path(self):
"""Test building CLI command with mcp_servers as file path."""
from pathlib import Path
# Test with string path
transport = SubprocessCLITransport(
prompt="test",
options=ClaudeCodeOptions(mcp_servers="/path/to/mcp-config.json"),
cli_path="/usr/bin/claude",
)
cmd = transport._build_command()
assert "--mcp-config" in cmd
mcp_idx = cmd.index("--mcp-config")
assert cmd[mcp_idx + 1] == "/path/to/mcp-config.json"
# Test with Path object
transport = SubprocessCLITransport(
prompt="test",
options=ClaudeCodeOptions(mcp_servers=Path("/path/to/mcp-config.json")),
cli_path="/usr/bin/claude",
)
cmd = transport._build_command()
assert "--mcp-config" in cmd
mcp_idx = cmd.index("--mcp-config")
assert cmd[mcp_idx + 1] == "/path/to/mcp-config.json"
def test_build_command_with_mcp_servers_as_json_string(self):
"""Test building CLI command with mcp_servers as JSON string."""
json_config = '{"mcpServers": {"server": {"type": "stdio", "command": "test"}}}'
transport = SubprocessCLITransport(
prompt="test",
options=ClaudeCodeOptions(mcp_servers=json_config),
cli_path="/usr/bin/claude",
)
cmd = transport._build_command()
assert "--mcp-config" in cmd
mcp_idx = cmd.index("--mcp-config")
assert cmd[mcp_idx + 1] == json_config