> ## Documentation Index
> Fetch the complete documentation index at: https://sunpeak.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Apps - Build Interactive UIs for AI Chat Hosts

> Learn how to build MCP Apps that render interactive UIs inside ChatGPT, Claude, and other AI hosts. Covers the App class, event handlers, styling, React hooks, and the MCP Apps protocol.

<Note>This documentation covers MCP Apps SDK v1.7.4 (`@modelcontextprotocol/ext-apps`).</Note>

## What are MCP Apps?

MCP Apps is an extension to the [Model Context Protocol](/mcp-apps/mcp/overview) that enables MCP servers to deliver interactive user interfaces to hosts. It defines how servers declare UI resources, how hosts render them securely in iframes, and how the two communicate.

MCP allows servers to expose [tools](/mcp-apps/mcp/tools) and [resources](/mcp-apps/mcp/resources) to AI assistants, but responses are limited to text and structured data. Many use cases need more:

* **Data visualization** — Charts, graphs, dashboards that update as data changes
* **Rich media** — Video players, audio waveforms, 3D models
* **Interactive forms** — Multi-step wizards, configuration panels, approval workflows
* **Real-time displays** — Live logs, progress indicators, streaming content

MCP Apps standardizes this. Servers declare their UIs once; any compliant host can render them.

## How do plugins relate to ChatGPT Apps?

ChatGPT apps are now submitted and published as plugins. A plugin can contain an MCP-backed app, skills, or both. The app portion still uses MCP Apps or the OpenAI Apps SDK, so this is a packaging and distribution change rather than a protocol change.

When you build with sunpeak, you still create an MCP server, tools, and UI resources. For local ChatGPT development, enable Developer mode and add that MCP server from the `Plugins` page. For public release, submit the MCP server as a plugin through the OpenAI Platform. See the [deployment guide](/app-framework/guides/deployment#publish-to-chatgpt) for both flows.

## How do MCP Apps work?

Three entities work together:

```mermaid theme={null}
flowchart LR
    subgraph Server ["MCP Server"]
        T[Tools]
        R[UI Resources]
    end

    subgraph Host ["Host (Chat Client)"]
        B[AppBridge]
    end

    subgraph View ["View (iframe)"]
        A[App]
    end

    Server <-->|MCP Protocol| Host
    Host <-->|postMessage| View
```

* **Server** — A standard MCP server that declares tools and UI resources. Defines what the UI looks like (HTML) and what tools it exposes.
* **Host** — The chat client (e.g., Claude, ChatGPT) that connects to servers, embeds Views in iframes, and proxies communication between them.
* **View** — The UI running inside a sandboxed iframe. Receives tool data from the Host and can call server tools or send messages back to the chat.

## What happens if a host doesn't support MCP Apps?

MCP Apps is designed for graceful degradation. Hosts advertise their UI support when connecting to servers; servers check these capabilities before registering UI-enabled tools. If a host doesn't support MCP Apps, tools still work — they just return text instead of UI.

See [Capability Detection](/mcp-apps/server/capability-detection) for implementation details.

## How are MCP App UIs delivered?

UI resources are HTML templates that servers declare using the `ui://` URI scheme. Resources are declared upfront during [tool registration](/mcp-apps/server/register-app-tool), enabling:

* **Prefetching** — Hosts can cache templates before tool execution
* **Separation of concerns** — Templates (presentation) are separate from tool results (data)
* **Review** — Hosts can inspect UI templates during connection setup

## How are tools linked to UIs?

Tools reference their UI templates through [tool metadata](/mcp-apps/server/tool-meta):

```json theme={null}
"_meta": {
  "ui": { "resourceUri": "ui://weather/forecast" }
}
```

When a tool with UI metadata is called, the Host fetches the corresponding resource, renders it in a sandboxed iframe, and passes the tool arguments and results to the View.

## What can MCP Apps do at runtime?

Views communicate with Hosts using JSON-RPC over `postMessage`. From a View, you can:

* **[Call server tools](/mcp-apps/app/requests/call-server-tool)** — Fetch fresh data or trigger server-side actions
* **[Send messages](/mcp-apps/app/requests/send-message)** — Add messages to the conversation thread
* **[Update model context](/mcp-apps/app/requests/update-model-context)** — Push structured data to the model's context
* **[Request LLM completions](/mcp-apps/app/requests/create-sampling-message)** — Ask the host to run `sampling/createMessage`
* **[Open links](/mcp-apps/app/requests/open-link)** — Request the host to open external URLs
* **[Download files](/mcp-apps/app/requests/download-file)** — Trigger host-mediated file downloads
* **[Request display modes](/mcp-apps/app/requests/request-display-mode)** — Switch between inline, fullscreen, and picture-in-picture

See the full [App lifecycle](/mcp-apps/lifecycle), [Requests API](/mcp-apps/app/requests), and [View API Guide](/mcp-apps/app/view-api-guide) for details.

## How does tool visibility work?

Tools can be visible to the model, the app, or both. By default, tools are visible to both (`visibility: ["model", "app"]`).

App-only tools (`visibility: ["app"]`) are useful for UI interactions that shouldn't clutter the agent's context — things like refresh buttons, pagination controls, or form submissions. The model never sees these tools; they exist purely for the View to call.

Views can also register their **own** tools that the host (and the model) can call back into. See [App Tools](/mcp-apps/app/app-tools) for the full bidirectional pattern.

## What display modes are available?

Views can be displayed in different modes:

* **inline** — Embedded in the chat flow (charts, previews, forms)
* **fullscreen** — Takes over the window (editors, games, dashboards)
* **pip** — Picture-in-picture overlay (music player, timer)

Views declare which modes they support; Hosts declare which they can provide. The Host always has final say over its own UI. See [Layout and Display](/mcp-apps/layout) for sizing, auto-resize, and safe area guidance.

## How are MCP Apps secured?

All Views run in sandboxed iframes with no access to the Host's DOM, cookies, or storage. Communication happens only through `postMessage`, making it auditable.

Servers declare which network domains their UI needs via [CSP metadata](/mcp-apps/server/resource-meta#csp--content-security-policy). Hosts enforce these declarations — if no domains are declared, no external connections are allowed.

## More questions?

The [Layout and Display](/mcp-apps/layout) guide covers iframe sizing, display modes, and responsive View CSS. The [Patterns](/mcp-apps/patterns) guide covers app-only tools, polling, large data, errors, and host adaptation. The [MCP Apps FAQ](/mcp-apps/faq) answers common questions about hosts, UI delivery, display modes, theming, security, and testing.

If you are wiring the server side from scratch, start with [Build an MCP App Server](/mcp-apps/server/build-server). If you already have a normal MCP tool and want to add an interactive View, use [Add a UI to an MCP Tool](/mcp-apps/server/add-ui-to-tool). For a field-by-field check before testing in a host, use the [Tool and Resource Contract](/mcp-apps/server/tool-resource-contract). For result payloads, use [Tool Results and Model Context](/mcp-apps/server/tool-results-model-context) to decide what belongs in `content`, `structuredContent`, `_meta`, and `updateModelContext`.

If you already have OpenAI Apps SDK code, use [Migrate from OpenAI Apps SDK to MCP Apps](/mcp-apps/server/migrate-openai-apps) to map `openai/outputTemplate`, `text/html+skybridge`, `widgetCSP`, and `window.openai` APIs to MCP Apps equivalents.
