Agent Skills

mitre-mcp

A Model Context Protocol (MCP) server that provides tools for working with the MITRE ATT&CK framework using the mitreattack-python library and the official MCP Python SDK.

Install

uvx mitre-mcp
README.md

mitre-mcp: MITRE ATT&CK MCP Server

MCP Registry PyPI Downloads

PyPI version Python versions Test status License Code style: black Pre-commit

Production-ready Model Context Protocol (MCP) server that exposes the MITRE ATT&CK® framework to LLMs, AI assistants, and automation workflows. Built with the official MCP Python SDK and mitreattack-python library for secure, high-performance access to adversary tactics, techniques, groups, software, and mitigations.

Available in the MCP Registry (search for io.github.luongnv89/mitre-mcp).

Highlights

  • LLM-native experience – Seamless integration with Claude, Windsurf, Cursor, and any MCP-compatible client
  • Secure-by-default – Validated inputs, TLS verification, disk-space checks, and structured error handling
  • High performance – O(1) technique lookups using pre-built indices (80-95% faster than scanning)
  • Flexible deployment – stdio for local clients or HTTP server for web-based integrations

Table of Contents

Features

  • Comprehensive MITRE ATT&CK Coverage - All techniques, tactics, groups, software, and mitigations
  • Multi-Domain Support - Enterprise, Mobile, and ICS ATT&CK domains
  • Intelligent Caching - Atomic, per-user caching with conditional refreshes, stale-serve with background refresh, and configurable expiry (default: 14 days)
  • Fast Startup - Enterprise loads eagerly; mobile and ICS domains lazy-load on first use
  • Performance Optimized - O(1) lookups using pre-built indices (80-95% faster)
  • Dual Transport Modes - stdio for local clients, HTTP for web integrations
  • CORS-Enabled HTTP Server - Async notifications and cross-origin request support
  • Comprehensive Testing - pytest suite with an enforced coverage gate
  • Pre-commit Quality Checks - Automated formatting, linting, type checking, and security scanning
  • Input Validation - Secure-by-default with validated inputs and sanitized responses
  • Programmatic API - Python and Node.js clients (see API-INTEGRATION.md)

Available MCP Tools

Tool Name Description
get_techniques List all techniques with filtering options
get_technique_by_id Look up specific technique by ID (e.g., T1055)
get_techniques_by_tactic Get techniques for a specific tactic (e.g., persistence)
get_tactics List all tactical categories
get_groups List all threat actor groups
get_techniques_used_by_group Get techniques used by a specific group (e.g., APT29)
get_software List malware and tools with filtering
get_mitigations List all security mitigations
get_techniques_mitigated_by_mitigation Get techniques addressed by a specific mitigation

All list and relationship tools accept limit/offset paging parameters (default page size 20, maximum 200 — see MITRE_DEFAULT_PAGE_SIZE and MITRE_MAX_PAGE_SIZE in CONTRIBUTING.md) and return a pagination block (total, offset, limit, has_more).

Quick Start

Installation

  1. Create and activate a virtual environment:
python3 -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate.bat
  1. Install from PyPI:
pip install mitre-mcp
  1. Verify installation:
mitre-mcp --help

HTTP Mode (Recommended)

Start the server:

mitre-mcp --http

Expected output:

2025-11-17 22:40:10,991 - mitre_mcp.mitre_mcp_server - INFO - Starting MITRE ATT&CK MCP Server (HTTP mode on localhost:8000)
======================================================================
MITRE ATT&CK MCP Server is ready (Streamable HTTP mode)
Server URL: http://localhost:8000
MCP Endpoint: http://localhost:8000/mcp

Add this to your MCP client configuration:
{
  "mcpServers": {
    "mitreattack": {
      "url": "http://localhost:8000/mcp"
    }
  }
}
======================================================================

Configure your MCP client:

Add this JSON to your client's configuration file:

{
  "mcpServers": {
    "mitreattack": {
      "url": "http://localhost:8000/mcp"
    }
  }
}

Configuration file locations:

  • macOS (Claude Desktop): ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows (Claude Desktop): %APPDATA%\Claude\claude_desktop_config.json
  • Linux (Claude Desktop): ~/.config/Claude/claude_desktop_config.json
  • VSCode: Configure in your MCP extension settings

Custom host and port:

mitre-mcp --http --host 0.0.0.0 --port 8080

Then use http://your-server-ip:8080/mcp in your client configuration.

Security — a non-loopback bind is unauthenticated by default. Binding --host 0.0.0.0 (or any non-loopback address) exposes the MCP endpoint to the whole network: the data is public, but the endpoint is an open CPU and memory amplifier. Either set MITRE_HTTP_AUTH_TOKEN so every request must carry Authorization: Bearer <token>:

MITRE_HTTP_AUTH_TOKEN=$(openssl rand -hex 32) mitre-mcp --http --host 0.0.0.0 --port 8080

or place an authenticating reverse proxy in front of a loopback-only server — nginx example (TLS + basic auth → 127.0.0.1:8000):

server {
    listen 443 ssl;
    server_name mcp.example.com;
    ssl_certificate     /etc/nginx/certs/mcp.example.com.pem;
    ssl_certificate_key /etc/nginx/certs/mcp.example.com.key;

    location / {
        auth_basic           "mitre-mcp";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass           http://127.0.0.1:8000;
        proxy_set_header     Host $host;
    }
}

The server logs a warning at startup whenever it binds a non-loopback host without MITRE_HTTP_AUTH_TOKEN set.

Why HTTP mode?

  • Multiple clients can connect simultaneously
  • Better concurrency and async support
  • Easier debugging with HTTP tools
  • CORS support for web-based clients
  • No path configuration needed

stdio Mode (Alternative)

For local-only clients that require stdio transport:

mitre-mcp

Client configuration:

{
  "mcpServers": {
    "mitreattack": {
      "command": "/absolute/path/to/.venv/bin/python",
      "args": ["-m", "mitre_mcp.mitre_mcp_server"]
    }
  }
}

Note: Use absolute paths. HTTP mode is recommended for most use cases.

Force Data Download

Force a fresh download of MITRE ATT&CK data:

mitre-mcp --http --force-download

Example Screenshots

VSCode Configuration:

Configure

Tool Invocation:

Tool call

Results:

Result

Web Frontend

A React chat UI lives in frontend/. A hosted copy is at https://montimage.github.io/mitre-mcp/. That public HTTPS page can call cloud LLM providers (Gemini, OpenRouter). It cannot reach anything on this machine — mitre-mcp on localhost:8000, Ollama, LM Studio, or any other loopback endpoint. The browser blocks public sites from the loopback address space (net::ERR_SSL_PROTOCOL_ERROR if it upgrades the MCP URL to https://localhost:8000/mcp, CORS / private-network errors for http://localhost:…/v1/models).

Use the local UI whenever the MCP server or the LLM runs on your computer.

Local setup (MCP server + chat UI)

Two terminals, from a clone of this repository.

1. Install and start the MCP server (Python >= 3.11):

uv sync --locked --extra dev
source .venv/bin/activate
mitre-mcp --http

Wait for MCP Endpoint: http://localhost:8000/mcp. The first start downloads ATT&CK data into ~/.cache/mitre-mcp.

2. Start the chat UI (Node 24):

cd frontend
npm ci
npm run dev

Open http://localhost:5173/ — not the GitHub Pages URL.

3. Settings (gear in the chat header):

Setting Local value
MCP host / port localhost / 8000 (dev proxies /mcp to the server)
LLM provider Ollama, Gemini, OpenRouter, or OpenAI-compatible

For a local OpenAI-compatible server (LM Studio, llama.cpp, vLLM, …):

  • Provider: OpenAI-compatible
  • Endpoint URL: http://localhost:<port>/v1 (example: http://localhost:20128/v1)
  • Model: an id the endpoint lists at /v1/models
  • API key: leave empty unless that server requires one

The endpoint must allow CORS from http://localhost:5173. If Ollama is not running, do not leave Ollama selected — the default probe hits localhost:11434 and Vite logs http proxy error: /api/tags.

For more details, see frontend/README.md.

Documentation

We provide three comprehensive guides tailored to different use cases:

1. Beginner's Guide

Beginner-Playbook.md - For those new to MITRE ATT&CK or cybersecurity

Ideal for:

  • Non-technical users
  • Security awareness training
  • Basic threat intelligence
  • General cybersecurity education

2. Advanced Playbook

Playbook.md - For security professionals using MCP clients

Ideal for:

  • Security analysts
  • Threat hunters
  • Incident responders
  • Security engineers

Includes 10 ready-to-use scenarios:

  • Threat Intelligence
  • Detection Engineering
  • Threat Hunting
  • Red Teaming
  • Security Assessment
  • Incident Response
  • Security Operations
  • Security Training
  • Vendor Evaluation
  • Risk Management

3. API Integration Guide

API-INTEGRATION.md - For developers building automation and custom integrations

Ideal for:

  • Backend developers
  • Automation engineers
  • Data pipeline developers
  • Custom tooling projects

Includes:

  • Complete Python and Node.js client implementations
  • Protocol requirements and examples
  • Testing and debugging tools
  • Common integration patterns

Configuration

Environment Variables

Set before starting mitre-mcp to customize behavior:

Variable Default Purpose
MITRE_ENTERPRISE_URL, MITRE_MOBILE_URL, MITRE_ICS_URL Official MITRE CTI GitHub URLs Override ATT&CK bundle locations or point to internal mirror
MITRE_DATA_DIR ~/.cache/mitre-mcp Store cached bundles in custom directory
MITRE_DOWNLOAD_TIMEOUT 120 HTTP timeout in seconds for bundle downloads
MITRE_CACHE_EXPIRY_DAYS 14 Maximum age before cached data is refreshed
MITRE_REQUIRED_SPACE_MB 200 Disk space threshold checked before downloading
MITRE_DEFAULT_PAGE_SIZE / MITRE_MAX_PAGE_SIZE 20 / 200 Default and maximum records returned by list tools
MITRE_MAX_DESC_LENGTH 500 Trimmed description length in responses
MITRE_LOG_LEVEL INFO Logging verbosity (DEBUG, INFO, WARNING, etc.)
MITRE_CORS_ORIGINS localhost origins CORS allowed origins for HTTP mode (comma-separated list; * is an explicit opt-in)
MITRE_HTTP_AUTH_TOKEN unset (no auth) Bearer token required on every HTTP request when set; recommended for non-loopback binds

To let a hosted UI (e.g. the Netlify deployment) call the server cross-origin, set MITRE_CORS_ORIGINS to its origin, e.g. MITRE_CORS_ORIGINS="https://mitre-mcp.netlify.app,http://localhost:5173". Credentials are never allowed in any CORS configuration.

Data Caching

The server automatically caches MITRE ATT&CK data to improve performance:

  1. On first run, downloads and stores data in the per-user cache directory ($XDG_CACHE_HOME/mitre-mcp, or ~/.cache/mitre-mcp by default)
  2. On subsequent runs, uses cached data if less than 14 days old
  3. Automatically refreshes data older than 14 days, using conditional requests — a 304 Not Modified answer reuses the cached bundles. Expired-but-present data is served immediately while the refresh runs in the background; startup never blocks on it and a failed refresh keeps the existing cache.
  4. Cache files are written atomically (temp file + rename), so a failed download never corrupts a good cache
  5. Only the enterprise domain is parsed at startup; the mobile and ICS bundles are lazy-loaded on first use, so cold starts stay fast when they are never queried
  6. Use --force-download to force fresh download

Performance

Scenario Improvement Notes
Enterprise technique lookup 80-95% faster Pre-built O(1) indices for groups, mitigations, and techniques
ATT&CK data downloads 20-40% faster HTTP connection pooling with TLS session reuse
Warm cache startup <2s Cached bundles reused for instant LLM queries

Benchmarks: macOS 14 / Apple M3 Pro with Python 3.11. Use MITRE_LOG_LEVEL=DEBUG for timing logs.

Programmatic API

For automation, custom integrations, and batch processing, see API-INTEGRATION.md.

Quick example (Python):

from clients.python.mini_mcp_client import MitreMCPClient


async def main():
    client = MitreMCPClient(host="localhost", port=8000)

    # Get all tactics
    tactics = await client.call_tool("get_tactics", {"domain": "enterprise-attack"})

    # Get techniques for a group
    techniques = await client.call_tool(
        "get_techniques_used_by_group", {"group_name": "APT29", "domain": "enterprise-attack"}
    )

Available clients:

  • Python: clients/python/mini-mcp-client.py with full CLI
  • Node.js: clients/nodejs/mini-mcp-client.js with full CLI

See API-INTEGRATION.md for complete documentation.

Development

Clone and Install

git clone https://github.com/montimage/mitre-mcp.git
cd mitre-mcp
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Install Pre-commit Hooks

pre-commit install

This sets up automatic code quality checks before each commit.

Run Tests

pytest                      # Full test suite with coverage
pre-commit run --all-files  # All quality checks

Code Quality Tools

Formatting:

  • black - Python code formatter
  • isort - Import organizer
  • prettier - YAML/JSON/Markdown formatter

Linting & Type Checking:

  • flake8 - Python linter
  • mypy - Static type checker
  • pydocstyle - Docstring checker

Security:

  • bandit - Security vulnerability scanner
  • File validators - YAML, JSON, TOML, private key detection

Testing:

  • pytest - test suite with coverage gate before commit
  • Installation test - Package verification
  • Import verification - Module importability
  • CLI test - Entry point validation

Troubleshooting

Download fails with "Insufficient disk space"

  • Free at least 200 MB in the data directory or set MITRE_DATA_DIR=/path/to/storage

Data never updates

  • Cached bundles refresh automatically after 14 days
  • Force refresh: mitre-mcp --force-download or delete ~/.cache/mitre-mcp

Tool calls return errors

  • Ensure technique IDs follow T#### or T####.### format
  • Keep names/tactics under 100 characters

MCP client cannot discover server

  • Verify client configuration points to correct Python path
  • Test manually: run mitre-mcp and verify server starts
  • For HTTP mode: ensure url field is set correctly

Chat UI: POST https://localhost:8000/mcp net::ERR_SSL_PROTOCOL_ERROR

  • The GitHub Pages UI is HTTPS, so it rewrites localhost to https://localhost:8000. mitre-mcp --http has no TLS. Open http://localhost:5173 instead (see Web Frontend).

Chat UI: CORS / “loopback address space” when calling a local LLM

  • Same cause: a public origin cannot fetch http://localhost:…. Run the frontend locally and point the OpenAI-compatible provider at http://localhost:<port>/v1.

Module not found: mcp.server.fastmcp

  • Reinstall the pinned MCP SDK: pip install "mcp>=1.28.1,<2" (or mcp[cli]>=1.28.1,<2 if you also want the CLI extra) in your virtual environment — the fastmcp distribution does not provide mcp.server.fastmcp; the package's declared pin does

FAQ

Does mitre-mcp work offline?

  • Yes. Once bundles are cached, the server works offline until cache expires.

Which Python versions are supported?

  • Python 3.11 through 3.14 (see pyproject.toml).

How often is data refreshed?

  • By default every 24 hours. Adjust MITRE_CACHE_EXPIRY_DAYS or use --force-download.

Is HTTP mode safe for production?

  • HTTP mode serves on localhost:8000 by default. Use firewall or reverse proxy if exposing externally.

License

MIT License - See LICENSE file for details.

About Montimage

mitre-mcp is developed and maintained by Montimage, a cybersecurity company specializing in network monitoring, security analysis, and AI-driven threat detection solutions. We develop innovative tools that help organizations protect their digital assets and ensure network security.

For questions or support: luong.nguyen@montimage.eu

Search skills and MCP servers

Fuzzy search across 23,137 skills and servers