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
|
|
@ -81,13 +81,9 @@ describe('MCP scanner — broken project', () => {
|
|||
assert.equal(unknown.severity, 'high');
|
||||
});
|
||||
|
||||
it('detects missing trust level', () => {
|
||||
assert.ok(result.findings.some(f => f.title.includes('Missing trust level')));
|
||||
});
|
||||
|
||||
it('missing trust is medium severity', () => {
|
||||
const trust = result.findings.find(f => f.title.includes('Missing trust level'));
|
||||
assert.equal(trust.severity, 'medium');
|
||||
it('does NOT flag any trust level — `trust` is not a real .mcp.json field (CC docs verified 2026-06-18)', () => {
|
||||
assert.ok(!result.findings.some(f => /trust level/i.test(f.title)),
|
||||
'no "Missing trust level"/"Invalid trust level" findings: the field does not exist in the official schema');
|
||||
});
|
||||
|
||||
it('detects unreferenced env vars in args', () => {
|
||||
|
|
@ -103,6 +99,43 @@ describe('MCP scanner — broken project', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('MCP scanner — stray `trust` field is an unknown field (verify-first, 2026-06-18)', () => {
|
||||
let result;
|
||||
let tmpRoot;
|
||||
|
||||
beforeEach(async () => {
|
||||
resetCounter();
|
||||
tmpRoot = await mkdtemp(join(tmpdir(), 'ca-mcp-trust-'));
|
||||
// `trust` is NOT a field in the official .mcp.json schema (verified against
|
||||
// code.claude.com/docs/en/mcp + /settings, 2026-06-18). Approval is
|
||||
// dialog/settings-based (enableAllProjectMcpServers / enabledMcpjsonServers /
|
||||
// disabledMcpjsonServers), never a per-server JSON field.
|
||||
const mcp = {
|
||||
mcpServers: {
|
||||
legacy: { type: 'stdio', command: 'node', args: ['server.mjs'], trust: 'workspace' },
|
||||
},
|
||||
};
|
||||
await writeFile(join(tmpRoot, '.mcp.json'), JSON.stringify(mcp, null, 2) + '\n', 'utf8');
|
||||
const discovery = await discoverConfigFiles(tmpRoot);
|
||||
result = await scan(tmpRoot, discovery);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
if (tmpRoot) await rm(tmpRoot, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it('flags `trust` as an unknown MCP server field', () => {
|
||||
const f = result.findings.find(x => x.title.includes('Unknown MCP server field')
|
||||
&& /trust/.test(x.description || ''));
|
||||
assert.ok(f, 'a `trust` field must now be reported as an unknown field');
|
||||
});
|
||||
|
||||
it('emits no "trust level" findings at all', () => {
|
||||
assert.ok(!result.findings.some(x => /trust level/i.test(x.title)),
|
||||
'the invented trust-level checks must be gone');
|
||||
});
|
||||
});
|
||||
|
||||
describe('MCP scanner — env-var false positives (CC 2.1.139/2.1.142, Batch 1)', () => {
|
||||
let tmpRoot;
|
||||
let envFindings;
|
||||
|
|
@ -118,13 +151,11 @@ describe('MCP scanner — env-var false positives (CC 2.1.139/2.1.142, Batch 1)'
|
|||
// CLAUDE_PROJECT_DIR is auto-injected (CC 2.1.139); ${VAR%…}/${VAR:-…}
|
||||
// are POSIX expansions CC resolves (2.1.142) — none need an env block.
|
||||
args: ['${CLAUDE_PROJECT_DIR}/server.mjs', '--root', '${HOME%/}', '--cfg', '${CONFIG_DIR:-/etc}'],
|
||||
trust: 'workspace',
|
||||
},
|
||||
legacy: {
|
||||
type: 'stdio',
|
||||
command: 'node',
|
||||
args: ['${REAL_MISSING}'],
|
||||
trust: 'workspace',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue