# Cve MCP Server Security Intelligence

> Production-grade MCP server providing Claude with 27 security intelligence tools across 21 APIs for vulnerability research, CVE analysis, threat intelligence, and risk scoring

- Skill: `aradotso/cve-mcp-server-security-intelligence` (Agent Skill)
- Install (CLI): `npx skillmds@latest add aradotso/cve-mcp-server-security-intelligence`
- Raw SKILL.md: https://api.skillmd.com/api/skills/aradotso/cve-mcp-server-security-intelligence/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: aradotso (https://skillmd.com/u/aradotso)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/aradotso/cve-mcp-server-security-intelligence

---


# CVE MCP Server Security Intelligence

> Skill by [ara.so](https://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)

```bash
# 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

```bash
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`

```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 key
- `SHODAN_API_KEY` - Shodan API key
- `GREYNOISE_API_KEY` - GreyNoise Community or Enterprise key
- `ABUSEIPDB_API_KEY` - AbuseIPDB v2 key
- `GITHUB_TOKEN` - GitHub personal access token (public repo read)
- `ABUSECH_AUTH_KEY` - Abuse.ch (MalwareBazaar/ThreatFox) auth key
- `CIRCL_PDNS_USER` - CIRCL Passive DNS username
- `CIRCL_PDNS_PASSWORD` - CIRCL Passive DNS password
- `ALIENVAULT_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_repo` scope)
- **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:

```python
# 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:

```python
# 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):

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```python
# 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:

```json
{
  "mcpServers": {
    "cve-security": {
      "env": {
        "NVD_API_KEY": "your-actual-key-here"
      }
    }
  }
}
```

### Issue: Rate limit errors from NVD

**Solution**: 
1. Ensure `NVD_API_KEY` is set (increases rate limit from 5/30s to 50/30s)
2. The server has built-in rate limiting and caching
3. Use `bulk_cve_lookup` instead of multiple `lookup_cve` calls

### 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**:
1. IP not in Shodan database (not scanned recently)
2. API key missing or invalid
3. Rate limit exceeded (1 request/second on free tier)

### Issue: CVE not found in NVD

**Check**:
1. CVE ID format is correct (CVE-YYYY-NNNNN)
2. CVE is recently published (NVD has 24-48h delay)
3. Try `search_cves` with 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**:
1. Restart Claude Desktop after config changes
2. Check config JSON syntax (use JSONLint)
3. Verify Python path in `command` field:
   ```bash
   which python  # macOS/Linux
   where python  # Windows
   ```
4. Check Claude Desktop logs:
   - macOS: `~/Library/Logs/Claude/mcp*.log`
   - Windows: `%APPDATA%\Claude\logs\mcp*.log`

## Testing the Installation

### Test from command line:

```bash
# 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:

```json
{
  "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

```json
{
  "env": {
    "CVE_MCP_DISABLE_CACHE": "true"
  }
}
```

### Custom Rate Limits

```json
{
  "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

1. **Always set NVD_API_KEY** - Dramatically increases rate limits
2. **Use bulk operations** - `bulk_cve_lookup` instead of loops
3. **Cache results** - Risk scores for same CVE rarely change within 24h
4. **Combine tools** - Use `calculate_risk_score` which aggregates CVSS+EPSS+KEV
5. **Check KEV first** - If in CISA KEV, patch immediately regardless of CVSS
6. **Interpret EPSS correctly** - 0.1 = 10% probability, not 10.0
7. **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 limits
- `VIRUSTOTAL_API_KEY` - 4 req/min on free tier
- `ABUSEIPDB_API_KEY` - IP reputation checks

**Optional (paid or limited free)**:
- `SHODAN_API_KEY` - 1 req/sec free, 100 credits/month
- `GREYNOISE_API_KEY` - Community tier available
- `ABUSECH_AUTH_KEY` - Higher rate limits

**Specialized**:
- `CIRCL_PDNS_USER/PASSWORD` - Passive DNS (requires registration)
- `ALIENVAULT_OTX_KEY` - Threat intelligence pulses

