MCP server for querying MITRE ATT&CK framework and generating Navigator layers
npm install mitre-attack-mcpAn MCP (Model Context Protocol) server that provides access to the MITRE ATT&CK framework and generates ATT&CK Navigator layers for coverage visualization.

- Full ATT&CK Framework Access - Query techniques, tactics, groups, software, mitigations, and data sources
- Navigator Layer Generation - Create ATT&CK Navigator layers for coverage visualization
- Coverage Analysis - Analyze your detection coverage and identify gaps
- Threat-Based Gap Analysis - Compare your coverage against specific threat groups
- Full-Text Search - SQLite FTS5 powered search across technique names and descriptions
- Auto-Indexing - Automatically downloads and indexes ATT&CK data on first run
- Works with security-detections-mcp - Cross-reference your detection rules with ATT&CK techniques
No installation required:
``bash`
npx -y mitre-attack-mcp
`bash`
git clone https://github.com/MHaggis/mitre-attack-mcp.git
cd mitre-attack-mcp
npm install
npm run build
Add to your MCP config (~/.cursor/mcp.json or .cursor/mcp.json):
`json`
{
"mcpServers": {
"mitre-attack": {
"command": "npx",
"args": ["-y", "mitre-attack-mcp"],
"env": {
"ATTACK_DOMAIN": "enterprise-attack"
}
}
}
}
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
`json`
{
"mcpServers": {
"mitre-attack": {
"command": "npx",
"args": ["-y", "mitre-attack-mcp"],
"env": {
"ATTACK_DOMAIN": "enterprise-attack"
}
}
}
}
| Variable | Description | Default |
|----------|-------------|---------|
| ATTACK_DOMAIN | ATT&CK domain to index | enterprise-attack |CUSTOM_ATTACK_PATH
| | Path to local STIX JSON (optional) | - |
Valid domains: enterprise-attack, mobile-attack, ics-attack
| Tool | Description |
|------|-------------|
| get_technique(id) | Get technique by ID (e.g., T1059.001) |search_techniques(query)
| | Search techniques by name/description |list_techniques(limit, offset)
| | List all techniques |list_techniques_by_tactic(tactic)
| | List techniques for a tactic |list_techniques_by_platform(platform)
| | Filter by Windows/Linux/macOS/etc |
| Tool | Description |
|------|-------------|
| get_group(id) | Get threat group details (e.g., G0016 for APT29) |search_groups(query)
| | Search groups by name/alias |get_group_techniques(group_id)
| | Get technique IDs used by a group |get_software(id)
| | Get malware/tool details |search_software(query)
| | Search malware and tools |
| Tool | Description |
|------|-------------|
| get_tactic(id) | Get tactic details |list_tactics()
| | List all tactics in matrix order |get_mitigations(technique_id)
| | Get mitigations for a technique |get_data_sources(technique_id)
| | Get data sources for detection |
| Tool | Description |
|------|-------------|
| generate_layer(techniques, name) | Create layer from technique list with scores |generate_coverage_layer(covered_ids, name)
| | Green=covered, red=gap visualization |generate_group_layer(group_id, name)
| | Highlight a threat group's techniques |generate_gap_layer(covered_ids, target_ids, name)
| | Gap analysis between coverage and target |
| Tool | Description |
|------|-------------|
| analyze_coverage(covered_ids) | Get coverage stats by tactic + gap list |find_group_gaps(group_id, covered_ids)
| | Find techniques you're missing vs a group |get_all_technique_ids()
| | Get all valid technique IDs |get_stats()
| | Framework statistics |
`
You: "I have these technique IDs from my detection rules: T1059.001, T1059.003, T1547.001, T1053.005.
What's my coverage like?"
LLM uses: analyze_coverage(covered_ids=["T1059.001", "T1059.003", "T1547.001", "T1053.005"])
Returns:
{
"total_techniques": 625,
"covered_techniques": 4,
"coverage_percentage": 0.6,
"by_tactic": {
"execution": { "total": 45, "covered": 2, "percentage": 4 },
"persistence": { "total": 52, "covered": 2, "percentage": 4 },
...
},
"gaps": ["T1059.002", "T1059.004", ...]
}
`
`
You: "Generate a Navigator layer showing my coverage"
LLM uses: generate_coverage_layer(
covered_ids=["T1059.001", "T1059.003", "T1547.001"],
name="My Detection Coverage"
)
Returns: Navigator layer JSON (paste into https://mitre-attack.github.io/attack-navigator/)
`
`
You: "What APT29 techniques am I missing?"
LLM uses:
1. get_group_techniques(group_id="G0016")
2. find_group_gaps(group_id="G0016", covered_ids=[your techniques])
Returns: List of technique IDs APT29 uses that you don't have coverage for
`
`
You: "Show me a visual of my gaps against APT29"
LLM uses: generate_gap_layer(
covered_ids=[your techniques],
target_ids=[APT29 techniques],
name="APT29 Gap Analysis"
)
Returns: Navigator layer showing green=covered, red=gaps
`
This MCP pairs perfectly with security-detections-mcp to create a complete threat detection workflow:
| MCP | Purpose |
|-----|---------|
| security-detections-mcp | Query 6,500+ detection rules (Sigma, Splunk ESCU, Elastic) |
| mitre-attack-mcp | Analyze coverage against ATT&CK framework |
`
You: "What's my MITRE coverage based on my Splunk detections?"
LLM workflow:
1. Query detections-mcp → get_stats() to see total detections with MITRE mappings
2. Query detections-mcp → list_by_mitre_tactic("execution") to get technique coverage
3. Query mitre-attack-mcp → analyze_coverage(covered_ids) to analyze gaps
4. Query mitre-attack-mcp → generate_coverage_layer() to visualize
Result: Full coverage analysis with visual Navigator layer
`
Add both to your ~/.cursor/mcp.json:
`json`
{
"mcpServers": {
"security-detections": {
"command": "npx",
"args": ["-y", "security-detections-mcp"],
"env": {
"SIGMA_PATHS": "/path/to/sigma/rules",
"SPLUNK_PATHS": "/path/to/security_content/detections",
"ELASTIC_PATHS": "/path/to/detection-rules/rules"
}
},
"mitre-attack": {
"command": "npx",
"args": ["-y", "mitre-attack-mcp"],
"env": {
"ATTACK_DOMAIN": "enterprise-attack"
}
}
}
}
The layer JSON is compatible with ATT&CK Navigator:
`json`
{
"name": "My Detection Coverage",
"versions": { "attack": "18", "navigator": "5.1.0", "layer": "4.5" },
"domain": "enterprise-attack",
"techniques": [
{ "techniqueID": "T1059.001", "score": 100, "color": "#31a354", "comment": "Covered" },
{ "techniqueID": "T1059.003", "score": 0, "color": "#ff6666", "comment": "Gap" }
],
"gradient": { "colors": ["#ff6666", "#fdae6b", "#31a354"], "minValue": 0, "maxValue": 100 }
}
To visualize:
1. Go to https://mitre-attack.github.io/attack-navigator/
2. Click "Open Existing Layer" → "Upload from local"
3. Paste the JSON
The ATT&CK index is stored at ~/.cache/mitre-attack-mcp/attack.sqlite.
- Auto-downloads STIX data from MITRE on first run
- Caches for 7 days
- Use rebuild_index() to force refresh
| Type | Count |
|------|-------|
| Techniques | ~200 |
| Sub-techniques | ~450 |
| Tactics | 14 |
| Groups | ~140 |
| Software | ~700 |
| Mitigations | ~280 |
| Data Sources | ~40 |
`bash
npm install
npm run build
npm start
Apache 2.0