Follow-up from #276 (merged as d5833dc), which pinned the three MCP surfaces as OR'd with no precedence but did not decide this asymmetry.
packages/create-agent-harness/src/mcp-scan.ts:77 on main:
!!policy || !!mcpJson || !!(settings && settings.mcpServers && Object.keys(settings.mcpServers).length > 0);
- A top-level
.mcp.json sets mcpEnabled by presence alone — an empty {} or {"mcpServers": {}} counts as MCP enabled, so a harness with a stub file and no servers is scanned as if it exposed MCP (and, with no policy, is flagged HIGH "MCP server with no policy").
.claude/settings.json sets it only when mcpServers is non-empty, so the same empty map there is treated as "MCP absent".
Same input, two verdicts, depending on which file it lives in. __tests__/mcp-scan.test.ts pins neither case ("reports nothing to scan when MCP is absent" uses no files at all).
Ask: pick one rule and pin it with tests for both surfaces — either (a) presence of any surface enables the scan (the conservative reading; then drop the length > 0 guard on settings), or (b) enabled only when some surface declares at least one server (then parse .mcp.json the same way). (a) is the safer default for a security gate: an empty .mcp.json today is usually a placeholder that will grow servers, and false-positive "no policy" is cheaper than a silent miss.
🤖 Generated with RuFlo
https://claude.ai/code/session_019xHM4rAH4aaShb4DTr1n6s
Follow-up from #276 (merged as
d5833dc), which pinned the three MCP surfaces as OR'd with no precedence but did not decide this asymmetry.packages/create-agent-harness/src/mcp-scan.ts:77onmain:.mcp.jsonsetsmcpEnabledby presence alone — an empty{}or{"mcpServers": {}}counts as MCP enabled, so a harness with a stub file and no servers is scanned as if it exposed MCP (and, with no policy, is flagged HIGH "MCP server with no policy")..claude/settings.jsonsets it only whenmcpServersis non-empty, so the same empty map there is treated as "MCP absent".Same input, two verdicts, depending on which file it lives in.
__tests__/mcp-scan.test.tspins neither case ("reports nothing to scan when MCP is absent" uses no files at all).Ask: pick one rule and pin it with tests for both surfaces — either (a) presence of any surface enables the scan (the conservative reading; then drop the
length > 0guard on settings), or (b) enabled only when some surface declares at least one server (then parse.mcp.jsonthe same way). (a) is the safer default for a security gate: an empty.mcp.jsontoday is usually a placeholder that will grow servers, and false-positive "no policy" is cheaper than a silent miss.🤖 Generated with RuFlo
https://claude.ai/code/session_019xHM4rAH4aaShb4DTr1n6s