mitre-attack-mcp
v1.0.1
Published
MCP server for querying MITRE ATT&CK framework and generating Navigator layers
Maintainers
Readme
MITRE ATT&CK MCP
An MCP (Model Context Protocol) server that provides access to the MITRE ATT&CK framework and generates ATT&CK Navigator layers for coverage visualization.
Features
- 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
Quick Start
Option 1: npx (Recommended)
No installation required:
npx -y mitre-attack-mcpOption 2: Clone and Build
git clone https://github.com/MHaggis/mitre-attack-mcp.git
cd mitre-attack-mcp
npm install
npm run buildConfiguration
Cursor IDE
Add to your MCP config (~/.cursor/mcp.json or .cursor/mcp.json):
{
"mcpServers": {
"mitre-attack": {
"command": "npx",
"args": ["-y", "mitre-attack-mcp"],
"env": {
"ATTACK_DOMAIN": "enterprise-attack"
}
}
}
}Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"mitre-attack": {
"command": "npx",
"args": ["-y", "mitre-attack-mcp"],
"env": {
"ATTACK_DOMAIN": "enterprise-attack"
}
}
}
}Environment Variables
| 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
MCP Tools
Technique Lookups
| 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 |
Threat Intelligence
| 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 |
Defensive Context
| 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 |
Navigator Layer Generation
| 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 |
Analysis
| 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 |
Example Workflows
Analyze Your Detection Coverage
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", ...]
}Generate a Coverage Navigator Layer
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/)Compare Against a Threat Group
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 forGenerate Gap Analysis Layer
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🔗 Using with Security Detections MCP
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 |
Combined Workflow Example
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 layerInstall Both Together
Add both to your ~/.cursor/mcp.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"
}
}
}
}Navigator Layer Output
The layer JSON is compatible with ATT&CK Navigator:
{
"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:
- Go to https://mitre-attack.github.io/attack-navigator/
- Click "Open Existing Layer" → "Upload from local"
- Paste the JSON
Database
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
Stats (Enterprise ATT&CK v18)
| Type | Count | |------|-------| | Techniques | ~200 | | Sub-techniques | ~450 | | Tactics | 14 | | Groups | ~140 | | Software | ~700 | | Mitigations | ~280 | | Data Sources | ~40 |
Development
npm install
npm run build
npm start
# Or with watch mode
npm run devLicense
Apache 2.0
