exploitwatch-mcp
An MCP server for CVE triage. Give your AI assistant a CVE ID and it can look up what the vulnerability is, whether attackers are exploiting it right now, how likely exploitation is, and how urgently to patch.
It is the vulnerability-intelligence half of ExploitWatch, packaged so any MCP client can use it.
Who it's for, and who it isn't
Everything it returns comes from free public sources (NVD, CISA KEV, FIRST EPSS, trusted news sites). What it adds is a consistent, versioned triage method; a score that always says who gave it and under which CVSS version; and access from inside the AI assistant your team already uses.
Good fit
- Analysts with one CVE in front of them, from a scanner finding, an advisory or a ticket, who want a sourced first answer in seconds instead of checking NVD, KEV and EPSS by hand.
- Explaining a CVE to leadership. The
triage_cveprompt'sexecformat writes a short summary: the risk, the urgency and why, and the decision needed. - Teams that want one method across different assistants. Everyone gets the same urgency rules and score
order whether they use Claude, Cursor or another MCP client, and
methodology_versionrecords which rules applied. - Builders of security agents, as a tested tool layer that keeps the urgency decision in code rather than in the model.
Not a fit
- Not a scanner or asset inventory. It doesn't know what you run or how exposed it is. Use it alongside the tool that does.
- Not a backlog prioritiser. It handles one CVE per call. For thousands of findings, use the KEV and EPSS feeds directly or your vulnerability management platform.
- Little new data if you already have a vulnerability management platform. If yours already shows KEV and EPSS, this adds conversational access and a shared method, not new intelligence.
- Not a compliance decision. The urgency bands are a sensible default, not your organisation's patch SLAs.
What it provides
| Kind | Name | What it does |
|---|---|---|
| Tool | lookup_cve |
Description, one CVSS score with its version and source, NVD's analysis status, publish date and references from the NIST National Vulnerability Database, plus a patch urgency rating |
| Tool | check_kev |
Whether CISA's Known Exploited Vulnerabilities catalog lists the CVE, with the date added, required action, federal due date and ransomware use |
| Tool | get_epss |
FIRST's EPSS probability that the CVE is exploited in the next 30 days, and its percentile |
| Tool | search_cve_news |
Recent articles about the CVE from an allowlist of trusted security news sites and vendor advisories |
| Resource | exploitwatch://methodology |
How urgency is calculated and which data sources are used |
| Prompt | triage_cve |
A full triage of one CVE, written for an engineer or an exec |
Patch urgency is decided by rules, not the model
The same data always gets the same urgency, so results are consistent and auditable and can't be changed by prompt wording or web content. The first matching rule wins:
- Actively exploited (in CISA KEV, checked live as well as NVD's copy, which can lag by days): patch now
- No CVSS score yet: needs review. Nobody has rated it, which is not the same as low risk.
- CVSS 9.0 or higher: patch now
- CVSS 7.0 to 8.9: patch this week
- CVSS 4.0 to 6.9: patch this month
- Below 4.0: monitor
Rejected (withdrawn) CVEs get no urgency; lookup_cve says the CVE was rejected. EPSS is reported
as context and does not change the urgency.
Which CVSS score
Most CVEs have several scores, and NVD no longer analyses most new ones, so the score is usually the one from the CNA (the organisation that assigned the CVE). The order is: NVD's own score, then the CNA's or CISA's; within each, CVSS 3.1, then 4.0, then 3.0; CVSS 2.0 only when nothing newer exists. 3.1 comes first because the thresholds are the CVSS 3 bands. In a sample of 2,000 October 2026 CVEs, a CVE's 4.0 and 3.1 scores fell in different bands 41% of the time.
Every result shows its working:
{
"id": "CVE-2021-44228",
"cvss_score": 10.0,
"severity": "CRITICAL",
"cvss_version": "3.1",
"cvss_source": "NVD",
"nvd_status": "Analyzed",
"actively_exploited": true,
"kev_checked": true,
"kev_catalog_version": "2026.10.30",
"urgency": "patch now",
"urgency_reason": "actively exploited; exploitation outranks the CVSS score",
"methodology_version": "1"
}
kev_checked: false means CISA's catalog could not be reached, so exploitation status rests on
NVD's copy alone; kev_catalog_version is the date of the catalog used. The full rules are in the exploitwatch://methodology resource.
Does it have a UI?
No. An MCP server has no interface of its own: your MCP client (Claude Desktop, Claude Code, Cursor and others) is the interface. You ask in plain language, for example "Triage CVE-2024-3094", and the client calls these tools.
To try the tools by hand, the MCP Inspector opens a browser page where you can call each one:
npx @modelcontextprotocol/inspector uvx exploitwatch-mcp
Install
You need uv. There is nothing else to install: uvx fetches and runs the server.
Claude Code
claude mcp add exploitwatch -- uvx exploitwatch-mcp
# with API keys: claude mcp add exploitwatch -e TAVILY_API_KEY=your-key -e NVD_API_KEY=your-key -- uvx exploitwatch-mcp
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"exploitwatch": {
"command": "uvx",
"args": ["exploitwatch-mcp"],
"env": {
"TAVILY_API_KEY": "your-key",
"NVD_API_KEY": "optional"
}
}
}
}
From a clone: replace uvx exploitwatch-mcp with uv run --directory /path/to/exploitwatch-mcp exploitwatch-mcp.
Configuration
| Variable | Needed for | |
|---|---|---|
TAVILY_API_KEY |
search_cve_news |
Optional. Without a key, news search uses Tavily's keyless mode, which is rate-limited and may be refused. Set a key from tavily.com for dependable results. The other tools never need it. |
NVD_API_KEY |
lookup_cve |
Optional. Raises NVD's rate limit. Request one from NIST. |
Set them in your MCP client's env block, as above. When running from a clone, a .env file in the directory you start the server from also works (see .env.example).
Data sources
| Source | Used for | Notes |
|---|---|---|
| NIST NVD | CVE details and CVSS | This product uses the NVD API but is not endorsed or certified by the NVD. |
| CISA KEV | Confirmed exploitation | The catalog is downloaded once and cached for 6 hours. If it can't be reached, urgency falls back to NVD's exploitation flag. |
| FIRST EPSS | Exploitation probability | Updated daily by FIRST. |
| Tavily | News search | Limited to an allowlist of security news and vendor sites, checked by the server on every result, not just requested from Tavily. Only articles that mention the exact CVE ID are returned. |
Validation
Before release, 10 base and edge cases were run end to end: Claude answered each one using this server's tools, code checked the raw tool output, and a separate LLM judge (gpt-5-mini) scored every answer on a 7-point rubric, with 3 runs per case. The server's output was correct in all 60 runs. Round 1 found two defects in the guidance the server gives assistants, both fixed before round 2; round 3 confirmed the urgency reason ("patch now" because it is actively exploited) on Heartbleed.
- Report (2 pages): evals/results/2026-11-04-mvp-validation.pdf
- Every case, run, tool output, answer and judge verdict: evals/results/2026-11-04-mvp-validation.csv
- Cases: evals/mvp_cases.yaml; rerun:
uv run --group eval python evals/run_mvp_validation.py --out new.csv
A second validation tested executive summaries and the news domain allowlist (10 cases, 3 runs each). Exec summaries met the sentence limit in 12 of 15 runs, up from 1 of 3, and no answer claimed to have read a site outside the allowlist. Two exec wording gaps it found were fixed and re-tested (6 of 6 runs). After the human review, exec summaries may again name an affected or fixed software version where the data states it, because the version to upgrade to is part of the decision.
- Report (2 pages): evals/results/2026-11-04-exec-domain-validation.pdf
- Every case, run and verdict: evals/results/2026-11-04-exec-domain-validation.csv
- Cases: evals/exec_domain_cases.yaml; rerun:
uv run --group eval python evals/run_mvp_validation.py --spec evals/exec_domain_cases.yaml --out new.csv
A human review checked the evaluation by hand: 10 of the judge's verdicts across both validations, and 3 expected values against NVD's and CISA's own pages (all 3 matched). The reviewer agreed with 6 of 9 judge verdicts. All 3 disagreements were the judge or a test criterion being too strict, and none was a wrong answer the judge had passed. Record and evidence: evals/human_review/.
Limits
- It knows about CVEs, not about you: it can't tell whether you run the affected software or how exposed it is.
- One CVE per call, and no search by product.
- CVSS is a severity score, not a risk score. Treat the urgency as a first answer, not a compliance decision.
- Without an
NVD_API_KEY, NVD allows about 5 requests per 30 seconds. - The urgency is enforced in code, but the wording of an answer is the client model's. In validation the server's own output was correct in every run, but some answers added background from the model's own knowledge, and exec summaries sometimes ran a sentence long.
- The domain allowlist governs
search_cve_newsonly. If your client also has its own web search or browsing, the model can use that, and no MCP server can prevent it.
Safety
- News is untrusted. Search results are third-party web content. The tool description tells the model to treat them as information, never as instructions, and they never change the urgency rating.
- Clean errors. Requests retry timeouts, rate limits and server errors. When a source is still unavailable, the tool returns a short message telling the model to report the data as missing rather than guess. Full errors go to the server log on stderr.
- Strict input. Every tool accepts exactly one CVE ID (
CVE-YYYY-NNNN, any case) and rejects anything else before a request is sent. - Read only. The server only reads public data. It changes nothing on your systems.
Roadmap
- Several CVEs per request, for triaging a list from a scanner or an advisory.
- Organisation context: pair this data with your own asset lists and policies (ExploitWatch's RAG layer).
- Source traceability: anything an answer takes from outside these tools is labelled as such, with its source.
- Configurable allowlist: an organisation can approve additional news and advisory domains.
- Optional decision inputs: SSVC decision points, and EPSS as an optional urgency input.
- Readability and upkeep: CNA names instead of IDs, and a scheduled live check against the real APIs.
Development
uv sync
uv run pytest # offline, uses saved NVD records
uv run python scripts/live_check.py # live end to end against NVD, KEV, EPSS and Tavily (about 1.5 minutes)
uv run exploitwatch-mcp
About
ExploitWatch is a multi-agent CVE triage system, in development, that pairs this public intelligence with an organisation's own documents, to answer both how dangerous a vulnerability is and what the organisation must do about it.
License
Metadata
Release files for exploitwatch-mcp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| exploitwatch_mcp-0.1.0.tar.gz | 154.9 kB | Without provenance | Details for exploitwatch_mcp-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| exploitwatch_mcp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for exploitwatch_mcp-0.1.0-py3-none-any.whl |
Total release size: 173.3 kB
Release files / exploitwatch_mcp-0.1.0.tar.gz
| Download URL | exploitwatch_mcp-0.1.0.tar.gz |
|---|---|
| Size | 154.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
260bc4190c77d99ef473a87a7c8dd6f825bc111884b4f35d67e3e86155981cc6
|
|
BLAKE2b-256 checksum How to use checksums |
16aaa96be643d129ce6d731af60c6dc98a2eed455c325ec493a1feb9ec530e9c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / exploitwatch_mcp-0.1.0-py3-none-any.whl
| Download URL | exploitwatch_mcp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 18.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7cf969fa333a6a8df46f663dfdbcce5001b04d4a3369942eb321b5c3fcdf3d2c
|
|
BLAKE2b-256 checksum How to use checksums |
ab99e917328543d75f804b516114bb4e2be634a768ac37d5258761488f294477
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for exploitwatch-mcp 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.