mcp-lint 0.9.0 → 1.0.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 +31 -12
- package/dist/audit/baseline.d.ts +3 -0
- package/dist/audit/baseline.js +18 -0
- package/dist/audit/baseline.js.map +1 -0
- package/dist/audit/index.d.ts +1 -0
- package/dist/audit/index.js +1 -0
- package/dist/audit/index.js.map +1 -1
- package/dist/catalog/connect.d.ts +3 -0
- package/dist/catalog/connect.js +54 -0
- package/dist/catalog/connect.js.map +1 -0
- package/dist/catalog/list.d.ts +39 -0
- package/dist/catalog/list.js +58 -0
- package/dist/catalog/list.js.map +1 -0
- package/dist/cli/commands/catalog.d.ts +2 -0
- package/dist/cli/commands/catalog.js +76 -0
- package/dist/cli/commands/catalog.js.map +1 -0
- package/dist/cli/commands/recover.js +22 -8
- package/dist/cli/commands/recover.js.map +1 -1
- package/dist/cli/commands/report.js +19 -1
- package/dist/cli/commands/report.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/recover/index.d.ts +1 -1
- package/dist/recover/index.js +1 -1
- package/dist/recover/index.js.map +1 -1
- package/dist/recover/probe.d.ts +10 -10
- package/dist/recover/probe.js +20 -0
- package/dist/recover/probe.js.map +1 -1
- package/dist/recover/score.d.ts +2 -1
- package/dist/recover/score.js +14 -0
- package/dist/recover/score.js.map +1 -1
- package/dist/recover/types.d.ts +4 -0
- package/dist/recover/types.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/examples/github-action.yml +2 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ Proof page, with a live bench: [mcp-lint-alpha.vercel.app](https://mcp-lint-alph
|
|
|
13
13
|
|
|
14
14
|
MCP servers expose tool schemas consumed by **Claude**, **Cursor**, **Gemini**, **VS Code Copilot**, **Windsurf**, **Cline**, **OpenAI Agents SDK**, and **Continue.dev**. Each client has different JSON Schema support and quirks — a schema that works in Claude may silently break in Cursor or OpenAI. `mcp-lint` catches these issues before your users do.
|
|
15
15
|
|
|
16
|
-
This repository is **0.
|
|
16
|
+
This repository is **1.0.0**. npm `latest` is 1.0.0. Design notes: [PRODUCT.md](PRODUCT.md), [ROADMAP.md](ROADMAP.md), [ARCHITECTURE.md](ARCHITECTURE.md), [SECURITY.md](SECURITY.md), [RELEASE.md](RELEASE.md). Those files describe the current code. They are not extra commands.
|
|
17
17
|
|
|
18
18
|
```
|
|
19
19
|
$ npx mcp-lint check tools.json
|
|
@@ -197,7 +197,25 @@ mcp-lint report tools.json --format html --output report.html
|
|
|
197
197
|
mcp-lint report tools.json --format markdown
|
|
198
198
|
```
|
|
199
199
|
|
|
200
|
-
Formats are `terminal`, `json`, `markdown`, `sarif`, and `html`. The HTML file has inline CSS and no script. Token totals are a local `chars / 4` estimate. Recovery, preflight, and live inspection stay marked as not run.
|
|
200
|
+
Formats are `terminal`, `json`, `markdown`, `sarif`, and `html`. The HTML file has inline CSS and no script. Token totals are a local `chars / 4` estimate. Recovery, preflight, and live inspection stay marked as not run. When the run has no schema errors, the report says: "No schema errors in this run. Recovery, preflight, and live inspection were not measured."
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
mcp-lint report tools.json --baseline audit.baseline.json
|
|
204
|
+
mcp-lint report tools.json --update-baseline audit.baseline.json
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
`--baseline` exits 1 when the stable snapshot differs. The snapshot pins `generatedAt` and keeps `tool.version`. Pass either `--baseline` or `--update-baseline`, not both. Exit `1` when the report contains an error, or when the file cannot be read.
|
|
208
|
+
|
|
209
|
+
### `mcp-lint catalog`
|
|
210
|
+
|
|
211
|
+
Lists resources and prompts from one live server. It does not read installed configs and it does not call a tool.
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
mcp-lint catalog --server stdio -- node server.js
|
|
215
|
+
mcp-lint catalog --server http --url https://example.com/mcp --format json
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
`--server` is `stdio`, `sse`, or `http`. Remote transports need `--url`. `--timeout`, `--max-items`, and `--max-bytes` bound each list. A method the server does not implement is `unsupported` and exits 0. Any other list failure exits 1. Usage errors exit 2. `--format` is `terminal` or `json`.
|
|
201
219
|
|
|
202
220
|
---
|
|
203
221
|
|
|
@@ -410,8 +428,8 @@ jobs:
|
|
|
410
428
|
runs-on: ubuntu-latest
|
|
411
429
|
steps:
|
|
412
430
|
- uses: actions/checkout@v4
|
|
413
|
-
- uses: robert19001-cmyk/mcp-lint@
|
|
414
|
-
# Tag
|
|
431
|
+
- uses: robert19001-cmyk/mcp-lint@v1.0.0
|
|
432
|
+
# Tag v1.0.0. The action installs npm latest.
|
|
415
433
|
with:
|
|
416
434
|
input: tools.json
|
|
417
435
|
severity: warning
|
|
@@ -431,7 +449,7 @@ jobs:
|
|
|
431
449
|
| `score` | `false` | Show quality score |
|
|
432
450
|
| `sarif` | `false` | Upload SARIF when this `mcp-lint` release includes `report`. The workflow needs `security-events: write`. |
|
|
433
451
|
|
|
434
|
-
The action in this repository writes a `::error`, `::warning`, or `::notice` annotation from `check --format json`. With an empty `input` it also looks one directory down, skipping `node_modules` and dot directories. `sarif: true` uploads SARIF when the installed CLI has `report`. The action installs npm `latest
|
|
452
|
+
The action in this repository writes a `::error`, `::warning`, or `::notice` annotation from `check --format json`. With an empty `input` it also looks one directory down, skipping `node_modules` and dot directories. `sarif: true` uploads SARIF when the installed CLI has `report`. The action installs npm `latest`, which is 1.0.0. The workflow needs `security-events: write`.
|
|
435
453
|
|
|
436
454
|
### Manual workflow
|
|
437
455
|
|
|
@@ -652,23 +670,24 @@ $ mcp-lint recover examples/recover/bad-credential.json
|
|
|
652
670
|
|
|
653
671
|
search#1
|
|
654
672
|
✖ Credential or permission error does not name a tool on this server. Say which tool to call, for example `login`, then retry.
|
|
655
|
-
[recover/names-tool]
|
|
673
|
+
[recover/names-tool] permanent
|
|
656
674
|
✖ Next step asks for a terminal command, which an agent limited to MCP tools cannot do. Name a tool from this server instead.
|
|
657
|
-
[recover/agent-reachable]
|
|
675
|
+
[recover/agent-reachable] permanent
|
|
658
676
|
|
|
659
677
|
search#2
|
|
660
678
|
✖ Retry text does not name the call to repeat. Name `search` instead of "wait and retry".
|
|
661
|
-
[recover/names-retry]
|
|
679
|
+
[recover/names-retry] transient
|
|
662
680
|
|
|
663
|
-
3 errors, 1 recoverable of 3
|
|
681
|
+
3 errors, 1 recoverable of 3, 1 transient, 2 permanent
|
|
664
682
|
```
|
|
665
683
|
|
|
666
|
-
Exit `1` when any sample has an error. Exit `0` when every failure is recoverable.
|
|
684
|
+
`rate_limit` and `timeout` count as transient. Every other kind counts as permanent. Exit `1` when any sample has an error. Exit `0` when every scored failure is recoverable.
|
|
667
685
|
|
|
668
|
-
|
|
686
|
+
A live probe lists tools and does not call them. Calling tools requires both `--sandbox` and `--invoke`. Tools with no required arguments are still skipped, so an empty call cannot fire a tool that declares no inputs.
|
|
669
687
|
|
|
670
688
|
```bash
|
|
671
689
|
mcp-lint recover --server stdio -- node server.js
|
|
690
|
+
mcp-lint recover --server stdio --sandbox --invoke -- node server.js
|
|
672
691
|
mcp-lint recover errors.json --hang-ms 8000 --format json
|
|
673
692
|
```
|
|
674
693
|
|
|
@@ -747,7 +766,7 @@ The repository includes `glama.json` and a production Dockerfile so MCP director
|
|
|
747
766
|
|
|
748
767
|
## Site
|
|
749
768
|
|
|
750
|
-
The proof page is in `site/`. Version 0.
|
|
769
|
+
The proof page is in `site/`. Version 1.0.0. It runs the same recovery scorer, schema linter, and preflight function as the CLI.
|
|
751
770
|
|
|
752
771
|
```bash
|
|
753
772
|
npm run site
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const STABLE_TIME = '1970-01-01T00:00:00.000Z';
|
|
2
|
+
export function projectAuditReport(report) {
|
|
3
|
+
return JSON.stringify({ ...report, generatedAt: STABLE_TIME }, null, 2) + '\n';
|
|
4
|
+
}
|
|
5
|
+
export function auditBaselineDiff(actual, expected) {
|
|
6
|
+
if (actual === expected)
|
|
7
|
+
return null;
|
|
8
|
+
const actualLines = actual.split('\n');
|
|
9
|
+
const expectedLines = expected.split('\n');
|
|
10
|
+
const limit = Math.max(actualLines.length, expectedLines.length);
|
|
11
|
+
for (let index = 0; index < limit; index += 1) {
|
|
12
|
+
if (actualLines[index] !== expectedLines[index]) {
|
|
13
|
+
return `Audit baseline differs at line ${index + 1}. Pass --update-baseline to replace the snapshot.`;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return 'Audit baseline differs. Pass --update-baseline to replace the snapshot.';
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=baseline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../../src/audit/baseline.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG,0BAA0B,CAAC;AAE/C,MAAM,UAAU,kBAAkB,CAAC,MAAsB;IACvD,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,QAAgB;IAChE,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACjE,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC9C,IAAI,WAAW,CAAC,KAAK,CAAC,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YAChD,OAAO,kCAAkC,KAAK,GAAG,CAAC,mDAAmD,CAAC;QACxG,CAAC;IACH,CAAC;IACD,OAAO,yEAAyE,CAAC;AACnF,CAAC"}
|
package/dist/audit/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { AUDIT_REPORT_SCHEMA_VERSION, QUALITY_ALGORITHM, AuditInputError, AuditReportSchema, buildAuditReport, parseAuditReport, } from './report.js';
|
|
2
2
|
export type { AuditFinding, AuditTool, BuildAuditReportInput, MCPAuditReport, QualitySectionData, Section, SectionStatus, SeverityCounts, } from './report.js';
|
|
3
3
|
export { AUDIT_FORMATS, escapeHtml, formatAuditReport } from './format.js';
|
|
4
|
+
export { auditBaselineDiff, projectAuditReport } from './baseline.js';
|
|
4
5
|
export type { AuditFormat } from './format.js';
|
|
5
6
|
export { DEFAULT_TOKEN_THRESHOLDS, TOKEN_ESTIMATE_METHOD, TokenEstimateError, assertThresholds, buildTokenBudget, compareTokenBudgets, estimateTokens, } from './tokens.js';
|
|
6
7
|
export type { RepeatedDescription, TokenBudget, TokenBudgetDiff, TokenEstimate, TokenThresholds, ToolTokenRank, } from './tokens.js';
|
package/dist/audit/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { AUDIT_REPORT_SCHEMA_VERSION, QUALITY_ALGORITHM, AuditInputError, AuditReportSchema, buildAuditReport, parseAuditReport, } from './report.js';
|
|
2
2
|
export { AUDIT_FORMATS, escapeHtml, formatAuditReport } from './format.js';
|
|
3
|
+
export { auditBaselineDiff, projectAuditReport } from './baseline.js';
|
|
3
4
|
export { DEFAULT_TOKEN_THRESHOLDS, TOKEN_ESTIMATE_METHOD, TokenEstimateError, assertThresholds, buildTokenBudget, compareTokenBudgets, estimateTokens, } from './tokens.js';
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/dist/audit/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/audit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAWrB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/audit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAWrB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,GACf,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type CatalogLimits, type CatalogReport } from './list.js';
|
|
2
|
+
export declare function catalogStdio(command: string, args: string[], limits?: CatalogLimits): Promise<CatalogReport>;
|
|
3
|
+
export declare function catalogRemote(url: string, remoteType: 'sse' | 'http', limits?: CatalogLimits): Promise<CatalogReport>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
3
|
+
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
4
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
5
|
+
import { listCatalog } from './list.js';
|
|
6
|
+
import { VERSION } from '../version.js';
|
|
7
|
+
export async function catalogStdio(command, args, limits = {}) {
|
|
8
|
+
const transport = new StdioClientTransport({ command, args, stderr: 'pipe' });
|
|
9
|
+
drain(transport.stderr);
|
|
10
|
+
return connect(transport, () => transport.close(), limits);
|
|
11
|
+
}
|
|
12
|
+
export async function catalogRemote(url, remoteType, limits = {}) {
|
|
13
|
+
const target = new URL(url);
|
|
14
|
+
const transport = remoteType === 'sse'
|
|
15
|
+
? new SSEClientTransport(target)
|
|
16
|
+
: new StreamableHTTPClientTransport(target);
|
|
17
|
+
return connect(transport, () => transport.close(), limits);
|
|
18
|
+
}
|
|
19
|
+
async function connect(transport, cancel, limits) {
|
|
20
|
+
const client = new Client({ name: 'mcp-lint', version: VERSION }, { capabilities: {} });
|
|
21
|
+
const timeoutMs = limits.timeoutMs;
|
|
22
|
+
let timer;
|
|
23
|
+
try {
|
|
24
|
+
const run = async () => {
|
|
25
|
+
await client.connect(transport);
|
|
26
|
+
const source = {
|
|
27
|
+
listResources: () => client.listResources(),
|
|
28
|
+
listPrompts: () => client.listPrompts(),
|
|
29
|
+
};
|
|
30
|
+
return listCatalog(source, limits);
|
|
31
|
+
};
|
|
32
|
+
if (!timeoutMs || timeoutMs < 1)
|
|
33
|
+
return await run();
|
|
34
|
+
return await Promise.race([
|
|
35
|
+
run(),
|
|
36
|
+
new Promise((_, reject) => {
|
|
37
|
+
timer = setTimeout(() => {
|
|
38
|
+
void cancel();
|
|
39
|
+
reject(new Error(`Timed out after ${timeoutMs}ms waiting for catalog`));
|
|
40
|
+
}, timeoutMs);
|
|
41
|
+
}),
|
|
42
|
+
]);
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
if (timer)
|
|
46
|
+
clearTimeout(timer);
|
|
47
|
+
await client.close().catch(() => { });
|
|
48
|
+
await cancel().catch(() => { });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function drain(stream) {
|
|
52
|
+
stream?.on('data', () => { });
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/catalog/connect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const DEFAULT_CATALOG_TIMEOUT_MS = 10000;
|
|
2
|
+
export declare const DEFAULT_CATALOG_MAX_ITEMS = 100;
|
|
3
|
+
export declare const DEFAULT_CATALOG_MAX_BYTES = 262144;
|
|
4
|
+
export interface CatalogResource {
|
|
5
|
+
uri: string;
|
|
6
|
+
name: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
mimeType?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface CatalogPrompt {
|
|
11
|
+
name: string;
|
|
12
|
+
title?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface CatalogSource {
|
|
16
|
+
listResources(): Promise<{
|
|
17
|
+
resources: CatalogResource[];
|
|
18
|
+
}>;
|
|
19
|
+
listPrompts(): Promise<{
|
|
20
|
+
prompts: CatalogPrompt[];
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
23
|
+
export interface CatalogLimits {
|
|
24
|
+
timeoutMs?: number;
|
|
25
|
+
maxItems?: number;
|
|
26
|
+
maxBytes?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface CatalogSection<T> {
|
|
29
|
+
status: 'ran' | 'unsupported' | 'failed';
|
|
30
|
+
items: T[];
|
|
31
|
+
truncated: boolean;
|
|
32
|
+
reason?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface CatalogReport {
|
|
35
|
+
resources: CatalogSection<CatalogResource>;
|
|
36
|
+
prompts: CatalogSection<CatalogPrompt>;
|
|
37
|
+
toolsInvoked: false;
|
|
38
|
+
}
|
|
39
|
+
export declare function listCatalog(source: CatalogSource, limits?: CatalogLimits): Promise<CatalogReport>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const DEFAULT_CATALOG_TIMEOUT_MS = 10_000;
|
|
2
|
+
export const DEFAULT_CATALOG_MAX_ITEMS = 100;
|
|
3
|
+
export const DEFAULT_CATALOG_MAX_BYTES = 262_144;
|
|
4
|
+
export async function listCatalog(source, limits = {}) {
|
|
5
|
+
const timeoutMs = limits.timeoutMs ?? DEFAULT_CATALOG_TIMEOUT_MS;
|
|
6
|
+
const maxItems = limits.maxItems ?? DEFAULT_CATALOG_MAX_ITEMS;
|
|
7
|
+
const maxBytes = limits.maxBytes ?? DEFAULT_CATALOG_MAX_BYTES;
|
|
8
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs < 1)
|
|
9
|
+
throw new Error('timeout must be a positive integer');
|
|
10
|
+
if (!Number.isInteger(maxItems) || maxItems < 1)
|
|
11
|
+
throw new Error('max items must be a positive integer');
|
|
12
|
+
if (!Number.isInteger(maxBytes) || maxBytes < 1)
|
|
13
|
+
throw new Error('max bytes must be a positive integer');
|
|
14
|
+
const [resources, prompts] = await Promise.all([
|
|
15
|
+
readSection('resources', () => source.listResources().then((result) => result.resources ?? []), timeoutMs, maxItems, maxBytes),
|
|
16
|
+
readSection('prompts', () => source.listPrompts().then((result) => result.prompts ?? []), timeoutMs, maxItems, maxBytes),
|
|
17
|
+
]);
|
|
18
|
+
return { resources, prompts, toolsInvoked: false };
|
|
19
|
+
}
|
|
20
|
+
async function readSection(label, read, timeoutMs, maxItems, maxBytes) {
|
|
21
|
+
try {
|
|
22
|
+
const all = await withTimeout(read(), timeoutMs, label);
|
|
23
|
+
return clip(all, maxItems, maxBytes);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
27
|
+
if (/method not found|-32601|not supported|unknown method/i.test(message)) {
|
|
28
|
+
return { status: 'unsupported', items: [], truncated: false, reason: message };
|
|
29
|
+
}
|
|
30
|
+
return { status: 'failed', items: [], truncated: false, reason: message };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function clip(all, maxItems, maxBytes) {
|
|
34
|
+
const items = [];
|
|
35
|
+
let bytes = 2;
|
|
36
|
+
for (const item of all) {
|
|
37
|
+
const next = Buffer.byteLength(JSON.stringify(item));
|
|
38
|
+
if (items.length >= maxItems || bytes + next > maxBytes) {
|
|
39
|
+
return { status: 'ran', items, truncated: true };
|
|
40
|
+
}
|
|
41
|
+
items.push(item);
|
|
42
|
+
bytes += next;
|
|
43
|
+
}
|
|
44
|
+
return { status: 'ran', items, truncated: false };
|
|
45
|
+
}
|
|
46
|
+
function withTimeout(work, timeoutMs, label) {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
const timer = setTimeout(() => reject(new Error(`Timed out after ${timeoutMs}ms waiting for ${label}`)), timeoutMs);
|
|
49
|
+
work.then((value) => {
|
|
50
|
+
clearTimeout(timer);
|
|
51
|
+
resolve(value);
|
|
52
|
+
}, (err) => {
|
|
53
|
+
clearTimeout(timer);
|
|
54
|
+
reject(err);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/catalog/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { catalogRemote, catalogStdio } from '../../catalog/connect.js';
|
|
2
|
+
import { DEFAULT_CATALOG_MAX_BYTES, DEFAULT_CATALOG_MAX_ITEMS, DEFAULT_CATALOG_TIMEOUT_MS, } from '../../catalog/list.js';
|
|
3
|
+
export function registerCatalogCommand(program) {
|
|
4
|
+
program
|
|
5
|
+
.command('catalog')
|
|
6
|
+
.description('List resources and prompts from a live MCP server. Does not call tools.')
|
|
7
|
+
.option('--server <type>', 'Server transport: stdio|sse|http')
|
|
8
|
+
.option('--url <url>', 'Remote server URL for sse or http')
|
|
9
|
+
.option('--timeout <ms>', 'Timeout in milliseconds', String(DEFAULT_CATALOG_TIMEOUT_MS))
|
|
10
|
+
.option('--max-items <n>', 'Maximum items kept per list', String(DEFAULT_CATALOG_MAX_ITEMS))
|
|
11
|
+
.option('--max-bytes <n>', 'Maximum JSON bytes kept per list', String(DEFAULT_CATALOG_MAX_BYTES))
|
|
12
|
+
.option('--format <format>', 'Output format: json|terminal', 'terminal')
|
|
13
|
+
.allowExcessArguments(true)
|
|
14
|
+
.action(async (options) => {
|
|
15
|
+
try {
|
|
16
|
+
const limits = {
|
|
17
|
+
timeoutMs: positiveInt(options.timeout, '--timeout'),
|
|
18
|
+
maxItems: positiveInt(options.maxItems, '--max-items'),
|
|
19
|
+
maxBytes: positiveInt(options.maxBytes, '--max-bytes'),
|
|
20
|
+
};
|
|
21
|
+
let report;
|
|
22
|
+
if (options.server === 'stdio') {
|
|
23
|
+
const rawArgv = process.argv;
|
|
24
|
+
const sepIdx = rawArgv.indexOf('--');
|
|
25
|
+
if (sepIdx === -1 || sepIdx >= rawArgv.length - 1) {
|
|
26
|
+
throw new Error('--server stdio requires a command after --, e.g.: mcp-lint catalog --server stdio -- node server.js');
|
|
27
|
+
}
|
|
28
|
+
const [cmd, ...cmdArgs] = rawArgv.slice(sepIdx + 1);
|
|
29
|
+
report = await catalogStdio(cmd, cmdArgs, limits);
|
|
30
|
+
}
|
|
31
|
+
else if (options.server === 'sse' || options.server === 'http') {
|
|
32
|
+
if (!options.url)
|
|
33
|
+
throw new Error(`--server ${options.server} requires --url <url>`);
|
|
34
|
+
report = await catalogRemote(options.url, options.server, limits);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
throw new Error('catalog requires --server stdio|sse|http. It does not scan installed configs and it does not call tools.');
|
|
38
|
+
}
|
|
39
|
+
if (options.format !== 'json' && options.format !== 'terminal') {
|
|
40
|
+
throw new Error('--format must be json or terminal');
|
|
41
|
+
}
|
|
42
|
+
process.stdout.write(options.format === 'json' ? JSON.stringify(report, null, 2) + '\n' : render(report));
|
|
43
|
+
const failed = report.resources.status === 'failed' || report.prompts.status === 'failed';
|
|
44
|
+
process.exit(failed ? 1 : 0);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
48
|
+
process.exit(2);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function render(report) {
|
|
53
|
+
const lines = ['', 'resources'];
|
|
54
|
+
lines.push(...sectionLines(report.resources, (item) => `${item.uri} ${item.name}`));
|
|
55
|
+
lines.push('', 'prompts');
|
|
56
|
+
lines.push(...sectionLines(report.prompts, (item) => item.title ? `${item.name} ${item.title}` : item.name));
|
|
57
|
+
lines.push('');
|
|
58
|
+
return lines.join('\n');
|
|
59
|
+
}
|
|
60
|
+
function sectionLines(section, line) {
|
|
61
|
+
if (section.status !== 'ran')
|
|
62
|
+
return [` ${section.status}: ${section.reason ?? section.status}`];
|
|
63
|
+
const rows = section.items.map((item) => ` ${line(item)}`);
|
|
64
|
+
if (section.truncated)
|
|
65
|
+
rows.push(' truncated');
|
|
66
|
+
if (rows.length === 0)
|
|
67
|
+
rows.push(' none');
|
|
68
|
+
return rows;
|
|
69
|
+
}
|
|
70
|
+
function positiveInt(value, flag) {
|
|
71
|
+
const parsed = Number(value);
|
|
72
|
+
if (!Number.isInteger(parsed) || parsed < 1)
|
|
73
|
+
throw new Error(`${flag} must be a positive integer`);
|
|
74
|
+
return parsed;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../../src/cli/commands/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,8 @@ export function registerRecoverCommand(program) {
|
|
|
11
11
|
.option('--no-color', 'Disable terminal colors')
|
|
12
12
|
.option('--server <type>', 'Probe a live server: stdio')
|
|
13
13
|
.option('--hang-ms <ms>', 'Hang budget in milliseconds', String(DEFAULT_HANG_MS))
|
|
14
|
+
.option('--sandbox', 'Allow --invoke to call tools inside a sandbox you control')
|
|
15
|
+
.option('--invoke', 'Call tools that declare required arguments. Requires --sandbox. Off by default.')
|
|
14
16
|
.allowExcessArguments(true)
|
|
15
17
|
.action(async (file, options) => {
|
|
16
18
|
if (!options.color)
|
|
@@ -23,6 +25,8 @@ export function registerRecoverCommand(program) {
|
|
|
23
25
|
try {
|
|
24
26
|
let report;
|
|
25
27
|
let skipped = [];
|
|
28
|
+
let listed = [];
|
|
29
|
+
let invoked = false;
|
|
26
30
|
if (options.server === 'stdio') {
|
|
27
31
|
const rawArgv = process.argv;
|
|
28
32
|
const sepIdx = rawArgv.indexOf('--');
|
|
@@ -30,9 +34,15 @@ export function registerRecoverCommand(program) {
|
|
|
30
34
|
throw new Error('--server stdio requires a command after --, e.g.: mcp-lint recover --server stdio -- node server.js');
|
|
31
35
|
}
|
|
32
36
|
const [cmd, ...cmdArgs] = rawArgv.slice(sepIdx + 1);
|
|
33
|
-
const probed = await probeStdio(cmd, cmdArgs, {
|
|
37
|
+
const probed = await probeStdio(cmd, cmdArgs, {
|
|
38
|
+
hangMs,
|
|
39
|
+
sandbox: Boolean(options.sandbox),
|
|
40
|
+
invoke: Boolean(options.invoke),
|
|
41
|
+
});
|
|
34
42
|
report = probed.report;
|
|
35
43
|
skipped = probed.skipped;
|
|
44
|
+
listed = probed.listed;
|
|
45
|
+
invoked = probed.invoked;
|
|
36
46
|
}
|
|
37
47
|
else if (options.server) {
|
|
38
48
|
throw new Error(`Unknown server transport "${options.server}". Use stdio.`);
|
|
@@ -44,8 +54,8 @@ export function registerRecoverCommand(program) {
|
|
|
44
54
|
report = scoreRecovery(samplesFromFile(parsed), { hangMs: parsed.hangMs ?? hangMs, tools: parsed.tools });
|
|
45
55
|
}
|
|
46
56
|
const output = options.format === 'json'
|
|
47
|
-
? JSON.stringify({ ...report, skipped }, null, 2) + '\n'
|
|
48
|
-
: renderTerminal(report, skipped);
|
|
57
|
+
? JSON.stringify({ ...report, skipped, listed, invoked }, null, 2) + '\n'
|
|
58
|
+
: renderTerminal(report, skipped, listed, invoked);
|
|
49
59
|
process.stdout.write(output);
|
|
50
60
|
process.exit(report.errors > 0 ? 1 : 0);
|
|
51
61
|
}
|
|
@@ -64,12 +74,16 @@ function samplesFromFile(parsed) {
|
|
|
64
74
|
}
|
|
65
75
|
return parsed.samples;
|
|
66
76
|
}
|
|
67
|
-
function renderTerminal(report, skipped) {
|
|
77
|
+
function renderTerminal(report, skipped, listed, invoked) {
|
|
68
78
|
const lines = [''];
|
|
69
|
-
if (
|
|
79
|
+
if (listed.length > 0 && !invoked) {
|
|
80
|
+
lines.push(chalk.dim(`Listed ${listed.length} tool${listed.length === 1 ? '' : 's'}. No tool was called.`));
|
|
81
|
+
lines.push('');
|
|
82
|
+
}
|
|
83
|
+
if (report.findings.length === 0 && report.samples > 0) {
|
|
70
84
|
lines.push(chalk.green(`All ${report.samples} failure${report.samples === 1 ? '' : 's'} are recoverable.`));
|
|
71
85
|
}
|
|
72
|
-
else {
|
|
86
|
+
else if (report.findings.length > 0) {
|
|
73
87
|
const grouped = new Map();
|
|
74
88
|
for (const item of report.findings) {
|
|
75
89
|
const bucket = grouped.get(item.sampleId) ?? [];
|
|
@@ -81,7 +95,7 @@ function renderTerminal(report, skipped) {
|
|
|
81
95
|
for (const item of items) {
|
|
82
96
|
const mark = item.severity === 'error' ? chalk.red('✖') : chalk.yellow('⚠');
|
|
83
97
|
lines.push(` ${mark} ${item.message}`);
|
|
84
|
-
lines.push(chalk.dim(` [${item.ruleId}]`));
|
|
98
|
+
lines.push(chalk.dim(` [${item.ruleId}] ${item.durability}`));
|
|
85
99
|
}
|
|
86
100
|
lines.push('');
|
|
87
101
|
}
|
|
@@ -89,7 +103,7 @@ function renderTerminal(report, skipped) {
|
|
|
89
103
|
if (skipped.length > 0) {
|
|
90
104
|
lines.push(chalk.dim(`Skipped ${skipped.length} tool${skipped.length === 1 ? '' : 's'} with no required arguments: ${skipped.join(', ')}`));
|
|
91
105
|
}
|
|
92
|
-
const summary = `${report.errors} error${report.errors === 1 ? '' : 's'}, ${report.recoverable} recoverable of ${report.samples}`;
|
|
106
|
+
const summary = `${report.errors} error${report.errors === 1 ? '' : 's'}, ${report.recoverable} recoverable of ${report.samples}, ${report.transient} transient, ${report.permanent} permanent`;
|
|
93
107
|
lines.push(report.errors > 0 ? chalk.red(summary) : chalk.green(summary));
|
|
94
108
|
lines.push('');
|
|
95
109
|
return lines.join('\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recover.js","sourceRoot":"","sources":["../../../src/cli/commands/recover.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACrD,OAAO;SACJ,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,2EAA2E,CAAC;SACxF,MAAM,CAAC,mBAAmB,EAAE,8BAA8B,EAAE,UAAU,CAAC;SACvE,MAAM,CAAC,YAAY,EAAE,yBAAyB,CAAC;SAC/C,MAAM,CAAC,iBAAiB,EAAE,4BAA4B,CAAC;SACvD,MAAM,CAAC,gBAAgB,EAAE,6BAA6B,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;SAChF,oBAAoB,CAAC,IAAI,CAAC;SAC1B,MAAM,CAAC,KAAK,EACX,IAAwB,EACxB,
|
|
1
|
+
{"version":3,"file":"recover.js","sourceRoot":"","sources":["../../../src/cli/commands/recover.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { writeFile } from 'node:fs/promises';
|
|
1
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { auditBaselineDiff, projectAuditReport } from '../../audit/baseline.js';
|
|
2
3
|
import { buildAuditReport } from '../../audit/report.js';
|
|
3
4
|
import { formatAuditReport } from '../../audit/format.js';
|
|
4
5
|
import { loadConfig } from '../../config/config.js';
|
|
@@ -31,6 +32,8 @@ export function registerReportCommand(program) {
|
|
|
31
32
|
.option('--ignore <tools>', 'Comma-separated tool names to skip')
|
|
32
33
|
.option('--token-warn <n>', 'Approximate token warn threshold', String(DEFAULT_TOKEN_THRESHOLDS.warn))
|
|
33
34
|
.option('--token-over <n>', 'Approximate token over threshold', String(DEFAULT_TOKEN_THRESHOLDS.over))
|
|
35
|
+
.option('--baseline <path>', 'Fail when the stable audit report differs from this snapshot')
|
|
36
|
+
.option('--update-baseline <path>', 'Write the stable audit report snapshot')
|
|
34
37
|
.action(async (file, options) => {
|
|
35
38
|
try {
|
|
36
39
|
const fileConfig = await loadConfig(options.config);
|
|
@@ -50,8 +53,23 @@ export function registerReportCommand(program) {
|
|
|
50
53
|
warn: positiveInt(options.tokenWarn, '--token-warn'),
|
|
51
54
|
over: positiveInt(options.tokenOver, '--token-over'),
|
|
52
55
|
};
|
|
56
|
+
if (options.baseline && options.updateBaseline) {
|
|
57
|
+
throw new Error('Pass either --baseline or --update-baseline, not both.');
|
|
58
|
+
}
|
|
53
59
|
const pluginRules = await loadPluginRules(fileConfig);
|
|
54
60
|
const report = await buildFileAuditReport(file, { config, pluginRules, thresholds });
|
|
61
|
+
const projection = projectAuditReport(report);
|
|
62
|
+
if (options.updateBaseline) {
|
|
63
|
+
await writeFile(options.updateBaseline, projection, 'utf8');
|
|
64
|
+
}
|
|
65
|
+
if (options.baseline) {
|
|
66
|
+
const expected = await readFile(options.baseline, 'utf8');
|
|
67
|
+
const diff = auditBaselineDiff(projection, expected);
|
|
68
|
+
if (diff) {
|
|
69
|
+
process.stderr.write(`Error: ${diff}\n`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
55
73
|
const rendered = formatAuditReport(report, options.format, !options.color);
|
|
56
74
|
if (options.output)
|
|
57
75
|
await writeFile(options.output, rendered, 'utf8');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/cli/commands/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/cli/commands/report.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { registerPreflightCommand } from './cli/commands/preflight.js';
|
|
|
10
10
|
import { registerRecoverCommand } from './cli/commands/recover.js';
|
|
11
11
|
import { registerSnapshotCommand } from './cli/commands/snapshot.js';
|
|
12
12
|
import { registerReportCommand } from './cli/commands/report.js';
|
|
13
|
+
import { registerCatalogCommand } from './cli/commands/catalog.js';
|
|
13
14
|
import { VERSION } from './version.js';
|
|
14
15
|
const program = new Command();
|
|
15
16
|
program
|
|
@@ -26,5 +27,6 @@ registerPreflightCommand(program);
|
|
|
26
27
|
registerRecoverCommand(program);
|
|
27
28
|
registerSnapshotCommand(program);
|
|
28
29
|
registerReportCommand(program);
|
|
30
|
+
registerCatalogCommand(program);
|
|
29
31
|
program.parse();
|
|
30
32
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,iFAAiF,CAAC;KAC9F,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAClC,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,qBAAqB,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,iFAAiF,CAAC;KAC9F,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAClC,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAEhC,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/recover/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { scoreRecovery, mentionedTool, unreachableStep, instructionBlocker, classifyFailure, normalizeSample } from './score.js';
|
|
1
|
+
export { scoreRecovery, mentionedTool, unreachableStep, instructionBlocker, classifyFailure, classifyDurability, normalizeSample } from './score.js';
|
|
2
2
|
export { probeClient, probeStdio } from './probe.js';
|
|
3
3
|
export type { ProbeClient, ProbeTool, ProbeCallResult } from './probe.js';
|
|
4
4
|
export type { FailureKind, RecoveryFile, RecoveryFinding, RecoveryReport, RecoveryRuleId, RecoverySample, RecoverySampleInput, } from './types.js';
|
package/dist/recover/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { scoreRecovery, mentionedTool, unreachableStep, instructionBlocker, classifyFailure, normalizeSample } from './score.js';
|
|
1
|
+
export { scoreRecovery, mentionedTool, unreachableStep, instructionBlocker, classifyFailure, classifyDurability, normalizeSample } from './score.js';
|
|
2
2
|
export { probeClient, probeStdio } from './probe.js';
|
|
3
3
|
export { DEFAULT_HANG_MS, FAILURE_KINDS } from './types.js';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/recover/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/recover/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACrJ,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAWrD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/recover/probe.d.ts
CHANGED
|
@@ -23,17 +23,17 @@ export interface ProbeClient {
|
|
|
23
23
|
timeout: number;
|
|
24
24
|
}): Promise<ProbeCallResult>;
|
|
25
25
|
}
|
|
26
|
-
export
|
|
26
|
+
export interface ProbeOptions {
|
|
27
27
|
hangMs?: number;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}>;
|
|
33
|
-
export declare function probeStdio(command: string, args: string[], options?: {
|
|
34
|
-
hangMs?: number;
|
|
35
|
-
}): Promise<{
|
|
28
|
+
sandbox?: boolean;
|
|
29
|
+
invoke?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface ProbeResult {
|
|
36
32
|
report: RecoveryReport;
|
|
37
33
|
samples: RecoverySampleInput[];
|
|
38
34
|
skipped: string[];
|
|
39
|
-
|
|
35
|
+
listed: string[];
|
|
36
|
+
invoked: boolean;
|
|
37
|
+
}
|
|
38
|
+
export declare function probeClient(client: ProbeClient, options?: ProbeOptions): Promise<ProbeResult>;
|
|
39
|
+
export declare function probeStdio(command: string, args: string[], options?: ProbeOptions): Promise<ProbeResult>;
|
package/dist/recover/probe.js
CHANGED
|
@@ -7,6 +7,16 @@ export async function probeClient(client, options = {}) {
|
|
|
7
7
|
const hangMs = options.hangMs ?? DEFAULT_HANG_MS;
|
|
8
8
|
const listed = await client.listTools();
|
|
9
9
|
const tools = listed.tools.map((tool) => tool.name);
|
|
10
|
+
const invoke = allowInvoke(options);
|
|
11
|
+
if (!invoke) {
|
|
12
|
+
return {
|
|
13
|
+
report: scoreRecovery([], { hangMs, tools }),
|
|
14
|
+
samples: [],
|
|
15
|
+
skipped: [],
|
|
16
|
+
listed: tools,
|
|
17
|
+
invoked: false,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
10
20
|
const samples = [];
|
|
11
21
|
const skipped = [];
|
|
12
22
|
for (const tool of listed.tools) {
|
|
@@ -44,8 +54,18 @@ export async function probeClient(client, options = {}) {
|
|
|
44
54
|
report: scoreRecovery(samples, { hangMs, tools }),
|
|
45
55
|
samples,
|
|
46
56
|
skipped,
|
|
57
|
+
listed: tools,
|
|
58
|
+
invoked: true,
|
|
47
59
|
};
|
|
48
60
|
}
|
|
61
|
+
function allowInvoke(options) {
|
|
62
|
+
if (!options.invoke)
|
|
63
|
+
return false;
|
|
64
|
+
if (!options.sandbox) {
|
|
65
|
+
throw new Error('Refusing to call tools. A probe lists tools unless both --sandbox and --invoke are set.');
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
49
69
|
export async function probeStdio(command, args, options = {}) {
|
|
50
70
|
const transport = new StdioClientTransport({ command, args });
|
|
51
71
|
const client = new Client({ name: 'mcp-lint-recover', version: VERSION }, { capabilities: {} });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../../src/recover/probe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../../src/recover/probe.ts"],"names":[],"mappings":"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"}
|
package/dist/recover/score.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { FailureKind, RecoveryReport, RecoverySample, RecoverySampleInput } from './types.js';
|
|
1
|
+
import type { FailureDurability, FailureKind, RecoveryReport, RecoverySample, RecoverySampleInput } from './types.js';
|
|
2
2
|
export declare function scoreRecovery(samples: RecoverySampleInput[], options?: {
|
|
3
3
|
hangMs?: number;
|
|
4
4
|
tools?: string[];
|
|
5
5
|
}): RecoveryReport;
|
|
6
|
+
export declare function classifyDurability(kind: FailureKind): FailureDurability;
|
|
6
7
|
export declare function normalizeSample(input: RecoverySampleInput, fallbackTools: string[] | undefined, index: number): RecoverySample;
|
|
7
8
|
export declare function mentionedTool(message: string, tools: string[]): string | null;
|
|
8
9
|
export type BlockedStep = 'a terminal command' | 'a config change' | 'a web page';
|
package/dist/recover/score.js
CHANGED
|
@@ -6,8 +6,14 @@ export function scoreRecovery(samples, options = {}) {
|
|
|
6
6
|
const hangMs = options.hangMs ?? DEFAULT_HANG_MS;
|
|
7
7
|
const findings = [];
|
|
8
8
|
let recoverable = 0;
|
|
9
|
+
let transient = 0;
|
|
10
|
+
let permanent = 0;
|
|
9
11
|
samples.forEach((input, index) => {
|
|
10
12
|
const sample = normalizeSample(input, options.tools, index);
|
|
13
|
+
if (classifyDurability(sample.kind) === 'transient')
|
|
14
|
+
transient += 1;
|
|
15
|
+
else
|
|
16
|
+
permanent += 1;
|
|
11
17
|
const before = findings.length;
|
|
12
18
|
findings.push(...scoreSample(sample, hangMs));
|
|
13
19
|
const errors = findings.slice(before).filter((finding) => finding.severity === 'error');
|
|
@@ -19,9 +25,16 @@ export function scoreRecovery(samples, options = {}) {
|
|
|
19
25
|
errors: findings.filter((finding) => finding.severity === 'error').length,
|
|
20
26
|
warnings: findings.filter((finding) => finding.severity === 'warning').length,
|
|
21
27
|
recoverable,
|
|
28
|
+
transient,
|
|
29
|
+
permanent,
|
|
22
30
|
findings,
|
|
23
31
|
};
|
|
24
32
|
}
|
|
33
|
+
export function classifyDurability(kind) {
|
|
34
|
+
if (kind === 'rate_limit' || kind === 'timeout')
|
|
35
|
+
return 'transient';
|
|
36
|
+
return 'permanent';
|
|
37
|
+
}
|
|
25
38
|
export function normalizeSample(input, fallbackTools, index) {
|
|
26
39
|
if (!input.tool?.trim()) {
|
|
27
40
|
throw new Error(`Sample ${index + 1} is missing a tool name`);
|
|
@@ -79,6 +92,7 @@ function finding(sample, ruleId, message, severity = 'error') {
|
|
|
79
92
|
tool: sample.tool,
|
|
80
93
|
sampleId: sample.id ?? sample.tool,
|
|
81
94
|
message,
|
|
95
|
+
durability: classifyDurability(sample.kind),
|
|
82
96
|
};
|
|
83
97
|
}
|
|
84
98
|
export function mentionedTool(message, tools) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"score.js","sourceRoot":"","sources":["../../src/recover/score.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"score.js","sourceRoot":"","sources":["../../src/recover/score.ts"],"names":[],"mappings":"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"}
|
package/dist/recover/types.d.ts
CHANGED
|
@@ -23,18 +23,22 @@ export interface RecoveryFile {
|
|
|
23
23
|
hangMs?: number;
|
|
24
24
|
samples: RecoverySampleInput[];
|
|
25
25
|
}
|
|
26
|
+
export type FailureDurability = 'transient' | 'permanent';
|
|
26
27
|
export interface RecoveryFinding {
|
|
27
28
|
ruleId: RecoveryRuleId;
|
|
28
29
|
severity: 'error' | 'warning';
|
|
29
30
|
tool: string;
|
|
30
31
|
sampleId: string;
|
|
31
32
|
message: string;
|
|
33
|
+
durability: FailureDurability;
|
|
32
34
|
}
|
|
33
35
|
export interface RecoveryReport {
|
|
34
36
|
samples: number;
|
|
35
37
|
errors: number;
|
|
36
38
|
warnings: number;
|
|
37
39
|
recoverable: number;
|
|
40
|
+
transient: number;
|
|
41
|
+
permanent: number;
|
|
38
42
|
findings: RecoveryFinding[];
|
|
39
43
|
}
|
|
40
44
|
export declare const DEFAULT_HANG_MS = 15000;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/recover/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/recover/types.ts"],"names":[],"mappings":"AA+DA,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC;AAEtC,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,UAAU;IACV,QAAQ;IACR,SAAS;IACT,WAAW;CACZ,CAAC"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
1
|
+
export declare const VERSION = "1.0.0";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '1.0.0';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
|
@@ -15,8 +15,8 @@ jobs:
|
|
|
15
15
|
- uses: actions/checkout@v4
|
|
16
16
|
|
|
17
17
|
- name: Lint MCP tool schemas
|
|
18
|
-
# Tag
|
|
19
|
-
uses: robert19001-cmyk/mcp-lint@
|
|
18
|
+
# Tag v1.0.0. The action installs npm latest, which is 1.0.0.
|
|
19
|
+
uses: robert19001-cmyk/mcp-lint@v1.0.0
|
|
20
20
|
with:
|
|
21
21
|
input: tools.json
|
|
22
22
|
severity: warning
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-lint",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"mcpName": "io.github.robert19001-cmyk/mcp-lint",
|
|
5
5
|
"description": "Lint MCP tool schemas before they break Claude, Cursor, Gemini, or OpenAI. Run npx mcp-lint.",
|
|
6
6
|
"type": "module",
|
|
@@ -94,9 +94,9 @@
|
|
|
94
94
|
"zod": "^4.3.6"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
|
+
"@fontsource/ibm-plex-mono": "^5.3.0",
|
|
98
|
+
"@fontsource/schibsted-grotesk": "^5.3.0",
|
|
97
99
|
"@types/node": "^25.5.0",
|
|
98
|
-
"@types/three": "^0.187.0",
|
|
99
|
-
"three": "^0.187.0",
|
|
100
100
|
"typescript": "^6.0.2",
|
|
101
101
|
"vite": "^8.3.5",
|
|
102
102
|
"vitest": "^4.1.1"
|