Skip to main content
Glama
millsks

nvd-cve-mcp-server

by millsks

NVD CVE MCP Server (Python, stdio)

A Model Context Protocol (MCP) server that exposes CVE search tools backed by the NVD API v2.0.

Features

  • search_cve_by_id — look up an exact CVE ID (e.g. CVE-2024-1234)

  • search_cve_by_keyword — search by product name/keyword, with optional days_back date filter

  • get_recent_cves — get newly published CVEs from a configurable time window (default: 7 days)

  • search_by_severity — filter by severity: CRITICAL, HIGH, MEDIUM, LOW

  • NVD API rate limiting + automatic retry with exponential backoff (handles 429, 5xx errors)

  • Respects Retry-After response headers; up to 3 retries per request

  • NVD API date range limit enforced: days_back is validated against the 120-day maximum

  • stdio transport (recommended for Claude Desktop and most MCP clients)

Related MCP server: NVD MCP Server

Data Source

Project Structure

nvd_cve_mcp_server/
├── pixi.toml
├── pyproject.toml
├── README.md
└── src/nvd_cve_mcp_server/
    ├── __init__.py
    ├── nvd_client.py
    └── server.py

Setup

Supported platforms: linux-64, linux-aarch64, osx-arm64, osx-64, win-64

cd nvd-cve-mcp-server
pixi install
pixi run run-mcp-server

Development workflow (pixi tasks)

The project uses pixi tasks for all quality and packaging workflows:

pixi run lint          # ruff lint
pixi run format        # ruff formatter
pixi run format-check  # verify formatting only
pixi run typecheck     # mypy (strict)
pixi run test          # pytest
pixi run check         # lint + format-check + typecheck + test

Build and release artifacts

  • PyPI artifacts (wheel + sdist) are built with Hatch:

pixi run build-pypi
  • Conda package is built from a v1 recipe (recipe/recipe.yaml) aligned with conda-forge/feedstock workflows. The recipe source is expected to be a version tag tarball (v<version>) with a pinned SHA256.

pixi run build-conda

Changelog generation

git-cliff is configured in pyproject.toml and generates CHANGELOG.md from Conventional Commit history.

pixi run changelog

Conventional Commits

Use commit messages that follow: type(scope): description

Common types:

  • feat: new functionality

  • fix: bug fix

  • docs: documentation changes

  • refactor: internal refactors

  • test: tests

  • build: packaging/build tooling

  • ci: CI/CD changes

  • chore: maintenance

Examples:

  • feat(server): add severity filter tool

  • fix(nvd): handle retry-after parsing

  • build(release): add hatch pypi build task

History rewrite note: if commit history is rewritten to conform to Conventional Commits, coordinate with collaborators and force-push carefully.

Option 2: pip / venv

cd nvd-cve-mcp-server
python -m venv .venv
source .venv/bin/activate
pip install -e .
python -m nvd_cve_mcp_server.server

Configuration

Environment variables:

  • NVD_API_KEY (optional, recommended for higher NVD rate limits)

  • NVD_RATE_LIMIT_REQUESTS (optional)

  • NVD_RATE_LIMIT_WINDOW_SECONDS (optional)

Defaults used by server:

  • Without API key: 5 requests / 30 seconds

  • With API key: 50 requests / 30 seconds

MCP Transport

The server uses stdio transport:

mcp.run(transport="stdio")

Example MCP Client Configuration (Claude Desktop style)

Adjust Python path/environment for your machine:

{
  "mcpServers": {
    "cve": {
      "command": "python",
      "args": ["-m", "nvd_cve_mcp_server.server"],
      "cwd": "/path/to/nvd-cve-mcp-server",
      "env": {
        "NVD_API_KEY": "your_api_key_here"
      }
    }
  }
}

Tool Usage Examples

1) search_cve_by_id

Input:

{ "cve_id": "CVE-2024-3094" }

2) search_cve_by_keyword

Search by keyword with no date filter:

Input:

{ "keyword": "openssl", "limit": 5 }

Search by keyword limited to the last 30 days (days_back max is 120):

Input:

{ "keyword": "openssl", "limit": 5, "days_back": 30 }

3) get_recent_cves

Defaults to the last 7 days. Accepts any value from 1–120 for days_back:

Input:

{ "limit": 10, "days_back": 7 }

4) search_by_severity

Input:

{ "severity": "HIGH", "limit": 10 }

Response Shape

Each tool returns a normalized structure like:

{
  "success": true,
  "total_results": 123,
  "returned_results": 10,
  "cves": [
    {
      "id": "CVE-2024-0001",
      "published": "2024-01-01T00:00:00.000",
      "last_modified": "2024-01-02T00:00:00.000",
      "description": "...",
      "severity": "HIGH",
      "base_score": 7.5,
      "vector": "CVSS:3.1/...",
      "cwes": ["CWE-79"],
      "references": ["https://..."]
    }
  ]
}

Error case:

{
  "success": false,
  "error": "NVD API request failed ..."
}

Error Handling & Retry Behavior

The NVDClient automatically retries transient failures up to 3 times using exponential backoff with jitter:

Condition

Behavior

HTTP 429 / 5xx

Retry with backoff; honour Retry-After header if present

Timeout

Retry with backoff

Network error

Retry with backoff

Invalid date range (days_back > 120)

Immediate error — no retry

Invalid severity value

Immediate error — no retry

Available Tools

4 tools
get_recent_cvesA

Fetch recent CVEs from the last days_back days (max 120 due to NVD API limit).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
days_backNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Without annotations, the description carries the burden of behavioral disclosure. It mentions the NVD API limit of 120 days, which is a key constraint, but does not describe other behaviors like pagination, rate limits, or that it returns a list of CVEs. Output schema exists but is not referenced.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, no redundant words, directly communicates the tool's core function and a key constraint. Every part is necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with two parameters and an existing output schema, the description is mostly complete. It mentions the critical API limit and the time-based nature. However, it lacks guidance on when to use this tool versus siblings, slightly reducing completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so description must compensate. It adds meaning for `days_back` by specifying 'last `days_back` days', but does not explain `limit` parameter (default 20) beyond what the schema provides. This partial clarification is insufficient for full compensation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the verb 'Fetch' and resource 'recent CVEs', specifies the time window via `days_back` parameter, and differentiates from siblings like search_by_severity or search_cve_by_id by focusing on recency.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implicitly conveys when to use (fetching recent CVEs by days back) but does not explicitly state when not to use or compare to sibling tools like search_by_severity or search_cve_by_keyword, leaving room for confusion.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_by_severityC

Filter CVEs by severity (CRITICAL, HIGH, MEDIUM, LOW).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
severityYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided; description only states it filters by severity. Missing details on pagination, authentication, or any side effects. A read-only filter tool should disclose at least the output nature.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence is concise but lacks structure. Could separate purpose from parameter details or add a note about usage. Not verbose, but too minimal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given output schema exists and context signals show simple parameters, the description is functional but incomplete. Does not mention return format or that it lists CVEs meeting the severity filter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so description must compensate. It mentions severity values but does not explain the 'limit' parameter (default 20). Only one parameter is addressed minimally.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states verb 'Filter' and resource 'CVEs by severity', listing possible values. However, it does not distinguish from sibling tools like get_recent_cves or search_cve_by_keyword.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool vs alternatives. Does not explain that it is for filtering specific severities while other tools handle recency, ID lookup, or keyword search.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_cve_by_idA

Search for a CVE by ID (example: CVE-2024-1234).

ParametersJSON Schema
NameRequiredDescriptionDefault
cve_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, and the description does not disclose behavior beyond the search action. It lacks details on missing IDs, rate limits, or authorization requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no wasted words, efficiently conveying the core functionality.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple lookup tool with an output schema, the description is largely complete. It could strengthen sibling differentiation, but the core task is well-covered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% for the parameter, but the description provides an example format (CVE-2024-1234), adding partial meaning. However, it does not specify exact format or constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches for a CVE by ID, with an example. It distinguishes from siblings that search by other criteria.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when a CVE ID is known, but does not explicitly state when to use this tool versus sibling tools like search_cve_by_keyword.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_cve_by_keywordB

Search CVEs by product name or any keyword. Optionally limit to the last days_back days (max 120).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
keywordYes
days_backNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose all behavioral traits. It mentions the days_back constraint (max 120) but omits details on pagination, result ordering, or whether the tool is read-only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no redundant words, though lacking structural elements like bullet points. Could be slightly more organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Provides core purpose and one optional parameter, but the output schema covers return structure. Missing description of 'limit' and any handling of null days_back. Adequate but with gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must explain parameters. It adds meaning for 'keyword' (product name or any keyword) and 'days_back' (optional with max 120), but does not describe the 'limit' parameter at all.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches CVEs by keyword or product name, and optionally filters by recency. It distinguishes from siblings like get_recent_cves and search_by_severity, though not from search_cve_by_id.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when a keyword is available, but does not provide explicit when-not-to-use guidance or alternatives like using search_cve_by_id for specific IDs.

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.

  1. 4 tool updatesv0.1.2
    • First observedget_recent_cves
    • First observedsearch_by_severity
    • First observedsearch_cve_by_id
    • First observedsearch_cve_by_keyword

TDQS

A3.5/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: recent CVEs, severity filter, ID lookup, and keyword search. No overlap or confusion.

Naming Consistency3/5

Mixed naming patterns: 'get_recent_cves' uses 'get' while others use 'search'. Also 'search_by_severity' lacks 'cve' unlike 'search_cve_by_id' and 'search_cve_by_keyword'.

Tool Count5/5

With 4 tools covering common CVE search methods, the count is well-scoped for the purpose without being excessive.

Completeness4/5

Core CVE queries (time, severity, ID, keyword) are covered. Missing explicit date range or CVSS score search but acceptable for a simple server.

Maintenance

ActivityInactive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    An MCP server for vulnerability management that provides tools for automated severity and CWE classification using NLP models. It enables AI agents to query the Vulnerability Lookup API for detailed CVE information and search for security vulnerabilities across various sources.
    16
    42
    AGPL 3.0
  • A
    license
    A
    quality
    C
    maintenance
    MCP server for the NIST National Vulnerability Database — lets AI assistants search CVEs by keyword, severity, CPE, CWE, KEV status, and date range via natural language.
    2
    GPL 3.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol (MCP) server for querying the NIST National Vulnerability Database (NVD) API, enabling search and retrieval of CVE details, temporal context, and KEV catalog entries.
    15
    MIT