Comparisons

MCP Apps vs MCP-UI vs OpenAI Apps SDK: which one to build on

Three names for the same idea: an interactive UI that a tool call draws inside a chat. In 2026 one of them is the standard and the other two are where it came from.

6 min read

The short answer

MCP Apps is the standard; MCP-UI and the OpenAI Apps SDK are the two projects it grew out of. If you are comparing MCP Apps vs MCP-UI, or MCP Apps vs ChatGPT apps, build to MCP Apps in 2026: it is an official MCP extension, ChatGPT implements it, Claude, VS Code and Microsoft 365 Copilot render it, and MCP-UI now emits it. Use the ChatGPT-only extensions on top of it when you need them, never instead of it.

The rest of this page explains where each one came from, how they differ field by field, and what to do with code you already wrote for either of the older two.

Where each one came from

MCP-UI came first. It was an open-source community project, led by Ido Salomon and Liad Yosef, that showed MCP tools could return interactive HTML instead of plain text. Its server SDKs covered TypeScript, Python and Ruby, and it was adopted by teams such as Postman, Hugging Face, Shopify, Goose and ElevenLabs (they are credited in the MCP Apps spec). Its site now says plainly that "MCP-UI is now standardized into MCP Apps" (mcpui.dev).

The OpenAI Apps SDK was OpenAI's way to put interfaces inside ChatGPT: an MCP server, an HTML template served as text/html+skybridge, and a window.openai object in the page. As of October 2026 OpenAI calls ChatGPT apps "plugins" and documents them under developers.openai.com/plugins. Many tutorials from late 2025 still teach the skybridge path.

MCP Apps is the merge. The spec, SEP-1865, was proposed on 21 November 2025 by authors from MCP-UI, OpenAI and Anthropic, and became the "first official MCP extension" on 26 January 2026 (MCP blog). Its extension id is io.modelcontextprotocol/ui. On 22 February 2026 OpenAI wrote that "ChatGPT is now fully compatible with the MCP Apps spec" (changelog).

If you want the concepts behind it first, start with what MCP Apps are.

MCP Apps vs MCP-UI vs Apps SDK, side by side

MCP AppsMCP-UIOpenAI Apps SDK
OwnerMCP project (official extension)Community project, now part of MCP AppsOpenAI
Status in 2026Stable since 26 Jan 2026Standardized into MCP Apps; old content types are legacyStill works; ChatGPT implements MCP Apps and keeps its own fields as aliases
MIME typetext/html;profile=mcp-appNow text/html;profile=mcp-app. Legacy: rawHtml, externalUrl (text/uri-list), remoteDom (application/vnd.mcp-ui.remote-dom)text/html+skybridge
How the tool points to the UI_meta.ui.resourceUri on the tool, a ui:// resourceLegacy: the tool returned the UI resource in its result. Now: _meta.ui.resourceUri_meta["openai/outputTemplate"]
CSP fields_meta.ui.csp: connectDomains, resourceDomains, frameDomains, baseUriDomainsNow the MCP Apps fieldsopenai/widgetCSP: connect_domains, resource_domains, frame_domains
Bridge APIJSON-RPC over postMessage (ui/initialize, ui/notifications/tool-result, tools/call, ui/message); App class in @modelcontextprotocol/ext-appsNow the MCP Apps bridge; AppRenderer in @mcp-ui/client for hostswindow.openai (callTool, widgetState, requestModal...)
Hosts that render itClaude (web and desktop), ChatGPT, VS Code GitHub Copilot, Microsoft 365 Copilot, Goose, Postman, MCPJam, Cursor and more (client matrix)MCP Apps hosts, plus legacy MCP-UI hosts for the old typesChatGPT

Two things stand out. First, the MCP Apps fields are almost a one-to-one rename of the OpenAI ones, which is why migrating is mostly mechanical. Second, the only host that reads the skybridge fields is ChatGPT, while the MCP Apps fields reach every host in the client matrix, ChatGPT included.

What if I have MCP-UI code?

Upgrade the packages and check which content type you used.

  • createUIResource in @mcp-ui/server now produces a resource with the MIME type text/html;profile=mcp-app. If you served HTML, upgrading moves you onto the standard with little else to change.
  • Make the tool point to the resource with _meta.ui.resourceUri and serve the HTML from a ui:// resource handler, instead of returning the UI inside the tool result. That is the MCP Apps pattern: the tool definition names its UI, and the host reads the resource separately.
  • externalUrl and remoteDom are legacy. An external URL becomes a self-contained HTML page (or an iframe declared in frameDomains, which some hosts restrict). A Remote DOM view needs to be rebuilt as an HTML view.
  • If you build a host rather than a server, AppRenderer in @mcp-ui/client is the renderer MCP-UI recommends, and the official @modelcontextprotocol/ext-apps/app-bridge is the other option.

What if I have OpenAI Apps SDK code?

Keep it running and move it field by field. The official migration guide maps each piece:

Apps SDKMCP Apps
openai/outputTemplateui.resourceUri
text/html+skybridgetext/html;profile=mcp-app
openai/widgetCSP (connect_domains, resource_domains, frame_domains)ui.csp (connectDomains, resourceDomains, frameDomains)
openai/widgetDomainui.domain
openai/widgetPrefersBorderui.prefersBorder
openai/widgetAccessible, openai/visibilityui.visibility
window.openai.callToolapp.callServerTool

ChatGPT still honors openai/outputTemplate as a compatibility alias, and openai/visibility was deprecated on 21 July 2026. The official repo also ships a migrate-oai-app agent skill that does the conversion with you. The step-by-step version, including the view code, is in ChatGPT plugin UI with MCP Apps.

What stays host-specific

The standard covers the common ground: the resource, the handshake, tool input and results, calling tools, opening links, sending messages, display modes and theme. Some things remain per host:

  • ChatGPT extensions. requestCheckout, requestModal, uploadFile, selectFiles, getFileDownloadUrl and widgetState / setWidgetState live on window.openai. OpenAI's own advice is to get the MCP Apps flow working first and use window.openai "only for capabilities that the shared specification does not cover", with feature detection and a fallback (OpenAI docs).
  • The sandbox domain. ui.domain is host-specific (for example a hash under claudemcpcontent.com on Claude, or a name under oaiusercontent.com on ChatGPT).
  • Nested frames. Claude restricts frameDomains pending security review, and ChatGPT blocks nested frames by default. See MCP Apps CSP explained.
  • Look and feel. Each host passes its own CSS variables, fonts and theme in the host context; your view should read them rather than hardcode colors. More in theming MCP Apps.
  • Where it renders at all. Text-only clients such as Claude Code in the terminal call the tool and show its text content. Which clients draw the UI is covered in MCP Apps clients.

Which one should I use?

  • Starting from scratch: MCP Apps. Use @modelcontextprotocol/ext-apps (registerAppTool, registerAppResource, the App class), or a framework on top of it. See build an MCP App in TypeScript.
  • You only target ChatGPT and need checkout, modals or files: still MCP Apps for the base, with those window.openai extensions layered on and feature-detected.
  • You have an Apps SDK app in production: migrate field by field; the aliases give you time, but new UI should use the shared fields.
  • You have MCP-UI code: upgrade @mcp-ui/server and move to _meta.ui.resourceUri; drop externalUrl and remoteDom.
  • You build a host: implement MCP Apps with the official app bridge or MCP-UI's AppRenderer.
  • You want the UI without writing the view: the builders and frameworks in MCP Apps builders compared all target MCP Apps.

Widgetry is one of those: it produces standard MCP Apps widgets (the text/html;profile=mcp-app document plus a manifest with _meta.ui.resourceUri and _meta.ui.csp) from a template and a design, previews them in a real MCP Apps host, and lets your server link to them. It never uses skybridge or window.openai, so the same widget renders in ChatGPT, Claude and the other hosts.

Your first widget, in the chat in minutes

Pick a template, drop in your data and see it as ChatGPT or Claude will show it. Then link it from your MCP server, or let your agent build the next one.