mcp-lint 0.7.0 → 0.9.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 +34 -7
- package/dist/audit/format.d.ts +5 -0
- package/dist/audit/format.js +246 -0
- package/dist/audit/format.js.map +1 -0
- package/dist/audit/index.d.ts +6 -0
- package/dist/audit/index.js +4 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/report.d.ts +268 -0
- package/dist/audit/report.js +327 -0
- package/dist/audit/report.js.map +1 -0
- package/dist/audit/tokens.d.ts +53 -0
- package/dist/audit/tokens.js +131 -0
- package/dist/audit/tokens.js.map +1 -0
- package/dist/cli/commands/check.js +45 -2
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/compat.js +4 -2
- package/dist/cli/commands/compat.js.map +1 -1
- package/dist/cli/commands/fix.js +6 -5
- package/dist/cli/commands/fix.js.map +1 -1
- package/dist/cli/commands/init.js +1 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/report.d.ts +12 -0
- package/dist/cli/commands/report.js +76 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/core/compat-matrix.d.ts +1 -0
- package/dist/core/compat-matrix.js +2 -1
- package/dist/core/compat-matrix.js.map +1 -1
- package/dist/core/diagnostic.d.ts +3 -1
- package/dist/core/engine.d.ts +1 -0
- package/dist/core/engine.js +33 -17
- package/dist/core/engine.js.map +1 -1
- package/dist/core/fixer.js +4 -3
- package/dist/core/fixer.js.map +1 -1
- package/dist/core/quality-score.d.ts +19 -0
- package/dist/core/quality-score.js +52 -13
- package/dist/core/quality-score.js.map +1 -1
- package/dist/core/rule.d.ts +1 -0
- package/dist/discover/files.d.ts +3 -0
- package/dist/discover/files.js +55 -0
- package/dist/discover/files.js.map +1 -0
- package/dist/discover/format.d.ts +6 -0
- package/dist/discover/format.js +20 -0
- package/dist/discover/format.js.map +1 -0
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/installed/config.js +15 -0
- package/dist/installed/config.js.map +1 -1
- package/dist/installed/lint.d.ts +2 -1
- package/dist/installed/lint.js +15 -0
- package/dist/installed/lint.js.map +1 -1
- package/dist/loaders/map-tools.d.ts +1 -0
- package/dist/loaders/map-tools.js +2 -0
- package/dist/loaders/map-tools.js.map +1 -1
- package/dist/loaders/remote-loader.js +2 -1
- package/dist/loaders/remote-loader.js.map +1 -1
- package/dist/loaders/stdio-loader.js +2 -1
- package/dist/loaders/stdio-loader.js.map +1 -1
- package/dist/mcp-server.js +1 -1
- package/dist/mcp-server.js.map +1 -1
- package/dist/preflight/engine.js +27 -0
- package/dist/preflight/engine.js.map +1 -1
- package/dist/recover/probe.js +2 -1
- package/dist/recover/probe.js.map +1 -1
- package/dist/rules/client-specific/claude.js +1 -0
- package/dist/rules/client-specific/claude.js.map +1 -1
- package/dist/rules/client-specific/cline.js +2 -0
- package/dist/rules/client-specific/cline.js.map +1 -1
- package/dist/rules/client-specific/cursor.js +9 -0
- package/dist/rules/client-specific/cursor.js.map +1 -1
- package/dist/rules/client-specific/openai.js +1 -0
- package/dist/rules/client-specific/openai.js.map +1 -1
- package/dist/rules/index.js +3 -1
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/no-content-encoding.js +1 -0
- package/dist/rules/no-content-encoding.js.map +1 -1
- package/dist/rules/no-empty-enum.js +1 -0
- package/dist/rules/no-empty-enum.js.map +1 -1
- package/dist/rules/no-required-false.js +1 -0
- package/dist/rules/no-required-false.js.map +1 -1
- package/dist/rules/no-unsupported-formats.js +1 -0
- package/dist/rules/no-unsupported-formats.js.map +1 -1
- package/dist/rules/tool-name.d.ts +9 -1
- package/dist/rules/tool-name.js +67 -0
- package/dist/rules/tool-name.js.map +1 -1
- package/dist/version.d.ts +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/examples/github-action.yml +2 -1
- package/package.json +13 -3
package/README.md
CHANGED
|
@@ -13,6 +13,8 @@ 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.9.0**. npm `latest` is still 0.8.0 until that release is published, so `npx mcp-lint` does not include `report` yet. 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 and the 1.0 plan. They are not extra commands.
|
|
17
|
+
|
|
16
18
|
```
|
|
17
19
|
$ npx mcp-lint check tools.json
|
|
18
20
|
|
|
@@ -30,7 +32,10 @@ search-tool
|
|
|
30
32
|
## Installation
|
|
31
33
|
|
|
32
34
|
```bash
|
|
33
|
-
#
|
|
35
|
+
# In a repo that already has tools.json
|
|
36
|
+
npx mcp-lint
|
|
37
|
+
|
|
38
|
+
# Or point at a file
|
|
34
39
|
npx mcp-lint check tools.json
|
|
35
40
|
|
|
36
41
|
# Global
|
|
@@ -45,6 +50,9 @@ npm install --save-dev mcp-lint
|
|
|
45
50
|
## Quick Start
|
|
46
51
|
|
|
47
52
|
```bash
|
|
53
|
+
# Look for tools.json, tools.yaml, or mcp-tools.json in this directory
|
|
54
|
+
npx mcp-lint
|
|
55
|
+
|
|
48
56
|
# Check a JSON or YAML file
|
|
49
57
|
mcp-lint check tools.json
|
|
50
58
|
|
|
@@ -178,6 +186,19 @@ mcp-lint check --server sse --url http://localhost:3000/sse
|
|
|
178
186
|
| `1` | One or more errors found |
|
|
179
187
|
| `2` | Invalid input or configuration error |
|
|
180
188
|
|
|
189
|
+
### `mcp-lint report <file>`
|
|
190
|
+
|
|
191
|
+
Writes the versioned audit report for one tools file. `check --format json` still prints the diagnostic array. `report --format json` prints `MCPAuditReport`.
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
mcp-lint report tools.json
|
|
195
|
+
mcp-lint report tools.json --format sarif --output results.sarif
|
|
196
|
+
mcp-lint report tools.json --format html --output report.html
|
|
197
|
+
mcp-lint report tools.json --format markdown
|
|
198
|
+
```
|
|
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. Exit `1` when the report contains an error, or when the file cannot be read.
|
|
201
|
+
|
|
181
202
|
---
|
|
182
203
|
|
|
183
204
|
### `mcp-lint diff <before> <after>`
|
|
@@ -210,10 +231,10 @@ Looked-up files:
|
|
|
210
231
|
|--------|------|
|
|
211
232
|
| Cursor | `~/.cursor/mcp.json` and `./.cursor/mcp.json` |
|
|
212
233
|
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) |
|
|
213
|
-
| Claude Code | `~/.claude.json`, `~/.claude/settings.json`, and `./.mcp.json` |
|
|
234
|
+
| Claude Code | `~/.claude.json`, `~/.claude/settings.json`, and `./.mcp.json`. `~/.claude.json` also contributes each `projects.<path>.mcpServers` entry. |
|
|
214
235
|
| VS Code | `~/Library/Application Support/Code/User/mcp.json` and `./.vscode/mcp.json` |
|
|
215
236
|
|
|
216
|
-
`--strict` also exits 1 when a configured server fails to start. Without it, a start failure is printed and the exit code follows the schema errors.
|
|
237
|
+
`--strict` also exits 1 when a configured server fails to start. Without it, a start failure is printed and the exit code follows the schema errors. If two started servers expose the same tool name, both reports include `tool-name/server-collision`.
|
|
217
238
|
|
|
218
239
|
---
|
|
219
240
|
|
|
@@ -231,7 +252,7 @@ mcp-lint diff tools.json tools.next.json
|
|
|
231
252
|
|
|
232
253
|
### `mcp-lint fix [input]`
|
|
233
254
|
|
|
234
|
-
|
|
255
|
+
Writes fixes marked `safe`. `review` and `manual` fixes are printed by `--dry-run` and left in the file. mcp-lint does not invent titles, descriptions, or hints.
|
|
235
256
|
|
|
236
257
|
```bash
|
|
237
258
|
mcp-lint fix tools.json # fixed output to stdout
|
|
@@ -274,6 +295,8 @@ mcp-lint init --force # overwrite existing
|
|
|
274
295
|
| Rule | Severity | Fixable | Description |
|
|
275
296
|
|------|----------|---------|-------------|
|
|
276
297
|
| `tool-name/client-safe` | 🔴 error, 🟡 warning | ❌ | Names must match `^[A-Za-z0-9_-]{1,64}$`. A leading digit is a warning because Gemini rejects it. |
|
|
298
|
+
| `tool-name/duplicate` | 🔴 error | ❌ | The same name appears twice in one tools list. |
|
|
299
|
+
| `tool-name/server-collision` | 🔴 error | ❌ | The same name is exposed by two servers during `check --installed` or `--from`. |
|
|
277
300
|
|
|
278
301
|
OpenAI and Azure use that pattern. A space, slash, or dot makes the tool disappear. See `examples/names/unsafe.json`.
|
|
279
302
|
|
|
@@ -387,7 +410,8 @@ jobs:
|
|
|
387
410
|
runs-on: ubuntu-latest
|
|
388
411
|
steps:
|
|
389
412
|
- uses: actions/checkout@v4
|
|
390
|
-
- uses: robert19001-cmyk/mcp-lint@v0.
|
|
413
|
+
- uses: robert19001-cmyk/mcp-lint@v0.9.0
|
|
414
|
+
# Tag v0.9.0. The action installs npm latest.
|
|
391
415
|
with:
|
|
392
416
|
input: tools.json
|
|
393
417
|
severity: warning
|
|
@@ -399,12 +423,15 @@ jobs:
|
|
|
399
423
|
|
|
400
424
|
| Input | Default | Description |
|
|
401
425
|
|-------|---------|-------------|
|
|
402
|
-
| `input` |
|
|
426
|
+
| `input` | first `tools.json` in the repo | Path to an MCP tools JSON or YAML file |
|
|
403
427
|
| `format` | `terminal` | `terminal\|json\|markdown` |
|
|
404
428
|
| `severity` | `info` | Minimum severity to report |
|
|
405
429
|
| `clients` | all | Comma-separated client filter |
|
|
406
430
|
| `fail_on` | `error` | Fail CI when issues at this severity found |
|
|
407
431
|
| `score` | `false` | Show quality score |
|
|
432
|
+
| `sarif` | `false` | Upload SARIF when this `mcp-lint` release includes `report`. The workflow needs `security-events: write`. |
|
|
433
|
+
|
|
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`. That is still 0.8.0, so the input warns and skips the upload until 0.9.0 is published.
|
|
408
435
|
|
|
409
436
|
### Manual workflow
|
|
410
437
|
|
|
@@ -720,7 +747,7 @@ The repository includes `glama.json` and a production Dockerfile so MCP director
|
|
|
720
747
|
|
|
721
748
|
## Site
|
|
722
749
|
|
|
723
|
-
The proof page is in `site/`. It runs the same recovery scorer as the CLI.
|
|
750
|
+
The proof page is in `site/`. Version 0.9.0. It runs the same recovery scorer as the CLI and explains every command in plain language. The pictures are generated stills, not screenshots of the tool.
|
|
724
751
|
|
|
725
752
|
```bash
|
|
726
753
|
npm run site
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { MCPAuditReport } from './report.js';
|
|
2
|
+
export declare const AUDIT_FORMATS: readonly ["terminal", "json", "markdown", "sarif", "html"];
|
|
3
|
+
export type AuditFormat = (typeof AUDIT_FORMATS)[number];
|
|
4
|
+
export declare function formatAuditReport(report: MCPAuditReport, format: string, noColor?: boolean): string;
|
|
5
|
+
export declare function escapeHtml(value: string): string;
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
export const AUDIT_FORMATS = ['terminal', 'json', 'markdown', 'sarif', 'html'];
|
|
3
|
+
const SITE = 'https://mcp-lint-alpha.vercel.app/';
|
|
4
|
+
export function formatAuditReport(report, format, noColor = false) {
|
|
5
|
+
switch (format) {
|
|
6
|
+
case 'json':
|
|
7
|
+
return JSON.stringify(report, null, 2) + '\n';
|
|
8
|
+
case 'markdown':
|
|
9
|
+
return formatMarkdownReport(report);
|
|
10
|
+
case 'terminal':
|
|
11
|
+
return formatTerminalReport(report, noColor);
|
|
12
|
+
case 'sarif':
|
|
13
|
+
return formatSarif(report);
|
|
14
|
+
case 'html':
|
|
15
|
+
return formatHtml(report);
|
|
16
|
+
default:
|
|
17
|
+
throw new Error(`Unknown format "${format}". Use ${AUDIT_FORMATS.join(', ')}.`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function escapeHtml(value) {
|
|
21
|
+
return value
|
|
22
|
+
.replace(/&/g, '&')
|
|
23
|
+
.replace(/</g, '<')
|
|
24
|
+
.replace(/>/g, '>')
|
|
25
|
+
.replace(/"/g, '"')
|
|
26
|
+
.replace(/'/g, ''');
|
|
27
|
+
}
|
|
28
|
+
function findingRows(findings) {
|
|
29
|
+
return findings.map((finding) => {
|
|
30
|
+
const cells = [finding.severity, finding.toolName, finding.ruleId, finding.path, finding.message]
|
|
31
|
+
.map((cell) => cell.replace(/\|/g, '\\|').replace(/\n/g, ' '));
|
|
32
|
+
return `| ${cells.join(' | ')} |`;
|
|
33
|
+
}).join('\n');
|
|
34
|
+
}
|
|
35
|
+
function formatMarkdownReport(report) {
|
|
36
|
+
const counts = report.severity.status === 'ran'
|
|
37
|
+
? `${report.severity.data.error} errors, ${report.severity.data.warning} warnings, ${report.severity.data.info} info`
|
|
38
|
+
: report.severity.reason;
|
|
39
|
+
const findings = report.findings.status === 'ran'
|
|
40
|
+
? (report.findings.data.length === 0
|
|
41
|
+
? 'No schema findings in this run.\n'
|
|
42
|
+
: [
|
|
43
|
+
'| Severity | Tool | Rule | Path | Message |',
|
|
44
|
+
'| --- | --- | --- | --- | --- |',
|
|
45
|
+
findingRows(report.findings.data),
|
|
46
|
+
'',
|
|
47
|
+
].join('\n'))
|
|
48
|
+
: `${report.findings.reason}\n`;
|
|
49
|
+
const tokens = report.tokenBudget.status === 'ran'
|
|
50
|
+
? [
|
|
51
|
+
`Approximate \`chars / 4\` estimate: **${report.tokenBudget.data.tokens}** tokens (${report.tokenBudget.data.chars} chars), level \`${report.tokenBudget.data.level}\`.`,
|
|
52
|
+
report.tokenBudget.data.note,
|
|
53
|
+
'',
|
|
54
|
+
].join('\n')
|
|
55
|
+
: `${report.tokenBudget.status === 'partial' ? report.tokenBudget.reason : report.tokenBudget.reason}\n`;
|
|
56
|
+
const notRun = report.coverage.notRun.map((name) => `- ${name}`).join('\n');
|
|
57
|
+
const recommendations = report.recommendations.map((line) => `- ${line}`).join('\n');
|
|
58
|
+
return [
|
|
59
|
+
`# mcp-lint report`,
|
|
60
|
+
'',
|
|
61
|
+
`Source: \`${report.scope.source}\``,
|
|
62
|
+
`Generated: ${report.generatedAt}`,
|
|
63
|
+
`Tool: mcp-lint ${report.tool.version}`,
|
|
64
|
+
`Schema: ${report.schemaVersion}`,
|
|
65
|
+
'',
|
|
66
|
+
'## Summary',
|
|
67
|
+
'',
|
|
68
|
+
counts,
|
|
69
|
+
`Confidence: ${report.coverage.confidence}. A section marked not run is not a pass.`,
|
|
70
|
+
'',
|
|
71
|
+
'## Findings',
|
|
72
|
+
'',
|
|
73
|
+
findings.trimEnd(),
|
|
74
|
+
'',
|
|
75
|
+
'## Token estimate',
|
|
76
|
+
'',
|
|
77
|
+
tokens.trimEnd(),
|
|
78
|
+
'',
|
|
79
|
+
'## Not measured',
|
|
80
|
+
'',
|
|
81
|
+
notRun || '- none',
|
|
82
|
+
'',
|
|
83
|
+
'## Recommendations',
|
|
84
|
+
'',
|
|
85
|
+
recommendations || '- none',
|
|
86
|
+
'',
|
|
87
|
+
].join('\n');
|
|
88
|
+
}
|
|
89
|
+
function formatTerminalReport(report, noColor) {
|
|
90
|
+
const tone = (severity, text) => {
|
|
91
|
+
if (noColor)
|
|
92
|
+
return text;
|
|
93
|
+
if (severity === 'error')
|
|
94
|
+
return chalk.red(text);
|
|
95
|
+
if (severity === 'warning')
|
|
96
|
+
return chalk.yellow(text);
|
|
97
|
+
return chalk.blue(text);
|
|
98
|
+
};
|
|
99
|
+
const lines = [
|
|
100
|
+
`${noColor ? '' : chalk.bold('')}mcp-lint report ${report.scope.source}`.trim(),
|
|
101
|
+
report.severity.status === 'ran'
|
|
102
|
+
? `${report.severity.data.error} errors, ${report.severity.data.warning} warnings, ${report.severity.data.info} info`
|
|
103
|
+
: report.severity.reason,
|
|
104
|
+
];
|
|
105
|
+
if (report.findings.status === 'ran') {
|
|
106
|
+
for (const finding of report.findings.data) {
|
|
107
|
+
lines.push(tone(finding.severity, `${finding.severity} ${finding.toolName} ${finding.message}`));
|
|
108
|
+
lines.push(` ${finding.path} [${finding.ruleId}]`);
|
|
109
|
+
}
|
|
110
|
+
if (report.findings.data.length === 0)
|
|
111
|
+
lines.push('No schema findings in this run.');
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
lines.push(report.findings.reason);
|
|
115
|
+
}
|
|
116
|
+
if (report.tokenBudget.status === 'ran') {
|
|
117
|
+
lines.push(`Token estimate (chars/4, approximate): ${report.tokenBudget.data.tokens} level ${report.tokenBudget.data.level}`);
|
|
118
|
+
}
|
|
119
|
+
for (const line of report.recommendations)
|
|
120
|
+
lines.push(line);
|
|
121
|
+
lines.push(`Not measured: ${report.coverage.notRun.join(', ')}`);
|
|
122
|
+
return lines.join('\n') + '\n';
|
|
123
|
+
}
|
|
124
|
+
function formatSarif(report) {
|
|
125
|
+
const findings = report.findings.status === 'ran' ? report.findings.data : [];
|
|
126
|
+
const ruleIds = [...new Set(findings.map((finding) => finding.ruleId))].sort((a, b) => a.localeCompare(b));
|
|
127
|
+
const ruleIndex = new Map(ruleIds.map((id, index) => [id, index]));
|
|
128
|
+
const notifications = report.coverage.notRun.map((name) => ({
|
|
129
|
+
message: { text: `${name} did not run. An empty result is not a pass for that section.` },
|
|
130
|
+
level: 'note',
|
|
131
|
+
}));
|
|
132
|
+
const sarif = {
|
|
133
|
+
$schema: 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json',
|
|
134
|
+
version: '2.1.0',
|
|
135
|
+
runs: [
|
|
136
|
+
{
|
|
137
|
+
tool: {
|
|
138
|
+
driver: {
|
|
139
|
+
name: 'mcp-lint',
|
|
140
|
+
version: report.tool.version,
|
|
141
|
+
informationUri: SITE,
|
|
142
|
+
rules: ruleIds.map((id) => ({
|
|
143
|
+
id,
|
|
144
|
+
shortDescription: { text: id },
|
|
145
|
+
})),
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
invocations: [
|
|
149
|
+
{
|
|
150
|
+
executionSuccessful: true,
|
|
151
|
+
toolExecutionNotifications: notifications,
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
results: findings.map((finding) => ({
|
|
155
|
+
ruleId: finding.ruleId,
|
|
156
|
+
ruleIndex: ruleIndex.get(finding.ruleId),
|
|
157
|
+
level: finding.severity === 'error' ? 'error' : finding.severity === 'warning' ? 'warning' : 'note',
|
|
158
|
+
message: { text: finding.message },
|
|
159
|
+
locations: [
|
|
160
|
+
{
|
|
161
|
+
physicalLocation: {
|
|
162
|
+
artifactLocation: { uri: encodeURI(report.scope.source) },
|
|
163
|
+
},
|
|
164
|
+
logicalLocations: [
|
|
165
|
+
{
|
|
166
|
+
name: finding.toolName,
|
|
167
|
+
fullyQualifiedName: `${finding.toolName}.${finding.path}`,
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
partialFingerprints: {
|
|
173
|
+
'mcpLint/v1': `${finding.toolName}/${finding.ruleId}/${finding.path}`,
|
|
174
|
+
},
|
|
175
|
+
properties: {
|
|
176
|
+
clients: finding.clients,
|
|
177
|
+
fixable: finding.fixable,
|
|
178
|
+
},
|
|
179
|
+
})),
|
|
180
|
+
},
|
|
181
|
+
],
|
|
182
|
+
};
|
|
183
|
+
return JSON.stringify(sarif, null, 2) + '\n';
|
|
184
|
+
}
|
|
185
|
+
function formatHtml(report) {
|
|
186
|
+
const findings = report.findings.status === 'ran'
|
|
187
|
+
? (report.findings.data.length === 0
|
|
188
|
+
? '<p>No schema findings in this run.</p>'
|
|
189
|
+
: `<table>
|
|
190
|
+
<thead><tr><th>Severity</th><th>Tool</th><th>Rule</th><th>Path</th><th>Message</th></tr></thead>
|
|
191
|
+
<tbody>
|
|
192
|
+
${report.findings.data.map((finding) => `<tr>
|
|
193
|
+
<td>${escapeHtml(finding.severity)}</td>
|
|
194
|
+
<td>${escapeHtml(finding.toolName)}</td>
|
|
195
|
+
<td><code>${escapeHtml(finding.ruleId)}</code></td>
|
|
196
|
+
<td><code>${escapeHtml(finding.path)}</code></td>
|
|
197
|
+
<td>${escapeHtml(finding.message)}</td>
|
|
198
|
+
</tr>`).join('\n')}
|
|
199
|
+
</tbody>
|
|
200
|
+
</table>`)
|
|
201
|
+
: `<p>${escapeHtml(report.findings.reason)}</p>`;
|
|
202
|
+
const tokens = report.tokenBudget.status === 'ran'
|
|
203
|
+
? `<p>Approximate chars/4 estimate: <strong>${report.tokenBudget.data.tokens}</strong> tokens, level ${escapeHtml(report.tokenBudget.data.level)}.</p><p>${escapeHtml(report.tokenBudget.data.note)}</p>`
|
|
204
|
+
: `<p>${escapeHtml(report.tokenBudget.reason)}</p>`;
|
|
205
|
+
const counts = report.severity.status === 'ran'
|
|
206
|
+
? `${report.severity.data.error} errors, ${report.severity.data.warning} warnings, ${report.severity.data.info} info`
|
|
207
|
+
: report.severity.reason;
|
|
208
|
+
const notRun = report.coverage.notRun.map((name) => `<li>${escapeHtml(name)}</li>`).join('');
|
|
209
|
+
const recommendations = report.recommendations.map((line) => `<li>${escapeHtml(line)}</li>`).join('');
|
|
210
|
+
return `<!DOCTYPE html>
|
|
211
|
+
<html lang="en">
|
|
212
|
+
<head>
|
|
213
|
+
<meta charset="utf-8">
|
|
214
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
215
|
+
<title>mcp-lint report: ${escapeHtml(report.scope.source)}</title>
|
|
216
|
+
<style>
|
|
217
|
+
body { margin: 0; background: #f3efe4; color: #1c1916; font: 16px/1.5 ui-sans-serif, system-ui, sans-serif; }
|
|
218
|
+
main { max-width: 880px; margin: 0 auto; padding: 32px 20px 64px; }
|
|
219
|
+
h1 { font-size: 32px; line-height: 1.15; margin-bottom: 8px; }
|
|
220
|
+
h2 { font-size: 18px; margin-top: 32px; }
|
|
221
|
+
p, li { max-width: 68ch; }
|
|
222
|
+
table { width: 100%; border-collapse: collapse; }
|
|
223
|
+
th, td { text-align: left; vertical-align: top; border-bottom: 1px solid #d9d2c5; padding: 8px; }
|
|
224
|
+
code { font-family: ui-monospace, monospace; }
|
|
225
|
+
.meta { color: #5c564e; }
|
|
226
|
+
</style>
|
|
227
|
+
</head>
|
|
228
|
+
<body>
|
|
229
|
+
<main>
|
|
230
|
+
<p class="meta">mcp-lint ${escapeHtml(report.tool.version)} · schema ${report.schemaVersion} · ${escapeHtml(report.generatedAt)}</p>
|
|
231
|
+
<h1>${escapeHtml(report.scope.source)}</h1>
|
|
232
|
+
<p>${escapeHtml(counts)}. Confidence ${escapeHtml(report.coverage.confidence)}. A section that did not run is not a pass.</p>
|
|
233
|
+
<h2>Findings</h2>
|
|
234
|
+
${findings}
|
|
235
|
+
<h2>Token estimate</h2>
|
|
236
|
+
${tokens}
|
|
237
|
+
<h2>Not measured</h2>
|
|
238
|
+
<ul>${notRun}</ul>
|
|
239
|
+
<h2>Recommendations</h2>
|
|
240
|
+
<ul>${recommendations}</ul>
|
|
241
|
+
</main>
|
|
242
|
+
</body>
|
|
243
|
+
</html>
|
|
244
|
+
`;
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/audit/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { AUDIT_REPORT_SCHEMA_VERSION, QUALITY_ALGORITHM, AuditInputError, AuditReportSchema, buildAuditReport, parseAuditReport, } from './report.js';
|
|
2
|
+
export type { AuditFinding, AuditTool, BuildAuditReportInput, MCPAuditReport, QualitySectionData, Section, SectionStatus, SeverityCounts, } from './report.js';
|
|
3
|
+
export { AUDIT_FORMATS, escapeHtml, formatAuditReport } from './format.js';
|
|
4
|
+
export type { AuditFormat } from './format.js';
|
|
5
|
+
export { DEFAULT_TOKEN_THRESHOLDS, TOKEN_ESTIMATE_METHOD, TokenEstimateError, assertThresholds, buildTokenBudget, compareTokenBudgets, estimateTokens, } from './tokens.js';
|
|
6
|
+
export type { RepeatedDescription, TokenBudget, TokenBudgetDiff, TokenEstimate, TokenThresholds, ToolTokenRank, } from './tokens.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { AUDIT_REPORT_SCHEMA_VERSION, QUALITY_ALGORITHM, AuditInputError, AuditReportSchema, buildAuditReport, parseAuditReport, } from './report.js';
|
|
2
|
+
export { AUDIT_FORMATS, escapeHtml, formatAuditReport } from './format.js';
|
|
3
|
+
export { DEFAULT_TOKEN_THRESHOLDS, TOKEN_ESTIMATE_METHOD, TokenEstimateError, assertThresholds, buildTokenBudget, compareTokenBudgets, estimateTokens, } from './tokens.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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;AAE3E,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,GACf,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { Diagnostic } from '../core/diagnostic.js';
|
|
3
|
+
import { type TokenBudget, type TokenThresholds } from './tokens.js';
|
|
4
|
+
export declare const AUDIT_REPORT_SCHEMA_VERSION: 1;
|
|
5
|
+
export declare const QUALITY_ALGORITHM: "quality-v2";
|
|
6
|
+
export declare class AuditInputError extends Error {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
export type SectionStatus = 'ran' | 'not_run' | 'partial' | 'failed';
|
|
10
|
+
export interface RanSection<T> {
|
|
11
|
+
status: 'ran';
|
|
12
|
+
data: T;
|
|
13
|
+
}
|
|
14
|
+
export interface NotRunSection {
|
|
15
|
+
status: 'not_run' | 'failed';
|
|
16
|
+
reason: string;
|
|
17
|
+
}
|
|
18
|
+
export interface PartialSection<T> {
|
|
19
|
+
status: 'partial';
|
|
20
|
+
reason: string;
|
|
21
|
+
data: T;
|
|
22
|
+
}
|
|
23
|
+
export type Section<T> = RanSection<T> | NotRunSection | PartialSection<T>;
|
|
24
|
+
export interface AuditFinding {
|
|
25
|
+
ruleId: string;
|
|
26
|
+
severity: 'error' | 'warning' | 'info';
|
|
27
|
+
message: string;
|
|
28
|
+
toolName: string;
|
|
29
|
+
path: string;
|
|
30
|
+
clients: string[];
|
|
31
|
+
fixable: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface AuditTool {
|
|
34
|
+
name: string;
|
|
35
|
+
hasDescription: boolean;
|
|
36
|
+
hasInputSchema: boolean;
|
|
37
|
+
hasOutputSchema: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface QualitySectionData {
|
|
40
|
+
algorithm: typeof QUALITY_ALGORITHM;
|
|
41
|
+
overall: number;
|
|
42
|
+
grade: 'A' | 'B' | 'C' | 'D' | 'F';
|
|
43
|
+
weights: {
|
|
44
|
+
description: number;
|
|
45
|
+
inputSchema: number;
|
|
46
|
+
outputSchema: number;
|
|
47
|
+
lintClean: number;
|
|
48
|
+
error: number;
|
|
49
|
+
warning: number;
|
|
50
|
+
};
|
|
51
|
+
coverage: {
|
|
52
|
+
toolCount: number;
|
|
53
|
+
withDescription: number;
|
|
54
|
+
withInputSchema: number;
|
|
55
|
+
withOutputSchema: number;
|
|
56
|
+
};
|
|
57
|
+
confidence: 'low' | 'medium';
|
|
58
|
+
note: string;
|
|
59
|
+
}
|
|
60
|
+
export interface SeverityCounts {
|
|
61
|
+
error: number;
|
|
62
|
+
warning: number;
|
|
63
|
+
info: number;
|
|
64
|
+
}
|
|
65
|
+
export interface MCPAuditReport {
|
|
66
|
+
schemaVersion: typeof AUDIT_REPORT_SCHEMA_VERSION;
|
|
67
|
+
generatedAt: string;
|
|
68
|
+
tool: {
|
|
69
|
+
name: 'mcp-lint';
|
|
70
|
+
version: string;
|
|
71
|
+
};
|
|
72
|
+
scope: {
|
|
73
|
+
source: string;
|
|
74
|
+
mode: 'offline-tools';
|
|
75
|
+
liveServer: false;
|
|
76
|
+
toolsInvoked: false;
|
|
77
|
+
};
|
|
78
|
+
tools: AuditTool[];
|
|
79
|
+
duplicateToolNames: string[];
|
|
80
|
+
findings: Section<AuditFinding[]>;
|
|
81
|
+
severity: Section<SeverityCounts>;
|
|
82
|
+
compatibility: NotRunSection;
|
|
83
|
+
tokenBudget: Section<TokenBudget>;
|
|
84
|
+
quality: Section<QualitySectionData>;
|
|
85
|
+
recovery: NotRunSection;
|
|
86
|
+
preflight: NotRunSection;
|
|
87
|
+
recommendations: string[];
|
|
88
|
+
coverage: {
|
|
89
|
+
ran: string[];
|
|
90
|
+
notRun: string[];
|
|
91
|
+
confidence: 'low' | 'medium' | 'high';
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export interface BuildAuditReportInput {
|
|
95
|
+
source: string;
|
|
96
|
+
tools: unknown;
|
|
97
|
+
diagnostics?: Diagnostic[];
|
|
98
|
+
version?: string;
|
|
99
|
+
generatedAt?: string;
|
|
100
|
+
thresholds?: TokenThresholds;
|
|
101
|
+
}
|
|
102
|
+
export declare const AuditReportSchema: z.ZodObject<{
|
|
103
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
104
|
+
generatedAt: z.ZodString;
|
|
105
|
+
tool: z.ZodObject<{
|
|
106
|
+
name: z.ZodLiteral<"mcp-lint">;
|
|
107
|
+
version: z.ZodString;
|
|
108
|
+
}, z.core.$strict>;
|
|
109
|
+
scope: z.ZodObject<{
|
|
110
|
+
source: z.ZodString;
|
|
111
|
+
mode: z.ZodLiteral<"offline-tools">;
|
|
112
|
+
liveServer: z.ZodLiteral<false>;
|
|
113
|
+
toolsInvoked: z.ZodLiteral<false>;
|
|
114
|
+
}, z.core.$strict>;
|
|
115
|
+
tools: z.ZodArray<z.ZodObject<{
|
|
116
|
+
name: z.ZodString;
|
|
117
|
+
hasDescription: z.ZodBoolean;
|
|
118
|
+
hasInputSchema: z.ZodBoolean;
|
|
119
|
+
hasOutputSchema: z.ZodBoolean;
|
|
120
|
+
}, z.core.$strict>>;
|
|
121
|
+
duplicateToolNames: z.ZodArray<z.ZodString>;
|
|
122
|
+
findings: z.ZodObject<{
|
|
123
|
+
status: z.ZodEnum<{
|
|
124
|
+
failed: "failed";
|
|
125
|
+
ran: "ran";
|
|
126
|
+
not_run: "not_run";
|
|
127
|
+
partial: "partial";
|
|
128
|
+
}>;
|
|
129
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
130
|
+
data: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
131
|
+
ruleId: z.ZodString;
|
|
132
|
+
severity: z.ZodEnum<{
|
|
133
|
+
error: "error";
|
|
134
|
+
warning: "warning";
|
|
135
|
+
info: "info";
|
|
136
|
+
}>;
|
|
137
|
+
message: z.ZodString;
|
|
138
|
+
toolName: z.ZodString;
|
|
139
|
+
path: z.ZodString;
|
|
140
|
+
clients: z.ZodArray<z.ZodString>;
|
|
141
|
+
fixable: z.ZodBoolean;
|
|
142
|
+
}, z.core.$strict>>>;
|
|
143
|
+
}, z.core.$strict>;
|
|
144
|
+
severity: z.ZodObject<{
|
|
145
|
+
status: z.ZodEnum<{
|
|
146
|
+
failed: "failed";
|
|
147
|
+
ran: "ran";
|
|
148
|
+
not_run: "not_run";
|
|
149
|
+
partial: "partial";
|
|
150
|
+
}>;
|
|
151
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
152
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
153
|
+
error: z.ZodNumber;
|
|
154
|
+
warning: z.ZodNumber;
|
|
155
|
+
info: z.ZodNumber;
|
|
156
|
+
}, z.core.$strict>>;
|
|
157
|
+
}, z.core.$strict>;
|
|
158
|
+
compatibility: z.ZodObject<{
|
|
159
|
+
status: z.ZodEnum<{
|
|
160
|
+
failed: "failed";
|
|
161
|
+
not_run: "not_run";
|
|
162
|
+
}>;
|
|
163
|
+
reason: z.ZodString;
|
|
164
|
+
}, z.core.$strict>;
|
|
165
|
+
tokenBudget: z.ZodObject<{
|
|
166
|
+
status: z.ZodEnum<{
|
|
167
|
+
failed: "failed";
|
|
168
|
+
ran: "ran";
|
|
169
|
+
not_run: "not_run";
|
|
170
|
+
partial: "partial";
|
|
171
|
+
}>;
|
|
172
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
173
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
174
|
+
method: z.ZodLiteral<"chars-div-4">;
|
|
175
|
+
approximate: z.ZodLiteral<true>;
|
|
176
|
+
chars: z.ZodNumber;
|
|
177
|
+
tokens: z.ZodNumber;
|
|
178
|
+
toolCount: z.ZodNumber;
|
|
179
|
+
thresholds: z.ZodObject<{
|
|
180
|
+
warn: z.ZodNumber;
|
|
181
|
+
over: z.ZodNumber;
|
|
182
|
+
schemaWarn: z.ZodNumber;
|
|
183
|
+
}, z.core.$strict>;
|
|
184
|
+
level: z.ZodEnum<{
|
|
185
|
+
ok: "ok";
|
|
186
|
+
warn: "warn";
|
|
187
|
+
over: "over";
|
|
188
|
+
}>;
|
|
189
|
+
tools: z.ZodArray<z.ZodObject<{
|
|
190
|
+
name: z.ZodString;
|
|
191
|
+
chars: z.ZodNumber;
|
|
192
|
+
tokens: z.ZodNumber;
|
|
193
|
+
schemaTokens: z.ZodNumber;
|
|
194
|
+
oversizedSchema: z.ZodBoolean;
|
|
195
|
+
}, z.core.$strict>>;
|
|
196
|
+
repeatedDescriptions: z.ZodArray<z.ZodObject<{
|
|
197
|
+
description: z.ZodString;
|
|
198
|
+
tools: z.ZodArray<z.ZodString>;
|
|
199
|
+
}, z.core.$strict>>;
|
|
200
|
+
note: z.ZodString;
|
|
201
|
+
}, z.core.$strict>>;
|
|
202
|
+
}, z.core.$strict>;
|
|
203
|
+
quality: z.ZodObject<{
|
|
204
|
+
status: z.ZodEnum<{
|
|
205
|
+
failed: "failed";
|
|
206
|
+
ran: "ran";
|
|
207
|
+
not_run: "not_run";
|
|
208
|
+
partial: "partial";
|
|
209
|
+
}>;
|
|
210
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
211
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
212
|
+
algorithm: z.ZodLiteral<"quality-v2">;
|
|
213
|
+
overall: z.ZodNumber;
|
|
214
|
+
grade: z.ZodEnum<{
|
|
215
|
+
A: "A";
|
|
216
|
+
B: "B";
|
|
217
|
+
C: "C";
|
|
218
|
+
D: "D";
|
|
219
|
+
F: "F";
|
|
220
|
+
}>;
|
|
221
|
+
weights: z.ZodObject<{
|
|
222
|
+
description: z.ZodLiteral<25>;
|
|
223
|
+
inputSchema: z.ZodLiteral<25>;
|
|
224
|
+
outputSchema: z.ZodLiteral<10>;
|
|
225
|
+
lintClean: z.ZodLiteral<40>;
|
|
226
|
+
error: z.ZodLiteral<15>;
|
|
227
|
+
warning: z.ZodLiteral<5>;
|
|
228
|
+
}, z.core.$strict>;
|
|
229
|
+
coverage: z.ZodObject<{
|
|
230
|
+
toolCount: z.ZodNumber;
|
|
231
|
+
withDescription: z.ZodNumber;
|
|
232
|
+
withInputSchema: z.ZodNumber;
|
|
233
|
+
withOutputSchema: z.ZodNumber;
|
|
234
|
+
}, z.core.$strict>;
|
|
235
|
+
confidence: z.ZodEnum<{
|
|
236
|
+
low: "low";
|
|
237
|
+
medium: "medium";
|
|
238
|
+
}>;
|
|
239
|
+
note: z.ZodString;
|
|
240
|
+
}, z.core.$strict>>;
|
|
241
|
+
}, z.core.$strict>;
|
|
242
|
+
recovery: z.ZodObject<{
|
|
243
|
+
status: z.ZodEnum<{
|
|
244
|
+
failed: "failed";
|
|
245
|
+
not_run: "not_run";
|
|
246
|
+
}>;
|
|
247
|
+
reason: z.ZodString;
|
|
248
|
+
}, z.core.$strict>;
|
|
249
|
+
preflight: z.ZodObject<{
|
|
250
|
+
status: z.ZodEnum<{
|
|
251
|
+
failed: "failed";
|
|
252
|
+
not_run: "not_run";
|
|
253
|
+
}>;
|
|
254
|
+
reason: z.ZodString;
|
|
255
|
+
}, z.core.$strict>;
|
|
256
|
+
recommendations: z.ZodArray<z.ZodString>;
|
|
257
|
+
coverage: z.ZodObject<{
|
|
258
|
+
ran: z.ZodArray<z.ZodString>;
|
|
259
|
+
notRun: z.ZodArray<z.ZodString>;
|
|
260
|
+
confidence: z.ZodEnum<{
|
|
261
|
+
low: "low";
|
|
262
|
+
medium: "medium";
|
|
263
|
+
high: "high";
|
|
264
|
+
}>;
|
|
265
|
+
}, z.core.$strict>;
|
|
266
|
+
}, z.core.$strict>;
|
|
267
|
+
export declare function buildAuditReport(input: BuildAuditReportInput): MCPAuditReport;
|
|
268
|
+
export declare function parseAuditReport(value: unknown): MCPAuditReport;
|