CAO MCP Apps
SkillMediaEnable, operate, and extend CAO's MCP Apps surface — the host-rendered fleet dashboard visible inside MCP App hosts (Claude Desktop, ChatGPT, VS Code Copilot, Goose, Postman). Use when the user says "enable MCP Apps in CAO", "the ui://cao views aren't rendering", "rebuild MCP Apps bundles", "add a new ui://cao/* view", or "configure the MCP Apps OAuth scope layer". Operates on the CAO_MCP_APPS_ENABLED surface and cao_mcp_apps/ build system. Not for the localhost:9889 browser dashboard, not for plugins, providers, or session management.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the CAO MCP Apps skill
What this skill tells your AI
The instructions your AI receives, as published by awslabs/cli-agent-orchestrator in skills/cao-mcp-apps/SKILL.md and read by ahel’s review.
Operator + developer playbook for CAO's host-rendered fleet UI. Reference docs:
docs/mcp-apps.md; example: examples/mcp-apps/.
Authoritative spec & sources of truth:
MCP Apps Overview ·
Build an MCP App ·
capability negotiation ·
client matrix ·
stable spec 2026-01-26/apps.mdx
(SEP-1865, Status: Stable) ·
SDK @modelcontextprotocol/ext-apps v1.7.4
(API ref ·
repo) ·
provenance PR #1865.
Turn it on
The surface is default-off. Enable and run:
export CAO_MCP_APPS_ENABLED=true
uv run cao-server # :9889 (REST + SSE /events)
uv run cao-mcp-server # registers tools/resources via the mcp_apps plugin
It is packaged as the built-in mcp_apps plugin (cao.plugins entry-point). The
plugin's on_mcp_server hook registers the ui://cao/* resources, the five app
tools, the topology widget, and advertises the io.modelcontextprotocol/ui
capability — best-effort and default-off, so nothing changes when the flag is unset.
What the operator gets
ui://cao/dashboard— fleet overview + the mutation entry point.ui://cao/agent— one terminal's status, output tail, inbox, sub-agents.ui://cao/event-stream— live governance ticker (app-only).cao://widget/topology+/widgets/topology/— build-free live event view.
All mutations flow through submit_command(kind, payload) — kinds:
send_message, assign, create_session (standard); interrupt, pause,
resume (lifecycle); shutdown_session (destructive).
For full payload schemas and scope requirements per kind, see references/submit-command-kinds.md.
Full capability scope (what the views use)
Beyond tools/call, the views exercise the spec's bidirectional channel:
- Host-delegated open-link (
ui/open-link) — the dashboard shows "Open full Web UI ↗" →http://127.0.0.1:9889only when the host advertiseshostCapabilities.openLinks(gate onapp.canOpenLinks(); the sandbox forbidswindow.open). - Display modes (
ui/request-display-mode) — views declareavailableDisplayModes: ["inline","fullscreen"]atui/initialize. - Streamed tool input (
ui/notifications/tool-input/-partial) — render before the result lands. - Model-context notes (
ui/update-model-context) — body-free gesture summaries keep the agent aware without leaking message contents.
preferredFrameSize and requiredScopes are CAO additions, not spec
_meta.ui fields (the spec sizes via containerDimensions +
ui/notifications/size-changed); CAO requests no elevated permissions.
See assets/mcp-apps-example.md for a worked MCP Apps integration example.
Gotchas
- Host doesn't offer the views → confirm
CAO_MCP_APPS_ENABLED=trueand thatinitializeadvertisesio.modelcontextprotocol/ui(the host must speak SEP-1865). Non-SEP-1865 hosts still get text-only tool results. - Views are blank / fail to load → the React bundles aren't built. Run
cd cao_mcp_apps && npm ci && npm run build:all. The topology widget needs no build and is the quickest smoke test (curl /widgets/topology/topology.html). - Mutations rejected with 403 → the auth layer is enabled and the token lacks
cao:write/cao:admin(cao:adminfordelete_session). UnsetAUTH0_DOMAIN/CAO_AUTH_JWKS_URIto disable enforcement. - Events don't stream → check
GET /events(SSE) directly; the bus is drop-on-slow, so a stalled consumer silently loses events — re-hydrate viacao_fetch_history.
Extending the surface
- Agents emitting UI intents into this surface? Load the
agui-authorskill — it teaches how to callemit_uiwith the six allow-listed components. Youremit_uiintents feed the L2 constructs that these views render. - Building or migrating an MCP App? Load the
mcp-apps-builderskill first. It equips the official ext-apps Agent Skills (create-mcp-app,add-app-to-server,migrate-oai-app,convert-web-app) and the build guide. Useadd-app-to-serverwhen adding a newui://cao/<name>view. - New command kind → add it to
submit_command's classifier + router inmcp_server/app_tools.py(map to a real Backplane HTTP endpoint; never bypass the HTTP-only boundary) and to the scope pre-check. - New view → add a
ui://cao/<name>resource inext_apps/apps.py+ an entry point undercao_mcp_apps/, build it, and tag the rendering tool withui_meta(...). For the full step-by-step view creation procedure, see references/extending-views.md. - New host-delegated action → add a thin method on the
McpAppbridge (cao_mcp_apps/src/shared/mcpApp.ts) that issues the specui/*request (e.g.openLink→ui/open-link,requestDisplayMode→ui/request-display-mode); gate UI on the matchinghostCapabilitiesflag and cover it with amockHosttest. - Keep the boundary →
mcp_server/*must reach state only over HTTP; the AST guard test (test/test_http_only_boundary.py) enforces it. - Keep bundles JIT-free → no
eval/new Function(host CSP forbids it); the CI scan fails the build otherwise.
Recording & Verification
After building or modifying views, regenerate the demo media:
cd cao_mcp_apps && npm run build:all && npm run demo
This runs scripts/record-demo.mjs which:
- Boots the E2E harness server (serves built bundles in a real MCP-host iframe)
- Drives Chromium through: dashboard → agent detail → unified → event-stream
- Records video (
docs/media/mcp-apps-demo.webm) - Captures screenshots (
docs/media/mcp-apps-{dashboard,agent,unified,event-stream}.png) - Generates an optimized GIF (
docs/media/mcp-apps-demo.gif) when ffmpeg is available
The GIF is referenced in README.md and docs/mcp-apps.md — always regenerate after
view changes so docs stay current.
Env overrides: CHROMIUM_BIN (path to Chrome), FFMPEG_BIN (for GIF), DEMO_PORT.
For a worked example of the full MCP Apps surface in action, see assets/mcp-apps-example.md.
Signals
- GitHub stars
- 1k
- Forks
- 262
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
cao-mcp-apps- Source
- github.com/awslabs/cli-agent-orchestrator