@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,183 @@
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 { 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 nvdGetCve = tool('nvd_get_cve', {
9
+ title: 'Get CVE Details',
10
+ description: 'Fetch one or more CVEs by ID from the NIST National Vulnerability Database. ' +
11
+ 'Returns CVSS scores across all available versions (v2.0, v3.0, v3.1, v4.0), CWE weakness classifications, ' +
12
+ 'affected CPE configurations, CISA KEV fields, and references. ' +
13
+ 'Up to 100 CVE IDs per call. For bulk lookups of more than 10 IDs, use brief: true — ' +
14
+ 'full records for 100 CVEs can exceed 1MB and exhaust context budgets.',
15
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },
16
+ input: z.object({
17
+ cveIds: z
18
+ .union([
19
+ z.string().describe('A single CVE ID (e.g., "CVE-2021-44228").'),
20
+ z
21
+ .array(z.string())
22
+ .min(1)
23
+ .max(100)
24
+ .describe('An array of CVE IDs — at least 1, up to 100 per call.'),
25
+ ])
26
+ .describe('One CVE ID or an array of up to 100 CVE IDs to fetch.'),
27
+ brief: z
28
+ .boolean()
29
+ .default(false)
30
+ .describe('When true, returns trimmed records (ID, status, top CVSS score, KEV name, published date) ' +
31
+ 'instead of full detail. Recommended for batches of more than 10 IDs.'),
32
+ includeReferences: z
33
+ .boolean()
34
+ .default(true)
35
+ .describe('When false, omits the references array to reduce response size.'),
36
+ }),
37
+ // Use passthrough to avoid aspirational over-typing of the upstream CVE schema.
38
+ // structuredContent will carry the full typed data; format() renders what matters.
39
+ output: z.object({
40
+ brief: z.boolean().describe('Whether brief or full records were returned.'),
41
+ cves: z
42
+ .array(z
43
+ .object({})
44
+ .passthrough()
45
+ .describe('One CVE record. Full mode includes CVSS scores, configurations, weaknesses, and references. ' +
46
+ 'Brief mode includes ID, status, top severity, and CISA KEV name.'))
47
+ .describe('CVE records. In full mode: complete records with CVSS scores, configurations, weaknesses, and references. ' +
48
+ 'In brief mode: trimmed records with ID, status, top severity, and CISA KEV name.'),
49
+ queryMeta: z
50
+ .object({
51
+ requested: z.number().describe('Number of CVE IDs requested.'),
52
+ returned: z.number().describe('Number of CVE records returned.'),
53
+ missingIds: z
54
+ .array(z.string().describe('A CVE ID not found in NVD.'))
55
+ .optional()
56
+ .describe('CVE IDs that were requested but returned no NVD data. Absent when all IDs matched.'),
57
+ })
58
+ .describe('Count metadata for verifying ID-to-record parity.'),
59
+ }),
60
+ errors: [
61
+ {
62
+ reason: 'invalid_cve_id_format',
63
+ code: JsonRpcErrorCode.InvalidParams,
64
+ when: 'One or more CVE IDs fail format validation (NVD returns HTTP 404 for malformed IDs).',
65
+ recovery: 'Use the format CVE-YYYY-NNNNN (e.g., CVE-2021-44228) and verify each ID.',
66
+ },
67
+ {
68
+ reason: 'cve_not_found',
69
+ code: JsonRpcErrorCode.NotFound,
70
+ when: 'A valid-format CVE ID returns no results — the ID is well-formed but does not exist in NVD.',
71
+ recovery: 'Verify the CVE ID is correct; use nvd_search_cves to search by keyword or date.',
72
+ },
73
+ {
74
+ reason: 'rate_limited',
75
+ code: JsonRpcErrorCode.ServiceUnavailable,
76
+ when: 'NVD returned HTTP 403 indicating the rate limit was exceeded.',
77
+ retryable: true,
78
+ recovery: 'Wait for the NVD rate window to reset or set the NVD_API_KEY environment variable for higher limits.',
79
+ },
80
+ ],
81
+ async handler(input, ctx) {
82
+ const ids = Array.isArray(input.cveIds) ? input.cveIds : [input.cveIds];
83
+ ctx.log.info('Fetching CVEs', { count: ids.length, brief: input.brief });
84
+ const service = getNvdCveService();
85
+ const result = await service.fetchById(ids, input.includeReferences, ctx);
86
+ const queryMeta = {
87
+ requested: result.requested,
88
+ returned: result.returned,
89
+ ...(result.missingIds.length > 0 && { missingIds: result.missingIds }),
90
+ };
91
+ if (input.brief) {
92
+ return {
93
+ brief: true,
94
+ cves: result.cves.map((cve) => ({
95
+ cveId: cve.cveId,
96
+ vulnStatus: cve.vulnStatus,
97
+ published: cve.published,
98
+ ...(cve.severity && { severity: cve.severity }),
99
+ ...(cve.cisaKev && { cisaVulnerabilityName: cve.cisaKev.vulnerabilityName }),
100
+ })),
101
+ queryMeta,
102
+ };
103
+ }
104
+ return {
105
+ brief: false,
106
+ cves: result.cves,
107
+ queryMeta,
108
+ };
109
+ },
110
+ format: (result) => {
111
+ const lines = [];
112
+ lines.push(`**Returned:** ${result.queryMeta.returned} / ${result.queryMeta.requested} requested`);
113
+ if (result.queryMeta.missingIds?.length) {
114
+ lines.push(`**Not found in NVD:** ${result.queryMeta.missingIds.join(', ')}`);
115
+ }
116
+ lines.push(`**Mode:** ${result.brief ? 'Brief' : 'Full'}\n`);
117
+ for (const rawCve of result.cves) {
118
+ if (result.brief) {
119
+ const cve = rawCve;
120
+ lines.push(`## ${cve.cveId}`);
121
+ lines.push(`**Status:** ${cve.vulnStatus} | **Published:** ${cve.published}`);
122
+ if (cve.severity) {
123
+ lines.push(`**Severity:** ${cve.severity.label} (${cve.severity.score}) from CVSS ${cve.severity.fromVersion}`);
124
+ }
125
+ else {
126
+ lines.push('**Severity:** Not available (no CVSS scores)');
127
+ }
128
+ if (cve.cisaVulnerabilityName) {
129
+ lines.push(`**CISA KEV:** ${cve.cisaVulnerabilityName}`);
130
+ }
131
+ }
132
+ else {
133
+ const cve = rawCve;
134
+ lines.push(`## ${cve.cveId}`);
135
+ lines.push(`**Status:** ${cve.vulnStatus} | **Published:** ${cve.published} | **Last Modified:** ${cve.lastModified}`);
136
+ if (cve.severity) {
137
+ lines.push(`**Severity:** ${cve.severity.label} (${cve.severity.score}) from CVSS ${cve.severity.fromVersion}`);
138
+ }
139
+ else {
140
+ lines.push('**Severity:** Not available (no CVSS scores)');
141
+ }
142
+ if (cve.cvssScores && cve.cvssScores.length > 0) {
143
+ lines.push('\n**CVSS Scores:**');
144
+ for (const s of cve.cvssScores) {
145
+ lines.push(`- v${s.version} (${s.sourceType}): ${s.baseScore} ${s.severity}${s.vectorString ? ` — ${s.vectorString}` : ''}`);
146
+ }
147
+ }
148
+ if (cve.descriptions && cve.descriptions.length > 0) {
149
+ const en = cve.descriptions.find((d) => d.lang === 'en');
150
+ if (en)
151
+ lines.push(`\n${en.value}`);
152
+ }
153
+ if (cve.weaknesses && cve.weaknesses.length > 0) {
154
+ const allCwes = cve.weaknesses.flatMap((w) => w.cweIds).filter(Boolean);
155
+ if (allCwes.length > 0)
156
+ lines.push(`**Weaknesses:** ${allCwes.join(', ')}`);
157
+ }
158
+ if (cve.configurations && cve.configurations.length > 0) {
159
+ lines.push(`**Configurations:** ${cve.configurations.length} node group(s)`);
160
+ }
161
+ if (cve.cisaKev) {
162
+ lines.push(`\n**CISA KEV Details:**`);
163
+ lines.push(`- Name: ${cve.cisaKev.vulnerabilityName}`);
164
+ lines.push(`- Added: ${cve.cisaKev.exploitAddDate}`);
165
+ lines.push(`- Action Due: ${cve.cisaKev.actionDueDate}`);
166
+ lines.push(`- Required Action: ${cve.cisaKev.requiredAction}`);
167
+ }
168
+ if (cve.references && cve.references.length > 0) {
169
+ lines.push(`\n**References (${cve.references.length}):**`);
170
+ for (const ref of cve.references.slice(0, 5)) {
171
+ lines.push(`- ${ref.url}${ref.tags?.length ? ` [${ref.tags.join(', ')}]` : ''}`);
172
+ }
173
+ if (cve.references.length > 5) {
174
+ lines.push(`- … ${cve.references.length - 5} more references`);
175
+ }
176
+ }
177
+ }
178
+ lines.push('');
179
+ }
180
+ return [{ type: 'text', text: lines.join('\n') }];
181
+ },
182
+ });
183
+ //# sourceMappingURL=nvd-get-cve.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nvd-get-cve.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/nvd-get-cve.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @fileoverview Tool for searching the NVD CPE dictionary by keyword or match string.
3
+ * @module src/mcp-server/tools/definitions/nvd-search-cpes
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ export declare const nvdSearchCpes: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
8
+ keyword: z.ZodOptional<z.ZodString>;
9
+ cpeMatchString: z.ZodOptional<z.ZodString>;
10
+ limit: z.ZodDefault<z.ZodNumber>;
11
+ }, z.core.$strip>, z.ZodObject<{
12
+ cpes: z.ZodArray<z.ZodObject<{
13
+ cpeName: z.ZodString;
14
+ title: z.ZodOptional<z.ZodString>;
15
+ deprecated: z.ZodBoolean;
16
+ deprecatedBy: z.ZodOptional<z.ZodArray<z.ZodString>>;
17
+ lastModified: z.ZodOptional<z.ZodString>;
18
+ }, z.core.$strip>>;
19
+ queryMeta: z.ZodObject<{
20
+ totalResults: z.ZodNumber;
21
+ returned: z.ZodNumber;
22
+ }, z.core.$strip>;
23
+ }, z.core.$strip>, readonly [{
24
+ readonly reason: "missing_search_input";
25
+ readonly code: JsonRpcErrorCode.InvalidParams;
26
+ readonly when: "Neither keyword nor cpeMatchString was provided.";
27
+ readonly recovery: "Provide at least one of keyword (e.g., \"apache http server\") or cpeMatchString (partial CPEv2.3 pattern).";
28
+ }, {
29
+ readonly reason: "invalid_cpe_format";
30
+ readonly code: JsonRpcErrorCode.InvalidParams;
31
+ readonly when: "The cpeMatchString does not start with \"cpe:2.3:\" — it is clearly not a valid CPEv2.3 string.";
32
+ readonly recovery: "Provide a valid CPEv2.3 string starting with \"cpe:2.3:\", or use keyword search to find the correct CPE name.";
33
+ }, {
34
+ readonly reason: "rate_limited";
35
+ readonly code: JsonRpcErrorCode.ServiceUnavailable;
36
+ readonly when: "NVD returned HTTP 403 indicating the rate limit was exceeded.";
37
+ readonly retryable: true;
38
+ readonly recovery: "Wait for the NVD rate window to reset or set the NVD_API_KEY environment variable for higher limits.";
39
+ }]>;
40
+ //# sourceMappingURL=nvd-search-cpes.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nvd-search-cpes.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/nvd-search-cpes.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAKjE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8KxB,CAAC"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * @fileoverview Tool for searching the NVD CPE dictionary by keyword or match string.
3
+ * @module src/mcp-server/tools/definitions/nvd-search-cpes
4
+ */
5
+ import { tool, z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ import { getNvdCpeService } from '../../../services/nvd-cpe/nvd-cpe-service.js';
8
+ const CPE_PREFIX_REGEX = /^cpe:2\.3:/i;
9
+ export const nvdSearchCpes = tool('nvd_search_cpes', {
10
+ title: 'Search CPE Dictionary',
11
+ description: 'Search the NVD CPE (Common Platform Enumeration) dictionary by product keyword or partial match string. ' +
12
+ 'Returns CPE names, human-readable titles, and deprecation status. ' +
13
+ 'Use before nvd_audit_cpe to resolve the correct CPE name for a product — CPE strings are precise identifiers ' +
14
+ '(e.g., cpe:2.3:a:apache:http_server:2.4.51:*:*:*:*:*:*:*) and must match exactly to audit the right product.',
15
+ annotations: { readOnlyHint: true, openWorldHint: false },
16
+ input: z.object({
17
+ keyword: z
18
+ .string()
19
+ .optional()
20
+ .describe('Product name or vendor keyword (e.g., "apache http server", "openssl", "nginx"). ' +
21
+ 'At least one of keyword or cpeMatchString is required.'),
22
+ cpeMatchString: z
23
+ .string()
24
+ .optional()
25
+ .describe('Partial CPEv2.3 pattern (e.g., "cpe:2.3:a:apache:http_server"). ' +
26
+ 'At least one of keyword or cpeMatchString is required.'),
27
+ limit: z
28
+ .number()
29
+ .int()
30
+ .min(1)
31
+ .max(10_000)
32
+ .default(20)
33
+ .describe('Maximum number of CPE entries to return (default 20, max 10000). ' +
34
+ 'If totalResults > returned, narrow the keyword for a more specific result.'),
35
+ }),
36
+ output: z.object({
37
+ cpes: z
38
+ .array(z
39
+ .object({
40
+ cpeName: z
41
+ .string()
42
+ .describe('Full CPEv2.3 name (use this as the cpeName in nvd_audit_cpe).'),
43
+ title: z
44
+ .string()
45
+ .optional()
46
+ .describe('Human-readable product title. Absent when NVD has no English title.'),
47
+ deprecated: z
48
+ .boolean()
49
+ .describe('Whether this CPE has been deprecated in the NVD dictionary.'),
50
+ deprecatedBy: z
51
+ .array(z.string().describe('Superseding CPE name.'))
52
+ .optional()
53
+ .describe('CPE names that supersede this deprecated entry.'),
54
+ lastModified: z
55
+ .string()
56
+ .optional()
57
+ .describe('ISO 8601 datetime when this CPE was last modified.'),
58
+ })
59
+ .describe('One CPE dictionary entry.'))
60
+ .describe('Matching CPE dictionary entries.'),
61
+ queryMeta: z
62
+ .object({
63
+ totalResults: z
64
+ .number()
65
+ .describe('Total matching CPE entries before the limit was applied.'),
66
+ returned: z.number().describe('Number of entries returned in this response.'),
67
+ })
68
+ .describe('Query metadata. When totalResults > returned, narrow the keyword for more specific results.'),
69
+ }),
70
+ errors: [
71
+ {
72
+ reason: 'missing_search_input',
73
+ code: JsonRpcErrorCode.InvalidParams,
74
+ when: 'Neither keyword nor cpeMatchString was provided.',
75
+ recovery: 'Provide at least one of keyword (e.g., "apache http server") or cpeMatchString (partial CPEv2.3 pattern).',
76
+ },
77
+ {
78
+ reason: 'invalid_cpe_format',
79
+ code: JsonRpcErrorCode.InvalidParams,
80
+ when: 'The cpeMatchString does not start with "cpe:2.3:" — it is clearly not a valid CPEv2.3 string.',
81
+ recovery: 'Provide a valid CPEv2.3 string starting with "cpe:2.3:", or use keyword search to find the correct CPE name.',
82
+ },
83
+ {
84
+ reason: 'rate_limited',
85
+ code: JsonRpcErrorCode.ServiceUnavailable,
86
+ when: 'NVD returned HTTP 403 indicating the rate limit was exceeded.',
87
+ retryable: true,
88
+ recovery: 'Wait for the NVD rate window to reset or set the NVD_API_KEY environment variable for higher limits.',
89
+ },
90
+ ],
91
+ async handler(input, ctx) {
92
+ if (!input.keyword && !input.cpeMatchString) {
93
+ throw ctx.fail('missing_search_input', 'At least one of keyword or cpeMatchString is required.', ctx.recoveryFor('missing_search_input'));
94
+ }
95
+ if (input.cpeMatchString && !CPE_PREFIX_REGEX.test(input.cpeMatchString)) {
96
+ throw ctx.fail('invalid_cpe_format', `Invalid CPE string: "${input.cpeMatchString}". CPEv2.3 strings must start with "cpe:2.3:".`, ctx.recoveryFor('invalid_cpe_format'));
97
+ }
98
+ ctx.log.info('Searching CPE dictionary', {
99
+ keyword: input.keyword,
100
+ cpeMatchString: input.cpeMatchString,
101
+ limit: input.limit,
102
+ });
103
+ const service = getNvdCpeService();
104
+ const result = await service.searchCpes({
105
+ limit: input.limit,
106
+ ...(input.keyword && { keyword: input.keyword }),
107
+ ...(input.cpeMatchString && { cpeMatchString: input.cpeMatchString }),
108
+ }, ctx);
109
+ return {
110
+ cpes: result.cpes,
111
+ queryMeta: { totalResults: result.totalResults, returned: result.returned },
112
+ };
113
+ },
114
+ format: (result) => {
115
+ const lines = [];
116
+ lines.push(`**Total:** ${result.queryMeta.totalResults} matching CPEs | **Returned:** ${result.queryMeta.returned}`);
117
+ if (result.queryMeta.totalResults > result.queryMeta.returned) {
118
+ lines.push(`> Results truncated — narrow the keyword for more specific results.`);
119
+ }
120
+ if (result.cpes.length === 0) {
121
+ lines.push('\nNo CPEs matched. Try a broader keyword or different spelling.');
122
+ return [{ type: 'text', text: lines.join('\n') }];
123
+ }
124
+ lines.push('');
125
+ for (const cpe of result.cpes) {
126
+ const depFlag = cpe.deprecated ? ' *(deprecated)*' : '';
127
+ lines.push(`### ${cpe.title ?? cpe.cpeName}${depFlag}`);
128
+ lines.push(`**CPE Name:** \`${cpe.cpeName}\``);
129
+ if (cpe.deprecated && cpe.deprecatedBy && cpe.deprecatedBy.length > 0) {
130
+ lines.push(`**Deprecated By:** ${cpe.deprecatedBy.join(', ')}`);
131
+ }
132
+ if (cpe.lastModified) {
133
+ lines.push(`**Last Modified:** ${cpe.lastModified}`);
134
+ }
135
+ lines.push('');
136
+ }
137
+ return [{ type: 'text', text: lines.join('\n') }];
138
+ },
139
+ });
140
+ //# sourceMappingURL=nvd-search-cpes.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nvd-search-cpes.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/nvd-search-cpes.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @fileoverview Tool for searching CVEs by keyword, severity, CWE, date range, or KEV status.
3
+ * @module src/mcp-server/tools/definitions/nvd-search-cves
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
+ export declare const nvdSearchCves: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
8
+ keyword: z.ZodOptional<z.ZodString>;
9
+ severity: z.ZodOptional<z.ZodEnum<{
10
+ LOW: "LOW";
11
+ MEDIUM: "MEDIUM";
12
+ HIGH: "HIGH";
13
+ CRITICAL: "CRITICAL";
14
+ }>>;
15
+ severityVersion: z.ZodDefault<z.ZodEnum<{
16
+ v2: "v2";
17
+ v3: "v3";
18
+ v4: "v4";
19
+ }>>;
20
+ cweId: z.ZodOptional<z.ZodString>;
21
+ pubDays: z.ZodOptional<z.ZodNumber>;
22
+ lastModDays: z.ZodOptional<z.ZodNumber>;
23
+ pubStartDate: z.ZodOptional<z.ZodString>;
24
+ pubEndDate: z.ZodOptional<z.ZodString>;
25
+ lastModStartDate: z.ZodOptional<z.ZodString>;
26
+ lastModEndDate: z.ZodOptional<z.ZodString>;
27
+ kevOnly: z.ZodDefault<z.ZodBoolean>;
28
+ noRejected: z.ZodDefault<z.ZodBoolean>;
29
+ limit: z.ZodDefault<z.ZodNumber>;
30
+ offset: z.ZodDefault<z.ZodNumber>;
31
+ }, z.core.$strip>, z.ZodObject<{
32
+ cves: z.ZodArray<z.ZodObject<{
33
+ cveId: z.ZodString;
34
+ vulnStatus: z.ZodString;
35
+ published: z.ZodString;
36
+ severity: z.ZodOptional<z.ZodObject<{
37
+ label: z.ZodString;
38
+ score: z.ZodNumber;
39
+ fromVersion: z.ZodString;
40
+ }, z.core.$strip>>;
41
+ cisaVulnerabilityName: z.ZodOptional<z.ZodString>;
42
+ }, z.core.$strip>>;
43
+ queryMeta: z.ZodObject<{
44
+ totalResults: z.ZodNumber;
45
+ returned: z.ZodNumber;
46
+ offset: z.ZodNumber;
47
+ datesClamped: z.ZodOptional<z.ZodArray<z.ZodObject<{
48
+ param: z.ZodString;
49
+ original: z.ZodNumber;
50
+ clamped: z.ZodNumber;
51
+ }, z.core.$strip>>>;
52
+ }, z.core.$strip>;
53
+ }, z.core.$strip>, readonly [{
54
+ readonly reason: "mutually_exclusive_params";
55
+ readonly code: JsonRpcErrorCode.InvalidParams;
56
+ readonly when: "Both pubDays and pubStartDate/pubEndDate provided, or both lastModDays and lastModStartDate/lastModEndDate.";
57
+ readonly recovery: "Use either the convenience shorthand (pubDays) or the explicit date range (pubStartDate + pubEndDate), not both.";
58
+ }, {
59
+ readonly reason: "missing_date_pair";
60
+ readonly code: JsonRpcErrorCode.InvalidParams;
61
+ readonly when: "Only one of pubStartDate/pubEndDate (or lastModStartDate/lastModEndDate) was provided — NVD requires both.";
62
+ readonly recovery: "Provide both the start and end date, or use pubDays/lastModDays instead of an explicit date range.";
63
+ }, {
64
+ readonly reason: "date_range_inverted";
65
+ readonly code: JsonRpcErrorCode.InvalidParams;
66
+ readonly when: "The end date is before the start date.";
67
+ readonly recovery: "Ensure the end date is after the start date.";
68
+ }, {
69
+ readonly reason: "date_range_exceeds_max";
70
+ readonly code: JsonRpcErrorCode.InvalidParams;
71
+ readonly when: "Explicit pubStartDate/pubEndDate or lastModStartDate/lastModEndDate span more than 120 days.";
72
+ readonly recovery: "Narrow the date range to 120 days or fewer, or use multiple paginated queries.";
73
+ }, {
74
+ readonly reason: "invalid_date_format";
75
+ readonly code: JsonRpcErrorCode.InvalidParams;
76
+ readonly when: "A date string provided for pubStartDate, pubEndDate, lastModStartDate, or lastModEndDate is not a valid ISO 8601 datetime.";
77
+ readonly recovery: "Use ISO 8601 format, e.g. 2024-01-01T00:00:00.000Z.";
78
+ }, {
79
+ readonly reason: "invalid_severity_for_version";
80
+ readonly code: JsonRpcErrorCode.InvalidParams;
81
+ readonly when: "severity=\"CRITICAL\" was specified with severityVersion=\"v2\" — CVSS v2 has no CRITICAL tier.";
82
+ readonly recovery: "Use LOW, MEDIUM, or HIGH when severityVersion is \"v2\". Use v3 or v4 for CRITICAL.";
83
+ }, {
84
+ readonly reason: "rate_limited";
85
+ readonly code: JsonRpcErrorCode.ServiceUnavailable;
86
+ readonly when: "NVD returned HTTP 403 indicating the rate limit was exceeded.";
87
+ readonly retryable: true;
88
+ readonly recovery: "Wait for the NVD rate window to reset or set the NVD_API_KEY environment variable for higher limits.";
89
+ }]>;
90
+ //# sourceMappingURL=nvd-search-cves.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nvd-search-cves.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/nvd-search-cves.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAmCjE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqaxB,CAAC"}