MCP Apps SDK

repository·main·Indexed 25 days ago

https://github.com/modelcontextprotocol/ext-apps

An extension to the Model Context Protocol that enables MCP servers to deliver interactive user interfaces, such as charts, forms, and dashboards, that render inline within compliant chat clients. The SDK provides an App class and React hooks for communication between the UI and the host, including methods like callServerTool, sendMessage, sendLog, and openLink. The repository includes reference implementations for hosts and servers using Preact, React, Solid, and Svelte.

Tokens
86.1K
Snippets
226
Records
362
Agent score
83%

What's inside @modelcontextprotocol/ext-apps

  1. Overview of MCP Apps: Interactive User Interfaces

    main

    MCP Apps is an extension to the Model Context Protocol (MCP) that allows servers to deliver interactive user interfaces (UIs) to hosts. It provides a standardized pattern for declaring UI resources using the ui:// URI scheme and associating them with tools via metadata. This enables rich, visual, and interactive experiences that go beyond plain text or structured data, while maintaining MCP's core principles of security and auditability.

    Key features include:

    • Standardized UI Declaration: Uses the ui:// URI scheme.
    • Tool Association: UI resources can be linked to specific tools through metadata.
    • Bidirectional Communication: Facilitates interaction between the UI and the host using the existing MCP JSON-RPC base protocol.
    • HTML Support: The initial specification focuses on HTML resources with the MIME type text/html;profile=mcp-app.
  2. Overview of Basic Vue MCP App architecture

    main

    The Basic Vue MCP App demonstrates how to link an MCP server tool to a rich Vue 3 user interface.

    Workflow

    1. Tool Registration: The server (defined in server.ts) registers a tool (e.g., get-time) and includes metadata that links the tool to a specific UI HTML resource (e.g., ui://get-time/mcp-app.html).
    2. UI Rendering: When a client invokes the tool, the Host renders the associated UI resource.
    3. Communication: The UI (built with Vue 3 in src/App.vue) uses the MCP App SDK's App class to communicate back to the host and call server tools.

    App Communication APIs

    The App class provides the following methods for the UI to interact with the environment:

    • callServerTool: Invokes a tool on the MCP server.
    • sendMessage: Sends a message to the host.
    • sendLog: Sends a log message.
    • openLink: Opens a URL.

    Build Strategy

    This example uses Vite with vite-plugin-singlefile to bundle the entire Vue application into a single HTML file. This ensures the entire UI can be served as a single MCP resource. For apps requiring external resources, you must define _meta.ui.csp.resourceDomains in the UI resource metadata.

  3. Overview of MCP Apps extension

    main

    MCP Apps (extension ID: io.modelcontextprotocol/ui) allows MCP servers to deliver interactive user interfaces to hosts. It enables servers to provide HTML-based UIs that communicate with the host via standard MCP JSON-RPC.

    Key components include:

    • UI Resources: Predeclared resources using the ui:// URI scheme.
    • Tool-UI Linkage: Tools that reference specific UI resources via metadata for rendering results.
    • Bidirectional Communication: UI iframes that interact with hosts using MCP.
    • Security Model: Mandatory iframe sandboxing and Content Security Policy (CSP) enforcement.

    Note: MCP Apps is an optional extension and must be negotiated between client and server via capability negotiation.

  4. Security model for MCP Apps

    main

    MCP Apps enforces security through two primary mechanisms:

    1. Sandboxing: All Views run in sandboxed iframes with no access to the Host's DOM, cookies, or local storage. Communication is strictly limited to postMessage.
    2. Network Control (CSP): Servers must declare which network domains their UI requires via Content Security Policy (CSP) metadata. Hosts enforce these declarations; if no domains are declared, the View is prevented from making any external connections, mitigating data exfiltration risks.
  5. Use MCP Transport for host communication

    main

    MCP Apps communicate with hosts using the standard MCP JSON-RPC base protocol over postMessage. This decision ensures compatibility with existing MCP infrastructure, including:

    • Standard type definitions and error handling
    • Timeouts and Tasks for long-running calls
    • Sampling and other core MCP features

    Developers can use the standard @modelcontextprotocol/sdk to implement these communications, avoiding the need for a custom message format.

  6. How MCP Apps work

    main

    MCP Apps extend the Model Context Protocol by allowing tools to declare interactive UI resources. The lifecycle follows these steps:

    1. Tool definition: An MCP tool declares a ui:// resource containing its HTML interface.
    2. Tool call: The LLM invokes the tool on the MCP server.
    3. Host renders: The chat client (host) fetches the ui:// resource and renders it within a sandboxed iframe.
    4. Bidirectional communication: The host sends tool data to the UI via notifications, and the UI can trigger other tools by communicating back through the host.
  7. Implement Host Theming using CSS Variables

    main

    To ensure visual cohesion across different host environments, MCP Apps use a standardized set of CSS custom properties (variables). UI views should apply styles using var(--name) with appropriate fallbacks.

    Theming Guidelines:

    • Supported Variables: Hosts provide values for colors, typography, and borders.
    • Exclusions: Hosts do not provide spacing variables, as varying spacing can break UI layouts.
    • Implementation: Views should be framework-agnostic and rely on these variables rather than hardcoded values or host-specific CSS-in-JS injection.
  8. Manage View Display Modes

    main

    MCP Views can be displayed in three modes: inline (default), fullscreen, or pip (picture-in-picture).

    For View Developers:

    1. Declare Support: You MUST declare all supported modes in the ui/initialize request using appCapabilities.availableDisplayModes.
    2. Check Compatibility: Before requesting a mode change, check the HostContext.availableDisplayModes to ensure the host supports it.
    3. Handle Responses: You MUST handle cases where the host returns a different mode than the one you requested.

    For Host Developers:

    1. Enforce Capabilities: Do NOT switch a view to a mode it hasn't declared support for.
    2. Respond to Requests: When a view calls ui/request-display-mode, return the actual resulting mode in the response.
    3. Notify Changes: Use ui/notifications/host-context-changed to inform the view when the displayMode changes.
    // Example: View declares support for inline and fullscreen during initialization
    {
      method: "ui/initialize",
      params: {
        appCapabilities: {
          availableDisplayModes: ["inline", "fullscreen"]
        }
      }
    }
  9. How MCP Apps work: The Tool + Resource model

    main

    An MCP App is a combination of two linked components that allow an LLM to trigger an interactive UI:

    1. Tool: Called by the LLM/host. It processes input and returns data.
    2. Resource: Serves the bundled HTML UI that displays the data.

    The Linkage: The tool's metadata must include a reference to the resource's URI using the _meta.ui.resourceUri key.

    Lifecycle Flow: Host calls tool $\rightarrow$ Host renders resource UI $\rightarrow$ Server returns result $\rightarrow$ UI receives result.

  10. Handle Host Context and Theming in a View

    main

    The Host provides environment and styling information in the hostContext field of the McpUiInitializeResult. Views should use this to adapt their appearance and behavior.

    Key context fields:

    • theme: Current preference ("light" or "dark").
    • styles: Contains variables (CSS custom properties) and css (e.g., @font-face rules) for the View to inject.
    • displayMode: How the View is currently rendered ("inline", "fullscreen", or "pip").
    • containerDimensions: Sizing constraints for the iframe.
    • locale & timeZone: User preferences for localization.
    • platform: The host platform ("web", "desktop", or "mobile").
    // Host responds with McpUiInitializeResult
    {
      "jsonrpc": "2.0",
      "id": 1,
      "result": {
        "protocolVersion": "2026-01-26",
        "hostCapabilities": { /* ... */ },
        "hostInfo": { "name": "claude-desktop", "version": "1.0.0" },
        "hostContext": {
          "theme": "dark",
          "styles": {
            "variables": {
              "--color-background-primary": "light-dark(#ffffff, #171717)",
              "--color-text-primary": "light-dark(#171717, #fafafa)",
              "--font-sans": "Anthropic Sans, sans-serif"
            },
            "css": {
              "fonts": "@font-face { font-family: \"Custom Font Name\"; src: url(\"https://...\"); }"
            }
          },
          "displayMode": "inline",
          "containerDimensions": { "width": 400, "maxHeight": 600 }
        }
      }
    }
  11. How MCP Apps architecture works

    main

    MCP Apps uses a three-entity architecture to deliver interactive UIs securely:

    1. Server: A standard MCP server that declares tools and UI resources (HTML templates) using the ui:// URI scheme.
    2. Host (Chat Client): The application (e.g., Claude Desktop) that connects to the server, embeds Views in sandboxed iframes, and acts as a proxy for communication.
    3. View (iframe): The UI running inside the sandboxed iframe. It acts as an MCP client, receiving tool data from the Host and communicating back via postMessage to call tools or interact with the chat.

    This model allows for Progressive Enhancement: if a Host does not support MCP Apps, tools still function as standard text/structured data tools. The UI is an optional enhancement.