// MCP Apps (extension `io.modelcontextprotocol/ui`, spec 2026-01-26) — the // interactive app shell for the `get_forecast_predictions` tool: WorldMonitor's // AI-generated geopolitical/economic forecasts as probability cards (title, // domain + region, probability bar). Built on the shared shell foundation. // // Tool result shape (cache tool — content[0].text JSON, freshness envelope). // The tool serves the raw `forecast:predictions:v2` cache value under label // `predictions`; items carry `probability` as a 0-1 fraction (see // src/components/ForecastPanel.ts): // { cached_at, stale, data: { // predictions: { predictions: [{ title, domain, region, probability }] } } } // probability is nullable (render "—" and hide the bar when absent). This widget // renders forecast titles and probabilities ONLY — no calibration / Brier / // scorecard claims (that is the get_forecast_scorecard tool's domain, guarded // elsewhere). // // textContent-only rendering; renderBody stays backtick/`${`/regex-free. import { buildAppHtml } from './shell'; const STYLES = ` .fc { padding: 8px 0; border-bottom: 1px solid var(--border); } .fc:last-child { border-bottom: none; } .fc-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; } .fc-title { font-size: 13px; color: var(--fg); min-width: 0; } .fc-prob { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 13px; white-space: nowrap; } .fc-meta { margin-top: 3px; display: flex; gap: 6px; flex-wrap: wrap; } .chip { font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); border: 1px solid var(--border); border-radius: 999px; padding: 1px 7px; } `; const BODY = `