Imported from reason-machines/mcp-skills (
skills/cve-mcp-server-security-intelligence/SKILL.md). Install upstream withnpx skills add reason-machines/mcp-skills --skill cve-mcp-server-security-intelligence. Copyright stays with the author.
CVE MCP Server Security Intelligence
Skill by ara.so — MCP Skills collection
What This Project Does
CVE MCP Server is a production-grade Model Context Protocol server that transforms Claude into a comprehensive security analyst. It provides 27 security intelligence tools that integrate with 21 different APIs including NVD, EPSS, CISA KEV, MITRE ATT&CK, Shodan, VirusTotal, GreyNoise, GitHub, and more.
Instead of manually querying multiple security databases, this MCP server allows Claude to:
- Look up detailed CVE information with CVSS scores and affected products
- Calculate composite risk scores using EPSS, KEV status, and PoC availability
- Search for public exploits and proof-of-concept code
- Check IP addresses against threat intelligence feeds
- Analyze malware samples and indicators of compromise
- Generate executive security reports with prioritized recommendations
- Map vulnerabilities to MITRE ATT&CK techniques
The server runs locally via stdio, makes only outbound HTTPS requests, and supports both free APIs (no key required) and premium services.
Installation
Prerequisites
- Python 3.10 or higher
- Claude Desktop or any MCP-compatible client
- (Optional) API keys for premium services
Install via pip/pipx (Recommended)
# Using pipx (isolated environment)
pipx install cve-mcp-server
# Using pip
pip install cve-mcp-server
# Using uv (faster)
uv pip install cve-mcp-server
Install from Source
git clone https://github.com/mukul975/cve-mcp-server.git
cd cve-mcp-server
pip install -e .
Configuration
Claude Desktop Setup
Add to your Claude Desktop config file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"cve-security": {
"command": "python",
"args": ["-m", "cve_mcp_server"],
"env": {
"NVD_API_KEY": "your-nvd-key-here",
"VIRUSTOTAL_API_KEY": "your-vt-key-here",
"SHODAN_API_KEY": "your-shodan-key-here",
"GREYNOISE_API_KEY": "your-greynoise-key-here",
"ABUSEIPDB_API_KEY": "your-abuseipdb-key-here",
"GITHUB_TOKEN": "your-github-token-here"
}
}
}
}
Environment Variables
Required API keys (most are optional, tools degrade gracefully):
NVD_API_KEY- NVD API 2.0 key (free, highly recommended for rate limits)VIRUSTOTAL_API_KEY- VirusTotal v3 API keySHODAN_API_KEY- Shodan API keyGREYNOISE_API_KEY- GreyNoise Community or Enterprise keyABUSEIPDB_API_KEY- AbuseIPDB v2 keyGITHUB_TOKEN- GitHub personal access token (public repo read)ABUSECH_AUTH_KEY- Abuse.ch (MalwareBazaar/ThreatFox) auth keyCIRCL_PDNS_USER- CIRCL Passive DNS usernameCIRCL_PDNS_PASSWORD- CIRCL Passive DNS passwordALIENVAULT_OTX_KEY- AlienVault OTX API key
Create API Keys
Free tier API keys:
- NVD: https://nvd.nist.gov/developers/request-an-api-key
- GitHub: https://github.com/settings/tokens (needs
public_reposcope) - VirusTotal: https://www.virustotal.com/gui/join-us
- AbuseIPDB: https://www.abuseipdb.com/register
Core Tool Categories
1. Vulnerability Intelligence (8 tools)
lookup_cve
Fetch detailed CVE record from NVD:
# Claude will call this as:
# lookup_cve(cve_id="CVE-2024-3400")
# Returns:
{
"id": "CVE-2024-3400",
"description": "Command injection vulnerability in...",
"cvss_v3_score": 10.0,
"cvss_v3_severity": "CRITICAL",
"cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
"published": "2024-04-12T00:00:00",
"last_modified": "2024-04-15T12:34:56",
"cwe_ids": ["CWE-77"],
"references": [...],
"affected_products": [...]
}
search_cves
Search NVD by keyword, product, or severity:
# search_cves(keyword="Apache Log4j", severity="CRITICAL", last_n_days=30)
# search_cves(product="palo alto networks", max_results=10)
get_epss_score
Get exploitation probability score (0.0-1.0):
# get_epss_score(cve_id="CVE-2024-3400")
# Returns:
{
"cve": "CVE-2024-3400",
"epss": 0.89234,
"percentile": 0.99123,
"date": "2024-05-16"
}
check_kev_status
Check if CVE is in CISA Known Exploited Vulnerabilities:
# check_kev_status(cve_id="CVE-2021-44228")
# Returns:
{
"in_kev": true,
"date_added": "2021-12-10",
"due_date": "2021-12-24",
"required_action": "Apply updates per vendor instructions",
"known_ransomware": true
}
bulk_cve_lookup
Batch fetch up to 20 CVEs in parallel:
# bulk_cve_lookup(cve_ids=["CVE-2024-3400", "CVE-2023-44487", "CVE-2021-44228"])
2. Exploit & Attack Intelligence (4 tools)
search_exploits
Search GitHub for public PoC exploits:
# search_exploits(cve_id="CVE-2024-3400")
# Returns:
{
"cve": "CVE-2024-3400",
"exploit_count": 12,
"exploits": [
{
"title": "CVE-2024-3400 PoC",
"url": "https://github.com/...",
"stars": 45,
"language": "Python",
"created_at": "2024-04-13"
}
]
}
get_mitre_techniques
Map CVE to MITRE ATT&CK framework:
# get_mitre_techniques(cve_id="CVE-2021-44228")
# Returns:
{
"cve": "CVE-2021-44228",
"techniques": [
{
"id": "T1190",
"name": "Exploit Public-Facing Application",
"tactic": "Initial Access",
"description": "...",
"mitigations": [...]
}
]
}
check_poc_availability
Determine if PoC code exists across multiple sources:
# check_poc_availability(cve_id="CVE-2024-3400")
# Returns:
{
"poc_available": true,
"sources": ["GitHub", "Exploit-DB"],
"confidence": "HIGH"
}
3. Risk Analysis & Reporting (4 tools)
calculate_risk_score
Compute composite 0-100 risk score:
# calculate_risk_score(cve_id="CVE-2024-3400")
# Returns:
{
"cve": "CVE-2024-3400",
"risk_score": 98.5,
"risk_level": "CRITICAL",
"components": {
"cvss_score": 10.0,
"epss_score": 0.89234,
"in_kev": true,
"poc_available": true,
"exploit_maturity": "FUNCTIONAL"
},
"recommendation": "Patch immediately - active exploitation confirmed"
}
Risk score formula:
Base = CVSS * 10 (0-100)
+ EPSS * 30 (0-30)
+ KEV bonus: +20
+ PoC bonus: +10
+ Capped at 100
prioritize_cves
Rank multiple CVEs by composite risk:
# prioritize_cves(cve_ids=["CVE-2024-3400", "CVE-2023-4966", "CVE-2023-44487"])
# Returns sorted list with risk scores:
[
{"cve": "CVE-2024-3400", "risk_score": 98.5, "priority": 1},
{"cve": "CVE-2023-44487", "risk_score": 87.3, "priority": 2},
{"cve": "CVE-2023-4966", "risk_score": 76.2, "priority": 3}
]
generate_risk_report
Create executive security report:
# generate_risk_report(cve_ids=["CVE-2024-3400"], include_mitigations=True)
# Returns formatted markdown report with:
# - Executive summary
# - CVE details with CVSS/EPSS
# - KEV status and exploit availability
# - MITRE ATT&CK mapping
# - Prioritized remediation steps
4. Network Intelligence (4 tools)
lookup_ip_reputation
Check IP against AbuseIPDB:
# lookup_ip_reputation(ip_address="185.220.101.34")
# Returns:
{
"ip": "185.220.101.34",
"abuse_confidence": 100,
"total_reports": 1234,
"is_public": true,
"is_whitelisted": false,
"country": "US",
"isp": "Example ISP",
"usage_type": "Data Center/Web Hosting/Transit"
}
check_ip_noise
Query GreyNoise for attack activity:
# check_ip_noise(ip_address="185.220.101.34")
# Returns:
{
"ip": "185.220.101.34",
"classification": "malicious",
"last_seen": "2024-05-16",
"tags": ["SSH Bruteforce", "Web Scanner"],
"cves": ["CVE-2024-1234"],
"actor": "Unknown"
}
shodan_host_lookup
Get open ports and vulnerabilities:
# shodan_host_lookup(ip_address="8.8.8.8")
# Returns:
{
"ip": "8.8.8.8",
"ports": [53, 443],
"vulns": [],
"services": [
{"port": 53, "protocol": "dns", "product": "Google DNS"}
],
"os": null,
"hostnames": ["dns.google"]
}
5. Threat Intelligence (4 tools)
virustotal_lookup
Analyze hashes/URLs/domains/IPs:
# virustotal_lookup(resource_type="hash", resource="44d88612fea8a8f36de82e1278abb02f")
# virustotal_lookup(resource_type="url", resource="https://malicious.example.com")
# virustotal_lookup(resource_type="domain", resource="malicious.example.com")
# virustotal_lookup(resource_type="ip", resource="192.0.2.1")
# Returns:
{
"resource": "44d88612fea8a8f36de82e1278abb02f",
"positives": 56,
"total": 70,
"scan_date": "2024-05-16 12:34:56",
"permalink": "https://virustotal.com/...",
"detections": {
"Kaspersky": "HEUR:Trojan.Win32.Generic",
"Microsoft": "Trojan:Win32/Meterpreter"
}
}
search_malware
Query MalwareBazaar for samples:
# search_malware(query_type="tag", query="Emotet", limit=10)
# search_malware(query_type="hash", query="44d88612fea8a8f36de82e1278abb02f")
# Returns:
{
"query_status": "ok",
"data": [
{
"sha256_hash": "abc123...",
"file_type": "exe",
"file_size": 123456,
"signature": "Emotet",
"first_seen": "2024-05-01",
"tags": ["Emotet", "trojan"]
}
]
}
search_iocs
Query ThreatFox for indicators of compromise:
# search_iocs(query_type="malware", query="CobaltStrike")
# search_iocs(query_type="ioc", query="192.0.2.1")
# Returns:
{
"query_status": "ok",
"data": [
{
"ioc": "192.0.2.1",
"ioc_type": "ip:port",
"malware": "CobaltStrike",
"confidence_level": 100,
"first_seen": "2024-05-10",
"tags": ["c2"]
}
]
}
Common Usage Patterns
Pattern 1: Complete Vulnerability Triage
When a user asks "Should we patch CVE-2024-3400?", orchestrate:
# Step 1: Get CVE details
cve_data = lookup_cve("CVE-2024-3400")
# Step 2: Calculate risk score (combines CVSS + EPSS + KEV + PoC)
risk = calculate_risk_score("CVE-2024-3400")
# Step 3: Check for public exploits
exploits = search_exploits("CVE-2024-3400")
# Step 4: Map to ATT&CK for context
attack = get_mitre_techniques("CVE-2024-3400")
# Step 5: Present unified recommendation
# Risk score 98.5/100 → Patch immediately
# KEV status: YES → Federal mandate to patch
# EPSS: 89% → High exploitation probability
# PoC available: YES → Exploitation barriers low
Pattern 2: Batch Vulnerability Prioritization
When user provides a list of CVEs:
# User: "Prioritize these CVEs: CVE-2024-3400, CVE-2023-4966, CVE-2023-44487"
# Single call to get ranked list
prioritized = prioritize_cves([
"CVE-2024-3400",
"CVE-2023-4966",
"CVE-2023-44487"
])
# Returns:
# 1. CVE-2024-3400 (98.5) - CRITICAL - Patch this week
# 2. CVE-2023-44487 (87.3) - HIGH - Patch this month
# 3. CVE-2023-4966 (76.2) - HIGH - Patch next quarter
Pattern 3: IP Threat Investigation
When investigating a suspicious IP:
# User: "Is 185.220.101.34 malicious?"
# Check reputation
abuse = lookup_ip_reputation("185.220.101.34")
# Check active scanning behavior
noise = check_ip_noise("185.220.101.34")
# Get infrastructure details
host = shodan_host_lookup("185.220.101.34")
# Cross-reference with VirusTotal
vt = virustotal_lookup("ip", "185.220.101.34")
# Synthesize verdict:
# AbuseIPDB: 100% confidence malicious
# GreyNoise: Active SSH bruteforce + web scanning
# Shodan: Exposed SSH, MySQL, RDP
# VT: Flagged by 12/90 vendors
# → Block immediately
Pattern 4: Malware Analysis Workflow
When user provides a file hash:
# User: "Analyze hash 44d88612fea8a8f36de82e1278abb02f"
# Check VirusTotal
vt = virustotal_lookup("hash", "44d88612fea8a8f36de82e1278abb02f")
# Search MalwareBazaar
mb = search_malware("hash", "44d88612fea8a8f36de82e1278abb02f")
# Find related IOCs in ThreatFox
if mb["data"]:
family = mb["data"][0]["signature"]
iocs = search_iocs("malware", family)
# Present:
# Detection: 56/70 engines (Meterpreter)
# Family: Generic backdoor
# Related IOCs: 12 C2 IPs, 5 domains
Pattern 5: Executive Security Report
When user needs a formal report:
# User: "Generate security report for CVEs found in our scan"
report = generate_risk_report(
cve_ids=["CVE-2024-3400", "CVE-2023-44487"],
include_mitigations=True
)
# Returns formatted markdown with:
# - Executive summary (risk level, count)
# - Per-CVE analysis (CVSS, EPSS, KEV)
# - Exploit landscape (PoC availability)
# - ATT&CK techniques mapped
# - Prioritized remediation timeline
# - Mitigation strategies per CVE
Troubleshooting
Issue: Tool returns "API key not configured"
Solution: Set the required environment variable in Claude Desktop config:
{
"mcpServers": {
"cve-security": {
"env": {
"NVD_API_KEY": "your-actual-key-here"
}
}
}
}
Issue: Rate limit errors from NVD
Solution:
- Ensure
NVD_API_KEYis set (increases rate limit from 5/30s to 50/30s) - The server has built-in rate limiting and caching
- Use
bulk_cve_lookupinstead of multiplelookup_cvecalls
Issue: "Private IP address blocked"
Solution: This is intentional security behavior. Network intelligence tools block RFC 1918 private IPs (10.x, 172.16.x, 192.168.x) to prevent internal network scanning. Only use public IPs.
Issue: Shodan returns empty results
Causes:
- IP not in Shodan database (not scanned recently)
- API key missing or invalid
- Rate limit exceeded (1 request/second on free tier)
Issue: CVE not found in NVD
Check:
- CVE ID format is correct (CVE-YYYY-NNNNN)
- CVE is recently published (NVD has 24-48h delay)
- Try
search_cveswith keyword instead
Issue: EPSS score returns 0.0
Explanation: EPSS updates daily. Newly published CVEs may not have EPSS scores yet. Score of 0.0 is valid (means <0.1% exploitation probability).
Issue: Tools work in CLI but not in Claude Desktop
Solution:
- Restart Claude Desktop after config changes
- Check config JSON syntax (use JSONLint)
- Verify Python path in
commandfield:which python # macOS/Linux where python # Windows - Check Claude Desktop logs:
- macOS:
~/Library/Logs/Claude/mcp*.log - Windows:
%APPDATA%\Claude\logs\mcp*.log
- macOS:
Testing the Installation
Test from command line:
# Test basic CVE lookup
python -m cve_mcp_server --test lookup_cve CVE-2021-44228
# Test risk calculation
python -m cve_mcp_server --test calculate_risk_score CVE-2024-3400
# Test with API key
NVD_API_KEY=your-key python -m cve_mcp_server --test search_cves "Apache"
Test in Claude Desktop:
After configuration, restart Claude Desktop and try:
"Can you look up CVE-2021-44228 and tell me its risk score?"
"Search for recent critical CVEs in Apache Log4j"
"Check if 185.220.101.34 is malicious"
"Analyze hash 44d88612fea8a8f36de82e1278abb02f"
Advanced Configuration
Custom Cache Location
Set cache directory via environment variable:
{
"env": {
"CVE_MCP_CACHE_DIR": "/path/to/cache"
}
}
Default locations:
- macOS:
~/Library/Caches/cve-mcp-server/ - Linux:
~/.cache/cve-mcp-server/ - Windows:
%LOCALAPPDATA%\cve-mcp-server\cache\
Disable Caching
{
"env": {
"CVE_MCP_DISABLE_CACHE": "true"
}
}
Custom Rate Limits
{
"env": {
"NVD_RATE_LIMIT": "10",
"VIRUSTOTAL_RATE_LIMIT": "4"
}
}
Security Considerations
- No inbound ports: Server runs via stdio only
- No data storage: Only caches API responses locally
- API key handling: Never logged or transmitted except to authorized APIs
- Private IP blocking: Prevents internal network scanning
- HTTPS only: All external requests use TLS
- Input validation: All inputs sanitized via Pydantic schemas
Best Practices
- Always set NVD_API_KEY - Dramatically increases rate limits
- Use bulk operations -
bulk_cve_lookupinstead of loops - Cache results - Risk scores for same CVE rarely change within 24h
- Combine tools - Use
calculate_risk_scorewhich aggregates CVSS+EPSS+KEV - Check KEV first - If in CISA KEV, patch immediately regardless of CVSS
- Interpret EPSS correctly - 0.1 = 10% probability, not 10.0
- Validate CVE IDs - Must match pattern CVE-YYYY-NNNNN
API Key Priority Guide
Essential (free):
NVD_API_KEY- 10x rate limit increase
High value (free tier):
GITHUB_TOKEN- Exploit search, better rate limitsVIRUSTOTAL_API_KEY- 4 req/min on free tierABUSEIPDB_API_KEY- IP reputation checks
Optional (paid or limited free):
SHODAN_API_KEY- 1 req/sec free, 100 credits/monthGREYNOISE_API_KEY- Community tier availableABUSECH_AUTH_KEY- Higher rate limits
Specialized:
CIRCL_PDNS_USER/PASSWORD- Passive DNS (requires registration)ALIENVAULT_OTX_KEY- Threat intelligence pulses