Skip to content

Commit 6e10b6d

Browse files
shunfuclaude[bot]
authored andcommitted
teach ClaudeCodeOptions.mcp_servers to accept a filepath (anthropics#114)
`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> Signed-off-by: Rushil Patel <rpatel@codegen.com>
1 parent 2ed25bf commit 6e10b6d

File tree

3 files changed

+84
-4
lines changed

3 files changed

+84
-4
lines changed

src/claude_code_sdk/_internal/transport/subprocess_cli.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,17 @@ def _build_command(self) -> list[str]:
140140
cmd.extend(["--add-dir", str(directory)])
141141

142142
if self._options.mcp_servers:
143-
cmd.extend(
144-
["--mcp-config", json.dumps({"mcpServers": self._options.mcp_servers})]
145-
)
143+
if isinstance(self._options.mcp_servers, dict):
144+
# Dict format: serialize to JSON
145+
cmd.extend(
146+
[
147+
"--mcp-config",
148+
json.dumps({"mcpServers": self._options.mcp_servers}),
149+
]
150+
)
151+
else:
152+
# String or Path format: pass directly as file path or JSON string
153+
cmd.extend(["--mcp-config", str(self._options.mcp_servers)])
146154

147155
# Add extra args for future CLI flags
148156
for flag, value in self._options.extra_args.items():

src/claude_code_sdk/types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class ClaudeCodeOptions:
117117
max_thinking_tokens: int = 8000
118118
system_prompt: str | None = None
119119
append_system_prompt: str | None = None
120-
mcp_servers: dict[str, McpServerConfig] = field(default_factory=dict)
120+
mcp_servers: dict[str, McpServerConfig] | str | Path = field(default_factory=dict)
121121
permission_mode: PermissionMode | None = None
122122
continue_conversation: bool = False
123123
resume: str | None = None

tests/test_transport.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,75 @@ def test_build_command_with_extra_args(self):
227227
boolean_idx = cmd.index("--boolean-flag")
228228
# Either it's the last element or the next element is another flag
229229
assert boolean_idx == len(cmd) - 1 or cmd[boolean_idx + 1].startswith("--")
230+
231+
def test_build_command_with_mcp_servers(self):
232+
"""Test building CLI command with mcp_servers option."""
233+
import json
234+
235+
mcp_servers = {
236+
"test-server": {
237+
"type": "stdio",
238+
"command": "/path/to/server",
239+
"args": ["--option", "value"],
240+
}
241+
}
242+
243+
transport = SubprocessCLITransport(
244+
prompt="test",
245+
options=ClaudeCodeOptions(mcp_servers=mcp_servers),
246+
cli_path="/usr/bin/claude",
247+
)
248+
249+
cmd = transport._build_command()
250+
251+
# Find the --mcp-config flag and its value
252+
assert "--mcp-config" in cmd
253+
mcp_idx = cmd.index("--mcp-config")
254+
mcp_config_value = cmd[mcp_idx + 1]
255+
256+
# Parse the JSON and verify structure
257+
config = json.loads(mcp_config_value)
258+
assert "mcpServers" in config
259+
assert config["mcpServers"] == mcp_servers
260+
261+
def test_build_command_with_mcp_servers_as_file_path(self):
262+
"""Test building CLI command with mcp_servers as file path."""
263+
from pathlib import Path
264+
265+
# Test with string path
266+
transport = SubprocessCLITransport(
267+
prompt="test",
268+
options=ClaudeCodeOptions(mcp_servers="/path/to/mcp-config.json"),
269+
cli_path="/usr/bin/claude",
270+
)
271+
272+
cmd = transport._build_command()
273+
assert "--mcp-config" in cmd
274+
mcp_idx = cmd.index("--mcp-config")
275+
assert cmd[mcp_idx + 1] == "/path/to/mcp-config.json"
276+
277+
# Test with Path object
278+
transport = SubprocessCLITransport(
279+
prompt="test",
280+
options=ClaudeCodeOptions(mcp_servers=Path("/path/to/mcp-config.json")),
281+
cli_path="/usr/bin/claude",
282+
)
283+
284+
cmd = transport._build_command()
285+
assert "--mcp-config" in cmd
286+
mcp_idx = cmd.index("--mcp-config")
287+
assert cmd[mcp_idx + 1] == "/path/to/mcp-config.json"
288+
289+
def test_build_command_with_mcp_servers_as_json_string(self):
290+
"""Test building CLI command with mcp_servers as JSON string."""
291+
json_config = '{"mcpServers": {"server": {"type": "stdio", "command": "test"}}}'
292+
transport = SubprocessCLITransport(
293+
prompt="test",
294+
options=ClaudeCodeOptions(mcp_servers=json_config),
295+
cli_path="/usr/bin/claude",
296+
)
297+
298+
cmd = transport._build_command()
299+
assert "--mcp-config" in cmd
300+
mcp_idx = cmd.index("--mcp-config")
301+
assert cmd[mcp_idx + 1] == json_config

0 commit comments

Comments
 (0)