Files
worldmonitor/docs/brainstorms
Elie Habib bca939c423 feat(mcp): PRO MCP server — WorldMonitor data via Model Context Protocol (#2382)
* feat(mcp): PRO MCP server — WorldMonitor data via Model Context Protocol

Adds api/mcp.ts: a Vercel edge function implementing MCP Streamable HTTP
transport (protocol 2025-03-26) for PRO API key holders.

PRO users point Claude Desktop (or any MCP client) at
https://api.worldmonitor.app/mcp with their X-WorldMonitor-Key header
and get 17 tools covering all major WorldMonitor data domains.

- Auth: validateApiKey(forceKey:true) — returns JSON-RPC -32001 on failure
- Rate limit: 60 calls/min per API key via Upstash sliding window (rl:mcp prefix)
- Tools read from existing Redis bootstrap cache (no upstream API calls)
- Each response includes cached_at (ISO timestamp) and stale (boolean)
- tools/list served from in-memory registry (<500ms, no Redis)
- Tool calls with warm cache respond in <800ms
- 11 tests covering auth, rate limit, protocol, tools/list, tools/call

* fix(mcp): handle Redis fetch throws + fix confusing label derivation

P1: wrap executeTool call in tools/call handler with try-catch so
TimeoutError/TypeError from AbortSignal.timeout in readJsonFromUpstash
returns JSON-RPC -32603 instead of an unhandled rejection → 500.
Mirrors the same guard already on the rate-limiter call above it.

P2: walk backwards through cache key segments, skipping version tags
(v\d+), bare numbers, 'stale', and 'sebuf' suffixes to find the first
meaningful label. Fixes 'economic:fred:v1:FEDFUNDS:0' → 'FEDFUNDS'
and 'risk:scores:sebuf:stale:v1' / 'theater_posture:sebuf:stale:v1'
both resolving to 'stale' (which collides with the top-level stale flag).

Adds test for P1 scenario (12 tests total, all pass).
2026-03-27 23:59:17 +04:00
..