Skip to content

WIP: Add MCP Apps interactive UI extensions#920

Draft
manusa wants to merge 5 commits intocontainers:mainfrom
marcnuri-forks:feat/mcp-apps
Draft

WIP: Add MCP Apps interactive UI extensions#920
manusa wants to merge 5 commits intocontainers:mainfrom
marcnuri-forks:feat/mcp-apps

Conversation

@manusa
Copy link
Member

@manusa manusa commented Mar 13, 2026

Summary

Add MCP Apps support as an opt-in feature (--apps flag / apps_enabled config) that enables tools to return interactive HTML-based UIs rendered in sandboxed iframes by MCP hosts (VS Code, Claude Desktop, ChatGPT, etc.).

Viewer built with Preact + HTM + Chart.js + Prism.js (~230 KB, no build step), served via embed.FS with per-tool ui:// resource URIs.

Closes #753

What's done

  • Infrastructure: Config, CLI flag, server capability negotiation, per-tool resource registration
  • Viewer: Dual-flow (spec-compliant tool-result + fallback tool-input), SortableTable, MetricsTable (Chart.js), YamlView (Prism.js), GenericView, theming with light-dark() CSS fallbacks
  • Output layer: PrintObjStructured on Output interface, tableToStructured for Kubernetes Table API, ensureStructuredObject array wrapping
  • Tools with structured content: pods_list, pods_list_in_namespace, pods_top, nodes_top, namespaces_list, projects_list, resources_list
  • Compatibility: VS Code pre-fetch race (resources registered before tools), both nested and flat _meta.ui keys
  • Tests: Unit tests (mcpapps, output, API) + browser integration tests (Rod)

What's pending

  • Structured content for remaining non-list tool handlers (YAML tools)
  • Refinement of table output rendering
  • Reanalyze overall effect of structured outputs on LLM performance
  • Refresh via callServerTool(), height management, filtering/pagination
  • Edge case handling (empty results, large datasets)
  • Documentation updates (docs/configuration.md for apps_enabled)

manusa added 4 commits March 13, 2026 12:24
Add comprehensive living specification for the MCP Apps integration
(issue containers#753). Covers architecture, configuration, frontend stack
decisions, MCP postMessage protocol, output layer design, per-tool
resource URIs, VS Code compatibility, and YAML syntax highlighting.

Signed-off-by: Marc Nuri <marc@marcnuri.com>
Add MCP Apps support as an opt-in feature (--apps flag, apps_enabled
config). When enabled, tools return structuredContent alongside text
and expose per-tool ui:// resource URIs for interactive HTML viewers.

Infrastructure:
- AppsEnabled config field with CLI flag and TOML support
- Server capability negotiation (io.modelcontextprotocol/ui extension)
- Per-tool resource registration with VS Code pre-fetch compatibility
- WithAppsMeta() tool mutator for centralized _meta.ui injection

Viewer (Preact + HTM + Chart.js, no build step):
- MCP postMessage protocol implementation (~80 lines)
- Dual-flow viewer: spec-compliant tool-result + fallback tool-input
- SortableTable, TableView, MetricsTable, GenericView components
- CSS theming with light-dark() fallbacks for host integration

Output layer:
- PrintObjStructured() on Output interface for generic extraction
- NewToolCallResultFull() constructor for text + structured content
- ensureStructuredObject() wraps arrays in {"items": [...]} per spec
- tableToStructured() converts Kubernetes Table API to []map[string]any

Signed-off-by: Marc Nuri <marc@marcnuri.com>
Add self-describing structured content for metrics tools and browser
integration tests for the MCP Apps viewer.

Metrics:
- extractNodesTopStructured() with CPU/memory and percentage utilization
- Self-describing format with columns, chart config, and items

Browser tests (Rod + wrapper iframe):
- Protocol handshake, table rendering, sorting, metrics charts
- YAML highlighting, theme application, data routing
- Items envelope unwrapping, error handling

Signed-off-by: Marc Nuri <marc@marcnuri.com>
Add Prism.js (core + YAML grammar, ~9.4 KB) for syntax-highlighted
YAML output in the MCP Apps viewer. Tools returning Kubernetes resource
YAML now render with color-coded keys, strings, numbers, and comments.

- YamlView component with Prism.highlight() and useMemo
- looksLikeYaml() heuristic for Kubernetes resource detection
- Custom theme CSS using light-dark() for host theme integration
- Prism.manual = true to prevent auto-highlighting

Signed-off-by: Marc Nuri <marc@marcnuri.com>
Add Section 12 documenting the content vs structuredContent model
context visibility contract. structuredContent is for UI rendering
only — the model sees only the content field. References ext-apps
spec, SEP-1624, and PR #2200. Includes current client behavior
matrix, eval accountability steps, and open questions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PoC: MCP Apps integration for interactive UI extensions

1 participant