mcp-lint 0.5.3 → 0.6.2

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 CHANGED
@@ -7,7 +7,9 @@
7
7
  [![MCP server ready](https://img.shields.io/badge/MCP-server_ready-6f42c1)](#mcp-server)
8
8
  [![robert19001-cmyk/mcp-lint MCP server](https://glama.ai/mcp/servers/robert19001-cmyk/mcp-lint/badges/score.svg)](https://glama.ai/mcp/servers/robert19001-cmyk/mcp-lint)
9
9
 
10
- **Lint MCP server tool schemas for cross-client compatibility.**
10
+ **Lint MCP server tool schemas, then check whether an agent can recover when a tool fails.**
11
+
12
+ Proof page, with a live bench: [mcp-lint-alpha.vercel.app](https://mcp-lint-alpha.vercel.app/)
11
13
 
12
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.
13
15
 
@@ -60,6 +62,9 @@ mcp-lint init
60
62
 
61
63
  # Run as an MCP server
62
64
  mcp-lint-server
65
+
66
+ # Score whether a tool failure tells the agent which tool to call next
67
+ mcp-lint recover examples/recover/bad-credential.json
63
68
  ```
64
69
 
65
70
  ---
@@ -332,7 +337,7 @@ jobs:
332
337
  runs-on: ubuntu-latest
333
338
  steps:
334
339
  - uses: actions/checkout@v4
335
- - uses: robert19001-cmyk/mcp-lint@v0.5.3
340
+ - uses: robert19001-cmyk/mcp-lint@v0.6.2
336
341
  with:
337
342
  input: tools.json
338
343
  severity: warning
@@ -556,6 +561,68 @@ Use them directly in shell wrappers or CI gates.
556
561
 
557
562
  ---
558
563
 
564
+ ## `mcp-lint recover` — Can the agent get back up?
565
+
566
+ Schema lint does not say what happens when a tool fails. `recover` reads the error text and checks four things an agent limited to MCP tools needs:
567
+
568
+ - A credential or permission error names a tool on this server, such as `login`.
569
+ - A rate limit or timeout names the call to repeat. "Wait and retry" is not enough.
570
+ - The next step is not a terminal command, a config edit, or a web page.
571
+ - The failure is not silent, and a hang is cut off at 15 seconds.
572
+
573
+ ```bash
574
+ $ mcp-lint recover examples/recover/bad-credential.json
575
+
576
+ search#1
577
+ ✖ Credential or permission error does not name a tool on this server. Say which tool to call, for example `login`, then retry.
578
+ [recover/names-tool]
579
+ ✖ Next step asks for a terminal command, which an agent limited to MCP tools cannot do. Name a tool from this server instead.
580
+ [recover/agent-reachable]
581
+
582
+ search#2
583
+ ✖ Retry text does not name the call to repeat. Name `search` instead of "wait and retry".
584
+ [recover/names-retry]
585
+
586
+ 3 errors, 1 recoverable of 3
587
+ ```
588
+
589
+ Exit `1` when any sample has an error. Exit `0` when every failure is recoverable.
590
+
591
+ Probe a live server. Tools with no required arguments are skipped, so an empty call cannot fire a real action.
592
+
593
+ ```bash
594
+ mcp-lint recover --server stdio -- node server.js
595
+ mcp-lint recover errors.json --hang-ms 8000 --format json
596
+ ```
597
+
598
+ File shape:
599
+
600
+ ```json
601
+ {
602
+ "tools": ["login", "search"],
603
+ "samples": [
604
+ {
605
+ "tool": "search",
606
+ "kind": "credential",
607
+ "message": "Unauthorized. Call the login tool, then retry search."
608
+ }
609
+ ]
610
+ }
611
+ ```
612
+
613
+ `kind` is `credential`, `permission`, `rate_limit`, `explicit`, `silent`, `timeout`, or `malformed`.
614
+
615
+ ```typescript
616
+ import { scoreRecovery } from 'mcp-lint/recover';
617
+
618
+ const report = scoreRecovery(
619
+ [{ tool: 'search', kind: 'rate_limit', message: 'Wait before retrying.' }],
620
+ { tools: ['login', 'search'] },
621
+ );
622
+ ```
623
+
624
+ ---
625
+
559
626
  ## MCP Server
560
627
 
561
628
  `mcp-lint` also ships as a stdio MCP server for Claude Desktop, Claude Code, Cursor, VS Code, and registry scanners such as Glama.
@@ -586,6 +653,7 @@ Available MCP tools:
586
653
  | `mcp_lint_check_tools` | Lint MCP tool schemas passed as JSON |
587
654
  | `mcp_lint_fix_tools` | Return safely auto-fixed tool schemas without writing files |
588
655
  | `mcp_lint_preflight_action` | Score a proposed agent action and return allow/deny/approval/rewrite |
656
+ | `mcp_lint_score_recovery` | Score a recorded tool failure for whether an agent can recover |
589
657
 
590
658
  All server tools are read-only from the host perspective: they return diagnostics, fixed JSON, or policy decisions and never execute the action being evaluated.
591
659
 
@@ -600,6 +668,24 @@ The repository includes `glama.json` and a production Dockerfile so MCP director
600
668
 
601
669
  ---
602
670
 
671
+ ## Site
672
+
673
+ The proof page is in `site/`. It runs the same recovery scorer as the CLI.
674
+
675
+ ```bash
676
+ npm run site
677
+ ```
678
+
679
+ The public page is https://mcp-lint-alpha.vercel.app/. The same page runs locally:
680
+
681
+ ```bash
682
+ npm run site
683
+ ```
684
+
685
+ Open http://127.0.0.1:4731. The built page is not part of the npm package.
686
+
687
+ ---
688
+
603
689
  ## License
604
690
 
605
691
  MIT © Robert
@@ -0,0 +1,2 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerRecoverCommand(program: Command): void;
@@ -0,0 +1,97 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import chalk from 'chalk';
3
+ import { scoreRecovery } from '../../recover/score.js';
4
+ import { probeStdio } from '../../recover/probe.js';
5
+ import { DEFAULT_HANG_MS } from '../../recover/types.js';
6
+ export function registerRecoverCommand(program) {
7
+ program
8
+ .command('recover [file]')
9
+ .description('Score MCP tool failures for whether an agent limited to tools can recover')
10
+ .option('--format <format>', 'Output format: terminal|json', 'terminal')
11
+ .option('--no-color', 'Disable terminal colors')
12
+ .option('--server <type>', 'Probe a live server: stdio')
13
+ .option('--hang-ms <ms>', 'Hang budget in milliseconds', String(DEFAULT_HANG_MS))
14
+ .allowExcessArguments(true)
15
+ .action(async (file, options) => {
16
+ if (!options.color)
17
+ chalk.level = 0;
18
+ const hangMs = Number(options.hangMs);
19
+ if (!Number.isInteger(hangMs) || hangMs < 1) {
20
+ process.stderr.write('Error: --hang-ms must be a positive integer\n');
21
+ process.exit(2);
22
+ }
23
+ try {
24
+ let report;
25
+ let skipped = [];
26
+ if (options.server === 'stdio') {
27
+ const rawArgv = process.argv;
28
+ const sepIdx = rawArgv.indexOf('--');
29
+ if (sepIdx === -1 || sepIdx >= rawArgv.length - 1) {
30
+ throw new Error('--server stdio requires a command after --, e.g.: mcp-lint recover --server stdio -- node server.js');
31
+ }
32
+ const [cmd, ...cmdArgs] = rawArgv.slice(sepIdx + 1);
33
+ const probed = await probeStdio(cmd, cmdArgs, { hangMs });
34
+ report = probed.report;
35
+ skipped = probed.skipped;
36
+ }
37
+ else if (options.server) {
38
+ throw new Error(`Unknown server transport "${options.server}". Use stdio.`);
39
+ }
40
+ else {
41
+ if (!file)
42
+ throw new Error('Specify a recovery file or use --server stdio -- <command>');
43
+ const parsed = JSON.parse(await readFile(file, 'utf8'));
44
+ report = scoreRecovery(samplesFromFile(parsed), { hangMs: parsed.hangMs ?? hangMs, tools: parsed.tools });
45
+ }
46
+ const output = options.format === 'json'
47
+ ? JSON.stringify({ ...report, skipped }, null, 2) + '\n'
48
+ : renderTerminal(report, skipped);
49
+ process.stdout.write(output);
50
+ process.exit(report.errors > 0 ? 1 : 0);
51
+ }
52
+ catch (err) {
53
+ process.stderr.write(`Error: ${err.message}\n`);
54
+ process.exit(2);
55
+ }
56
+ });
57
+ }
58
+ function samplesFromFile(parsed) {
59
+ if (!parsed || !Array.isArray(parsed.samples)) {
60
+ throw new Error('Recovery file must be { "tools": string[], "samples": [...] }');
61
+ }
62
+ if (!Array.isArray(parsed.tools) || parsed.tools.length === 0) {
63
+ throw new Error('Recovery file must list the server tools in "tools"');
64
+ }
65
+ return parsed.samples;
66
+ }
67
+ function renderTerminal(report, skipped) {
68
+ const lines = [''];
69
+ if (report.findings.length === 0) {
70
+ lines.push(chalk.green(`All ${report.samples} failure${report.samples === 1 ? '' : 's'} are recoverable.`));
71
+ }
72
+ else {
73
+ const grouped = new Map();
74
+ for (const item of report.findings) {
75
+ const bucket = grouped.get(item.sampleId) ?? [];
76
+ bucket.push(item);
77
+ grouped.set(item.sampleId, bucket);
78
+ }
79
+ for (const [sampleId, items] of grouped) {
80
+ lines.push(chalk.bold(sampleId));
81
+ for (const item of items) {
82
+ const mark = item.severity === 'error' ? chalk.red('✖') : chalk.yellow('⚠');
83
+ lines.push(` ${mark} ${item.message}`);
84
+ lines.push(chalk.dim(` [${item.ruleId}]`));
85
+ }
86
+ lines.push('');
87
+ }
88
+ }
89
+ if (skipped.length > 0) {
90
+ lines.push(chalk.dim(`Skipped ${skipped.length} tool${skipped.length === 1 ? '' : 's'} with no required arguments: ${skipped.join(', ')}`));
91
+ }
92
+ const summary = `${report.errors} error${report.errors === 1 ? '' : 's'}, ${report.recoverable} recoverable of ${report.samples}`;
93
+ lines.push(report.errors > 0 ? chalk.red(summary) : chalk.green(summary));
94
+ lines.push('');
95
+ return lines.join('\n');
96
+ }
97
+ //# sourceMappingURL=recover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recover.js","sourceRoot":"","sources":["../../../src/cli/commands/recover.ts"],"names":[],"mappings":"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"}
@@ -30,11 +30,19 @@ export interface JSONSchema {
30
30
  description?: string;
31
31
  [key: string]: unknown;
32
32
  }
33
+ export interface ToolAnnotations {
34
+ title?: string;
35
+ readOnlyHint?: boolean;
36
+ destructiveHint?: boolean;
37
+ idempotentHint?: boolean;
38
+ openWorldHint?: boolean;
39
+ }
33
40
  export interface MCPTool {
34
41
  name: string;
35
42
  title?: string;
36
43
  description?: string;
37
44
  inputSchema: JSONSchema;
45
+ annotations?: ToolAnnotations;
38
46
  }
39
47
  export interface Config {
40
48
  extends?: string;
package/dist/index.js CHANGED
@@ -7,11 +7,12 @@ import { registerCompatCommand } from './cli/commands/compat.js';
7
7
  import { registerExplainCommand } from './cli/commands/explain.js';
8
8
  import { registerDiffCommand } from './cli/commands/diff.js';
9
9
  import { registerPreflightCommand } from './cli/commands/preflight.js';
10
+ import { registerRecoverCommand } from './cli/commands/recover.js';
10
11
  const program = new Command();
11
12
  program
12
13
  .name('mcp-lint')
13
- .description('Lint MCP server tool schemas for cross-client compatibility')
14
- .version('0.5.3');
14
+ .description('Lint MCP tool schemas and score whether an agent can recover from tool failures')
15
+ .version('0.6.0');
15
16
  registerCheckCommand(program);
16
17
  registerFixCommand(program);
17
18
  registerInitCommand(program);
@@ -19,5 +20,6 @@ registerCompatCommand(program);
19
20
  registerExplainCommand(program);
20
21
  registerDiffCommand(program);
21
22
  registerPreflightCommand(program);
23
+ registerRecoverCommand(program);
22
24
  program.parse();
23
25
  //# 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;AAEvE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,6DAA6D,CAAC;KAC1E,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;AAElC,OAAO,CAAC,KAAK,EAAE,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;AAEnE,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;AAEhC,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -11,7 +11,9 @@ import { DEFAULT_CONFIG } from './config/config.js';
11
11
  import { allRules } from './rules/index.js';
12
12
  import { preflight } from './preflight/engine.js';
13
13
  import { parsePolicy } from './preflight/policy.js';
14
- const VERSION = '0.5.3';
14
+ import { scoreRecovery } from './recover/score.js';
15
+ import { FAILURE_KINDS } from './recover/types.js';
16
+ const VERSION = '0.6.0';
15
17
  const ClientIdSchema = z.enum([
16
18
  'claude',
17
19
  'cursor',
@@ -229,6 +231,35 @@ export function createMcpLintServer() {
229
231
  const policy = policyYaml ? parsePolicy(policyYaml) : undefined;
230
232
  return result({ decision: preflight(action, policy) });
231
233
  });
234
+ server.registerTool('mcp_lint_score_recovery', {
235
+ title: 'Score MCP Failure Recovery',
236
+ description: 'Score MCP tool failure text for whether an agent that can only call tools can recover. Does not call the failing tool.',
237
+ inputSchema: {
238
+ tools: z.array(z.string().min(1)).min(1).describe('Tool names the agent is allowed to call.'),
239
+ hangMs: z.number().int().positive().optional().describe('Hang budget in milliseconds. Defaults to 15000.'),
240
+ samples: z.array(z.object({
241
+ id: z.string().optional(),
242
+ tool: z.string().min(1).describe('Tool that failed.'),
243
+ kind: z.enum(FAILURE_KINDS).describe('Failure kind: credential, permission, rate_limit, explicit, silent, timeout, or malformed.'),
244
+ message: z.string().optional().describe('Error text shown to the agent.'),
245
+ isError: z.boolean().optional(),
246
+ durationMs: z.number().int().nonnegative().optional(),
247
+ })).describe('Recorded tool failures to score.'),
248
+ },
249
+ outputSchema: {
250
+ report: JsonObjectSchema,
251
+ },
252
+ annotations: {
253
+ readOnlyHint: true,
254
+ destructiveHint: false,
255
+ idempotentHint: true,
256
+ openWorldHint: false,
257
+ },
258
+ }, async ({ tools, hangMs, samples }) => {
259
+ return result({
260
+ report: scoreRecovery(samples, { tools, hangMs }),
261
+ });
262
+ });
232
263
  return server;
233
264
  }
234
265
  async function main() {
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC;IAC5B,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,OAAO;IACP,QAAQ;IACR,UAAU;CACX,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAC5D,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEvE,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AAEpD,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IAC1D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;IAChF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;IAC7E,WAAW,EAAE,gBAAgB,CAAC,QAAQ,CAAC,6CAA6C,CAAC;CACtF,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG;IAClB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;IAC7F,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;IACxE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;IAC1G,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;CAC9G,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC;QAChB,OAAO;QACP,WAAW;QACX,YAAY;QACZ,aAAa;QACb,MAAM;QACN,UAAU;QACV,OAAO;QACP,SAAS;QACT,UAAU;QACV,OAAO;KACR,CAAC;IACF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;IACrD,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACjD,CAAC,CAAC;AAEH,SAAS,eAAe,CAAC,KAAsB;IAC7C,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO;QAChD,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM;QAC7C,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,cAAc,CAAC,QAAQ;QACnD,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,KAAgB,EAAE,WAA4B;IAC/D,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG;QACd,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,WAAW,EAAE,WAAW,CAAC,MAAM;QAC/B,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM;QAChE,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM;QACpE,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM;KAC9D,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,MAAM,CAAC,MAA+B;IAC7C,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3E,iBAAiB,EAAE,MAAM;KAC1B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,kGAAkG;QAC/G,YAAY,EAAE;YACZ,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC;YAChC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;SAClB;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,IAAI,EAAE;QACT,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACpC,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;YACpC,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC,CAAC,CAAC;QACJ,OAAO,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EAAE,uFAAuF;QACpG,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kDAAkD,CAAC;SACvF;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,gBAAgB;SACvB;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;QACnE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,iBAAiB,MAAM,4DAA4D,CAAC,CAAC;QACvG,CAAC;QACD,OAAO,MAAM,CAAC;YACZ,IAAI,EAAE;gBACJ,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;gBACpC,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;aACxB;SACF,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EAAE,uIAAuI;QACpJ,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,6DAA6D,CAAC;YAC1G,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,2CAA2C,CAAC;YAC9F,GAAG,WAAW;SACf;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,gBAAgB;YACzB,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC;YACtC,OAAO,EAAE,gBAAgB,CAAC,QAAQ,EAAE;SACrC;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;QAClE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC,KAAkB,EAAE;YAC7D,OAAO;YACP,MAAM;YACN,KAAK;YACL,QAAQ;SACT,CAAC,CAAC;QACH,MAAM,MAAM,GAAG;YACb,OAAO;YACP,WAAW;YACX,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,oBAAoB,CAAC,KAAkB,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5F,CAAC;QACF,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,2BAA2B;QAClC,WAAW,EAAE,qGAAqG;QAClH,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,qCAAqC,CAAC;YAClF,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YACjG,GAAG,WAAW;SACf;QACD,YAAY,EAAE;YACZ,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC;YACrC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;YACxB,oBAAoB,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC;YAC/C,mBAAmB,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC;SAC/C;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC/D,MAAM,MAAM,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAkB,EAAE,MAAM,CAAC,CAAC;QACrD,MAAM,UAAU,GAAG,UAAU,CAAC,KAAkB,EAAE,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACjF,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC5C,OAAO,MAAM,CAAC;YACZ,UAAU;YACV,YAAY,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM;YAC5G,oBAAoB,EAAE,MAAM,CAAC,WAAW;YACxC,mBAAmB,EAAE,KAAK,CAAC,WAAW;SACvC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,2BAA2B,EAC3B;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EAAE,uJAAuJ;QACpK,WAAW,EAAE;YACX,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,sCAAsC,CAAC;YACrE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2EAA2E,CAAC;SACxH;QACD,YAAY,EAAE;YACZ,QAAQ,EAAE,gBAAgB;SAC3B;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE;QAC/B,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAChE,OAAO,MAAM,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,MAAgB,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACnE,CAAC,CACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAC;IACrC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7F,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAAgC,KAAe,CAAC,OAAO,IAAI,CAAC,CAAC;QAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { scoreRecovery, mentionedTool, unreachableStep, instructionBlocker, classifyFailure, normalizeSample } from './score.js';
2
+ export { probeClient, probeStdio } from './probe.js';
3
+ export type { ProbeClient, ProbeTool, ProbeCallResult } from './probe.js';
4
+ export type { FailureKind, RecoveryFile, RecoveryFinding, RecoveryReport, RecoveryRuleId, RecoverySample, RecoverySampleInput, } from './types.js';
5
+ export { DEFAULT_HANG_MS, FAILURE_KINDS } from './types.js';
@@ -0,0 +1,4 @@
1
+ export { scoreRecovery, mentionedTool, unreachableStep, instructionBlocker, classifyFailure, normalizeSample } from './score.js';
2
+ export { probeClient, probeStdio } from './probe.js';
3
+ export { DEFAULT_HANG_MS, FAILURE_KINDS } from './types.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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;AACjI,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAWrD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,39 @@
1
+ import type { RecoveryReport, RecoverySampleInput } from './types.js';
2
+ export interface ProbeTool {
3
+ name: string;
4
+ inputSchema?: {
5
+ required?: unknown;
6
+ };
7
+ }
8
+ export interface ProbeCallResult {
9
+ isError?: boolean;
10
+ content?: Array<{
11
+ type: string;
12
+ text?: string;
13
+ }>;
14
+ }
15
+ export interface ProbeClient {
16
+ listTools(): Promise<{
17
+ tools: ProbeTool[];
18
+ }>;
19
+ callTool(params: {
20
+ name: string;
21
+ arguments: Record<string, unknown>;
22
+ }, resultSchema: undefined, options: {
23
+ timeout: number;
24
+ }): Promise<ProbeCallResult>;
25
+ }
26
+ export declare function probeClient(client: ProbeClient, options?: {
27
+ hangMs?: number;
28
+ }): Promise<{
29
+ report: RecoveryReport;
30
+ samples: RecoverySampleInput[];
31
+ skipped: string[];
32
+ }>;
33
+ export declare function probeStdio(command: string, args: string[], options?: {
34
+ hangMs?: number;
35
+ }): Promise<{
36
+ report: RecoveryReport;
37
+ samples: RecoverySampleInput[];
38
+ skipped: string[];
39
+ }>;
@@ -0,0 +1,80 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3
+ import { classifyFailure, scoreRecovery } from './score.js';
4
+ import { DEFAULT_HANG_MS } from './types.js';
5
+ export async function probeClient(client, options = {}) {
6
+ const hangMs = options.hangMs ?? DEFAULT_HANG_MS;
7
+ const listed = await client.listTools();
8
+ const tools = listed.tools.map((tool) => tool.name);
9
+ const samples = [];
10
+ const skipped = [];
11
+ for (const tool of listed.tools) {
12
+ const required = Array.isArray(tool.inputSchema?.required) ? tool.inputSchema.required : [];
13
+ if (required.length === 0) {
14
+ skipped.push(tool.name);
15
+ continue;
16
+ }
17
+ const started = Date.now();
18
+ let timedOut = false;
19
+ let isError;
20
+ let message = '';
21
+ try {
22
+ const result = await withHang(client.callTool({ name: tool.name, arguments: {} }, undefined, { timeout: hangMs }), hangMs);
23
+ isError = result.isError;
24
+ message = textFromContent(result.content);
25
+ }
26
+ catch (err) {
27
+ timedOut = Date.now() - started >= hangMs || /timed out|timeout/i.test(err.message);
28
+ message = err.message;
29
+ isError = true;
30
+ }
31
+ const durationMs = Date.now() - started;
32
+ samples.push({
33
+ id: tool.name,
34
+ tool: tool.name,
35
+ kind: classifyFailure({ message, isError, durationMs, hangMs, timedOut }),
36
+ message,
37
+ isError,
38
+ durationMs,
39
+ tools,
40
+ });
41
+ }
42
+ return {
43
+ report: scoreRecovery(samples, { hangMs, tools }),
44
+ samples,
45
+ skipped,
46
+ };
47
+ }
48
+ export async function probeStdio(command, args, options = {}) {
49
+ const transport = new StdioClientTransport({ command, args });
50
+ const client = new Client({ name: 'mcp-lint-recover', version: '0.6.0' }, { capabilities: {} });
51
+ await client.connect(transport);
52
+ try {
53
+ return await probeClient(client, options);
54
+ }
55
+ finally {
56
+ await client.close();
57
+ }
58
+ }
59
+ function textFromContent(content) {
60
+ if (!content)
61
+ return '';
62
+ return content
63
+ .filter((block) => block.type === 'text' && typeof block.text === 'string')
64
+ .map((block) => block.text)
65
+ .join('\n')
66
+ .trim();
67
+ }
68
+ function withHang(work, hangMs) {
69
+ return new Promise((resolve, reject) => {
70
+ const timer = setTimeout(() => reject(new Error(`timed out after ${hangMs}ms`)), hangMs);
71
+ work.then((value) => {
72
+ clearTimeout(timer);
73
+ resolve(value);
74
+ }, (err) => {
75
+ clearTimeout(timer);
76
+ reject(err);
77
+ });
78
+ });
79
+ }
80
+ //# sourceMappingURL=probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe.js","sourceRoot":"","sources":["../../src/recover/probe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { FailureKind, RecoveryReport, RecoverySample, RecoverySampleInput } from './types.js';
2
+ export declare function scoreRecovery(samples: RecoverySampleInput[], options?: {
3
+ hangMs?: number;
4
+ tools?: string[];
5
+ }): RecoveryReport;
6
+ export declare function normalizeSample(input: RecoverySampleInput, fallbackTools: string[] | undefined, index: number): RecoverySample;
7
+ export declare function mentionedTool(message: string, tools: string[]): string | null;
8
+ export type BlockedStep = 'a terminal command' | 'a config change' | 'a web page';
9
+ export declare function unreachableStep(message: string): BlockedStep | null;
10
+ /** Description lint ignores a bare URL. Error text still treats a URL as a step the agent cannot open. */
11
+ export declare function instructionBlocker(message: string): BlockedStep | null;
12
+ export declare function classifyFailure(input: {
13
+ message: string;
14
+ isError?: boolean;
15
+ durationMs: number;
16
+ hangMs: number;
17
+ timedOut?: boolean;
18
+ }): FailureKind;
@@ -0,0 +1,145 @@
1
+ import { DEFAULT_HANG_MS, FAILURE_KINDS } from './types.js';
2
+ const NAMED_TOOL_KINDS = new Set(['credential', 'permission']);
3
+ const RETRY_KINDS = new Set(['rate_limit', 'timeout']);
4
+ const SILENT_KINDS = new Set(['silent', 'malformed']);
5
+ export function scoreRecovery(samples, options = {}) {
6
+ const hangMs = options.hangMs ?? DEFAULT_HANG_MS;
7
+ const findings = [];
8
+ let recoverable = 0;
9
+ samples.forEach((input, index) => {
10
+ const sample = normalizeSample(input, options.tools, index);
11
+ const before = findings.length;
12
+ findings.push(...scoreSample(sample, hangMs));
13
+ const errors = findings.slice(before).filter((finding) => finding.severity === 'error');
14
+ if (errors.length === 0)
15
+ recoverable += 1;
16
+ });
17
+ return {
18
+ samples: samples.length,
19
+ errors: findings.filter((finding) => finding.severity === 'error').length,
20
+ warnings: findings.filter((finding) => finding.severity === 'warning').length,
21
+ recoverable,
22
+ findings,
23
+ };
24
+ }
25
+ export function normalizeSample(input, fallbackTools, index) {
26
+ if (!input.tool?.trim()) {
27
+ throw new Error(`Sample ${index + 1} is missing a tool name`);
28
+ }
29
+ if (!FAILURE_KINDS.includes(input.kind)) {
30
+ throw new Error(`Sample ${index + 1} has unknown kind "${String(input.kind)}"`);
31
+ }
32
+ const tools = input.tools ?? fallbackTools;
33
+ if (!tools || tools.length === 0) {
34
+ throw new Error(`Sample ${index + 1} has no tool list. Put tool names on the sample or on the file.`);
35
+ }
36
+ return {
37
+ id: input.id ?? `${input.tool}#${index + 1}`,
38
+ tool: input.tool,
39
+ kind: input.kind,
40
+ message: input.message,
41
+ isError: input.isError,
42
+ durationMs: input.durationMs,
43
+ tools,
44
+ };
45
+ }
46
+ function scoreSample(sample, hangMs) {
47
+ const findings = [];
48
+ const text = sample.message?.trim() ?? '';
49
+ const named = mentionedTool(text, sample.tools);
50
+ const blocked = unreachableStep(text);
51
+ if (SILENT_KINDS.has(sample.kind) || (sample.kind === 'explicit' && text.length === 0)) {
52
+ findings.push(finding(sample, 'recover/not-silent', 'Failure has no text an agent can act on. Return an error that names the tool to call next.'));
53
+ }
54
+ const hung = sample.durationMs === undefined
55
+ ? sample.kind === 'timeout'
56
+ : sample.durationMs >= hangMs;
57
+ if (hung) {
58
+ const took = sample.durationMs !== undefined ? `${sample.durationMs}ms` : 'too long';
59
+ findings.push(finding(sample, 'recover/bounded-hang', `Call ran ${took}, past the ${hangMs}ms hang budget. Cut it off instead of waiting.`));
60
+ }
61
+ if (NAMED_TOOL_KINDS.has(sample.kind) && !named) {
62
+ findings.push(finding(sample, 'recover/names-tool', 'Credential or permission error does not name a tool on this server. Say which tool to call, for example `login`, then retry.'));
63
+ }
64
+ if (RETRY_KINDS.has(sample.kind) && !named) {
65
+ findings.push(finding(sample, 'recover/names-retry', `Retry text does not name the call to repeat. Name \`${sample.tool}\` instead of "wait and retry".`));
66
+ }
67
+ if (blocked && !named) {
68
+ findings.push(finding(sample, 'recover/agent-reachable', `Next step asks for ${blocked}, which an agent limited to MCP tools cannot do. Name a tool from this server instead.`));
69
+ }
70
+ else if (blocked && named) {
71
+ findings.push(finding(sample, 'recover/agent-reachable', `Next step still mentions ${blocked} beside tool \`${named}\`. Agents follow that step and stop. Leave only the tool call.`, 'warning'));
72
+ }
73
+ return findings;
74
+ }
75
+ function finding(sample, ruleId, message, severity = 'error') {
76
+ return {
77
+ ruleId,
78
+ severity,
79
+ tool: sample.tool,
80
+ sampleId: sample.id ?? sample.tool,
81
+ message,
82
+ };
83
+ }
84
+ export function mentionedTool(message, tools) {
85
+ const visible = message
86
+ .replace(/\b(npm|npx|pnpm|yarn|pip|brew|sudo)\s+\S+/gi, ' ')
87
+ .replace(/`[^`]*(?:npm |npx |sudo |export )[^`]*`/gi, ' ')
88
+ .replace(/\bhttps?:\/\/\S+/gi, ' ');
89
+ const ordered = [...tools].filter((tool) => tool.trim().length > 0).sort((a, b) => b.length - a.length);
90
+ for (const tool of ordered) {
91
+ const pattern = new RegExp(`(^|[^A-Za-z0-9_-])${escapeRegExp(tool)}(?![A-Za-z0-9_-])`);
92
+ if (pattern.test(visible))
93
+ return tool;
94
+ }
95
+ return null;
96
+ }
97
+ export function unreachableStep(message) {
98
+ if (!message.trim())
99
+ return null;
100
+ if (TERMINAL.test(message))
101
+ return 'a terminal command';
102
+ if (CONFIG.test(message))
103
+ return 'a config change';
104
+ if (WEB.test(message))
105
+ return 'a web page';
106
+ return null;
107
+ }
108
+ /** Description lint ignores a bare URL. Error text still treats a URL as a step the agent cannot open. */
109
+ export function instructionBlocker(message) {
110
+ if (!message.trim())
111
+ return null;
112
+ if (TERMINAL.test(message))
113
+ return 'a terminal command';
114
+ if (CONFIG.test(message))
115
+ return 'a config change';
116
+ if (WEB_INSTRUCTION.test(message))
117
+ return 'a web page';
118
+ return null;
119
+ }
120
+ const TERMINAL = /\b(npm|npx|pnpm|yarn|pip|brew|sudo)\s+\S|\b(in (your |the )?terminal|command line|shell command)\b|`[^`]*(npm |npx |sudo |export )/i;
121
+ const CONFIG = /\b(config(uration)? file|\.env|environment variable|edit your config)\b|\bset [A-Z][A-Z0-9_]{2,}\b/;
122
+ const WEB = /\bhttps?:\/\/\S|\b(open|visit|go to|sign in at|log in at)\b[^.]{0,80}\b(browser|page|dashboard)\b/i;
123
+ const WEB_INSTRUCTION = /\b(open|visit|go to|sign in at|log in at)\b[^.]{0,80}\b(browser|page|dashboard)\b/i;
124
+ function escapeRegExp(value) {
125
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
126
+ }
127
+ export function classifyFailure(input) {
128
+ const text = input.message.trim();
129
+ if (input.timedOut || input.durationMs >= input.hangMs || /\btime(?:d)? out\b/i.test(text)) {
130
+ return 'timeout';
131
+ }
132
+ if (/rate limit|too many requests|\b429\b/i.test(text))
133
+ return 'rate_limit';
134
+ if (/unauthori[sz]ed|invalid (token|api key|credential)|expired (token|credential)|\b401\b/i.test(text)) {
135
+ return 'credential';
136
+ }
137
+ if (/\bforbidden\b|permission denied|\b403\b/i.test(text))
138
+ return 'permission';
139
+ if (input.isError === false && text.length === 0)
140
+ return 'silent';
141
+ if (text.length === 0)
142
+ return 'malformed';
143
+ return 'explicit';
144
+ }
145
+ //# sourceMappingURL=score.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"score.js","sourceRoot":"","sources":["../../src/recover/score.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ export type FailureKind = 'credential' | 'permission' | 'rate_limit' | 'explicit' | 'silent' | 'timeout' | 'malformed';
2
+ export type RecoveryRuleId = 'recover/names-tool' | 'recover/names-retry' | 'recover/agent-reachable' | 'recover/not-silent' | 'recover/bounded-hang';
3
+ export interface RecoverySample {
4
+ id?: string;
5
+ tool: string;
6
+ kind: FailureKind;
7
+ message?: string;
8
+ isError?: boolean;
9
+ durationMs?: number;
10
+ tools: string[];
11
+ }
12
+ export interface RecoverySampleInput {
13
+ id?: string;
14
+ tool: string;
15
+ kind: FailureKind;
16
+ message?: string;
17
+ isError?: boolean;
18
+ durationMs?: number;
19
+ tools?: string[];
20
+ }
21
+ export interface RecoveryFile {
22
+ tools: string[];
23
+ hangMs?: number;
24
+ samples: RecoverySampleInput[];
25
+ }
26
+ export interface RecoveryFinding {
27
+ ruleId: RecoveryRuleId;
28
+ severity: 'error' | 'warning';
29
+ tool: string;
30
+ sampleId: string;
31
+ message: string;
32
+ }
33
+ export interface RecoveryReport {
34
+ samples: number;
35
+ errors: number;
36
+ warnings: number;
37
+ recoverable: number;
38
+ findings: RecoveryFinding[];
39
+ }
40
+ export declare const DEFAULT_HANG_MS = 15000;
41
+ export declare const FAILURE_KINDS: readonly FailureKind[];
@@ -0,0 +1,11 @@
1
+ export const DEFAULT_HANG_MS = 15_000;
2
+ export const FAILURE_KINDS = [
3
+ 'credential',
4
+ 'permission',
5
+ 'rate_limit',
6
+ 'explicit',
7
+ 'silent',
8
+ 'timeout',
9
+ 'malformed',
10
+ ];
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/recover/types.ts"],"names":[],"mappings":"AA0DA,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"}
@@ -0,0 +1,2 @@
1
+ import type { Rule } from '../core/rule.js';
2
+ export declare const noUnreachableInstruction: Rule;
@@ -0,0 +1,36 @@
1
+ import { instructionBlocker } from '../recover/score.js';
2
+ const CLIENTS = ['claude', 'cursor', 'gemini', 'vscode', 'windsurf', 'cline', 'openai', 'continue'];
3
+ export const noUnreachableInstruction = {
4
+ id: 'agent/no-unreachable-instruction',
5
+ severity: 'warning',
6
+ description: 'Tool text must not send an agent to a terminal, a config file, or a web page.',
7
+ clients: CLIENTS,
8
+ docs: {
9
+ why: 'An agent that can only call MCP tools follows the step it is given. A terminal command, config edit, or browser page stops the task.',
10
+ badExample: {
11
+ name: 'search',
12
+ description: 'Search issues. If this fails, run npm login in your terminal.',
13
+ inputSchema: { type: 'object', properties: {} },
14
+ },
15
+ goodExample: {
16
+ name: 'search',
17
+ description: 'Search issues. If authorization fails, call the login tool, then retry search.',
18
+ inputSchema: { type: 'object', properties: {} },
19
+ },
20
+ },
21
+ check(tool, _context) {
22
+ const text = [tool.title, tool.description].filter(Boolean).join('\n');
23
+ const blocked = instructionBlocker(text);
24
+ if (!blocked)
25
+ return [];
26
+ return [{
27
+ ruleId: 'agent/no-unreachable-instruction',
28
+ severity: 'warning',
29
+ message: `Tool "${tool.name}" tells the agent to use ${blocked}. Name a tool on this server instead.`,
30
+ toolName: tool.name,
31
+ path: 'description',
32
+ clients: CLIENTS,
33
+ }];
34
+ },
35
+ };
36
+ //# sourceMappingURL=agent-unreachable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-unreachable.js","sourceRoot":"","sources":["../../src/rules/agent-unreachable.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,OAAO,GAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;AAEhH,MAAM,CAAC,MAAM,wBAAwB,GAAS;IAC5C,EAAE,EAAE,kCAAkC;IACtC,QAAQ,EAAE,SAAS;IACnB,WAAW,EAAE,+EAA+E;IAC5F,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE;QACJ,GAAG,EAAE,sIAAsI;QAC3I,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,+DAA+D;YAC5E,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;SAChD;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,gFAAgF;YAC7F,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;SAChD;KACF;IAED,KAAK,CAAC,IAAa,EAAE,QAAqB;QACxC,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvE,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC;gBACN,MAAM,EAAE,kCAAkC;gBAC1C,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,SAAS,IAAI,CAAC,IAAI,4BAA4B,OAAO,uCAAuC;gBACrG,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE,OAAO;aACjB,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '../core/rule.js';
2
+ export declare const destructiveUnmarked: Rule;
3
+ export declare const readonlyConflict: Rule;
@@ -0,0 +1,82 @@
1
+ const CLIENTS = ['claude', 'cursor', 'gemini', 'vscode', 'windsurf', 'cline', 'openai', 'continue'];
2
+ const DESTRUCTIVE = /\b(delete|drop|destroy|wipe|truncate|unlink|send|pay|charge|deploy|overwrite)\b/i;
3
+ export const destructiveUnmarked = {
4
+ id: 'annotations/destructive-unmarked',
5
+ severity: 'warning',
6
+ description: 'A tool whose name deletes, sends, pays, or deploys must set annotations.destructiveHint.',
7
+ clients: CLIENTS,
8
+ docs: {
9
+ why: 'Clients use destructiveHint to decide whether a call needs a person. A delete tool with no hint looks the same as a read.',
10
+ badExample: {
11
+ name: 'delete_file',
12
+ description: 'Delete a file.',
13
+ inputSchema: { type: 'object', properties: {} },
14
+ },
15
+ goodExample: {
16
+ name: 'delete_file',
17
+ description: 'Delete a file.',
18
+ annotations: { destructiveHint: true, readOnlyHint: false },
19
+ inputSchema: { type: 'object', properties: {} },
20
+ },
21
+ fixNote: 'Set annotations.destructiveHint to true, or to false only when the name is not actually destructive.',
22
+ },
23
+ check(tool, _context) {
24
+ if (!isDestructive(tool) || tool.annotations?.readOnlyHint === true)
25
+ return [];
26
+ if (tool.annotations?.destructiveHint === true)
27
+ return [];
28
+ if (tool.annotations?.destructiveHint === false) {
29
+ return [diagnostic(tool, 'error', `Tool "${tool.name}" looks destructive but annotations.destructiveHint is false.`)];
30
+ }
31
+ return [diagnostic(tool, 'warning', `Tool "${tool.name}" looks destructive and has no annotations.destructiveHint.`)];
32
+ },
33
+ };
34
+ export const readonlyConflict = {
35
+ id: 'annotations/readonly-conflict',
36
+ severity: 'error',
37
+ description: 'A tool marked readOnlyHint must not be named like a delete, send, payment, or deploy.',
38
+ clients: CLIENTS,
39
+ docs: {
40
+ why: 'readOnlyHint tells the client the call cannot change anything. A conflicting name hides a write.',
41
+ badExample: {
42
+ name: 'delete_file',
43
+ annotations: { readOnlyHint: true },
44
+ inputSchema: { type: 'object', properties: {} },
45
+ },
46
+ goodExample: {
47
+ name: 'delete_file',
48
+ annotations: { readOnlyHint: false, destructiveHint: true },
49
+ inputSchema: { type: 'object', properties: {} },
50
+ },
51
+ },
52
+ check(tool, _context) {
53
+ if (tool.annotations?.readOnlyHint !== true || !isDestructive(tool))
54
+ return [];
55
+ return [{
56
+ ruleId: 'annotations/readonly-conflict',
57
+ severity: 'error',
58
+ message: `Tool "${tool.name}" is marked read-only but its name is destructive.`,
59
+ toolName: tool.name,
60
+ path: 'annotations.readOnlyHint',
61
+ clients: CLIENTS,
62
+ }];
63
+ },
64
+ };
65
+ function isDestructive(tool) {
66
+ const words = [tool.name, tool.title ?? '']
67
+ .join(' ')
68
+ .replace(/[_-]+/g, ' ')
69
+ .replace(/([a-z])([A-Z])/g, '$1 $2');
70
+ return DESTRUCTIVE.test(words);
71
+ }
72
+ function diagnostic(tool, severity, message) {
73
+ return {
74
+ ruleId: 'annotations/destructive-unmarked',
75
+ severity,
76
+ message,
77
+ toolName: tool.name,
78
+ path: 'annotations.destructiveHint',
79
+ clients: CLIENTS,
80
+ };
81
+ }
82
+ //# sourceMappingURL=destructive-hint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"destructive-hint.js","sourceRoot":"","sources":["../../src/rules/destructive-hint.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,8 @@ import { vscodeMaxParams } from './client-specific/vscode.js';
14
14
  import { windsurfNoUnionTypes } from './client-specific/windsurf.js';
15
15
  import { clineDescriptionMaxLength } from './client-specific/cline.js';
16
16
  import { openaiNoAdditionalProperties, openaiStrictTypes } from './client-specific/openai.js';
17
+ import { noUnreachableInstruction } from './agent-unreachable.js';
18
+ import { destructiveUnmarked, readonlyConflict } from './destructive-hint.js';
17
19
  export const allRules = [
18
20
  noRequiredFalse,
19
21
  noContentEncoding,
@@ -34,5 +36,8 @@ export const allRules = [
34
36
  clineDescriptionMaxLength,
35
37
  openaiNoAdditionalProperties,
36
38
  openaiStrictTypes,
39
+ noUnreachableInstruction,
40
+ destructiveUnmarked,
41
+ readonlyConflict,
37
42
  ];
38
43
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC/F,OAAO,EAAE,8BAA8B,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpG,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAE9F,MAAM,CAAC,MAAM,QAAQ,GAAW;IAC9B,eAAe;IACf,iBAAiB;IACjB,iBAAiB;IACjB,WAAW;IACX,QAAQ;IACR,eAAe;IACf,qBAAqB;IACrB,oBAAoB;IACpB,iBAAiB;IACjB,uBAAuB;IACvB,0BAA0B;IAC1B,oBAAoB;IACpB,8BAA8B;IAC9B,qBAAqB;IACrB,eAAe;IACf,oBAAoB;IACpB,yBAAyB;IACzB,4BAA4B;IAC5B,iBAAiB;CAClB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC/F,OAAO,EAAE,8BAA8B,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpG,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAC9F,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9E,MAAM,CAAC,MAAM,QAAQ,GAAW;IAC9B,eAAe;IACf,iBAAiB;IACjB,iBAAiB;IACjB,WAAW;IACX,QAAQ;IACR,eAAe;IACf,qBAAqB;IACrB,oBAAoB;IACpB,iBAAiB;IACjB,uBAAuB;IACvB,0BAA0B;IAC1B,oBAAoB;IACpB,8BAA8B;IAC9B,qBAAqB;IACrB,eAAe;IACf,oBAAoB;IACpB,yBAAyB;IACzB,4BAA4B;IAC5B,iBAAiB;IACjB,wBAAwB;IACxB,mBAAmB;IACnB,gBAAgB;CACjB,CAAC"}
@@ -15,7 +15,7 @@ jobs:
15
15
  - uses: actions/checkout@v4
16
16
 
17
17
  - name: Lint MCP tool schemas
18
- uses: robert19001-cmyk/mcp-lint@v0.3.0
18
+ uses: robert19001-cmyk/mcp-lint@v0.6.2
19
19
  with:
20
20
  input: tools.json
21
21
  severity: warning
@@ -0,0 +1,20 @@
1
+ {
2
+ "tools": ["login", "search"],
3
+ "samples": [
4
+ {
5
+ "tool": "search",
6
+ "kind": "credential",
7
+ "message": "Unauthorized. Run npm login in your terminal."
8
+ },
9
+ {
10
+ "tool": "search",
11
+ "kind": "rate_limit",
12
+ "message": "Wait before retrying."
13
+ },
14
+ {
15
+ "tool": "search",
16
+ "kind": "credential",
17
+ "message": "Unauthorized. Call the login tool, then retry search."
18
+ }
19
+ ]
20
+ }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "mcp-lint",
3
- "version": "0.5.3",
3
+ "version": "0.6.2",
4
4
  "mcpName": "io.github.robert19001-cmyk/mcp-lint",
5
- "description": "Lint MCP server tool schemas for cross-client compatibility + runtime preflight for agent tool calls",
5
+ "description": "Lint MCP server tool schemas for cross-client compatibility, runtime preflight, and agent recovery from tool failures",
6
6
  "type": "module",
7
7
  "repository": {
8
8
  "type": "git",
@@ -11,7 +11,7 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/robert19001-cmyk/mcp-lint/issues"
13
13
  },
14
- "homepage": "https://github.com/robert19001-cmyk/mcp-lint#readme",
14
+ "homepage": "https://mcp-lint-alpha.vercel.app/",
15
15
  "bin": {
16
16
  "mcp-lint": "dist/index.js",
17
17
  "mcp-lint-server": "dist/mcp-server.js"
@@ -27,6 +27,10 @@
27
27
  "types": "./dist/preflight/index.d.ts",
28
28
  "default": "./dist/preflight/index.js"
29
29
  },
30
+ "./recover": {
31
+ "types": "./dist/recover/index.d.ts",
32
+ "default": "./dist/recover/index.js"
33
+ },
30
34
  "./rules": {
31
35
  "types": "./dist/rules/index.d.ts",
32
36
  "default": "./dist/rules/index.js"
@@ -55,6 +59,7 @@
55
59
  "schema",
56
60
  "validation",
57
61
  "preflight",
62
+ "recover",
58
63
  "agent-safety",
59
64
  "policy",
60
65
  "guardrails"
@@ -69,6 +74,8 @@
69
74
  "test": "vitest run",
70
75
  "test:watch": "vitest",
71
76
  "test:coverage": "vitest run --coverage",
77
+ "site": "vite --config site/vite.config.ts",
78
+ "site:build": "vite build --config site/vite.config.ts",
72
79
  "prepublishOnly": "npm run build && npm run test"
73
80
  },
74
81
  "dependencies": {
@@ -81,6 +88,7 @@
81
88
  "devDependencies": {
82
89
  "@types/node": "^25.5.0",
83
90
  "typescript": "^6.0.2",
91
+ "vite": "^8.3.5",
84
92
  "vitest": "^4.1.1"
85
93
  }
86
94
  }