mcp-medic 1.2.10 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +40 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -101,6 +101,9 @@ npx mcp-medic
|
|
|
101
101
|
# Run check on a specific configuration file
|
|
102
102
|
npx mcp-medic check path/to/config.json
|
|
103
103
|
|
|
104
|
+
# Run selected checks only (quality coverage is shown automatically)
|
|
105
|
+
npx mcp-medic check path/to/config.json --only-checks schema.missing-description,quality.prompt
|
|
106
|
+
|
|
104
107
|
# Validate all configs across a monorepo
|
|
105
108
|
npx mcp-medic check-all "configs/**/*.json"
|
|
106
109
|
|
|
@@ -145,6 +148,7 @@ npx mcp-medic watch path/to/config.json
|
|
|
145
148
|
| `--export-json <file>` | Export report in JSON format (always includes `quality`) |
|
|
146
149
|
| `--export-sarif <file>` | Export report in SARIF 2.1.0 format (GitHub Code Scanning, etc.) |
|
|
147
150
|
| `--score` | Include the MCP quality score section in the human report |
|
|
151
|
+
| `--only-checks <id,...>` | Run selected check IDs for `check`, `score`, or `watch`; also displays quality coverage |
|
|
148
152
|
| `--protocol-version <v>` | MCP protocolVersion to request: `auto` (default) or an explicit version |
|
|
149
153
|
| `--show-fixes` | Show suggested fixes inline under diagnostics |
|
|
150
154
|
| `--fail-on <severity>` | Fail with exit code 1 on `error` (default) or `warning` |
|
|
@@ -308,9 +312,7 @@ The `security.*` checks are heuristic — they pattern-match on what a server *d
|
|
|
308
312
|
- **`security.*` checks are heuristic pattern-matching**, not a security audit — see the note above. They can both miss real issues and flag benign configs (e.g. a legitimate local dev server on plain `http://`).
|
|
309
313
|
- **The VS Code extension and community check packages are not shipped/published** — see the sections above.
|
|
310
314
|
- **The Reliability quality dimension is currently binary**: 100 if the server connected, 0 if it didn't (plus any future `reliability.*` diagnostics — none exist yet). Signals like latency trends, retry behavior, or flakiness across repeated runs aren't scored yet.
|
|
311
|
-
- **`resources/list`/`prompts/list` pagination (`nextCursor`) is not followed** — mcp-medic inspects only the first page a server returns, matching the existing (also unpaginated) `tools/list` handling. A server with a very large resource/prompt catalog behind pagination will be under-inspected.
|
|
312
315
|
- **The quality score never calls `resources/read`, `prompts/get`, or any tool** — it's entirely derived from the passive `initialize`/`tools/list`/`resources/list`/`prompts/list` responses already gathered during a normal `check`. See [SECURITY.md](./SECURITY.md) for the full passive-only guarantee.
|
|
313
|
-
- **The CLI cannot currently restrict the check set** (no `--only-checks` flag), so `coverage` is always 100% via `check`/`score`. Partial coverage (and the coverage-aware `minimumScore` warning) only happens when the library API's `runChecks({ checks: [...] })` is called with a restricted list.
|
|
314
316
|
- **No currently-supported MCP protocol version defines a hard tool-name length or character-pattern constraint**, so `src/protocol/quality-rules.ts`'s protocol-vs-quality distinction for tool names is real but currently dormant — every finding today is a quality recommendation, never a protocol violation, because no version actually requires one. The abstraction is there for when a future version does.
|
|
315
317
|
- **npm README sync**: Latest docs live on GitHub main; npm README updates on the next publish.
|
|
316
318
|
- **First run via `npx`** pays a one-time cost to resolve and download the package; once installed (or on a warm npx cache), `--help`/`--version` return in well under 100ms.
|
package/dist/cli.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ export interface ParsedArgs {
|
|
|
23
23
|
showScore: boolean;
|
|
24
24
|
/** "auto" (default) or an explicit MCP protocolVersion string, e.g. "2025-06-18". */
|
|
25
25
|
protocolVersion: string;
|
|
26
|
+
/** IDs selected by `--only-checks` (applies to check, score, and watch). */
|
|
27
|
+
onlyCheckIds?: string[];
|
|
26
28
|
}
|
|
27
29
|
/** Prompts the user with `question` and resolves true for an explicit "y"/"yes" answer. */
|
|
28
30
|
export type ConfirmFn = (question: string) => Promise<boolean>;
|
package/dist/cli.js
CHANGED
|
@@ -46,6 +46,23 @@ export function parseArgs(argv) {
|
|
|
46
46
|
else if (arg === '--score') {
|
|
47
47
|
args.showScore = true;
|
|
48
48
|
}
|
|
49
|
+
else if (arg === '--only-checks') {
|
|
50
|
+
const value = argv[++i];
|
|
51
|
+
if (!value || value.startsWith('-')) {
|
|
52
|
+
throw new Error('--only-checks requires a comma-separated list of check IDs');
|
|
53
|
+
}
|
|
54
|
+
if (args.onlyCheckIds) {
|
|
55
|
+
throw new Error('--only-checks may only be specified once');
|
|
56
|
+
}
|
|
57
|
+
const ids = value.split(',').map((id) => id.trim());
|
|
58
|
+
if (ids.some((id) => id.length === 0)) {
|
|
59
|
+
throw new Error('--only-checks does not allow empty IDs; provide comma-separated check IDs');
|
|
60
|
+
}
|
|
61
|
+
if (new Set(ids).size !== ids.length) {
|
|
62
|
+
throw new Error('--only-checks does not allow duplicate check IDs');
|
|
63
|
+
}
|
|
64
|
+
args.onlyCheckIds = ids;
|
|
65
|
+
}
|
|
49
66
|
else if (arg === '--help' || arg === '-h') {
|
|
50
67
|
args.command = 'help';
|
|
51
68
|
}
|
|
@@ -214,6 +231,7 @@ OPTIONS
|
|
|
214
231
|
--export-json <file> Export report in JSON format
|
|
215
232
|
--export-sarif <file> Export report in SARIF 2.1.0 format (GitHub Code Scanning, etc.)
|
|
216
233
|
--score Include the MCP quality score in the report (implied by the "score" command)
|
|
234
|
+
--only-checks <ids> Run only comma-separated check IDs (check, score, watch)
|
|
217
235
|
--show-fixes Print actionable suggested fixes under diagnostics
|
|
218
236
|
--fail-on <severity> Exit with code 1 on 'error' (default) or 'warning'
|
|
219
237
|
--verbose, -v Print raw JSON-RPC traffic and debug messages
|
|
@@ -279,7 +297,20 @@ function colorizeHumanReport(text) {
|
|
|
279
297
|
.join('\n');
|
|
280
298
|
}
|
|
281
299
|
async function executeCheck(config, args) {
|
|
282
|
-
const [
|
|
300
|
+
const [availableChecks] = await Promise.all([loadChecks(args.policyPath), loadProtocol()]);
|
|
301
|
+
let checks = availableChecks;
|
|
302
|
+
if (args.onlyCheckIds) {
|
|
303
|
+
const availableIds = new Set(availableChecks.map((check) => check.id));
|
|
304
|
+
const unknownIds = args.onlyCheckIds.filter((id) => !availableIds.has(id));
|
|
305
|
+
if (unknownIds.length > 0) {
|
|
306
|
+
console.error(pc.red(`mcp-medic usage error: unknown check ID(s): ${unknownIds.join(', ')}. ` +
|
|
307
|
+
`Available IDs: ${[...availableIds].join(', ')}.` +
|
|
308
|
+
`${args.policyPath ? ' Verify policy check IDs are enabled by the selected policy.' : ''}`));
|
|
309
|
+
return 2;
|
|
310
|
+
}
|
|
311
|
+
// Keep the registry's canonical order regardless of the order in the CLI list.
|
|
312
|
+
checks = availableChecks.filter((check) => args.onlyCheckIds.includes(check.id));
|
|
313
|
+
}
|
|
283
314
|
let report = await runChecks(config, {
|
|
284
315
|
timeoutMs: args.timeoutMs,
|
|
285
316
|
checks,
|
|
@@ -356,7 +387,10 @@ async function executeCheck(config, args) {
|
|
|
356
387
|
console.log(formatReportJSON(report));
|
|
357
388
|
}
|
|
358
389
|
else {
|
|
359
|
-
console.log(colorizeHumanReport(formatReportHuman(report, {
|
|
390
|
+
console.log(colorizeHumanReport(formatReportHuman(report, {
|
|
391
|
+
showFixes: args.showFixes,
|
|
392
|
+
showScore: args.showScore || Boolean(args.onlyCheckIds),
|
|
393
|
+
})));
|
|
360
394
|
}
|
|
361
395
|
const hasErrors = report.summary.errors > 0;
|
|
362
396
|
const hasWarnings = report.summary.warnings > 0;
|
|
@@ -524,6 +558,10 @@ export async function main(argv = process.argv.slice(2), deps = {}) {
|
|
|
524
558
|
console.log(getPackageVersion());
|
|
525
559
|
return 0;
|
|
526
560
|
}
|
|
561
|
+
if (args.onlyCheckIds && !['check', 'score', 'watch'].includes(args.command)) {
|
|
562
|
+
console.error(pc.red('--only-checks is supported only by the check, score, and watch commands.'));
|
|
563
|
+
return 2;
|
|
564
|
+
}
|
|
527
565
|
if (args.command === 'fix' && args.registryServer) {
|
|
528
566
|
console.error(pc.red('mcp-doctor fix does not support --registry — there is no local file to write the fix to.'));
|
|
529
567
|
return 2;
|