Skip to content

fix(claude_code): pass --strict-mcp-config so unrelated MCP servers stay out of every role - #75

Open
maaz-codes wants to merge 1 commit into
AMAP-ML:mainfrom
maaz-codes:fix/claude-code-strict-mcp-config
Open

fix(claude_code): pass --strict-mcp-config so unrelated MCP servers stay out of every role#75
maaz-codes wants to merge 1 commit into
AMAP-ML:mainfrom
maaz-codes:fix/claude-code-strict-mcp-config

Conversation

@maaz-codes

Copy link
Copy Markdown

Summary

  • add --strict-mcp-config to the Claude Code command, so a role loads only the servers in an
    explicit --mcp-config and none when there is no config
  • correct the comment at claude_code.py:65, which described the flag as if it were already passed
  • add tests/test_claude_code_adapter.py: every role carries the flag, and an explicit or
    environment-provided --mcp-config stays the only source

Root cause

claude_code.py:65 states that --strict-mcp-config keeps unrelated user/project MCP servers out of
every role, but the flag was never appended to command_parts — it occurred exactly once in the
repository, inside that comment. Without it the claude CLI reads its normal MCP configuration
sources, so every user-scope server on the operator's account and any .mcp.json in the workspace
is loaded into the manager, executor, auditor and final-response episodes. Because the adapter also
passes --dangerously-skip-permissions, a workspace .mcp.json loads with no approval prompt.

policy_for_role denies mcp__* for manager and final_response only; the executor deny-list is
("Agent",) and the auditor deny-list is the write tools plus "Agent". For the roles that act,
those servers' tools were therefore callable.

User impact

Runs that never configured MCP now start no MCP servers at all, which is what the comment always
claimed. Runs that pass --claude-mcp-config / LH_HARNESS_CLAUDECODE_MCP_CONFIG, or that use a
computer-use plugin, are unchanged: that config remains loaded and is now the only source. The
change is behaviour-preserving for the documented configuration paths and closes the undocumented
one.

This is orthogonal to #61, which opts agents out of plugins and skills via --setting-sources project. MCP servers are a separate configuration source; in the verification run below the
plugin/skill surface is unchanged (63 slash commands, 5 sub-agents still visible) while
mcp_servers becomes empty.

Validation

Measured from the system/init event in each role's captured claude_stream.jsonl, same task,
same workspace, one .mcp.json declaring a placeholder leak-probe server, --max-rounds 1 --no-dashboard:

before                                          after
manager        leak-probe, <user-scope server>  manager        []
cli_executor   leak-probe, <user-scope server>  cli_executor   []
cli_auditor    leak-probe, <user-scope server>  cli_auditor    []
final_response leak-probe, <user-scope server>  final_response []

Both runs produced the correct total.txt and the same status / abort_reason
(incomplete / max_rounds_exhausted, from --max-rounds 1).

  • new tests fail on main (9 failed) and pass with this change (9 passed)
  • full Python suite, Python 3.14.6: 414 passed, 1 skipped (405 + 1 before this PR)
  • git diff --check: passed
  • live end-to-end run on claude 2.1.251, macOS 26.3 arm64

Fixes #74.

…tay out of every role

claude_code.py:65 said --strict-mcp-config keeps unrelated user/project MCP
servers out of every role, but the flag was never appended to command_parts;
it occurred exactly once in the repository, inside that comment.

Without it the claude CLI reads its normal MCP configuration sources, so every
user-scope server on the operator's account and any .mcp.json in the workspace
is loaded into the manager, executor, auditor and final-response episodes.
Because the adapter also passes --dangerously-skip-permissions, a workspace
.mcp.json loads with no approval prompt. policy_for_role denies mcp__* for
manager and final_response only, so for the roles that act those tools were
callable.

Add the flag, correct the comment, and add tests/test_claude_code_adapter.py
covering every role and both explicit and environment-provided --mcp-config.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

claude_code roles load the operator's user- and project-scope MCP servers; --strict-mcp-config is only a comment

1 participant