fix(mcp-config-validator): remove invented trust field (verify-first)
`.mcp.json` has no per-server `trust` key — verified 2026-06-18 against code.claude.com/docs/en/mcp + /settings. MCP server approval is dialog/settings-based (enableAllProjectMcpServers / enabledMcpjsonServers / disabledMcpjsonServers), never a JSON field. The scanner's "Missing trust level" (CA-MCP-001, medium) and "Invalid trust level" (high) were false positives flagging a field that does not exist. - scanner: delete both trust checks + VALID_TRUST_LEVELS; drop `trust` from VALID_SERVER_FIELDS so a stray `trust` is now flagged as an unknown field - humanizer: remove the two trust-level entries - knowledge (5 files): point to the real approval mechanism, not a trust field - fixtures: scrub `trust` (incl. the invalid "local" in optimal-setup) - tests: flip assertions (no trust-level finding; stray trust -> unknown field) + add knowledge-staleness re-freeze guards - snapshots: reseed (marketplace-medium .mcp.json -8 tokens, hermetic) - gap-matrix: mark the trust verify-first item DONE Suite: 853/853 green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ter3E2JSi1Khgmuf2kady8
This commit is contained in:
parent
624f5edabc
commit
b3c572ad46
22 changed files with 110 additions and 100 deletions
|
|
@ -273,16 +273,6 @@ export const TRANSLATIONS = {
|
|||
description: 'The `type` field doesn\'t match one Claude Code knows how to start (typically `stdio`, `sse`, or `http`).',
|
||||
recommendation: 'Change the `type` to one of the supported values shown in the details.',
|
||||
},
|
||||
'Invalid trust level': {
|
||||
title: 'A connected service has an unrecognized trust setting',
|
||||
description: 'Trust controls whether Claude can use the service\'s tools without asking.',
|
||||
recommendation: 'Set the trust value to one of the accepted ones (see details).',
|
||||
},
|
||||
'Missing trust level': {
|
||||
title: 'A connected service has no trust setting',
|
||||
description: 'Without an explicit trust value, Claude has to ask before each tool use, which slows your work.',
|
||||
recommendation: 'Add a trust value to the entry. The details show the accepted values.',
|
||||
},
|
||||
'Unknown MCP server field': {
|
||||
title: 'A connected service has an unrecognized setting',
|
||||
description: 'The setting isn\'t one Claude Code reads, so it will be ignored.',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* MCP Scanner — MCP Configuration Validator
|
||||
* Validates .mcp.json files: server types, trust levels, env vars, unknown fields.
|
||||
* Validates .mcp.json files: server types, env vars, unknown fields.
|
||||
* Finding IDs: CA-MCP-NNN
|
||||
*/
|
||||
|
||||
|
|
@ -13,9 +13,11 @@ import { truncate } from './lib/string-utils.mjs';
|
|||
const SCANNER = 'MCP';
|
||||
|
||||
const VALID_SERVER_TYPES = new Set(['stdio', 'http', 'sse']);
|
||||
const VALID_TRUST_LEVELS = new Set(['workspace', 'trusted', 'untrusted']);
|
||||
// No `trust` field: MCP server approval is dialog/settings-based
|
||||
// (enableAllProjectMcpServers / enabledMcpjsonServers / disabledMcpjsonServers),
|
||||
// not a per-server .mcp.json field. Verified against code.claude.com/docs 2026-06-18.
|
||||
const VALID_SERVER_FIELDS = new Set([
|
||||
'type', 'command', 'args', 'env', 'url', 'headers', 'timeout', 'trust',
|
||||
'type', 'command', 'args', 'env', 'url', 'headers', 'timeout',
|
||||
]);
|
||||
|
||||
// Match only bare ${IDENTIFIER} references. POSIX expansions like ${VAR%pattern}
|
||||
|
|
@ -92,28 +94,6 @@ export async function scan(targetPath, discovery) {
|
|||
}));
|
||||
}
|
||||
|
||||
// Check trust level
|
||||
if (!config.trust) {
|
||||
findings.push(finding({
|
||||
scanner: SCANNER,
|
||||
severity: SEVERITY.medium,
|
||||
title: 'Missing trust level',
|
||||
description: `${file.relPath}: Server "${name}" has no trust level configured.`,
|
||||
file: file.absPath,
|
||||
recommendation: 'Add "trust": "workspace"|"trusted"|"untrusted" to explicitly set the trust level.',
|
||||
}));
|
||||
} else if (!VALID_TRUST_LEVELS.has(config.trust)) {
|
||||
findings.push(finding({
|
||||
scanner: SCANNER,
|
||||
severity: SEVERITY.high,
|
||||
title: 'Invalid trust level',
|
||||
description: `${file.relPath}: Server "${name}" has invalid trust level "${config.trust}".`,
|
||||
file: file.absPath,
|
||||
evidence: `trust: "${config.trust}"`,
|
||||
recommendation: 'Use one of: workspace, trusted, untrusted.',
|
||||
}));
|
||||
}
|
||||
|
||||
// Check for env var references in args without env block
|
||||
if (Array.isArray(config.args)) {
|
||||
for (const arg of config.args) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue