mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
* feat(cii): add displacement signal and extend ACLED window for post-conflict accuracy ACLED's 7-day window scores post-ceasefire countries (e.g. Lebanon) near zero despite ongoing destruction, because battle events dried up after the November 2024 ceasefire. Two fixes: 1. Displacement signal (UNHCR): reads displacement:summary:v1:YEAR from Redis and maps ISO3→ISO2 codes. Log-scaled boost (max +20pts) means Lebanon (~1.2M displaced) gets ~12pts, Syria (~7M) gets ~18pts, and peaceful countries get 0. This signal persists long after a ceasefire because UNHCR data updates annually, not per-battle. 2. ACLED 30-day window with time decay: extends from 7 to 30 days. Events 0-7 days old: weight 1.0 | Events 8-30 days old: weight 0.4. Captures conflict tail without over-weighting stale events. Together these make CII reflect structural reality (displaced populations, reconstruction crisis) rather than just last-week's ACLED event count. * fix(cii): add displacedByIso3 to emptyAux fallback * fix(cii): rescale displacement boost and paginate 30-day ACLED query P1: The previous formula Math.log10(n)*4 capped at 100K displaced (log10(100000)=5, 5*4=20), making 100K and 10M identical. Rescaled to (log10(n)-5)*8+4 anchored at the 100K threshold: 100K→+4 | 500K→+10 | 1M→+12 | 5M→+18 | 10M→+20, floor 0. P2: A single 30-day fetch with limit:1500 silently drops tail events once the global count exceeds the cap, which cuts post-conflict countries (low recent, higher older activity) exactly when they need the signal most. Split into two independent cached queries: - days 0-7: limit 1000 (full weight, same as before) - days 8-30: limit 1000 (0.4 weight, separate Redis cache key) Each window gets its own event budget; no shared-function changes. * feat(mcp): add MCP data panel to let users connect any MCP server Users can now connect an MCP server directly from the dashboard via a new "Connect MCP" block alongside "Create with AI". The modal fetches available tools from the server, lets the user pick a tool + configure args + refresh interval, then renders a live auto-refreshing panel. - api/mcp-proxy.js: Vercel edge proxy implementing MCP streamable-HTTP protocol (initialize + tools/list / tools/call, SSE + JSON responses) - src/services/mcp-store.ts: localStorage CRUD for McpPanelSpec configs - src/components/McpConnectModal.ts: connection wizard (URL, auth header, tool selection, args, title, refresh interval) - src/components/McpDataPanel.ts: auto-refreshing panel with configure (⚙) and refresh-now (↻) buttons; renders text or formatted JSON from tool result - panel-layout.ts: loads persisted MCP panels on boot, adds "Connect MCP" block, addMcpPanel() integration - event-handlers.ts: handles mcp- panel close (confirm + delete) and wm:mcp-configure event for re-opening the modal - CSS: mcp-connect-modal, mcp-data-panel, shared btn/btn-primary/etc classes - i18n: mcp.* keys in en.json - tests: mcp-proxy.js added to ALLOWED_LEGACY_ENDPOINTS allowlist * fix(mcp): add common.cancel i18n key used by McpConnectModal * feat(mcp): add Quick Connect presets for Brave, Exa, Tavily, Context7, Web Fetch * fix(mcp): replace search-heavy presets with diverse tool presets (GitHub, Slack, Radar, Maps, Postgres, Fetch) * feat(mcp): add 10 quick-connect presets Add Linear, Sentry, Datadog, Stripe, Overpass (OSM), Perplexity, Polygon.io, Notion, Airtable, and Shodan to MCP_PRESETS, bringing the total to 16 diverse integrations. Make preset list scrollable (max-height 260px) to accommodate the longer list. * fix(mcp): SSRF protection, CRLF sanitization, auth hint styling - Block private IP ranges (RFC1918, link-local, cloud metadata 169.254.x.x) in mcp-proxy validateServerUrl; remove dead localhost-allow logic - Strip CRLF from forwarded header keys/values to prevent header injection - Use mcp-status-info class (amber) for auth notes instead of mcp-status-loading - Simplify redundant JSON.parse guard in preset click handler * fix(mcp): correct protocol version and send notifications/initialized - Bump MCP_PROTOCOL_VERSION from 2024-11-05 to 2025-03-26: the current transport (direct POST, JSON or SSE response) is Streamable HTTP defined in the 2025-03-26 revision. The 2024-11-05 HTTP transport requires opening an SSE endpoint first to discover the JSON-RPC URL, which this proxy does not do. Advertising the wrong version caused compliant 2024-11-05 servers to fail during connection. - Add sendInitialized() helper that fires notifications/initialized after a successful initialize handshake. MCP lifecycle requires this notification before any tool traffic; servers that enforce it would reject every tools/list or tools/call from this proxy. Called in both mcpListTools() and mcpCallTool(). Response is awaited but treated as fire-and-forget so non-compliant servers do not break.