Conversation
--strict-mcp-config does not control error handling for invalid MCP configs; it restricts the CLI to only use MCP servers passed via mcp_servers/--mcp-config, ignoring filesystem and settings-based MCP configurations (.mcp.json, user/global settings, plugins). Update the docstring to describe the actual behavior.
There was a problem hiding this comment.
Thanks for fixing the docstring — looks good now. (PR description still mentions "raises on invalid MCP server config", but the shipped docstring is correct.)
Extended reasoning...
Overview
Adds a strict_mcp_config: bool = False field to ClaudeAgentOptions, wires it to the --strict-mcp-config CLI flag in _build_command(), and adds a unit test asserting the flag is emitted only when enabled. Three files touched, ~20 lines net.
Security risks
None. The new option is off by default and only appends a static flag string to the subprocess argv — no user-controlled data, no injection surface, no permission/auth changes.
Level of scrutiny
Low. This is a mechanical pass-through following the exact pattern of neighboring boolean options (include_partial_messages, fork_session). Default False means no behavior change for existing callers.
Other factors
I previously flagged that the docstring misdescribed the flag's semantics (validation-strictness vs. config-source isolation). The author addressed this in commit c93d97e — the docstring now correctly states that it restricts MCP server loading to mcp_servers and ignores filesystem configs, matching the CLI help and the TypeScript SDK. The PR description still has the old wording, but that doesn't ship. Test coverage is adequate for the change. No new bugs found this round.
E2E proof — strict_mcp_config isolates to mcp_servers onlyMethod: Created a temp cwd with a Result:
Also verified the bundled CLI advertises the flag: Verdict: ✅ proof.pyimport anyio, sys
sys.path.insert(0, "/tmp/e2e-915/src")
from claude_agent_sdk import query, ClaudeAgentOptions
from claude_agent_sdk.types import SystemMessage
async def run(strict):
opts = ClaudeAgentOptions(
cwd="/tmp/e2e-915-cwd", # contains .mcp.json with a "phantom" server
max_turns=1,
strict_mcp_config=strict,
mcp_servers={},
)
init = None
async for m in query(prompt="hi", options=opts):
if isinstance(m, SystemMessage) and m.subtype == "init":
init = m.data
break
names = [s.get("name") for s in init.get("mcp_servers", [])] if init else []
print(f"strict={strict}: mcp_servers={names}")
return names
async def main():
a = await run(False)
b = await run(True)
print("phantom in strict=False:", "phantom" in a)
print("phantom in strict=True:", "phantom" in b)
anyio.run(main)Output: |
Add
strict_mcp_configtoClaudeAgentOptions, mapped to the CLI's--strict-mcp-configflag.When
True, the CLI only uses MCP servers passed viamcp_servers(--mcp-config), ignoring all other MCP configurations it would otherwise load — project.mcp.json, user/global settings, and plugin-provided servers. Matches the TypeScript SDK'sstrictMcpConfigoption.Useful for SDK callers who want a fully deterministic MCP server set independent of the working directory or local settings.