| title | MCP Apps: interactive ui:// widgets for WorldMonitor |
|---|---|
| description | Complete contract for WorldMonitor's MCP Apps interactive ui:// resources, tool links, host flow, security posture, and drift checks. |
WorldMonitor supports MCP Apps through the io.modelcontextprotocol/ui extension. The current fleet ships 10 MCP Apps: self-contained ui:// HTML resources that an MCP Apps host can render inline after a linked tool call.
This page is the source-of-truth guide for the interactive surface. Use it with the MCP Server overview for auth, quota, transport, and general JSON-RPC behavior.
| Field | Value |
|---|---|
| Extension | io.modelcontextprotocol/ui |
| Spec version | 2026-01-26 |
| UI resource MIME type | text/html;profile=mcp-app |
| Transport endpoint | https://worldmonitor.app/mcp |
| UI resource scheme | ui://worldmonitor/... |
| Data path | normal gated tools/call, then host postMessage into the iframe |
| Template path | resources/read of ui://..., public and quota-exempt |
Three discovery signals must stay aligned:
| Signal | Where it appears | Purpose |
|---|---|---|
initialize.result.capabilities.extensions["io.modelcontextprotocol/ui"] |
initialize response |
Negotiates MCP Apps support with the host. |
_meta.ui.resourceUri and _meta["ui/resourceUri"] |
tools/list / describe_tool entries for linked tools |
Tells the host which app shell should render a tool result. |
ui://... resources with _meta.ui.csp |
resources/list and resources/read |
Lets the host discover and fetch the static HTML template plus view policy. |
| UI resource URI | Linked tool | App | Renders |
|---|---|---|---|
ui://worldmonitor/country-risk.html |
get_country_risk |
Country Risk (interactive) | Composite Instability Index score, component breakdown, travel advisory, and sanctions exposure. |
ui://worldmonitor/world-brief.html |
get_world_brief |
World Brief (interactive) | AI-summarised global brief, grounding headlines, and source feed articles. |
ui://worldmonitor/country-brief.html |
get_country_brief |
Country Brief (interactive) | Per-country intelligence brief, analytical framework lens, and grounding sources. |
ui://worldmonitor/market-radar.html |
get_market_data |
Market Radar (interactive) | Fear & Greed composite plus equity, commodity, crypto, Gulf, and sector quote tables with signed, colour-coded change. |
ui://worldmonitor/chokepoint-monitor.html |
get_chokepoint_status |
Chokepoint Monitor (interactive) | Per-chokepoint transit summaries, week-over-week change, tanker split, and risk-level badge. |
ui://worldmonitor/news-intelligence.html |
get_news_intelligence |
News Intelligence (interactive) | AI-classified top stories with category, alert flag, country, and source. |
ui://worldmonitor/conflict-events.html |
get_conflict_events |
Conflict Events (interactive) | Active armed-conflict events (belligerents, violence type, country, fatalities, date) from UCDP. |
ui://worldmonitor/natural-disasters.html |
get_natural_disasters |
Natural Disasters (interactive) | Recent earthquakes (USGS magnitude, place, time) and active wildfires (NASA FIRMS), grouped. |
ui://worldmonitor/prediction-markets.html |
get_prediction_markets |
Prediction Markets (interactive) | Event-contract odds grouped by category (geopolitical, tech, finance) with a probability bar per market. |
ui://worldmonitor/forecasts.html |
get_forecast_predictions |
Forecasts (interactive) | AI-generated geopolitical and economic forecasts as probability cards (title, domain, region). |
- The host calls
initializeonhttps://worldmonitor.app/mcp. - WorldMonitor returns the normal MCP capabilities plus
capabilities.extensions["io.modelcontextprotocol/ui"]. - The host calls
tools/list. UI-linked tools carry_meta.ui.resourceUriand the deprecated flat_meta["ui/resourceUri"]alias. - The host calls
resources/listand sees theui://app resources. Each UI entry includesmimeType: text/html;profile=mcp-appand_meta.ui.csp. - The host calls
resources/readfor the chosenui://URI. This read is public and quota-exempt because it returns only a static, data-free template. - The host performs the normal authenticated
tools/callfor the linked tool. This is the only step that fetches live data and consumes any applicable quota. - The host embeds the returned HTML in a sandboxed iframe and exchanges MCP Apps messages:
View -> Host: ui/initialize
Host -> View: initialize result with hostContext
View -> Host: ui/notifications/initialized
Host -> View: ui/notifications/tool-result
View -> Host: ui/notifications/size-changed
The view never fetches live WorldMonitor data itself. Live data always reaches the app through the host after a normal tool call.
resources/list exposes concrete public resources, including all ui:// templates. resources/templates/list exposes parameterised data resources.
| Read kind | Example | Auth | Pro daily quota | Why |
|---|---|---|---|---|
| UI template | resources/read ui://worldmonitor/market-radar.html |
No | No | Static HTML shell, no data and no upstream fetch. |
| Public metadata | resources/read worldmonitor://seed-meta/freshness |
No | No | Metadata-only health/freshness probe. |
| Data template instantiation | resources/read worldmonitor://countries/de/risk |
Yes | Yes | Routes through the same dispatcher as the equivalent tools/call. |
| Tool data | tools/call get_market_data |
Yes | Yes for OAuth/Pro contexts | Fetches live or cached data. |
All methods still count toward the 60/minute per-key, per-user, or anonymous-IP rate limiter.
The app shells are deliberately static and narrow:
- They are self-contained HTML: no external scripts, styles, images, iframes, fonts, or network fetches.
- Rendering uses DOM construction and
textContent, neverinnerHTML. - Links are admitted only through
http:orhttps:URL parsing and are rendered withrel="noopener noreferrer". - The shared shell reports size after initialization and after every render so hosts can resize the iframe.
- Soft-error envelopes (
_budget_exceeded,_jmespath_error, and top-level stringerror) render as visible error messages instead of blank success states. - The HTML includes a meta CSP with
default-src 'none', scoped inline script/style allowances, lockedform-actionandbase-uri, and a connect-src mirror of the_meta.ui.csp.connectDomainspolicy.
Important limitation: frame-ancestors inside a meta CSP is advisory only. Browsers enforce frame-ancestors only from an HTTP Content-Security-Policy response header. The meta directive remains in the shell for static scanners and intent documentation; do not treat it as browser-level clickjacking protection.
- Add the self-contained app shell under
api/mcp/ui/*-app.ts. - Reuse
buildAppHtml()fromapi/mcp/ui/shell.tsunless there is a protocol reason not to. - Add a canonical
*_UI_URIconstant and registry entry inapi/mcp/ui/registry.ts. - Set
_uiResourceUrion exactly one backing tool inapi/mcp/registry/rpc-tools.tsorapi/mcp/registry/cache-tools.ts. - Update
docs/mcp-apps.mdx, the short MCP overview, andpublic/.well-known/mcp/server-card.json. - Run
npm run docs:statsto refreshdocs/generated/stats.json. - Run
npm run docs:checkand the focused MCP resource/tool tests.
The docs-stat gate derives the app inventory from api/mcp/ui/registry.ts and the tool registries. It fails when:
docs/mcp-apps.mdx,docs/mcp-overview.mdx, orpublic/mcp-server.mdomits a linked tool orui://URI.public/.well-known/mcp/server-card.json.metadata.mcpAppsdrifts from the code-derived app list, spec version, or MIME type.docs/docs.jsondrops this page from navigation.- The documented MCP tool count drifts from the server-card tool inventory.
| Source | Owns |
|---|---|
api/mcp/ui/shell.ts |
Shared HTML builder, protocol bridge, MIME type, spec version, CSP, theme, soft-error handling. |
api/mcp/ui/registry.ts |
Canonical ui:// resource inventory and resources/read response builder. |
api/mcp/registry/rpc-tools.ts |
UI links for RPC-backed tools such as get_world_brief, get_country_brief, and get_country_risk. |
api/mcp/registry/cache-tools.ts |
UI links for cache-backed tools such as get_market_data and get_chokepoint_status. |
api/mcp/handler.ts |
Public ui:// read promotion, resources/list, resources/read, and initialize capability advertisement. |
public/.well-known/mcp/server-card.json |
Static pre-connection discovery metadata for scanners and agents. |
scripts/docs-stats.mjs |
Drift guard for docs, server-card metadata, navigation, and app inventory. |