Files
world-intel-mcp/CLAUDE.md
T
Marc ShadeandClaude Opus 4.6 a72fdc50f7 fix: dashboard instant boot, pipeline map layer, theater data bugs
- Add /api/static endpoint for instant geospatial data on boot (158 items)
- Add per-coroutine 45s timeout to prevent SSE first-frame blocking
- Dismiss loading overlay after static fetch instead of waiting for SSE
- Render 24 oil/gas/hydrogen pipelines as colored polylines on map
- Fix theaters dict-vs-list bug in posture.py and fleet.py
- Add exposure detail modal and color/label entries

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:09:14 -05:00

4.5 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What This Is

World Intelligence MCP Server — 68 tools across 27 domains providing real-time global intelligence from free public APIs. Serves three interfaces: MCP stdio (for Claude Code/Cursor), a live Starlette dashboard with SSE, and a Click CLI with Rich output.

Commands

# Install
pip install -e ".[dev,dashboard]"

# Run MCP server (stdio mode)
world-intel-mcp

# Run tests (pytest-asyncio, auto mode)
pytest
pytest --cov=world_intel_mcp
pytest src/world_intel_mcp/tests/test_sources.py::test_fetch_market_quotes -v  # single test

# CLI
intel markets                    # stock indices
intel earthquakes --min-mag 5.0  # USGS quakes
intel report daily               # generate HTML report
intel status                     # cache + circuit breaker health

# Dashboard (requires [dashboard] extra)
intel-dashboard --port 8501

Architecture

Three consumers share the same source modules and infrastructure stack:

server.py (MCP stdio)  ─┐
cli.py (Click CLI)      ├─> sources/*.py ─> Fetcher ─> CircuitBreaker ─> Cache (SQLite)
dashboard/app.py (SSE)  ─┘                                                  │
                                                                   ~/.cache/world-intel-mcp/cache.db

Infrastructure layer (fetcher.py, cache.py, circuit_breaker.py):

  • Fetcher: Centralized async HTTP client (httpx). All external calls go through get_json(), get_text(), or get_xml(). Handles retries (2 max), per-source rate limiting, and stale-data fallback (never returns blank if old data exists).
  • CircuitBreaker: Per-source tracking. 3 consecutive failures trips the breaker for 5 minutes. Each RSS feed gets its own breaker (rss:bbc_world).
  • Cache: SQLite WAL-mode TTL cache. get() returns live data, get_stale() returns expired data for fallback.

Source modules (sources/*.py): Each module exports async def fetch_*(fetcher: Fetcher, **kwargs) -> dict. Pure data fetching — no MCP awareness. 25 modules covering markets, seismology, military, cyber, health, etc.

Analysis modules (analysis/*.py): Cross-domain intelligence that consumes outputs from multiple sources. Includes signal aggregation, instability indexing, NLP (entity extraction, classification, clustering, spike detection via Welford's algorithm), and strategic synthesis.

Static config (config/*.py): Curated datasets — 22 intel hotspots, 70+ military bases, 40 ports, 24 pipelines, 24 nuclear facilities, 105 major cities, 28 world leaders, 36 APT groups.

Adding a New Tool

  1. Create sources/your_source.py with async def fetch_your_data(fetcher: Fetcher, **kwargs) -> dict
  2. Use fetcher.get_json(url, source="your-source", cache_key=..., cache_ttl=300) — this gives you caching, retries, circuit breaking, and rate limiting automatically
  3. In server.py: import the module, add a Tool(...) to the TOOLS list, add a case to _dispatch()
  4. Optionally add to dashboard/app.py (SSE endpoint) and cli.py (Click command)
  5. Add tests using respx to mock HTTP (see tests/test_sources.py for pattern)

Key Patterns

  • Source name string: The source parameter in fetcher.get_json() identifies the API for circuit breaking and rate limiting. Must match entries in _SOURCE_RATE_LIMITS if rate-limited (e.g., "yahoo-finance", "coingecko", "adsblol").
  • Tool dispatch: server.py uses Python match/case to route tool names to source functions. Tool names follow intel_* convention.
  • All source functions take fetcher as first arg — never construct your own httpx client.
  • Dashboard SSE: dashboard/app.py fetches all domains in parallel via asyncio.gather(), streams updates every 30 seconds.
  • Tests strip proxy env vars automatically via conftest.py fixture (prevents SOCKS proxy interference).

Environment Variables

Only these unlock additional data sources (everything else works unauthenticated):

  • ACLED_ACCESS_TOKEN — conflict events
  • NASA_FIRMS_API_KEY — satellite wildfire data
  • EIA_API_KEY — energy prices
  • CLOUDFLARE_API_TOKEN — internet outage data
  • FRED_API_KEY — macro economic data
  • OPENSKY_CLIENT_ID / OPENSKY_CLIENT_SECRET — military flight fallback

Testing

Tests use respx to mock httpx responses. Fixtures in conftest.py provide cache (tmp_path SQLite) and fetcher (with clean breaker). Tests are async (pytest-asyncio in auto mode). Proxy env vars are stripped automatically.