NVD/NIST MCP server
The NIST NVD MCP server lets an MCP client query NVD CVE and CPE data read-only over stdio, with caching, pagination, and KEV/CPE context.
Retrieve one full CVE record: description, all CVSS metrics, CWEs, configurations, references, CISA KEV status, and raw payload option.
Get compact CVE summaries for one CVE or batches of up to 100 CVE IDs.
Search CVEs by keyword, CVE IDs, CPE name/match string, CWE, CVSS, KEV, source identifier, vuln status, published/last-modified windows, and CERT flags.
Get recent CVEs ordered by publication date or last-modified date, with filters and cursor pagination.
Retrieve CVE change history with event-name and date-range filters.
Search the NVD CPE Dictionary by keyword, match string, criteria UUID, or last-modified window, and include/exclude deprecated entries.
Get one CPE Dictionary entry by CPE name or CPE name UUID.
Search CPE Match Criteria linking CVEs to CPE names and version ranges.
Use cursor-based pagination, cache/freshness metadata, stale-fallback warnings, and local SQLite/JSON caching to reduce upstream NVD calls.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@NVD/NIST MCP servershow me the full details for CVE-2021-44228, including CVSS and KEV status"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
NIST NVD MCP server
MCP server exposing the NVD APIs (CVE search, history, CPE dictionary, CPE match criteria) over stdio, with a local SQLite + JSON disk cache so repeated lookups do not hit the upstream API.
Requirements
Node.js >= 22.5 (uses the built-in
node:sqlitemodule)A free NVD API key is recommended
Related MCP server: Vulnerability Registry MCP Server
Register with an MCP client
npm install && npm run build{
"mcpServers": {
"nist-nvd": {
"command": "node",
"args": ["/absolute/path/to/dist/main.js"],
"env": { "NVD_API_KEY": "your-key" }
}
}
}The server speaks JSON-RPC on stdin/stdout; every log line goes to stderr.
Tools
Tool | Purpose |
| Full record for one CVE |
| Compact summary of one CVE |
| Batch summaries (up to 100 IDs) |
| Search CVEs by keyword, IDs, CPE, CWE, CVSS, KEV, dates |
| Newest CVEs by publication date |
| Newest CVEs by last-modified date |
| Change history of one CVE |
| Search the CPE Dictionary |
| One CPE Dictionary entry |
| Search CPE Match Criteria |
All tools are read-only. Use fields to narrow payloads, and pageSize/cursor to paginate lists.
Example
Call nvd_get_cve_summary with:
{ "cveId": "CVE-2021-44228" }Returns a compact CVE summary and cache metadata. See usage for batch, search, pagination and CPE examples.
Defaults and limits
Fresh cache hits avoid NVD; outage fallback is marked by
meta.staleandmeta.warnings.Upstream requests are serialized, 6 seconds apart by default. Tool deadline: 120 seconds.
Modified feeds are bounded to 10,000 CVEs and a roughly 4 MB snapshot; narrow large queries.
Unknown inputs and oversized output return errors; use smaller pages or fewer
fields.
Configuration is optional: copy .env.example to .env or set environment
variables in your MCP client. See operations for details and troubleshooting.
Docker
docker build -t nist-nvd-mcp-server .
docker run -i --rm -e NVD_API_KEY=your-key -v nvd-data:/data nist-nvd-mcp-serverUse -i (not -t) so stdin stays open. The container runs as a non-root user and shuts down cleanly on docker stop.
Development
npm run typecheck # tsc --noEmit
npm run lint # eslint
npm test # vitest (unit + integration + contract); runs build first
npm run build # emit dist/
npm run dev # tsx src/main.ts, no build stepTests never touch the real NVD API - they use a mock server, a temp SQLite DB, and a temp cache dir. GitHub Actions runs the same checks on Node.js 22 and 24.
Documentation
License
MIT - this project is not affiliated with or endorsed by NIST/NVD.
Available Tools
10 toolsnvd_get_cpeGet a CPE nameARead-onlyIdempotent
Return one entry of the NVD Official CPE Dictionary. Provide exactly one of cpeNameId (preferred, exact) or cpeName. cpeName is resolved by upstream pattern search over at most 3 pages; if the exact name is not in that window the tool returns CPE_NOT_FOUND with the scanned/total counts and suggests nvd_search_cpes. That search ignores the deprecation filter, so deprecated entries resolve too. Entries are cached for 7 days.
| Name | Required | Description | Default |
|---|---|---|---|
| cpeName | No | Exact CPE name to resolve | |
| cpeNameId | No | CPE name UUID (preferred lookup key) |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes | Cache/freshness metadata; warnings carries stale-fallback and truncation notices |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), yet the description adds substantial behavior that structured fields do not: a 3-page pattern-search bound, a CPE_NOT_FOUND error shape with scanned/total counts, the fact that the upstream search ignores the deprecation filter, and a 7-day cache. These are exactly the operational traits an agent needs to reason about failure and staleness.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four compact sentences, front-loaded with what is returned, then the key-selection rule, then failure behavior, then caching. Every sentence carries distinct operational information with no repetition of the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return structure need not be explained, and the description instead covers the one output case that matters (CPE_NOT_FOUND). For a two-parameter, read-only lookup with a documented fallback path, nothing needed to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both properties carry descriptions, so the baseline is 3. The description adds real value beyond the schema by declaring cpeNameId 'preferred, exact' versus cpeName, which is only 'resolved by upstream pattern search' — a semantic distinction the schema does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource ('Return one entry of the NVD Official CPE Dictionary'), immediately scoping it to a single-entry lookup. The mention of nvd_search_cpes on failure distinguishes it from the sibling search tools without the agent needing to open either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the selection rule explicitly: 'Provide exactly one of cpeNameId (preferred, exact) or cpeName', and names the alternative (nvd_search_cpes) for the failure case. It also explains what happens when the exact name is outside the scanned window, so the agent knows the escape hatch.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvd_get_cveGet CVE detailsARead-onlyIdempotent
Return the full NVD record for one CVE: description, all CVSS metrics, CWEs, configurations, references and CISA KEV status. Use nvd_get_cve_summary for the essentials, nvd_get_cves for a batch. Cached for 24 hours; on an NVD outage the stale copy is returned with a warning in meta.warnings.
| Name | Required | Description | Default |
|---|---|---|---|
| cveId | Yes | CVE identifier such as CVE-2024-3094 (case insensitive) | |
| includeRaw | No | Include the raw NVD payload when it is available in the local cache (default false) | |
| includeReferences | No | Include the reference list (default true) | |
| includeConfigurations | No | Include the CPE configuration tree (default true) |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes | Cache/freshness metadata; warnings carries stale-fallback and truncation notices |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations establish read-only, idempotent, non-destructive and open-world, but the description adds behavior they cannot express: a 24-hour cache and a documented degradation path where a stale copy is returned during an NVD outage with a warning surfaced in meta.warnings. That is real operational context about freshness and failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences with no waste: the payload comes first, the sibling routing second, the caching/outage caveat last. Nothing is repeated and every clause carries new information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be described, and the description still covers the caching horizon and outage fallback. For a single-record fetch tool with 100% schema coverage and annotations, nothing an agent needs is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the three optional toggles (includeRaw, includeReferences, includeConfigurations) and the cveId pattern are already fully documented in the schema. The description implies the default shape of the record but adds no syntax or default-override guidance beyond it, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Return) and resource (the full NVD record for one CVE) and enumerates the payload contents: description, CVSS metrics, CWEs, configurations, references and CISA KEV status. It also explicitly distinguishes itself from nvd_get_cve_summary and nvd_get_cves, so an agent can pick it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names two concrete alternatives with the condition that selects each: nvd_get_cve_summary for the essentials and nvd_get_cves for a batch. The full/summary/batch trichotomy is exactly the routing decision an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvd_get_cve_historyGet CVE change historyARead-onlyIdempotent
Return the change history of one CVE: "New CVE Received", "Initial Analysis", "CVE Modified", "Rejected" and similar events, with their field-level changes and timestamps. Filter by eventName or changeBetween (maximum 120 days). Cached for 1 hour; paginate with the opaque cursor.
| Name | Required | Description | Default |
|---|---|---|---|
| cveId | Yes | CVE identifier such as CVE-2024-3094 (case insensitive) | |
| cursor | No | Opaque signed cursor from the previous page: pass the response's pagination.nextCursor. Never build it by hand; it expires after 30 minutes and is bound to the filters, pageSize and date window. | |
| pageSize | No | Page size (default 20, maximum 50) | |
| eventName | No | Exact event name, for example "CVE Modified" or "Initial Analysis" | |
| changeBetween | No | Filter on the change creation date (max 120 days) |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | Yes | Cache/freshness metadata; warnings carries stale-fallback and truncation notices |
| items | Yes | |
| pagination | Yes | Pagination block; nextCursor is null on the last page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description adds non-structured behavior: a 1-hour cache and the 120-day maximum window, plus the opaque-cursor pagination model. It does not mention rate limits or auth, so it stops short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, front-loaded with what is returned, followed by filtering, caching, and pagination constraints. No filler and every clause carries operational information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described. For a single-CVE read with nested filter objects, the description covers scope, filters, cache TTL, window limit, and pagination, leaving nothing an agent needs before calling it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so cveId, cursor, pageSize, eventName and changeBetween are already fully documented at the schema level. The description restates eventName and changeBetween and the 120-day cap but adds no syntax, default, or format detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Return the change history of one CVE') and enumerates the concrete event types returned, so an agent can distinguish it from nvd_get_cve, nvd_get_cve_summary, and nvd_get_modified_cves (which is multi-CVE) without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied through the description of filters ('Filter by eventName or changeBetween') and pagination, but there is no explicit when-to-use guidance, no prerequisites, and no named alternative such as nvd_get_modified_cves for bulk change tracking. Adequate but leaves routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvd_get_cvesGet multiple CVE summariesARead-onlyIdempotent
Return summaries for up to 100 CVE identifiers in one call. Identifiers are uppercased and de-duplicated; only missing or stale ones are fetched, in one batch. Reports foundIds, missingIds and meta.requested/found/missing; use nvd_get_cve for a full record.
| Name | Required | Description | Default |
|---|---|---|---|
| cveIds | Yes | 1-100 CVE identifiers; duplicates are removed and identifiers normalized to uppercase |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | Yes | |
| items | Yes | |
| foundIds | Yes | |
| missingIds | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/openWorld, so safety is covered; the description adds non-obvious behavior: identifiers are uppercased, de-duplicated, and only missing/stale entries are fetched (a cache-aware batch read). That is real value beyond the annotations, though it overlaps the output schema by naming the response fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense, front-loaded sentences with no filler; the batch limit and routing to nvd_get_cve come early. Minor redundancy in enumerating response fields (foundIds, missingIds, meta.*) that the output schema already exposes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a complete input schema, an output schema, and rich read-only annotations, the description supplies the remaining essentials: batch cap, normalization/dedup semantics, cache behavior, and sibling routing. Nothing needed to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single param already documents the 1-100 range, case-insensitivity, and de-duplication. The description restates the same normalization/limit facts rather than adding format or syntax detail beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with scope ('summaries for up to 100 CVE identifiers in one call') and explicitly routes the single-record case to nvd_get_cve, which lets an agent separate it from siblings without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the alternative (nvd_get_cve for a full record) with the condition that selects it, giving clear batch-vs-single guidance. It stops short of addressing the other siblings (nvd_get_cve_summary, nvd_search_cves, nvd_search_cves), so no explicit exclusions beyond the one alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvd_get_cve_summaryGet CVE summaryARead-onlyIdempotent
Return a compact view of one CVE: id, timestamps, status, English summary, primary CVSS score, CWEs, affected products, KEV flag and reference count. Configurations, references and the raw payload are omitted - use nvd_get_cve for those. Derived from the cached record, so it shares the same 24 hour freshness window.
| Name | Required | Description | Default |
|---|---|---|---|
| cveId | Yes | CVE identifier such as CVE-2024-3094 (case insensitive) |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes | Cache/freshness metadata; warnings carries stale-fallback and truncation notices |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds genuinely new behavioral context: the result is derived from a cached record sharing a 24 hour freshness window, which tells the agent results may be stale. It does not mention rate limits or auth, but the caching disclosure is the meaningful extra.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: field inventory first, exclusions and the alternative second, freshness caveat last. Every sentence carries information and nothing is repeated from the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no prose, yet the field list usefully frames the compactness tradeoff. Combined with the named alternative and the cache-freshness disclosure, an agent has everything needed to select and call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and there is only one parameter (cveId) with a regex pattern and example already in the schema. The description adds no format or case-handling detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (return) and resource (compact view of one CVE) and enumerates exactly what the view contains (id, timestamps, status, summary, CVSS, CWEs, products, KEV flag, reference count). It also names the sibling it differs from (nvd_get_cve), so an agent can separate the two without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It routes the agent explicitly: configurations, references and raw payload are omitted, so 'use nvd_get_cve for those'. That gives a clear condition for choosing this tool versus its sibling. It stops short of stating broader when-not-to-use conditions (e.g., bulk retrieval, history), but the core routing decision is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvd_get_modified_cvesGet recently modified CVEsARead-onlyIdempotent
Return CVEs ordered by last-modified date, newest first (ordering "last_modified_desc"). Defaults to the last 7 days: use days or an explicit start+end window (mutually exclusive, maximum 120 days). All filters are sent to NVD, so totalResults is the exact upstream total. Cached for 5 minutes; paginate by passing pagination.nextCursor back as cursor with the same filters and pageSize - the resolved window travels inside the cursor, so a relative days window stays stable across pages.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ISO-8601 window end (use with `start`) | |
| cvss | No | CVSS metric filter; requires at least one of severity or metrics | |
| days | No | Relative window in days counted back from now (default 7) | |
| start | No | ISO-8601 window start (use with `end`) | |
| cursor | No | Opaque signed cursor from the previous page: pass the response's pagination.nextCursor. Never build it by hand; it expires after 30 minutes and is bound to the filters, pageSize and date window. | |
| cpeName | No | Optional CPE name filter | |
| kevOnly | No | Only CISA KEV entries | |
| keyword | No | Optional keyword filter | |
| pageSize | No | Page size (default 20, maximum 50) | |
| noRejected | No | Exclude rejected CVEs | |
| vulnStatuses | No | Vulnerability statuses (Received, Awaiting Analysis, Undergoing Analysis, Analyzed, Modified, Deferred, Rejected). Spaced and camel-case spellings are both canonicalized, and the filter is applied by NVD. |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | Yes | Cache/freshness metadata; warnings carries stale-fallback and truncation notices |
| items | Yes | |
| pagination | Yes | Pagination block; nextCursor is null on the last page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond annotations: notes the 5-minute cache, that filters are pushed upstream so totalResults is exact, that the resolved window is embedded in the cursor so a relative `days` window stays stable across pages, and the 30-minute cursor TTL. This is exactly the kind of pagination/caching contract an agent needs for a read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with return semantics and ordering, then window rules, then caching and pagination. Four dense sentences, no filler, every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, it needn't describe return values, and it covers the operational hazards (caching, cursor lifetime/binding, window exclusivity, upstream filtering) that an agent would otherwise guess wrong. Complete for an 11-param read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents most params with enums and constraints. The description still adds non-obvious semantics: cursor binding to filters/pageSize/window and cursor stability with relative days, which the schema only partly conveys.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states precisely what the tool returns (CVEs ordered by last-modified date, newest first) and separates it from siblings like nvd_search_cves or nvd_get_cve by its ordering and windowing behavior. An agent can immediately tell this is the 'recently modified' feed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains the default window (last 7 days), the exclusive `days` vs `start`+`end` choice, and the 120-day cap. It doesn't explicitly say when to prefer a sibling (e.g. search_cves for keyword-driven queries), so it's clear but not fully routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvd_get_recent_cvesGet recently published CVEsARead-onlyIdempotent
Return CVEs ordered by publication date, newest first (ordering "published_desc"). Defaults to the last 7 days: use days or an explicit start+end window (mutually exclusive, maximum 120 days). Cached for 5 minutes; paginate by passing pagination.nextCursor back as cursor with the same filters and pageSize - the resolved window travels inside the cursor, so a relative days window stays stable across pages.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ISO-8601 window end (use with `start`) | |
| cvss | No | CVSS metric filter; requires at least one of severity or metrics | |
| days | No | Relative window in days counted back from now (default 7) | |
| start | No | ISO-8601 window start (use with `end`) | |
| cursor | No | Opaque signed cursor from the previous page: pass the response's pagination.nextCursor. Never build it by hand; it expires after 30 minutes and is bound to the filters, pageSize and date window. | |
| cpeName | No | Optional CPE name filter | |
| kevOnly | No | Only CISA KEV entries | |
| keyword | No | Optional keyword filter | |
| pageSize | No | Page size (default 20, maximum 50) | |
| noRejected | No | Exclude rejected CVEs |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | Yes | Cache/freshness metadata; warnings carries stale-fallback and truncation notices |
| items | Yes | |
| pagination | Yes | Pagination block; nextCursor is null on the last page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, it discloses two non-obvious behaviors: results are cached for 5 minutes (a freshness caveat), and the resolved date window is embedded in the cursor so a relative `days` window stays stable across pages while filters and pageSize are bound. Neither fact is derivable from the annotations or top-level schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, front-loaded with the ordering and default window before pagination mechanics. The parenthetical `("published_desc")` and nested asides add some visual noise but every clause carries operational information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 10 optional parameters, a nested CVSS object, and an output schema present, the description covers the things structured fields cannot: default window, window-size cap, mutual exclusivity, cache TTL, and the exact cursor round-trip protocol. An agent has everything needed to call and paginate correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameter baseline is 3. The description exceeds that by stating the cross-parameter constraint (days vs start/end mutual exclusivity, 120-day max) and the default lookback, none of which appear in the per-parameter schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ("Return CVEs") plus the ordering dimension ("ordered by publication date, newest first"), which separates it from date-based siblings like nvd_get_modified_cves. It does not explicitly name or contrast any sibling tool (nvd_get_cves, nvd_search_cves), so differentiation is implied by scope rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete usage rules: default 7-day lookback, and that `days` and `start`+`end` are mutually exclusive alternatives capped at 120 days. What it lacks is guidance on when to prefer this over nvd_get_cves or nvd_search_cves — no tool-level alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvd_search_cpe_matchesSearch CPE Match CriteriaARead-onlyIdempotent
Search CPE Match Criteria, which link CVEs to CPE names and version ranges. At least one filter is required: cveId, matchCriteriaId, matchStringSearch or lastModified (maximum 120 days). matchStringSearch must be a complete CPE match string such as cpe:2.3:a:vendor:product::::::::; upstream rejects partial keywords and version ranges. Cached for 24 hours; paginate with the opaque cursor.
| Name | Required | Description | Default |
|---|---|---|---|
| cveId | No | Return the match criteria referenced by this CVE | |
| cursor | No | Opaque signed cursor from the previous page: pass the response's pagination.nextCursor. Never build it by hand; it expires after 30 minutes and is bound to the filters, pageSize and date window. | |
| pageSize | No | Page size (default 20, maximum 100) | |
| lastModified | No | Filter on the match criteria last-modified date (max 120 days) | |
| matchCriteriaId | No | Match criteria UUID | |
| matchStringSearch | No | Complete CPE match string (wildcards allowed, no version ranges) |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | Yes | Cache/freshness metadata; warnings carries stale-fallback and truncation notices |
| items | Yes | |
| pagination | Yes | Pagination block; nextCursor is null on the last page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the description's job is to add operational context — and it does: 24-hour caching, cursor-based pagination, and the upstream rejection of partial keywords and version ranges in matchStringSearch. These are non-obvious behaviors an agent cannot infer from the annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three densely packed sentences with the resource definition front-loaded, then the filter requirement, then the two gotchas (matchString syntax, caching/pagination). No filler, nothing repeated from the schema verbatim.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter, nested-object search with an output schema present, the description covers what the tool returns conceptually, the filter precondition, the pagination mechanics, the cache window, and the input-format trap. An agent can call it correctly without opening anything else.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds real meaning on top: matchStringSearch must be a complete CPE match string with the cpe:2.3:a:vendor:product:*... form, and the lastModified window is capped at 120 days. It does not add anything further about cursor freshness or pageSize, which the schema already handles.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Search) and resource (CPE Match Criteria) and explains what the resource is: the join that links CVEs to CPE names and version ranges. That implicitly separates it from nvd_search_cpes / nvd_get_cpe, but no sibling is named explicitly and no exclusion is stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a hard precondition ('At least one filter is required') and enumerates the four admissible filters plus the 120-day ceiling on lastModified, so an agent knows how to form a valid call. It does not, however, say when to reach for this tool over nvd_search_cpes or how it complements nvd_get_cve.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvd_search_cpesSearch CPE namesARead-onlyIdempotent
Search the NVD Official CPE Dictionary by keyword, match string, criteria UUID, or last-modified window. At least one filter is required; date windows are limited to 120 days. Deprecated CPEs are filtered locally unless includeDeprecated is true. totalResults is the upstream NVD count before local filtering, so it may be greater than returned items or even > 0 with an empty items array when matching entries are filtered out. Results are cached for 24 hours and use opaque cursor pagination; reuse nextCursor with the same filters and pageSize.
| Name | Required | Description | Default |
|---|---|---|---|
| cursor | No | Opaque signed cursor from the previous page: pass the response's pagination.nextCursor. Never build it by hand; it expires after 30 minutes and is bound to the filters, pageSize and date window. | |
| keyword | No | Keyword matched against CPE titles | |
| pageSize | No | Page size (default 20, maximum 100) | |
| lastModified | No | Filter on the CPE last-modified date (max 120 days) | |
| cpeMatchString | No | CPE match string to look up | |
| matchCriteriaId | No | CPE Match Criteria UUID whose CPE names should be returned | |
| includeDeprecated | No | Include deprecated CPE names (default false). This filter runs locally; see meta.filteredOut. | |
| keywordExactMatch | No | Require the exact keyword phrase (requires keyword) |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | Yes | Cache/freshness metadata; warnings carries stale-fallback and truncation notices |
| items | Yes | |
| pagination | Yes | Pagination block; nextCursor is null on the last page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already covering read-only/idempotent/non-destructive/open-world, the description still adds substantial non-obvious behavior: deprecated CPEs filtered locally unless includeDeprecated, totalResults being the upstream count that can exceed returned items or be positive with an empty items array, and 24-hour caching. This is exactly the operational context annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences, all load-bearing, with the core scope stated first and constraints/edge cases after. The totalResults explanation is the longest clause but justifies its length because it prevents a misinterpretation of an empty result set.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter, nested-object tool with an output schema, the description covers the prerequisites, the local-vs-upstream filtering split, cache lifetime, and cursor lifetime/binding — everything an agent needs to call it correctly and interpret pagination. Return-value shape is rightly left to the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds genuine cross-parameter semantics: cursors must be reused with the same filters and pageSize, the 120-day cap on the date window, and that includeDeprecated is a local filter reflected in meta.filteredOut. keywordExactMatch and cpeMatchString get no extra narrative, but the schema already documents them.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Search the NVD Official CPE Dictionary") and enumerates the four filter modes (keyword, match string, criteria UUID, last-modified window), so the agent knows exactly what the tool operates on. It is clear it deals with the CPE Dictionary rather than CPE matches, but it never names the nearest sibling (nvd_search_cpe_matches or nvd_get_cpe) to harden the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"At least one filter is required; date windows are limited to 120 days" gives a firm precondition the agent must satisfy before calling. It stops short of routing guidance — no statement of when to prefer nvd_get_cpe or nvd_search_cpe_matches instead — so the alternative-selection layer is missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvd_search_cvesSearch CVEsARead-onlyIdempotent
Search CVE records with the NVD 2.0 filters: keyword, CVE IDs, CPE name or match string, CWE, source identifier, vuln statuses, published/last-modified windows, KEV window, CVSS metrics and CERT flags. Rules: keywordExactMatch requires keyword; isVulnerable requires cpeName; cpeName and virtualMatchString are mutually exclusive; date windows are limited to 120 days. NVD evaluates every filter, so totalResults is the exact upstream total. Cached for 15 minutes; paginate by passing pagination.nextCursor back as cursor with the same filters and pageSize.
| Name | Required | Description | Default |
|---|---|---|---|
| kev | No | ||
| cvss | No | CVSS metric filter; requires at least one of severity or metrics | |
| cweId | No | CWE identifier such as CWE-79 | |
| cursor | No | Opaque signed cursor from the previous page: pass the response's pagination.nextCursor. Never build it by hand; it expires after 30 minutes and is bound to the filters, pageSize and date window. | |
| cveIds | No | Restrict the search to these CVE identifiers | |
| cpeName | No | CPE name filter; translates to the upstream cpeName parameter | |
| hasOval | No | Only CVEs with OVAL definitions | |
| keyword | No | Keyword matched against CVE descriptions | |
| pageSize | No | Page size (default 20, maximum 50) | |
| published | No | Filter on the published date (max 120 days) | |
| noRejected | No | Exclude rejected CVEs (upstream noRejected) | |
| hasCertNotes | No | Only CVEs with CERT notes | |
| isVulnerable | No | Only CVEs where cpeName is marked vulnerable; requires cpeName, incompatible with virtualMatchString | |
| lastModified | No | Filter on the last-modified date (max 120 days) | |
| vulnStatuses | No | Vulnerability statuses (Received, Awaiting Analysis, Undergoing Analysis, Analyzed, Modified, Deferred, Rejected). Spaced and camel-case spellings are both canonicalized, and the filter is applied by NVD. | |
| hasCertAlerts | No | Only CVEs with CERT alerts | |
| sourceIdentifier | No | CNA or NVD source identifier, for example secalert@redhat.com | |
| keywordExactMatch | No | Require the exact keyword phrase (requires keyword) | |
| virtualMatchString | No | CPE match string (supports wildcards and version ranges); mutually exclusive with cpeName |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | Yes | Cache/freshness metadata; warnings carries stale-fallback and truncation notices |
| items | Yes | |
| pagination | Yes | Pagination block; nextCursor is null on the last page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, open-world behavior, so the description need not restate safety. It adds genuinely non-obvious traits: results are cached for 15 minutes, and NVD evaluates every filter so totalResults is the exact upstream total, plus how to paginate via nextCursor. Missing details like rate limits or cache-staleness implications keep it below 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with purpose then rules then caching/pagination, with no filler. The opening filter enumeration slightly overlaps with what the schema already lists, so it is not maximally economical, but every clause carries usable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 19-parameter, nested-object tool with an output schema present, the description covers the essential non-schema gaps: constraint interactions, window caps, caching, exactness of totals, and pagination mechanics. An agent can call it correctly without opening the schema, though sibling routing is the one untouched area.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 95%, so the baseline is 3, but the description adds cross-parameter semantics the schema only partially encodes: the keyword/keywordExactMatch and cpeName/isVulnerable dependencies, the exclusivity pair, and the shared 120-day window limit. It also clarifies that statuses and filters are applied upstream by NVD, which is meaning beyond the field-level text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Search CVE records') and enumerates the exact NVD 2.0 filter dimensions the tool accepts, so the agent knows precisely what surface it covers. It is clearly distinct from get-style siblings in name and behavior, but never explicitly names those siblings or contrasts itself with them, keeping it short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Rules' sentence gives real operational constraints (keywordExactMatch requires keyword; isVulnerable requires cpeName; cpeName/virtualMatchString mutually exclusive; 120-day windows) and explains pagination. However, there is no guidance on when to choose this over sibling tools like nvd_get_cves or nvd_get_recent_cves, which is the main 'when-to-use' question for a search tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
10 tool updates
v0.1.0- First observed
nvd_get_cpe - First observed
nvd_get_cve - First observed
nvd_get_cve_history - First observed
nvd_get_cve_summary - First observed
nvd_get_cves - First observed
nvd_get_modified_cves - First observed
nvd_get_recent_cves - First observed
nvd_search_cpe_matches - First observed
nvd_search_cpes - First observed
nvd_search_cves
TDQS
Scored across 10 tools
Tool names and descriptions clearly delineate resource+action, but nvd_get_recent_cves and nvd_get_modified_cves are nearly identical except for ordering, and nvd_get_cve, nvd_get_cve_summary, and nvd_get_cves all target CVE records with overlapping semantics. The descriptions do distinguish scope and detail level, but an agent could easily misselect between the full, summary, and batch variants without careful reading.
Every tool follows a consistent nvd_ verb_noun pattern (get, search, and entity names like cve, cves, cpe). Variants like nvd_get_cve_summary and nvd_get_cve_history extend the base name predictably. No mixed conventions or inconsistent casing.
Ten tools is well within the sweet spot for a domain-specific API wrapper. Each tool maps to a distinct NVD endpoint or use case (single record, batch, search, history, CPE dictionary, CPE matches), so the surface feels scoped rather than padded.
The surface covers CVE retrieval (single, batch, summary, search, history, recent, modified) and CPE lookup (search, get, matches), which is core NVD functionality. Missing operations like CVE creation or modification don't apply since NVD is read-only, but there is no tool for bulk CPE dictionary listing or NVD API status, which could be minor gaps for some workflows.
Maintenance
Related MCP Connectors
NVD MCP — wraps the NIST National Vulnerability Database API.
MCP server for the Vulners.com API
ZEN SecDB MCP server for CVE intelligence, CVSS/EPSS scoring, advisories, SSVC, and package audits.
Search and audit NIST NVD CVEs by keyword, severity, CWE, CISA KEV status, and CPE.
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server that provides tools to search, filter, and retrieve CVE data from the NVD API, including by ID, keyword, severity, and recency.4MIT
- AlicenseAqualityDmaintenanceEnables querying and analyzing a legacy, file-based vulnerability registry via MCP tools for CVE lookup, search, vendor navigation, and aggregate statistics.5ISC
- AlicenseAqualityBmaintenanceMCP server for querying CVE and package vulnerability data from NVD and OSV.dev, allowing CVE lookups and dependency scanning.41MIT
- FlicenseNot gradedqualityAmaintenanceEnables querying the CVE-Search API to browse vendors and products, retrieve vulnerabilities by vendor/product or CVE ID, fetch the latest CVEs with CAPEC/CWE/CPE details, and check database update status via MCP tools.-