@cyanheads/nist-nvd-mcp-server 0.1.3

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 (72) hide show
  1. package/AGENTS.md +410 -0
  2. package/CLAUDE.md +410 -0
  3. package/Dockerfile +99 -0
  4. package/LICENSE +201 -0
  5. package/README.md +306 -0
  6. package/changelog/0.1.x/0.1.0.md +19 -0
  7. package/changelog/0.1.x/0.1.1.md +29 -0
  8. package/changelog/0.1.x/0.1.2.md +12 -0
  9. package/changelog/0.1.x/0.1.3.md +22 -0
  10. package/changelog/template.md +119 -0
  11. package/dist/config/server-config.d.ts +15 -0
  12. package/dist/config/server-config.d.ts.map +1 -0
  13. package/dist/config/server-config.js +27 -0
  14. package/dist/config/server-config.js.map +1 -0
  15. package/dist/index.d.ts +8 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +32 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/mcp-server/resources/definitions/index.d.ts +6 -0
  20. package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -0
  21. package/dist/mcp-server/resources/definitions/index.js +6 -0
  22. package/dist/mcp-server/resources/definitions/index.js.map +1 -0
  23. package/dist/mcp-server/resources/definitions/nvd-cve.resource.d.ts +9 -0
  24. package/dist/mcp-server/resources/definitions/nvd-cve.resource.d.ts.map +1 -0
  25. package/dist/mcp-server/resources/definitions/nvd-cve.resource.js +36 -0
  26. package/dist/mcp-server/resources/definitions/nvd-cve.resource.js.map +1 -0
  27. package/dist/mcp-server/tools/definitions/index.d.ts +10 -0
  28. package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
  29. package/dist/mcp-server/tools/definitions/index.js +10 -0
  30. package/dist/mcp-server/tools/definitions/index.js.map +1 -0
  31. package/dist/mcp-server/tools/definitions/nvd-audit-cpe.tool.d.ts +116 -0
  32. package/dist/mcp-server/tools/definitions/nvd-audit-cpe.tool.d.ts.map +1 -0
  33. package/dist/mcp-server/tools/definitions/nvd-audit-cpe.tool.js +329 -0
  34. package/dist/mcp-server/tools/definitions/nvd-audit-cpe.tool.js.map +1 -0
  35. package/dist/mcp-server/tools/definitions/nvd-get-cve-history.tool.d.ts +45 -0
  36. package/dist/mcp-server/tools/definitions/nvd-get-cve-history.tool.d.ts.map +1 -0
  37. package/dist/mcp-server/tools/definitions/nvd-get-cve-history.tool.js +132 -0
  38. package/dist/mcp-server/tools/definitions/nvd-get-cve-history.tool.js.map +1 -0
  39. package/dist/mcp-server/tools/definitions/nvd-get-cve.tool.d.ts +36 -0
  40. package/dist/mcp-server/tools/definitions/nvd-get-cve.tool.d.ts.map +1 -0
  41. package/dist/mcp-server/tools/definitions/nvd-get-cve.tool.js +183 -0
  42. package/dist/mcp-server/tools/definitions/nvd-get-cve.tool.js.map +1 -0
  43. package/dist/mcp-server/tools/definitions/nvd-search-cpes.tool.d.ts +40 -0
  44. package/dist/mcp-server/tools/definitions/nvd-search-cpes.tool.d.ts.map +1 -0
  45. package/dist/mcp-server/tools/definitions/nvd-search-cpes.tool.js +140 -0
  46. package/dist/mcp-server/tools/definitions/nvd-search-cpes.tool.js.map +1 -0
  47. package/dist/mcp-server/tools/definitions/nvd-search-cves.tool.d.ts +90 -0
  48. package/dist/mcp-server/tools/definitions/nvd-search-cves.tool.d.ts.map +1 -0
  49. package/dist/mcp-server/tools/definitions/nvd-search-cves.tool.js +342 -0
  50. package/dist/mcp-server/tools/definitions/nvd-search-cves.tool.js.map +1 -0
  51. package/dist/services/nvd-cpe/nvd-cpe-service.d.ts +27 -0
  52. package/dist/services/nvd-cpe/nvd-cpe-service.d.ts.map +1 -0
  53. package/dist/services/nvd-cpe/nvd-cpe-service.js +58 -0
  54. package/dist/services/nvd-cpe/nvd-cpe-service.js.map +1 -0
  55. package/dist/services/nvd-cpe/types.d.ts +41 -0
  56. package/dist/services/nvd-cpe/types.d.ts.map +1 -0
  57. package/dist/services/nvd-cpe/types.js +6 -0
  58. package/dist/services/nvd-cpe/types.js.map +1 -0
  59. package/dist/services/nvd-cve/nvd-cve-service.d.ts +79 -0
  60. package/dist/services/nvd-cve/nvd-cve-service.d.ts.map +1 -0
  61. package/dist/services/nvd-cve/nvd-cve-service.js +345 -0
  62. package/dist/services/nvd-cve/nvd-cve-service.js.map +1 -0
  63. package/dist/services/nvd-cve/types.d.ts +185 -0
  64. package/dist/services/nvd-cve/types.d.ts.map +1 -0
  65. package/dist/services/nvd-cve/types.js +6 -0
  66. package/dist/services/nvd-cve/types.js.map +1 -0
  67. package/dist/services/nvd-http/nvd-http-client.d.ts +26 -0
  68. package/dist/services/nvd-http/nvd-http-client.d.ts.map +1 -0
  69. package/dist/services/nvd-http/nvd-http-client.js +175 -0
  70. package/dist/services/nvd-http/nvd-http-client.js.map +1 -0
  71. package/package.json +91 -0
  72. package/server.json +125 -0
@@ -0,0 +1,329 @@
1
+ /**
2
+ * @fileoverview Tool for finding CVEs affecting a specific product and version by CPE.
3
+ * @module src/mcp-server/tools/definitions/nvd-audit-cpe
4
+ */
5
+ import { tool, z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ import { getNvdCveService } from '../../../services/nvd-cve/nvd-cve-service.js';
8
+ const CPE_V23_REGEX = /^cpe:2\.3:/i;
9
+ const CvssScoreSchema = z.object({
10
+ version: z.string().describe('CVSS version (e.g., "2.0", "3.1", "4.0").'),
11
+ sourceType: z.string().describe('Score source: "Primary" = NVD, "Secondary" = CNA.'),
12
+ baseScore: z.number().describe('Base score (0.0–10.0).'),
13
+ severity: z.string().describe('Severity label: CRITICAL, HIGH, MEDIUM, or LOW.'),
14
+ vectorString: z.string().optional().describe('CVSS vector string.'),
15
+ });
16
+ const TopSeveritySchema = z.object({
17
+ label: z.string().describe('Highest severity label across all CVSS versions.'),
18
+ score: z.number().describe('Highest base score (0.0–10.0).'),
19
+ fromVersion: z.string().describe('Which CVSS version this top score came from.'),
20
+ });
21
+ const CveRecordSchema = z.object({
22
+ cveId: z.string().describe('CVE identifier (e.g., "CVE-2021-44228").'),
23
+ vulnStatus: z.string().describe('NVD analysis status.'),
24
+ published: z.string().describe('ISO 8601 publication datetime.'),
25
+ lastModified: z.string().describe('ISO 8601 last-modified datetime.'),
26
+ descriptions: z
27
+ .array(z
28
+ .object({
29
+ lang: z.string().describe('Language code.'),
30
+ value: z.string().describe('CVE description.'),
31
+ })
32
+ .describe('One localized CVE description.'))
33
+ .describe('CVE descriptions by language.'),
34
+ cvssScores: z
35
+ .array(CvssScoreSchema.describe('One CVSS score entry.'))
36
+ .describe('All available CVSS scores across versions.'),
37
+ severity: TopSeveritySchema.optional().describe('Top severity. Absent if no CVSS scores present.'),
38
+ weaknesses: z
39
+ .array(z
40
+ .object({
41
+ source: z.string().describe('Weakness source (NVD or CNA).'),
42
+ cweIds: z
43
+ .array(z.string().describe('One CWE identifier.'))
44
+ .describe('CWE identifiers for this source.'),
45
+ })
46
+ .describe('One weakness classification entry.'))
47
+ .describe('CWE weakness classifications.'),
48
+ configurations: z
49
+ .array(z
50
+ .object({
51
+ nodes: z
52
+ .array(z
53
+ .object({
54
+ operator: z.string().optional().describe('Logical operator (AND/OR).'),
55
+ cpeMatch: z
56
+ .array(z
57
+ .object({
58
+ vulnerable: z
59
+ .boolean()
60
+ .describe('Whether this CPE is the vulnerable component.'),
61
+ criteria: z.string().describe('CPEv2.3 match criteria string.'),
62
+ versionStartIncluding: z
63
+ .string()
64
+ .optional()
65
+ .describe('Inclusive lower version bound.'),
66
+ versionStartExcluding: z
67
+ .string()
68
+ .optional()
69
+ .describe('Exclusive lower version bound.'),
70
+ versionEndIncluding: z
71
+ .string()
72
+ .optional()
73
+ .describe('Inclusive upper version bound.'),
74
+ versionEndExcluding: z
75
+ .string()
76
+ .optional()
77
+ .describe('Exclusive upper version bound.'),
78
+ })
79
+ .describe('One CPE match criterion.'))
80
+ .describe('CPE match criteria for this node.'),
81
+ })
82
+ .describe('One configuration node with its CPE match criteria.'))
83
+ .describe('Configuration nodes.'),
84
+ })
85
+ .describe('One affected product configuration group.'))
86
+ .describe('Affected product configurations.'),
87
+ references: z
88
+ .array(z
89
+ .object({
90
+ url: z.string().describe('Reference URL.'),
91
+ source: z.string().optional().describe('Reference source.'),
92
+ tags: z
93
+ .array(z.string().describe('One classification tag.'))
94
+ .optional()
95
+ .describe('Classification tags.'),
96
+ })
97
+ .describe('One external reference.'))
98
+ .optional()
99
+ .describe('External references.'),
100
+ cisaKev: z
101
+ .object({
102
+ exploitAddDate: z.string().describe('Date added to CISA KEV catalog.'),
103
+ actionDueDate: z.string().describe('Federal agency remediation deadline.'),
104
+ requiredAction: z.string().describe('Required remediation steps.'),
105
+ vulnerabilityName: z.string().describe("CISA's vulnerability name."),
106
+ })
107
+ .optional()
108
+ .describe('CISA KEV fields. Present only when CVE is in the KEV catalog.'),
109
+ });
110
+ export const nvdAuditCpe = tool('nvd_audit_cpe', {
111
+ title: 'Audit CPE for Vulnerabilities',
112
+ description: 'Find all CVEs affecting a specific product and version using CPE (Common Platform Enumeration). ' +
113
+ 'Requires either an exact CPE name (cpeName) or a partial match string (virtualMatchString) with optional version range bounds. ' +
114
+ 'With cpeName, NVD scopes results to configurations where the product is directly vulnerable, not merely referenced as a dependency. ' +
115
+ 'Use nvd_search_cpes first to resolve the correct CPE string for a product. ' +
116
+ 'Returns full CVE records.',
117
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },
118
+ input: z.object({
119
+ cpeName: z
120
+ .string()
121
+ .optional()
122
+ .describe('Full CPEv2.3 name (e.g., "cpe:2.3:a:apache:http_server:2.4.51:*:*:*:*:*:*:*"). ' +
123
+ 'NVD adds isVulnerable automatically. Mutually exclusive with virtualMatchString.'),
124
+ virtualMatchString: z
125
+ .string()
126
+ .optional()
127
+ .describe('Partial CPE match pattern (e.g., "cpe:2.3:a:apache:http_server:*"). ' +
128
+ 'Use with versionStart/versionEnd for version range audits. Mutually exclusive with cpeName.'),
129
+ versionStart: z
130
+ .string()
131
+ .optional()
132
+ .describe('Lower version bound. Requires virtualMatchString.'),
133
+ versionStartType: z
134
+ .enum(['including', 'excluding'])
135
+ .default('including')
136
+ .describe('Whether the lower version bound is inclusive or exclusive.'),
137
+ versionEnd: z.string().optional().describe('Upper version bound. Requires virtualMatchString.'),
138
+ versionEndType: z
139
+ .enum(['including', 'excluding'])
140
+ .default('including')
141
+ .describe('Whether the upper version bound is inclusive or exclusive.'),
142
+ severityMin: z
143
+ .enum(['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'])
144
+ .optional()
145
+ .describe('Filter out CVEs below this severity level.'),
146
+ limit: z
147
+ .number()
148
+ .int()
149
+ .min(1)
150
+ .max(2000)
151
+ .default(20)
152
+ .describe('Maximum number of CVEs to return (default 20, max 2000).'),
153
+ }),
154
+ output: z.object({
155
+ cves: z
156
+ .array(CveRecordSchema.describe('Full CVE record for one vulnerability affecting the product.'))
157
+ .describe('Full CVE records for CVEs affecting the specified product.'),
158
+ queryMeta: z
159
+ .object({
160
+ totalResults: z.number().describe('Total CVEs matched before pagination.'),
161
+ returned: z.number().describe('Number of CVE records returned.'),
162
+ cpeName: z
163
+ .string()
164
+ .optional()
165
+ .describe('The exact CPE name used in the query, if provided.'),
166
+ virtualMatchString: z
167
+ .string()
168
+ .optional()
169
+ .describe('The virtual match string used, if provided.'),
170
+ })
171
+ .describe('Query metadata echoing the CPE identifier and match counts for the audit.'),
172
+ }),
173
+ errors: [
174
+ {
175
+ reason: 'missing_cpe_input',
176
+ code: JsonRpcErrorCode.InvalidParams,
177
+ when: 'Neither cpeName nor virtualMatchString was provided.',
178
+ recovery: 'Provide either cpeName (exact CPEv2.3 string) or virtualMatchString (partial match pattern) — use nvd_search_cpes to find the correct CPE.',
179
+ },
180
+ {
181
+ reason: 'conflicting_cpe_inputs',
182
+ code: JsonRpcErrorCode.InvalidParams,
183
+ when: 'Both cpeName and virtualMatchString were provided simultaneously.',
184
+ recovery: 'Provide only one of cpeName or virtualMatchString per call, not both.',
185
+ },
186
+ {
187
+ reason: 'version_range_without_match_string',
188
+ code: JsonRpcErrorCode.InvalidParams,
189
+ when: 'versionStart or versionEnd was provided without virtualMatchString.',
190
+ recovery: 'Version range parameters require virtualMatchString; provide that parameter or use cpeName for exact-version queries.',
191
+ },
192
+ {
193
+ reason: 'invalid_cpe_format',
194
+ code: JsonRpcErrorCode.InvalidParams,
195
+ when: 'cpeName or virtualMatchString does not start with "cpe:2.3:" — not a valid CPEv2.3 string.',
196
+ recovery: 'Provide a valid CPEv2.3 string starting with "cpe:2.3:". Use nvd_search_cpes to find the correct CPE name.',
197
+ },
198
+ {
199
+ reason: 'cpe_not_found',
200
+ code: JsonRpcErrorCode.NotFound,
201
+ when: 'The cpeName is valid format but NVD returns no matching CVEs — the CPE may be misspelled or absent from NVD.',
202
+ recovery: 'Use nvd_search_cpes to verify the exact CPE name exists in the NVD dictionary before auditing.',
203
+ },
204
+ {
205
+ reason: 'rate_limited',
206
+ code: JsonRpcErrorCode.ServiceUnavailable,
207
+ when: 'NVD returned HTTP 403 indicating the rate limit was exceeded.',
208
+ retryable: true,
209
+ recovery: 'Wait for the NVD rate window to reset or set the NVD_API_KEY environment variable for higher limits.',
210
+ },
211
+ ],
212
+ async handler(input, ctx) {
213
+ // Validate inputs
214
+ if (!input.cpeName && !input.virtualMatchString) {
215
+ throw ctx.fail('missing_cpe_input', 'Either cpeName or virtualMatchString is required.', ctx.recoveryFor('missing_cpe_input'));
216
+ }
217
+ if (input.cpeName && input.virtualMatchString) {
218
+ throw ctx.fail('conflicting_cpe_inputs', 'Provide only one of cpeName or virtualMatchString, not both.', ctx.recoveryFor('conflicting_cpe_inputs'));
219
+ }
220
+ if ((input.versionStart || input.versionEnd) && !input.virtualMatchString) {
221
+ throw ctx.fail('version_range_without_match_string', 'versionStart/versionEnd require virtualMatchString.', ctx.recoveryFor('version_range_without_match_string'));
222
+ }
223
+ if (input.cpeName && !CPE_V23_REGEX.test(input.cpeName)) {
224
+ throw ctx.fail('invalid_cpe_format', `Invalid CPE name: "${input.cpeName}". CPEv2.3 names must start with "cpe:2.3:".`, ctx.recoveryFor('invalid_cpe_format'));
225
+ }
226
+ if (input.virtualMatchString && !CPE_V23_REGEX.test(input.virtualMatchString)) {
227
+ throw ctx.fail('invalid_cpe_format', `Invalid CPE string: "${input.virtualMatchString}". CPEv2.3 strings must start with "cpe:2.3:".`, ctx.recoveryFor('invalid_cpe_format'));
228
+ }
229
+ ctx.log.info('Auditing CPE for vulnerabilities', {
230
+ cpeName: input.cpeName,
231
+ virtualMatchString: input.virtualMatchString,
232
+ limit: input.limit,
233
+ });
234
+ const service = getNvdCveService();
235
+ const result = await service.auditCpe({
236
+ ...(input.cpeName && { cpeName: input.cpeName }),
237
+ ...(input.virtualMatchString && { virtualMatchString: input.virtualMatchString }),
238
+ ...(input.versionStart && { versionStart: input.versionStart }),
239
+ versionStartType: input.versionStartType,
240
+ ...(input.versionEnd && { versionEnd: input.versionEnd }),
241
+ versionEndType: input.versionEndType,
242
+ ...(input.severityMin && { severityMin: input.severityMin }),
243
+ limit: input.limit,
244
+ }, ctx);
245
+ return {
246
+ cves: result.cves,
247
+ queryMeta: {
248
+ totalResults: result.totalResults,
249
+ returned: result.returned,
250
+ ...(result.cpeName && { cpeName: result.cpeName }),
251
+ ...(result.virtualMatchString && { virtualMatchString: result.virtualMatchString }),
252
+ },
253
+ };
254
+ },
255
+ format: (result) => {
256
+ const lines = [];
257
+ const cpeName = result.queryMeta.cpeName;
258
+ const virtualMatchString = result.queryMeta.virtualMatchString;
259
+ const target = cpeName ?? virtualMatchString ?? 'unknown CPE';
260
+ lines.push(`**CPE Audit:** ${target}`);
261
+ if (cpeName)
262
+ lines.push(`**CPE Name:** ${cpeName}`);
263
+ if (virtualMatchString)
264
+ lines.push(`**Virtual Match String:** ${virtualMatchString}`);
265
+ lines.push(`**Total CVEs:** ${result.queryMeta.totalResults} | **Returned:** ${result.queryMeta.returned}\n`);
266
+ if (result.cves.length === 0) {
267
+ lines.push('No CVEs found for this product. Verify the CPE name with nvd_search_cpes.');
268
+ return [{ type: 'text', text: lines.join('\n') }];
269
+ }
270
+ for (const cve of result.cves) {
271
+ lines.push(`## ${cve.cveId}`);
272
+ lines.push(`**Status:** ${cve.vulnStatus} | **Published:** ${cve.published} | **Last Modified:** ${cve.lastModified}`);
273
+ if (cve.severity) {
274
+ lines.push(`**Severity:** ${cve.severity.label} (${cve.severity.score}) from CVSS ${cve.severity.fromVersion}`);
275
+ }
276
+ else {
277
+ lines.push('**Severity:** Not available (no CVSS scores)');
278
+ }
279
+ if (cve.cvssScores && cve.cvssScores.length > 0) {
280
+ lines.push('**CVSS Scores:**');
281
+ for (const s of cve.cvssScores) {
282
+ lines.push(` - v${s.version} (${s.sourceType}): ${s.baseScore} ${s.severity}` +
283
+ (s.vectorString ? ` — ${s.vectorString}` : ''));
284
+ }
285
+ }
286
+ if (cve.weaknesses && cve.weaknesses.length > 0) {
287
+ lines.push('**Weaknesses:**');
288
+ for (const w of cve.weaknesses) {
289
+ if (w.cweIds.length > 0) {
290
+ lines.push(` - ${w.source}: ${w.cweIds.join(', ')}`);
291
+ }
292
+ }
293
+ }
294
+ // Descriptions — render lang and value for all entries to satisfy format-parity
295
+ for (const desc of cve.descriptions) {
296
+ const truncated = desc.value.length > 300 ? `${desc.value.slice(0, 300)}…` : desc.value;
297
+ lines.push(`\n[${desc.lang}] ${truncated}`);
298
+ }
299
+ if (cve.cisaKev) {
300
+ lines.push(`\n**CISA KEV:** ${cve.cisaKev.vulnerabilityName}`);
301
+ lines.push(` - Added: ${cve.cisaKev.exploitAddDate}`);
302
+ lines.push(` - Action Due: ${cve.cisaKev.actionDueDate}`);
303
+ lines.push(` - Required Action: ${cve.cisaKev.requiredAction}`);
304
+ }
305
+ if (cve.configurations && cve.configurations.length > 0) {
306
+ lines.push(`**Configurations:** ${cve.configurations.length} node group(s)`);
307
+ for (const cfg of cve.configurations) {
308
+ for (const node of cfg.nodes) {
309
+ if (node.operator)
310
+ lines.push(` - Operator: ${node.operator}`);
311
+ }
312
+ }
313
+ }
314
+ if (cve.references && cve.references.length > 0) {
315
+ lines.push(`**References (${cve.references.length}):**`);
316
+ for (const ref of cve.references.slice(0, 5)) {
317
+ const sourcePart = ref.source ? ` [${ref.source}]` : '';
318
+ const tagPart = ref.tags?.length ? ` (${ref.tags.join(', ')})` : '';
319
+ lines.push(` - ${ref.url}${sourcePart}${tagPart}`);
320
+ }
321
+ if (cve.references.length > 5)
322
+ lines.push(` - … ${cve.references.length - 5} more`);
323
+ }
324
+ lines.push('');
325
+ }
326
+ return [{ type: 'text', text: lines.join('\n') }];
327
+ },
328
+ });
329
+ //# sourceMappingURL=nvd-audit-cpe.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nvd-audit-cpe.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/nvd-audit-cpe.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @fileoverview Tool for retrieving the change history of a CVE from the NIST NVD API.
3
+ * @module src/mcp-server/tools/definitions/nvd-get-cve-history
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ export declare const nvdGetCveHistory: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
8
+ cveId: z.ZodString;
9
+ limit: z.ZodDefault<z.ZodNumber>;
10
+ offset: z.ZodDefault<z.ZodNumber>;
11
+ }, z.core.$strip>, z.ZodObject<{
12
+ cveId: z.ZodString;
13
+ changes: z.ZodArray<z.ZodObject<{
14
+ changeDate: z.ZodString;
15
+ eventName: z.ZodOptional<z.ZodString>;
16
+ details: z.ZodArray<z.ZodObject<{
17
+ action: z.ZodOptional<z.ZodString>;
18
+ type: z.ZodOptional<z.ZodString>;
19
+ oldValue: z.ZodOptional<z.ZodString>;
20
+ newValue: z.ZodOptional<z.ZodString>;
21
+ }, z.core.$strip>>;
22
+ }, z.core.$strip>>;
23
+ queryMeta: z.ZodObject<{
24
+ totalResults: z.ZodNumber;
25
+ returned: z.ZodNumber;
26
+ offset: z.ZodNumber;
27
+ }, z.core.$strip>;
28
+ }, z.core.$strip>, readonly [{
29
+ readonly reason: "invalid_cve_id_format";
30
+ readonly code: JsonRpcErrorCode.InvalidParams;
31
+ readonly when: "The CVE ID fails format validation (NVD returns HTTP 404 for malformed IDs).";
32
+ readonly recovery: "Use the format CVE-YYYY-NNNNN (e.g., CVE-2021-44228) and verify the ID is correct.";
33
+ }, {
34
+ readonly reason: "cve_not_found";
35
+ readonly code: JsonRpcErrorCode.NotFound;
36
+ readonly when: "The CVE exists in NVD but has no recorded history events, or the CVE ID does not exist.";
37
+ readonly recovery: "Confirm the CVE ID exists in NVD using nvd_get_cve; newly published CVEs may have no history yet.";
38
+ }, {
39
+ readonly reason: "rate_limited";
40
+ readonly code: JsonRpcErrorCode.ServiceUnavailable;
41
+ readonly when: "NVD returned HTTP 403 indicating the rate limit was exceeded.";
42
+ readonly retryable: true;
43
+ readonly recovery: "Wait for the NVD rate window to reset or set the NVD_API_KEY environment variable for higher limits.";
44
+ }]>;
45
+ //# sourceMappingURL=nvd-get-cve-history.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nvd-get-cve-history.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/nvd-get-cve-history.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiJ3B,CAAC"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * @fileoverview Tool for retrieving the change history of a CVE from the NIST NVD API.
3
+ * @module src/mcp-server/tools/definitions/nvd-get-cve-history
4
+ */
5
+ import { tool, z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ import { getNvdCveService } from '../../../services/nvd-cve/nvd-cve-service.js';
8
+ export const nvdGetCveHistory = tool('nvd_get_cve_history', {
9
+ title: 'Get CVE Change History',
10
+ description: 'Retrieve the change history for a single CVE — CVSS score revisions, reference additions, ' +
11
+ 'status transitions (e.g., "Received" → "Analyzed"), and CPE configuration updates. ' +
12
+ "Use when tracking a CVE's escalation or investigating when a score changed. " +
13
+ 'For the current record, call nvd_get_cve instead. ' +
14
+ 'The NVD history endpoint is significantly slower than other NVD endpoints, especially without an API key — set NVD_API_KEY for reliable operation.',
15
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },
16
+ input: z.object({
17
+ cveId: z.string().describe('CVE identifier to retrieve history for (e.g., "CVE-2021-44228").'),
18
+ limit: z
19
+ .number()
20
+ .int()
21
+ .min(1)
22
+ .max(2000)
23
+ .default(20)
24
+ .describe('Maximum number of change events to return (default 20, max 2000).'),
25
+ offset: z
26
+ .number()
27
+ .int()
28
+ .min(0)
29
+ .default(0)
30
+ .describe('Zero-based offset for paginating through change events.'),
31
+ }),
32
+ output: z.object({
33
+ cveId: z.string().describe('The CVE ID for which history was retrieved.'),
34
+ changes: z
35
+ .array(z
36
+ .object({
37
+ changeDate: z.string().describe('ISO 8601 datetime when this change occurred.'),
38
+ eventName: z
39
+ .string()
40
+ .optional()
41
+ .describe('Name of the change event (e.g., "CVE Modified", "Initial Analysis").'),
42
+ details: z
43
+ .array(z
44
+ .object({
45
+ action: z
46
+ .string()
47
+ .optional()
48
+ .describe('The action taken (e.g., "Added", "Changed", "Removed").'),
49
+ type: z
50
+ .string()
51
+ .optional()
52
+ .describe('The type of data changed (e.g., "CVSS V3.1", "CWE", "Reference").'),
53
+ oldValue: z.string().optional().describe('The value before the change.'),
54
+ newValue: z.string().optional().describe('The value after the change.'),
55
+ })
56
+ .describe('One field-level change within this event.'))
57
+ .describe('Individual change detail entries within this event.'),
58
+ })
59
+ .describe('One CVE change event with its field-level details.'))
60
+ .describe('CVE change events in reverse-chronological order.'),
61
+ queryMeta: z
62
+ .object({
63
+ totalResults: z.number().describe('Total change events on record for this CVE.'),
64
+ returned: z.number().describe('Number of change events returned in this response.'),
65
+ offset: z.number().describe('Page offset used in this query.'),
66
+ })
67
+ .describe('Pagination metadata.'),
68
+ }),
69
+ errors: [
70
+ {
71
+ reason: 'invalid_cve_id_format',
72
+ code: JsonRpcErrorCode.InvalidParams,
73
+ when: 'The CVE ID fails format validation (NVD returns HTTP 404 for malformed IDs).',
74
+ recovery: 'Use the format CVE-YYYY-NNNNN (e.g., CVE-2021-44228) and verify the ID is correct.',
75
+ },
76
+ {
77
+ reason: 'cve_not_found',
78
+ code: JsonRpcErrorCode.NotFound,
79
+ when: 'The CVE exists in NVD but has no recorded history events, or the CVE ID does not exist.',
80
+ recovery: 'Confirm the CVE ID exists in NVD using nvd_get_cve; newly published CVEs may have no history yet.',
81
+ },
82
+ {
83
+ reason: 'rate_limited',
84
+ code: JsonRpcErrorCode.ServiceUnavailable,
85
+ when: 'NVD returned HTTP 403 indicating the rate limit was exceeded.',
86
+ retryable: true,
87
+ recovery: 'Wait for the NVD rate window to reset or set the NVD_API_KEY environment variable for higher limits.',
88
+ },
89
+ ],
90
+ async handler(input, ctx) {
91
+ ctx.log.info('Fetching CVE history', { cveId: input.cveId, limit: input.limit });
92
+ const service = getNvdCveService();
93
+ const result = await service.getCveHistory(input.cveId, input.limit, input.offset, ctx);
94
+ if (result.changes.length === 0) {
95
+ throw ctx.fail('cve_not_found', `No change history found for ${result.cveId}.`, {
96
+ ...ctx.recoveryFor('cve_not_found'),
97
+ cveId: result.cveId,
98
+ });
99
+ }
100
+ return {
101
+ cveId: result.cveId,
102
+ changes: result.changes,
103
+ queryMeta: {
104
+ totalResults: result.totalResults,
105
+ returned: result.returned,
106
+ offset: result.offset,
107
+ },
108
+ };
109
+ },
110
+ format: (result) => {
111
+ const lines = [];
112
+ lines.push(`## Change History: ${result.cveId}`);
113
+ lines.push(`**Total Events:** ${result.queryMeta.totalResults} | ` +
114
+ `**Showing:** ${result.queryMeta.returned} (offset ${result.queryMeta.offset})\n`);
115
+ for (const change of result.changes) {
116
+ lines.push(`### ${change.eventName ?? 'Change'} — ${change.changeDate}`);
117
+ for (const detail of change.details) {
118
+ const action = detail.action ?? '';
119
+ const type = detail.type ?? '';
120
+ const label = [action, type].filter(Boolean).join(' — ');
121
+ lines.push(`- **${label || 'Update'}**`);
122
+ if (detail.oldValue)
123
+ lines.push(` - Before: ${detail.oldValue}`);
124
+ if (detail.newValue)
125
+ lines.push(` - After: ${detail.newValue}`);
126
+ }
127
+ lines.push('');
128
+ }
129
+ return [{ type: 'text', text: lines.join('\n') }];
130
+ },
131
+ });
132
+ //# sourceMappingURL=nvd-get-cve-history.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nvd-get-cve-history.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/nvd-get-cve-history.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @fileoverview Tool for fetching one or more CVEs by ID from the NIST NVD API.
3
+ * @module src/mcp-server/tools/definitions/nvd-get-cve
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ export declare const nvdGetCve: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
8
+ cveIds: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
9
+ brief: z.ZodDefault<z.ZodBoolean>;
10
+ includeReferences: z.ZodDefault<z.ZodBoolean>;
11
+ }, z.core.$strip>, z.ZodObject<{
12
+ brief: z.ZodBoolean;
13
+ cves: z.ZodArray<z.ZodObject<{}, z.core.$loose>>;
14
+ queryMeta: z.ZodObject<{
15
+ requested: z.ZodNumber;
16
+ returned: z.ZodNumber;
17
+ missingIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
18
+ }, z.core.$strip>;
19
+ }, z.core.$strip>, readonly [{
20
+ readonly reason: "invalid_cve_id_format";
21
+ readonly code: JsonRpcErrorCode.InvalidParams;
22
+ readonly when: "One or more CVE IDs fail format validation (NVD returns HTTP 404 for malformed IDs).";
23
+ readonly recovery: "Use the format CVE-YYYY-NNNNN (e.g., CVE-2021-44228) and verify each ID.";
24
+ }, {
25
+ readonly reason: "cve_not_found";
26
+ readonly code: JsonRpcErrorCode.NotFound;
27
+ readonly when: "A valid-format CVE ID returns no results — the ID is well-formed but does not exist in NVD.";
28
+ readonly recovery: "Verify the CVE ID is correct; use nvd_search_cves to search by keyword or date.";
29
+ }, {
30
+ readonly reason: "rate_limited";
31
+ readonly code: JsonRpcErrorCode.ServiceUnavailable;
32
+ readonly when: "NVD returned HTTP 403 indicating the rate limit was exceeded.";
33
+ readonly retryable: true;
34
+ readonly recovery: "Wait for the NVD rate window to reset or set the NVD_API_KEY environment variable for higher limits.";
35
+ }]>;
36
+ //# sourceMappingURL=nvd-get-cve.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nvd-get-cve.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/nvd-get-cve.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiNpB,CAAC"}