Skip to content
This repository was archived by the owner on Feb 27, 2026. It is now read-only.

scriptedstatement/opencti-mcp

Repository files navigation

Important

This repository has been retired. It is no longer maintained.

This package is now part of the AppliedIR/sift-mcp monorepo.

Documentation: appliedir.github.io/aiir


OpenCTI MCP Server

An MCP (Model Context Protocol) server providing comprehensive threat intelligence access to OpenCTI for Claude Code and other MCP clients.

Note: Validate and harden appropriately for your environment before production use.

Installation Options

Option A: As Part of Claude-IR (Recommended)

This MCP is designed as a component of the Claude-IR AI-assisted incident response workstation.

git clone https://github.com/scriptedstatement/claude-ir.git
cd claude-ir
./setup.sh
claude

Benefits of Claude-IR installation:

  • Guided setup with component selection
  • Pre-configured MCP integration
  • Works alongside forensic-rag-mcp (knowledge search) and windows-triage-mcp (file validation)
  • Forensic discipline rules and investigation workflows

Note: This MCP requires an OpenCTI instance. See SETUP.md for guidance on connecting to or deploying OpenCTI.

Option B: Standalone Installation

Use standalone when you only need threat intelligence lookups without the full IR workstation.

git clone https://github.com/scriptedstatement/opencti-mcp.git
cd opencti-mcp

# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate

# Install
pip install -e .

# Configure (requires OpenCTI instance - see SETUP.md)
export OPENCTI_TOKEN="your-api-token"
export OPENCTI_URL="http://localhost:8080"          # Local Docker
# export OPENCTI_URL="https://opencti.example.com"  # Remote/cloud

# Run server
python -m opencti_mcp

For OpenCTI setup guidance: See SETUP.md

Features

Search Operations (32 tools, 28 visible in read-only mode)

Category Tools Description
Unified Search search_threat_intel Search across all entity types
Threats search_threat_actor, search_campaign APT groups, campaigns
Arsenal search_malware, search_tool, search_vulnerability Malware, tools, CVEs
Techniques search_attack_pattern, search_course_of_action MITRE ATT&CK, mitigations
Observations search_observable, search_sighting IOCs, detection events
Events search_incident Security incidents
Analysis search_reports, search_grouping, search_note Reports, groupings, notes
Entities search_organization, search_sector Organizations, industries
Locations search_location Countries, regions, cities
Infrastructure search_infrastructure C2, hosting, botnets

Entity Operations

Tool Description
lookup_ioc Get full IOC context with relationships
lookup_hash Look up file hash (MD5/SHA1/SHA256)
get_entity Get any entity by ID
get_relationships Get entity relationships
get_recent_indicators Get indicators from last N days

Write Operations (requires OPENCTI_READ_ONLY=false)

Tool Description
create_indicator Create new IOC
create_note Add analyst note to entities
create_sighting Record detection event
trigger_enrichment Trigger VirusTotal/Shodan enrichment

System Operations

Tool Description
get_health Check OpenCTI connectivity
list_connectors List enrichment connectors
get_network_status View adaptive metrics and recommendations
force_reconnect Force reconnection (clears caches, resets circuit breaker)
get_cache_stats View response cache statistics

Advanced Filtering

All search tools support advanced filtering:

{
  "query": "APT29",
  "limit": 10,
  "offset": 0,
  "labels": ["tlp:amber", "apt"],
  "confidence_min": 70,
  "created_after": "2024-01-01",
  "created_before": "2024-12-31"
}

Configuration

Settings are loaded via Config.load() classmethod (config.py) with SecretStr token protection and helper parsers for typed env vars.

Environment Variables

Variable Default Description
OPENCTI_URL http://localhost:8080 OpenCTI instance URL (use https:// for remote)
OPENCTI_TOKEN - API token (required)
OPENCTI_READ_ONLY true Disable write operations
OPENCTI_TIMEOUT 60 Request timeout in seconds
OPENCTI_MAX_RESULTS 100 Maximum results per query
OPENCTI_MAX_RETRIES 3 Retry attempts for failures
OPENCTI_RETRY_DELAY 1.0 Initial retry delay (seconds)
OPENCTI_RETRY_MAX_DELAY 30.0 Maximum retry delay (seconds)
OPENCTI_SSL_VERIFY true Verify SSL certificates (set false for self-signed)
OPENCTI_CIRCUIT_THRESHOLD 5 Failures before circuit opens
OPENCTI_CIRCUIT_TIMEOUT 60 Seconds before circuit recovery
OPENCTI_EXTRA_OBSERVABLE_TYPES - Custom observable types (comma-separated)
OPENCTI_EXTRA_PATTERN_TYPES - Custom pattern types (comma-separated)
OPENCTI_LOG_FORMAT json Log format: "json" or "text"

Feature Flags

Control optional features via environment variables (prefix: FF_):

Variable Default Description
FF_STARTUP_VALIDATION true Test API connectivity on server start
FF_RESPONSE_CACHING false Cache search results (reduces API calls)
FF_GRACEFUL_DEGRADATION true Return cached results when service unavailable
FF_NEGATIVE_CACHING true Cache "not found" results

Token Configuration

Option 1: Environment variable (recommended for production)

export OPENCTI_TOKEN="your-api-token"

Option 2: Token file

mkdir -p ~/.config/opencti-mcp
echo "your-api-token" > ~/.config/opencti-mcp/token
chmod 600 ~/.config/opencti-mcp/token

Option 3: .env file (development)

OPENCTI_TOKEN=your-api-token

Custom Types for Extended OpenCTI

If your OpenCTI instance has custom observable types or pattern types (e.g., proprietary IOC formats, additional detection languages), configure them via environment variables:

# Add custom observable types (case-sensitive, comma-separated)
export OPENCTI_EXTRA_OBSERVABLE_TYPES="Internal-Host,Cloud-Resource,Custom-IOC"

# Add custom pattern types (case-insensitive, comma-separated)
export OPENCTI_EXTRA_PATTERN_TYPES="osquery,kql,custom-sig"

These extend the built-in allow-lists without removing standard STIX types.

Claude Code Configuration

Add to your project-local .mcp.json (or see the parent claude-ir project for automated setup):

{
  "mcpServers": {
    "opencti": {
      "command": "/path/to/venv/bin/python",
      "args": ["-m", "opencti_mcp"],
      "cwd": "/path/to/opencti-mcp",
      "env": {
        "PYTHONPATH": "/path/to/opencti-mcp/src",
        "OPENCTI_TOKEN": "your-api-token",
        "OPENCTI_URL": "http://localhost:8080",
        "OPENCTI_READ_ONLY": "true",
        "OPENCTI_SSL_VERIFY": "true"
      }
    }
  }
}

Project Structure

opencti-mcp/
├── src/opencti_mcp/
│   ├── __init__.py       # Package exports
│   ├── __main__.py       # Entry point (with startup validation)
│   ├── server.py         # MCP server (32 tools)
│   ├── client.py         # OpenCTI API client (with caching)
│   ├── config.py         # Configuration management
│   ├── validation.py     # Input validation
│   ├── errors.py         # Error hierarchy
│   ├── logging.py        # Structured logging
│   ├── adaptive.py       # Network metrics
│   ├── cache.py          # TTL-based response caching
│   └── feature_flags.py  # Feature flag management
├── tests/                # Test suite (1530 tests)
├── docs/                 # Documentation
├── README.md             # This file
├── CLAUDE.md             # Development guide
├── IMPLEMENTATION.md     # Technical architecture
└── pyproject.toml        # Package configuration

Development

Run Tests

# Install dev dependencies
pip install -e ".[dev]"

# Run all tests
pytest

# With coverage
pytest --cov=opencti_mcp --cov-report=html

# Type checking
mypy src/opencti_mcp

Test with MCP Inspector

npx @anthropic/mcp-inspector python -m opencti_mcp

Key Commands

# Run MCP server
python -m opencti_mcp

# Test connection (original CLI)
python opencti_query.py "APT29" --type threat_actor

# Quick health check
python -c "from opencti_mcp import OpenCTIClient, Config; c = OpenCTIClient(Config.load()); print('OK' if c.is_available() else 'FAIL')"

Production Considerations

Local Docker vs Remote/Cloud

The default OPENCTI_URL=http://localhost:8080 matches OpenCTI's standard Docker deployment, where the platform serves HTTP on port 8080. This is correct for local instances — traffic never leaves the machine.

For remote or cloud instances, use HTTPS. OpenCTI supports TLS either natively (APP__HTTPS_CERT__* env vars) or via a reverse proxy (Nginx, Caddy, Traefik) — the reverse proxy approach is more common in production.

Recommended Settings for Remote/Cloud Instances

export OPENCTI_URL=https://opencti.example.com  # HTTPS for remote
export OPENCTI_TIMEOUT=120         # Higher for cloud (default 60 may be tight for complex queries)
export OPENCTI_MAX_RETRIES=3       # Retry on transient failures
export OPENCTI_SSL_VERIFY=true     # Always for production (false only for self-signed certs)
export OPENCTI_READ_ONLY=true      # Unless writes needed

Cloud users: If you experience timeouts or circuit breaker trips, increase OPENCTI_TIMEOUT to 120-180. Complex threat intel queries on remote instances can take 60+ seconds under load.

Adaptive Metrics

Use get_network_status tool to view:

  • Latency statistics (P50/P95/P99)
  • Success rates
  • Circuit breaker state
  • Recommended timeout/retry settings

Requirements

  • Python 3.10+
  • OpenCTI 6.x instance
  • pycti 6.x
  • mcp 1.x

Acknowledgments

Architecture and direction by Steve Anson. Implementation by Claude Code (Anthropic).

License

MIT

About

[RETIRED] Moved to AppliedIR/sift-mcp

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors