Skip to main content
Glama
marcoeg

mcp-nvd

by marcoeg

NVD Database MCP Server

PyPI - Version

A Model Context Protocol server implementation to query the NIST National Vulnerability Database (NVD) via its API. https://nvd.nist.gov/

As a prerequisite an NVD API key is required. (Request here).

Status

Works with Claude Desktop app and other MCP compliant hosts and clients using both the stdio and sse transports.

Related MCP server: MCP NVD Server

Features

  • Query specific CVEs by ID with detailed vulnerability data.

  • Search the NVD database by keyword with customizable result options.

  • Supports Server-Sent Events (SSE) transport for real-time communication.

  • Compatible with MCP-compliant clients like Claude Desktop.

Tools

The server implements the following tools to query the NVD Database:

  • get_cve:

    • Description: Retrieves a CVE record by its ID.

    • Parameters:

      • cve_id (str): The CVE ID (e.g., CVE-2019-1010218).

      • concise (bool, default False): If True, returns a shorter format.

    • Returns: Detailed CVE info including scores, weaknesses, and references.

  • search_cve:

    • Description: Searches the NVD database by keyword.

    • Parameters:

      • keyword (str): Search term (e.g., Red Hat).

      • exact_match (bool, default False): If True, requires an exact phrase match.

      • concise (bool, default False): If True, returns shorter CVE records.

      • results (int, default 10): Maximum number of CVE records (1-2000).

    • Returns: List of matching CVEs with total count.

Configuration

  1. Create or edit the Claude Desktop configuration file located at:

    • On macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

    • On Windows: %APPDATA%/Claude/claude_desktop_config.json

  2. Add the following:

{
  "mcpServers": {
    "mcp-nvd": {
      "command": "/path/to/uvx",
      "args": ["mcp-nvd"],
      "env": {
        "NVD_API_KEY": "your-api-key"
      }
    }
  }
}
  1. Replace /path/to/uvx with the absolute path to the uvx executable. Find the path with which uvx command in a terminal. This ensures that the correct version of uvx is used when starting the server.

  2. Restart Claude Desktop to apply the changes.

Development

Setup

  1. Prerequisites:

  2. Clone the Repository:

git clone https://github.com/marcoeg/mcp-nvd
cd mcp-nvd
  1. Set Environment Variables:

    • Create a .env file in the project root:

      NVD_API_KEY=your-api-key
    • Replace your-api-key with your NVD API key.

  2. Install Dependencies:

uv sync
uv pip install -e .

Run with the MCP Inspector

cd /path/to/the/repo
source .env

npx @modelcontextprotocol/inspector uv \
    --directory /path/to/repo/mcp-nvd run mcp-nvd

Then open the browser to the URL indicated by the MCP Inspector, typically http://localhost:8077?proxyPort=8078

Switch freely between stdio and sse transport types in the inspector.

Testing with the SSE Client

Run the Server:

cd /path/to/the/repo
source .env

uv run mcp-nvd --transport sse --port 9090
  • Runs with SSE transport on port 9090 by default.

Run the Client:

Test get_cve:

uv run client.py http://localhost:9090/sse CVE-2019-1010218

Test search_cve (default 10 results):

uv run client.py http://localhost:9090/sse "search:Red Hat"

Test search_cve (exact match, 5 results):

uv run client.py http://localhost:9090/sse "search:Microsoft Windows:exact:5"

Docker Setup

Build

docker build -t mcp-nvd:latest .

Run

With .env:

docker run -d -p 9090:9090 -v /path/to/.env:/app/.env mcp-nvd:latest

With env var:

docker run -d -p 9090:9090 -e NVD_API_KEY="your-key" mcp-nvd:latest

Custom port:

docker run -d -p 8080:8080 -v /path/to/.env:/app/.env mcp-nvd:latest uv run mcp-nvd --transport sse --port 8080 --host 0.0.0.0

Verify

docker logs <container_id>
# Expect: INFO: Uvicorn running on http://0.0.0.0:9090

Test:

uv run client.py http://localhost:9090/sse CVE-2019-1010218

Notes

  • Ensure .env has NVD_API_KEY=your-key or use -e.

  • Default port: 9090.


Here’s the summary formatted as Markdown comments within a code block, suitable for inclusion in a file like docker-compose.yaml or README.md:

Using Docker Compose for Testing

This docker-compose.yaml, located in the tests/ directory, defines a service for testing the MCP-NVD server using a pre-built Docker image. It’s designed for a testing use case, similar to a standalone service like clickhouse, and assumes the image is built beforehand rather than rebuilt each time.

Assumptions

  • Pre-built Image: The service uses a pre-built image tagged as mcp-nvd:test, available locally or in a registry. The image is based on the Dockerfile in the parent directory, which sets up the MCP-NVD server with uv and runs it in SSE mode on port 9090.

How to Build the Image

To create the mcp-nvd:test image:

  1. Navigate to the project root:

    cd ./mcp-nvd
  2. Build the image using the Dockerfile:

    docker build -t mcp-nvd:test .
    • This builds the image with all dependencies from pyproject.toml and the mcp_nvd/ module, setting the default command to run the server.

Running the Service

From the tests/ directory:

cd tests
docker-compose up
  • Access: The server runs at http://localhost:9090.

  • Stop: docker-compose down.

  • Environment: Ensure NVD_API_KEY is in ../.env or use docker-compose --env-file ../.env up.

Running test_tools.py in the Docker Compose Scenario

To run the unit tests (test_tools.py) within the Docker environment:

  1. Start the Service: Ensure the mcp-nvd service is running via docker-compose up.

  2. Exec into the Container:

    • Identify the container name (e.g., mcp-nvd-mcp-nvd-1) with:

      docker ps
    • Run the tests inside the container:

      docker exec -it mcp-nvd-mcp-nvd-1 python /app/tests/test_tools.py
    • Note: Assumes test_tools.py is copied into the image at /app/tests/. If not, modify the Dockerfile to include:

      COPY tests/ ./tests/

      Then rebuild the image with docker build -t mcp-nvd:test . from the root.

  3. Alternative: Run tests locally against the containerized service:

    cd tests
    python test_tools.py
    • This tests against http://localhost:9090 while the service runs.

Key Details

  • Port: 9090 is exposed for SSE access.

  • Logs: Stored in a log-data volume (optional).

  • Image: Must be built once and tagged as mcp-nvd:test before running docker-compose.


Credits to @sidharthrajaram for its working pattern for SSE-based MCP clients and servers: https://github.com/sidharthrajaram/mcp-sse

Available Tools

2 tools
get_cveC

Get a CVE based on the ID and return a formatted string with detailed attributes.

ParametersJSON Schema
NameRequiredDescriptionDefault
cve_idYes
conciseNo

TDQS

C2.7/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the tool returns a 'formatted string with detailed attributes,' which hints at read-only behavior but lacks specifics on permissions, rate limits, error handling, or data sources. For a tool with zero annotation coverage, this is insufficient to inform the agent about key operational traits like safety or performance constraints.

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?

The description is a single, straightforward sentence that efficiently conveys the core action and output. It's front-loaded with the main purpose and avoids unnecessary words, making it easy to parse. However, it could be slightly more structured by separating usage notes or parameter hints, but overall, it's concise and effective for its length.

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

Completeness2/5

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

Given the complexity of retrieving CVE data, the lack of annotations, no output schema, and low schema description coverage, the description is incomplete. It doesn't address critical aspects like what 'detailed attributes' include, how errors are handled, or dependencies on external databases. For a tool with two parameters and no structured support, more context is needed to ensure reliable agent invocation.

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?

The schema description coverage is 0%, meaning parameters are undocumented in the schema. The description mentions 'based on the ID' and 'concise' (implied by 'formatted string'), but it doesn't explain what 'cve_id' entails (e.g., format like 'CVE-2024-12345') or what 'concise' does (e.g., reduces output detail). With low coverage, the description adds minimal value beyond the schema, failing to compensate for the documentation gap.

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's purpose: 'Get a CVE based on the ID and return a formatted string with detailed attributes.' It specifies the verb ('Get'), resource ('CVE'), and output format ('formatted string with detailed attributes'), which is specific and actionable. However, it doesn't explicitly differentiate from its sibling tool 'search_cve', which likely searches for CVEs rather than retrieving a specific one by ID, leaving room for improvement in sibling distinction.

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?

The description provides no guidance on when to use this tool versus alternatives. It mentions retrieving a CVE by ID but doesn't clarify scenarios where this is appropriate compared to 'search_cve' or other potential tools. There's no mention of prerequisites, exclusions, or contextual cues for selection, leaving the agent with minimal usage direction.

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

search_cveC

Search CVEs by keyword and return formatted results matching the get_cve format.

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordYes
exact_matchNo
conciseNo
resultsNo

TDQS

C2.8/5.0
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions that results are 'formatted' to match 'get_cve format,' which adds some context about output behavior. However, it doesn't disclose critical behavioral traits such as whether this is a read-only operation, potential rate limits, authentication requirements, error handling, or what happens when no results are found. For a search tool with zero annotation coverage, this is insufficient.

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 extremely concise—a single sentence that efficiently communicates the core functionality. Every word earns its place: it specifies the action ('Search'), target ('CVEs'), method ('by keyword'), and output characteristic ('formatted results matching the get_cve format'). There's no wasted verbiage or redundancy.

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

Completeness2/5

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

Given the tool's complexity (4 parameters, no annotations, no output schema), the description is incomplete. It doesn't explain parameter meanings, behavioral constraints, or output details beyond referencing another tool's format. For a search function that likely returns structured data, more context is needed about what 'formatted results' entail and how parameters affect the search.

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?

The schema description coverage is 0%, meaning none of the 4 parameters have descriptions in the schema. The description only mentions 'keyword' generically and doesn't explain what 'exact_match', 'concise', or 'results' parameters do, their effects, or practical usage. It fails to compensate for the complete lack of schema documentation, leaving parameters largely unexplained.

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's purpose: 'Search CVEs by keyword and return formatted results matching the get_cve format.' It specifies the verb ('Search'), resource ('CVEs'), and scope ('by keyword'), but doesn't explicitly differentiate from its sibling tool 'get_cve' beyond mentioning the output format. This makes it clear but lacks sibling differentiation.

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?

The description provides no guidance on when to use this tool versus alternatives. It mentions the sibling tool 'get_cve' only in the context of output format, not as an alternative for different use cases. There are no explicit instructions on when to choose search_cve over get_cve or other potential tools, leaving the agent without contextual usage direction.

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

TDQS

B3/5.0
Disambiguation5/5

The two tools have clearly distinct purposes: get_cve retrieves a specific CVE by ID, while search_cve finds CVEs by keyword. There is no overlap in functionality, making it easy for an agent to choose the correct tool based on whether it needs a specific item or a broader search.

Naming Consistency5/5

Both tools follow a consistent verb_noun pattern (get_cve and search_cve), using the same base noun 'cve' and descriptive verbs that clearly indicate their actions. This consistency enhances readability and predictability.

Tool Count2/5

With only 2 tools, the server feels thin for the domain of CVE management, as it lacks essential operations like filtering by date, severity, or vendor, or updating/creating entries. While the tools cover basic retrieval and search, the scope is incomplete for typical security workflows.

Completeness2/5

The tool surface is severely incomplete for CVE management, missing critical operations such as filtering by parameters like date range or CVSS score, handling CVE updates or annotations, and providing bulk operations. This will likely cause agent failures when more complex queries or actions are needed.

Maintenance

ActivityInactive
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    A Model Context Protocol (MCP) server for querying the CVE-Search API. This server provides comprehensive access to CVE-Search, browse vendor and product、get CVE per CVE-ID、get the last updated CVEs.
    6
    103
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    A Model Context Protocol server that retrieves CVE information from the National Vulnerability Database, allowing AI models to access up-to-date vulnerability data.
    1
    7
    Apache 2.0
  • A
    license
    A
    quality
    D
    maintenance
    A Model Context Protocol server providing security vulnerability intelligence tools including CVE lookup, EPSS scoring, CVSS calculation, exploit detection, and Python package vulnerability checking.
    8
    9
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/marcoeg/mcp-nvd'

If you have feedback or need assistance with the MCP directory API, please join our Discord server