Skip to main content
Glama
ard1102

IP Intelligence MCP Server

by ard1102
README.md
# IP Intelligence Platform

A self-hosted, containerized threat intelligence aggregation and enrichment service. Ingests 10 open-source threat feeds, enriches IP queries with normalized security context, and exposes results via REST API and MCP server. All output is normalized to [OCSF Class 4001 (Network Activity)](https://schema.ocsf.io/classes/network_activity).

## Features

- **10 threat feeds** — Feodo Tracker, Emerging Threats, Spamhaus, TOR exits, CINS, Blocklist.de, SAPICS ASN, ThreatFox, OTX, Shadowserver
- **Real-time enrichment** — Geolocation (ip-api.com), Shodan InternetDB, Reverse DNS, AbuseIPDB
- **OCSF Class 4001 output** — All responses normalized to the Open Cybersecurity Schema Framework
- **REST API** — FastAPI with OpenAPI docs at `/docs`
- **MCP server** — FastMCP 2.x Streamable HTTP, compatible with claude.ai MCP connectors
- **Self-healing feeds** — SelfRepairAgent auto-quarantines drifted or stale feeds
- **Firewall export** — NDJSON, plain-text, and CIDR-block exports
- **Zero-key Phase 1** — All open feeds work without API keys

## Quick Start

```bash
# 1. Clone and configure
git clone https://github.com/your-username/ip-intelligence.git
cd ip-intelligence
cp .env.example .env
# Edit .env — at minimum set ADMIN_KEY

# 2. Run with Docker Compose
docker compose up -d

# 3. Verify
curl http://localhost:8004/health
```

The API will be available at `http://localhost:8004` and OpenAPI docs at `http://localhost:8004/docs`.

## API Reference

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/lookup/{ip}` | Enrich a single IP — returns OCSF 4001 |
| `POST` | `/bulk` | Bulk lookup up to 500 IPs |
| `GET` | `/health` | Feed health and repair agent status |
| `GET` | `/export/{format}` | Export blocklist (ndjson, txt, cidr) |
| `GET` | `/asn/{asn}/ranges` | Expand ASN to IP ranges |
| `POST` | `/admin/*` | Admin operations (requires `ADMIN_KEY`) |

### Example

```bash
curl http://localhost:8004/lookup/1.2.3.4
```

```json
{
  "class_uid": 4001,
  "severity_id": 4,
  "dst_endpoint": { "ip": "1.2.3.4" },
  "enrichments": [
    { "name": "geo", "value": { "country": "CN", "city": "Beijing" } },
    { "name": "feodo", "value": { "tags": ["C2", "Emotet"] } }
  ],
  "attacks": [{ "technique": { "uid": "T1071" } }]
}
```

## MCP Tools

Connect to `http://localhost:8004/mcp` from any MCP-compatible client (Claude Desktop, claude.ai).

| Tool | Description |
|------|-------------|
| `ip_lookup` | Enrich a single IP |
| `bulk_hunt` | Bulk IP enrichment |
| `asn_expand` | Expand ASN to IP ranges |
| `feed_status` | Query feed health |
| `promote_ioc` | Promote an IP to the watchlist |
| `explain_verdict` | Human-readable verdict for an IP |

## Threat Feeds

### Phase 1 — No API Keys Required

| Feed | Source | Update Cadence |
|------|--------|---------------|
| Feodo Tracker | abuse.ch | Every 30 min |
| Emerging Threats | ProofPoint | Every 60 min |
| Spamhaus DROP | Spamhaus | Every 12 hr |
| TOR Exit Nodes | torproject.org | Every 60 min |
| CINS Army | CINS | Every 60 min |
| Blocklist.de | blocklist.de | Every 60 min |
| SAPICS ASN | SAPICS | Every 24 hr |

### Phase 2 — Optional API Keys

| Feed | Env Var | Where to Get |
|------|---------|-------------|
| ThreatFox | `THREATFOX_API_KEY` | [abuse.ch/threatfox](https://abuse.ch/threatfox) |
| OTX | `OTX_API_KEY` | [otx.alienvault.com](https://otx.alienvault.com) |
| Shadowserver | `SHADOWSERVER_API_KEY` | [shadowserver.org](https://www.shadowserver.org) |
| AbuseIPDB | `ABUSEIPDB_API_KEY` | [abuseipdb.com](https://www.abuseipdb.com) |

## Architecture

```
┌─────────────────────────────────────────────┐
│                  Clients                    │
│   curl / Claude Desktop / Browser UI        │
└──────────────┬──────────────────────────────┘
               │
┌──────────────▼──────────────────────────────┐
│           FastAPI + FastMCP                 │
│        app/main.py  (port 8004)             │
├─────────────────────────────────────────────┤
│  LookupEngine   │  Enrichers  │  MCP Tools  │
│  (bisect)       │  geo/shodan │  6 tools    │
├─────────────────────────────────────────────┤
│              IntelStore                     │
│       (in-memory, atomic swap)              │
├─────────────────────────────────────────────┤
│  APScheduler   │  SelfRepairAgent           │
│  (10 cron jobs)│  (health monitoring)       │
├─────────────────────────────────────────────┤
│              Feed Updaters (10)             │
└─────────────────────────────────────────────┘
```

## Configuration

All configuration is via environment variables. Copy `.env.example` to `.env`:

```bash
cp .env.example .env
```

Key settings:

| Variable | Default | Description |
|----------|---------|-------------|
| `PORT` | `8004` | Server port |
| `ADMIN_KEY` | — | Required for admin endpoints |
| `REPAIR_AGENT_ENABLED` | `true` | Enable auto-repair of degraded feeds |
| `FRESHNESS_ALERT_HOURS` | `48` | Alert if feed data is older than N hours |

## Development

```bash
# Install dependencies
pip install -r requirements.txt

# Run locally (without Docker)
uvicorn app.main:app --reload --port 8004

# Run tests (unit only, no network)
pytest tests/ -v -m "not live_feeds"

# Run all tests (requires network access)
pytest tests/ -v
```

### Project Structure

```
app/
├── main.py           # FastAPI app + FastMCP mount
├── mcp_tools.py      # MCP @mcp.tool() definitions
├── intel_store.py    # Unified in-memory store
├── lookup.py         # Bisect engine
├── scorer.py         # Risk score computation
├── repair_agent.py   # Self-healing feed monitor
├── scheduler.py      # APScheduler cron setup
├── ocsf.py           # OCSF 4001 serialization
├── enrichers/        # Geo, Shodan, rDNS, AbuseIPDB
├── models/           # Pydantic v2 models
└── updaters/         # Per-feed update scripts (10 feeds)
```

## Claude Code Integration

This repo ships with a complete [Claude Code](https://claude.ai/code) setup. When you open the project in Claude Code, it automatically loads:

- **Project instructions** (`CLAUDE.md`) — architecture, invariants, conventions, and test commands
- **Specialized subagents** (`.claude/agents/`) — each agent knows one layer of the stack:

| Agent | Owns |
|-------|------|
| `api-builder` | `app/main.py`, `app/mcp_tools.py`, all REST routes and MCP tools |
| `feed-builder` | `app/updaters/` — feed fetch, parse, validate, swap |
| `repair-engineer` | `app/repair_agent.py`, `app/scheduler.py` — health state machine |
| `schema-validator` | `app/models/`, `app/ocsf.py`, `app/config.py` — Pydantic v2 models |
| `test-writer` | `tests/` — pytest fixtures, coverage, regression IPs |

- **Auto-test hooks** (`.claude/settings.json`) — runs `pytest -m "not live_feeds"` after every Python file edit
- **Dev server launch** (`.claude/launch.json`) — starts the UI dev server on port 5173

No extra setup needed — clone the repo, open it in Claude Code, and the agents are ready to use.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

## Security

To report a vulnerability, see [SECURITY.md](SECURITY.md). Do not open a public issue.

## License

[MIT](LICENSE)