mcp-lint 0.8.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.
Files changed (106) hide show
  1. package/README.md +51 -11
  2. package/dist/audit/baseline.d.ts +3 -0
  3. package/dist/audit/baseline.js +18 -0
  4. package/dist/audit/baseline.js.map +1 -0
  5. package/dist/audit/format.d.ts +5 -0
  6. package/dist/audit/format.js +246 -0
  7. package/dist/audit/format.js.map +1 -0
  8. package/dist/audit/index.d.ts +7 -0
  9. package/dist/audit/index.js +5 -0
  10. package/dist/audit/index.js.map +1 -0
  11. package/dist/audit/report.d.ts +268 -0
  12. package/dist/audit/report.js +327 -0
  13. package/dist/audit/report.js.map +1 -0
  14. package/dist/audit/tokens.d.ts +53 -0
  15. package/dist/audit/tokens.js +131 -0
  16. package/dist/audit/tokens.js.map +1 -0
  17. package/dist/catalog/connect.d.ts +3 -0
  18. package/dist/catalog/connect.js +54 -0
  19. package/dist/catalog/connect.js.map +1 -0
  20. package/dist/catalog/list.d.ts +39 -0
  21. package/dist/catalog/list.js +58 -0
  22. package/dist/catalog/list.js.map +1 -0
  23. package/dist/cli/commands/catalog.d.ts +2 -0
  24. package/dist/cli/commands/catalog.js +76 -0
  25. package/dist/cli/commands/catalog.js.map +1 -0
  26. package/dist/cli/commands/check.js +8 -1
  27. package/dist/cli/commands/check.js.map +1 -1
  28. package/dist/cli/commands/compat.js +4 -2
  29. package/dist/cli/commands/compat.js.map +1 -1
  30. package/dist/cli/commands/fix.js +6 -5
  31. package/dist/cli/commands/fix.js.map +1 -1
  32. package/dist/cli/commands/recover.js +22 -8
  33. package/dist/cli/commands/recover.js.map +1 -1
  34. package/dist/cli/commands/report.d.ts +12 -0
  35. package/dist/cli/commands/report.js +94 -0
  36. package/dist/cli/commands/report.js.map +1 -0
  37. package/dist/core/compat-matrix.d.ts +1 -0
  38. package/dist/core/compat-matrix.js +2 -1
  39. package/dist/core/compat-matrix.js.map +1 -1
  40. package/dist/core/diagnostic.d.ts +3 -1
  41. package/dist/core/engine.d.ts +1 -0
  42. package/dist/core/engine.js +33 -17
  43. package/dist/core/engine.js.map +1 -1
  44. package/dist/core/fixer.js +4 -3
  45. package/dist/core/fixer.js.map +1 -1
  46. package/dist/core/quality-score.d.ts +19 -0
  47. package/dist/core/quality-score.js +52 -13
  48. package/dist/core/quality-score.js.map +1 -1
  49. package/dist/core/rule.d.ts +1 -0
  50. package/dist/discover/files.js +23 -3
  51. package/dist/discover/files.js.map +1 -1
  52. package/dist/index.js +6 -1
  53. package/dist/index.js.map +1 -1
  54. package/dist/installed/config.js +15 -0
  55. package/dist/installed/config.js.map +1 -1
  56. package/dist/installed/lint.d.ts +2 -1
  57. package/dist/installed/lint.js +15 -0
  58. package/dist/installed/lint.js.map +1 -1
  59. package/dist/loaders/map-tools.d.ts +1 -0
  60. package/dist/loaders/map-tools.js +2 -0
  61. package/dist/loaders/map-tools.js.map +1 -1
  62. package/dist/loaders/remote-loader.js +2 -1
  63. package/dist/loaders/remote-loader.js.map +1 -1
  64. package/dist/loaders/stdio-loader.js +2 -1
  65. package/dist/loaders/stdio-loader.js.map +1 -1
  66. package/dist/mcp-server.js +1 -1
  67. package/dist/mcp-server.js.map +1 -1
  68. package/dist/preflight/engine.js +27 -0
  69. package/dist/preflight/engine.js.map +1 -1
  70. package/dist/recover/index.d.ts +1 -1
  71. package/dist/recover/index.js +1 -1
  72. package/dist/recover/index.js.map +1 -1
  73. package/dist/recover/probe.d.ts +10 -10
  74. package/dist/recover/probe.js +22 -1
  75. package/dist/recover/probe.js.map +1 -1
  76. package/dist/recover/score.d.ts +2 -1
  77. package/dist/recover/score.js +14 -0
  78. package/dist/recover/score.js.map +1 -1
  79. package/dist/recover/types.d.ts +4 -0
  80. package/dist/recover/types.js.map +1 -1
  81. package/dist/rules/client-specific/claude.js +1 -0
  82. package/dist/rules/client-specific/claude.js.map +1 -1
  83. package/dist/rules/client-specific/cline.js +2 -0
  84. package/dist/rules/client-specific/cline.js.map +1 -1
  85. package/dist/rules/client-specific/cursor.js +9 -0
  86. package/dist/rules/client-specific/cursor.js.map +1 -1
  87. package/dist/rules/client-specific/openai.js +1 -0
  88. package/dist/rules/client-specific/openai.js.map +1 -1
  89. package/dist/rules/index.js +3 -1
  90. package/dist/rules/index.js.map +1 -1
  91. package/dist/rules/no-content-encoding.js +1 -0
  92. package/dist/rules/no-content-encoding.js.map +1 -1
  93. package/dist/rules/no-empty-enum.js +1 -0
  94. package/dist/rules/no-empty-enum.js.map +1 -1
  95. package/dist/rules/no-required-false.js +1 -0
  96. package/dist/rules/no-required-false.js.map +1 -1
  97. package/dist/rules/no-unsupported-formats.js +1 -0
  98. package/dist/rules/no-unsupported-formats.js.map +1 -1
  99. package/dist/rules/tool-name.d.ts +9 -1
  100. package/dist/rules/tool-name.js +67 -0
  101. package/dist/rules/tool-name.js.map +1 -1
  102. package/dist/version.d.ts +1 -0
  103. package/dist/version.js +2 -0
  104. package/dist/version.js.map +1 -0
  105. package/examples/github-action.yml +2 -1
  106. package/package.json +7 -1
@@ -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;
@@ -0,0 +1,327 @@
1
+ import { z } from 'zod';
2
+ import { computeQualityReport } from '../core/quality-score.js';
3
+ import { buildTokenBudget, DEFAULT_TOKEN_THRESHOLDS, } from './tokens.js';
4
+ import { VERSION } from '../version.js';
5
+ export const AUDIT_REPORT_SCHEMA_VERSION = 1;
6
+ export const QUALITY_ALGORITHM = 'quality-v2';
7
+ export class AuditInputError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = 'AuditInputError';
11
+ }
12
+ }
13
+ const severitySchema = z.enum(['error', 'warning', 'info']);
14
+ const findingSchema = z.object({
15
+ ruleId: z.string().min(1),
16
+ severity: severitySchema,
17
+ message: z.string(),
18
+ toolName: z.string(),
19
+ path: z.string(),
20
+ clients: z.array(z.string()),
21
+ fixable: z.boolean(),
22
+ }).strict();
23
+ const auditToolSchema = z.object({
24
+ name: z.string().min(1),
25
+ hasDescription: z.boolean(),
26
+ hasInputSchema: z.boolean(),
27
+ hasOutputSchema: z.boolean(),
28
+ }).strict();
29
+ const tokenBudgetSchema = z.object({
30
+ method: z.literal('chars-div-4'),
31
+ approximate: z.literal(true),
32
+ chars: z.number().int().nonnegative(),
33
+ tokens: z.number().int().nonnegative(),
34
+ toolCount: z.number().int().nonnegative(),
35
+ thresholds: z.object({
36
+ warn: z.number().int().positive(),
37
+ over: z.number().int().positive(),
38
+ schemaWarn: z.number().int().positive(),
39
+ }).strict(),
40
+ level: z.enum(['ok', 'warn', 'over']),
41
+ tools: z.array(z.object({
42
+ name: z.string(),
43
+ chars: z.number().int().nonnegative(),
44
+ tokens: z.number().int().nonnegative(),
45
+ schemaTokens: z.number().int().nonnegative(),
46
+ oversizedSchema: z.boolean(),
47
+ }).strict()),
48
+ repeatedDescriptions: z.array(z.object({
49
+ description: z.string(),
50
+ tools: z.array(z.string()),
51
+ }).strict()),
52
+ note: z.string().min(1),
53
+ }).strict();
54
+ const qualitySchema = z.object({
55
+ algorithm: z.literal(QUALITY_ALGORITHM),
56
+ overall: z.number().int().min(0).max(100),
57
+ grade: z.enum(['A', 'B', 'C', 'D', 'F']),
58
+ weights: z.object({
59
+ description: z.literal(25),
60
+ inputSchema: z.literal(25),
61
+ outputSchema: z.literal(10),
62
+ lintClean: z.literal(40),
63
+ error: z.literal(15),
64
+ warning: z.literal(5),
65
+ }).strict(),
66
+ coverage: z.object({
67
+ toolCount: z.number().int().nonnegative(),
68
+ withDescription: z.number().int().nonnegative(),
69
+ withInputSchema: z.number().int().nonnegative(),
70
+ withOutputSchema: z.number().int().nonnegative(),
71
+ }).strict(),
72
+ confidence: z.enum(['low', 'medium']),
73
+ note: z.string().min(1),
74
+ }).strict();
75
+ function sectionSchema(data) {
76
+ return z.object({
77
+ status: z.enum(['ran', 'not_run', 'partial', 'failed']),
78
+ reason: z.string().min(1).optional(),
79
+ data: data.optional(),
80
+ }).strict().superRefine((value, ctx) => {
81
+ if (value.status === 'ran' && value.data === undefined) {
82
+ ctx.addIssue({ code: 'custom', message: 'A ran section needs data.' });
83
+ }
84
+ if ((value.status === 'not_run' || value.status === 'failed') && (value.reason === undefined || value.data !== undefined)) {
85
+ ctx.addIssue({ code: 'custom', message: 'A not_run or failed section needs a reason and no data.' });
86
+ }
87
+ if (value.status === 'partial' && (value.reason === undefined || value.data === undefined)) {
88
+ ctx.addIssue({ code: 'custom', message: 'A partial section needs a reason and data.' });
89
+ }
90
+ });
91
+ }
92
+ const notRunSchema = z.object({
93
+ status: z.enum(['not_run', 'failed']),
94
+ reason: z.string().min(1),
95
+ }).strict();
96
+ export const AuditReportSchema = z.object({
97
+ schemaVersion: z.literal(AUDIT_REPORT_SCHEMA_VERSION),
98
+ generatedAt: z.string().min(1),
99
+ tool: z.object({ name: z.literal('mcp-lint'), version: z.string().min(1) }).strict(),
100
+ scope: z.object({
101
+ source: z.string().min(1),
102
+ mode: z.literal('offline-tools'),
103
+ liveServer: z.literal(false),
104
+ toolsInvoked: z.literal(false),
105
+ }).strict(),
106
+ tools: z.array(auditToolSchema),
107
+ duplicateToolNames: z.array(z.string()),
108
+ findings: sectionSchema(z.array(findingSchema)),
109
+ severity: sectionSchema(z.object({
110
+ error: z.number().int().nonnegative(),
111
+ warning: z.number().int().nonnegative(),
112
+ info: z.number().int().nonnegative(),
113
+ }).strict()),
114
+ compatibility: notRunSchema,
115
+ tokenBudget: sectionSchema(tokenBudgetSchema),
116
+ quality: sectionSchema(qualitySchema),
117
+ recovery: notRunSchema,
118
+ preflight: notRunSchema,
119
+ recommendations: z.array(z.string()),
120
+ coverage: z.object({
121
+ ran: z.array(z.string()),
122
+ notRun: z.array(z.string()),
123
+ confidence: z.enum(['low', 'medium', 'high']),
124
+ }).strict(),
125
+ }).strict();
126
+ function notRun(reason) {
127
+ return { status: 'not_run', reason };
128
+ }
129
+ function isRecord(value) {
130
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
131
+ }
132
+ function requireTools(value) {
133
+ if (!Array.isArray(value)) {
134
+ throw new AuditInputError('tools must be an array.');
135
+ }
136
+ return value.map((tool, index) => {
137
+ if (!isRecord(tool))
138
+ throw new AuditInputError(`tools[${index}] must be an object.`);
139
+ if (typeof tool.name !== 'string' || tool.name.trim() === '') {
140
+ throw new AuditInputError(`tools[${index}].name must be a non-empty string.`);
141
+ }
142
+ if (tool.description !== undefined && typeof tool.description !== 'string') {
143
+ throw new AuditInputError(`tools[${index}].description must be a string.`);
144
+ }
145
+ if (tool.inputSchema !== undefined && !isRecord(tool.inputSchema)) {
146
+ throw new AuditInputError(`tools[${index}].inputSchema must be an object.`);
147
+ }
148
+ if (tool.outputSchema !== undefined && !isRecord(tool.outputSchema)) {
149
+ throw new AuditInputError(`tools[${index}].outputSchema must be an object.`);
150
+ }
151
+ return tool;
152
+ });
153
+ }
154
+ function duplicateNames(tools) {
155
+ const counts = new Map();
156
+ for (const tool of tools) {
157
+ const name = tool.name;
158
+ counts.set(name, (counts.get(name) ?? 0) + 1);
159
+ }
160
+ return [...counts.entries()]
161
+ .filter(([, count]) => count > 1)
162
+ .map(([name]) => name)
163
+ .sort((a, b) => a.localeCompare(b));
164
+ }
165
+ function findingsFrom(diagnostics) {
166
+ return diagnostics
167
+ .map((diagnostic) => ({
168
+ ruleId: diagnostic.ruleId,
169
+ severity: diagnostic.severity,
170
+ message: diagnostic.message,
171
+ toolName: diagnostic.toolName,
172
+ path: diagnostic.path,
173
+ clients: [...diagnostic.clients].sort((a, b) => a.localeCompare(b)),
174
+ fixable: diagnostic.fix != null,
175
+ }))
176
+ .sort((a, b) => a.toolName.localeCompare(b.toolName)
177
+ || a.path.localeCompare(b.path)
178
+ || a.ruleId.localeCompare(b.ruleId)
179
+ || a.message.localeCompare(b.message));
180
+ }
181
+ function recommendations(input) {
182
+ const lines = [];
183
+ if (!input.findingsRan) {
184
+ lines.push('Schema lint did not run. A missing finding list is not a pass.');
185
+ }
186
+ else if ((input.counts?.error ?? 0) > 0) {
187
+ lines.push('Fix error findings before shipping this tools list.');
188
+ }
189
+ if (input.duplicates.length > 0) {
190
+ lines.push(`Rename duplicate tool names: ${input.duplicates.join(', ')}.`);
191
+ }
192
+ if (input.missingDescriptions > 0) {
193
+ lines.push('Add a description to every tool. Clients use it to choose a call.');
194
+ }
195
+ if (input.missingSchemas > 0) {
196
+ lines.push('Add inputSchema to every tool. An absent schema was not scored as valid.');
197
+ }
198
+ if (input.tokenLevel === 'over' || input.tokenLevel === 'warn') {
199
+ lines.push('The approximate token estimate is at or above a configured threshold.');
200
+ }
201
+ if (input.repeated > 0) {
202
+ lines.push('Repeated descriptions hide which tool the agent should call.');
203
+ }
204
+ if (input.toolCount === 0) {
205
+ lines.push('No tools were supplied, so the quality score was withheld.');
206
+ }
207
+ else if (input.findingsRan && (input.counts?.error ?? 0) === 0 && lines.length === 0) {
208
+ lines.push('No schema errors in this run. Recovery, preflight, and live inspection were not measured.');
209
+ }
210
+ return lines;
211
+ }
212
+ export function buildAuditReport(input) {
213
+ if (input.source.trim() === '')
214
+ throw new AuditInputError('source must be a non-empty string.');
215
+ const tools = requireTools(input.tools);
216
+ const inventory = tools.map((tool) => ({
217
+ name: tool.name,
218
+ hasDescription: typeof tool.description === 'string' && tool.description.trim() !== '',
219
+ hasInputSchema: isRecord(tool.inputSchema),
220
+ hasOutputSchema: isRecord(tool.outputSchema),
221
+ }));
222
+ const duplicates = duplicateNames(tools);
223
+ const findingsRan = input.diagnostics !== undefined;
224
+ const findings = findingsRan ? findingsFrom(input.diagnostics ?? []) : undefined;
225
+ const counts = findings
226
+ ? {
227
+ error: findings.filter((finding) => finding.severity === 'error').length,
228
+ warning: findings.filter((finding) => finding.severity === 'warning').length,
229
+ info: findings.filter((finding) => finding.severity === 'info').length,
230
+ }
231
+ : undefined;
232
+ let tokenSection;
233
+ try {
234
+ tokenSection = {
235
+ status: 'ran',
236
+ data: buildTokenBudget(tools, input.thresholds ?? DEFAULT_TOKEN_THRESHOLDS),
237
+ };
238
+ }
239
+ catch (err) {
240
+ tokenSection = {
241
+ status: 'failed',
242
+ reason: err instanceof Error ? err.message : 'Token estimate failed.',
243
+ };
244
+ }
245
+ let quality;
246
+ if (!findingsRan) {
247
+ quality = notRun('Schema lint did not run, so the quality score was withheld.');
248
+ }
249
+ else if (tools.length === 0) {
250
+ quality = notRun('No tools were supplied, so the quality score was withheld.');
251
+ }
252
+ else {
253
+ const scored = computeQualityReport(tools, input.diagnostics ?? []);
254
+ quality = {
255
+ status: 'ran',
256
+ data: {
257
+ algorithm: QUALITY_ALGORITHM,
258
+ overall: scored.overall,
259
+ grade: scored.grade,
260
+ weights: scored.weights,
261
+ coverage: scored.coverage,
262
+ confidence: scored.confidence,
263
+ note: 'quality-v2 adds points only for a description, an input schema, an output schema, and a clean lint. Missing fields add nothing. This is not a security guarantee.',
264
+ },
265
+ };
266
+ }
267
+ const tokenLevel = tokenSection.status === 'ran' ? tokenSection.data.level : undefined;
268
+ const lines = recommendations({
269
+ findingsRan,
270
+ counts,
271
+ duplicates,
272
+ missingDescriptions: inventory.filter((tool) => !tool.hasDescription).length,
273
+ missingSchemas: inventory.filter((tool) => !tool.hasInputSchema).length,
274
+ toolCount: tools.length,
275
+ tokenLevel,
276
+ repeated: tokenSection.status === 'ran' ? tokenSection.data.repeatedDescriptions.length : 0,
277
+ });
278
+ const ran = ['tools'];
279
+ if (tokenSection.status === 'ran')
280
+ ran.push('tokenBudget');
281
+ if (findingsRan)
282
+ ran.push('findings', 'severity');
283
+ if (quality.status === 'ran')
284
+ ran.push('quality');
285
+ const notRunNames = ['compatibility', 'recovery', 'preflight'];
286
+ if (!findingsRan)
287
+ notRunNames.push('findings', 'severity');
288
+ if (quality.status !== 'ran')
289
+ notRunNames.push('quality');
290
+ if (tokenSection.status !== 'ran')
291
+ notRunNames.push('tokenBudget');
292
+ const confidence = tools.length === 0 || !findingsRan
293
+ ? 'low'
294
+ : quality.status === 'ran' && tokenSection.status === 'ran'
295
+ ? 'medium'
296
+ : 'low';
297
+ return {
298
+ schemaVersion: AUDIT_REPORT_SCHEMA_VERSION,
299
+ generatedAt: input.generatedAt ?? new Date().toISOString(),
300
+ tool: { name: 'mcp-lint', version: input.version ?? VERSION },
301
+ scope: {
302
+ source: input.source,
303
+ mode: 'offline-tools',
304
+ liveServer: false,
305
+ toolsInvoked: false,
306
+ },
307
+ tools: inventory,
308
+ duplicateToolNames: duplicates,
309
+ findings: findings ? { status: 'ran', data: findings } : notRun('Schema lint did not run.'),
310
+ severity: counts ? { status: 'ran', data: counts } : notRun('Schema lint did not run.'),
311
+ compatibility: notRun('Client compatibility was not re-checked for this report.'),
312
+ tokenBudget: tokenSection,
313
+ quality,
314
+ recovery: notRun('Recovery was not scored.'),
315
+ preflight: notRun('Preflight was not evaluated.'),
316
+ recommendations: lines,
317
+ coverage: {
318
+ ran,
319
+ notRun: notRunNames,
320
+ confidence,
321
+ },
322
+ };
323
+ }
324
+ export function parseAuditReport(value) {
325
+ return AuditReportSchema.parse(value);
326
+ }
327
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/audit/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ export declare const TOKEN_ESTIMATE_METHOD: "chars-div-4";
2
+ export declare class TokenEstimateError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export interface TokenEstimate {
6
+ method: typeof TOKEN_ESTIMATE_METHOD;
7
+ approximate: true;
8
+ chars: number;
9
+ tokens: number;
10
+ }
11
+ export interface TokenThresholds {
12
+ warn: number;
13
+ over: number;
14
+ schemaWarn: number;
15
+ }
16
+ export interface ToolTokenRank {
17
+ name: string;
18
+ chars: number;
19
+ tokens: number;
20
+ schemaTokens: number;
21
+ oversizedSchema: boolean;
22
+ }
23
+ export interface RepeatedDescription {
24
+ description: string;
25
+ tools: string[];
26
+ }
27
+ export interface TokenBudget {
28
+ method: typeof TOKEN_ESTIMATE_METHOD;
29
+ approximate: true;
30
+ chars: number;
31
+ tokens: number;
32
+ toolCount: number;
33
+ thresholds: TokenThresholds;
34
+ level: 'ok' | 'warn' | 'over';
35
+ tools: ToolTokenRank[];
36
+ repeatedDescriptions: RepeatedDescription[];
37
+ note: string;
38
+ }
39
+ export interface TokenBudgetDiff {
40
+ method: typeof TOKEN_ESTIMATE_METHOD;
41
+ approximate: true;
42
+ beforeTokens: number;
43
+ afterTokens: number;
44
+ deltaTokens: number;
45
+ addedTools: string[];
46
+ removedTools: string[];
47
+ grew: string[];
48
+ }
49
+ export declare const DEFAULT_TOKEN_THRESHOLDS: TokenThresholds;
50
+ export declare function estimateTokens(value: unknown): TokenEstimate;
51
+ export declare function assertThresholds(thresholds: TokenThresholds): void;
52
+ export declare function buildTokenBudget(tools: ReadonlyArray<Record<string, unknown>>, thresholds?: TokenThresholds): TokenBudget;
53
+ export declare function compareTokenBudgets(before: TokenBudget, after: TokenBudget): TokenBudgetDiff;