Large Language ModelsGenerate imagesGenerate videos
MCP UI vs MCP Apps: Differences, SDK and Examples
MCP UI started as a community SDK for interactive tool interfaces, and MCP Apps is the official extension that standardized the idea in January 2026. This article sets the two side by side: delivery model, sandboxing, host support, SDK packages and runnable code for servers, Views and hosts, plus advice on which one to pick for a new project.
Ask ten developers what separates MCP UI from MCP Apps and you will hear ten different answers. The reason is simple: the two names describe a community project and the official standard that grew out of it, and plenty of posts treat them as rivals. If one of your MCP tools should render a chart, a form or a map instead of a wall of text, you need to know which package to install, where the HTML lives and which hosts will actually draw it. This comparison of MCP UI vs MCP Apps lays out the differences, the SDK pieces on every side and code you can adapt today.
💡 Short answer: MCP Apps is the official MCP extension that went live on January 26, 2026. MCP-UI is the earlier SDK project that pioneered the idea, and its packages now work with the MCP Apps standard. Treat them as ancestor and successor, not as competitors.
What Each One Actually Is
MCP UI in Plain Terms
MCP-UI is an SDK for building interactive interface components for Model Context Protocol tools. It showed up in 2025 and pioneered the idea that an MCP server could answer with a live interface instead of plain text. According to the MCP-UI documentation, the project directly influenced the MCP Apps specification.
The toolkit is split in two:
@mcp-ui/server exposes createUIResource, which builds a UI resource from an HTML string or an external URL.
@mcp-ui/client exposes AppRenderer for rendering a tool's interface and AppFrame for HTML you already fetched.
Server helpers also exist for Ruby (mcp_ui_server) and Python (mcp-ui-server), a real advantage when your MCP server is not written in TypeScript. In its early form, MCP-UI offered several content flavors, including raw HTML, external URLs and Remote DOM, and the interface traveled inside the tool response.
MCP Apps in Plain Terms
MCP Apps is the official extension that lets a tool return an interactive component, such as a dashboard, a form or a multi-step workflow, rendered inside the conversation in a sandboxed iframe. The official announcement calls it the first official MCP extension and says it is ready for production.
It rests on two ordinary MCP primitives:
A tool that carries UI metadata in the _meta.ui.resourceUri field.
A UI resource served through the ui:// scheme, holding bundled HTML and JavaScript.
The SDK lives in one npm package, @modelcontextprotocol/ext-apps, with subpaths for React hooks, host embedding and server registration.
How the Two Projects Merged
From Experiment to Extension
The maintainers proposed MCP Apps in November 2025, building on the work of MCP-UI and the OpenAI Apps SDK. Two months later, on January 26, 2026, the extension went live. The announcement is explicit that MCP-UI continues as a separate project and that moving to the official extension is optional.
That detail matters for anyone holding older code. Nothing forces a rewrite tomorrow, and the MCP-UI packages now point to registerAppTool and registerAppResource from the MCP Apps standard as the way to wire tools and resources.
Why a Standard Mattered
Before the merge, interface experiments were tied to individual clients. A panel designed around one host could not be counted on to run in another without client-specific code. Folding the MCP-UI and Apps SDK ideas into one extension means a server author writes one interface and any compliant host can render it.
For teams shipping MCP servers to many customers, that is the whole point: one build, many hosts, one security story.
Differences That Actually Matter
The Comparison Table
Aspect
MCP-UI
MCP Apps
Origin
Community SDK project from 2025
Official MCP extension, proposed November 2025, live January 26, 2026
Role
Pioneered interactive UI over MCP and supplies helpers
Standard specification plus a reference SDK
Tool link
Original model returns the UI inside the tool response
_meta.ui.resourceUri points at a ui:// resource
MIME type
text/html;profile=mcp-app when used with the standard
text/html;profile=mcp-app
Server helpers
createUIResource in @mcp-ui/server
registerAppTool and registerAppResource in ext-apps/server
View and client
AppRenderer and AppFrame in @mcp-ui/client
App class, plus app-bridge for hosts
Languages
TypeScript, Ruby, Python server helpers
TypeScript SDK with React hooks
Status
Continues as a separate project, migration optional
Described as ready for production
Read the table as a map of layers, not a scoreboard. MCP Apps defines the contract, and MCP-UI offers convenience on top of that contract.
Where the HTML Lives
The biggest structural difference is where the interface sits. In MCP Apps, the server stores the UI under a ui:// URI and the tool points at it through _meta.ui.resourceUri. The host fetches that resource separately and renders it on its own schedule, so the HTML is not stuffed into every tool response.
The practical gains:
Reviewable templates. A host can read the template before it ever runs.
Clean separation. Tool results stay data, and the resource stays the interface.
Security and Sandboxing
Interactive code inside a chat is a risk, so the security model is a first-class feature. The announcement lists four layers:
Iframe sandboxing with restricted permissions
Pre-declared templates that hosts can review
Auditable JSON-RPC messaging for every UI-to-host exchange
Optional user consent before a UI-initiated tool call
On the MCP-UI side, AppRenderer takes a sandbox prop that points at a separate proxy page, which the documentation example serves from its own port. Untrusted HTML never shares a page with your host app.
💡 Tip: The documented onOpenLink handler checks that a URL starts with https:// or http:// before calling window.open. Copy that habit. A View is untrusted input, so filter what it asks the host to do.
Hosts That Render Views
At launch, the announcement named Claude (web and desktop), Goose and Visual Studio Code Insiders, with ChatGPT arriving the same week. The ext-apps repository now lists ChatGPT, Claude, VS Code, Goose, Postman, MCPJam, the mcp-use inspector and the Alpic Playground. JetBrains, AWS, Google DeepMind and Antigravity were named as parties looking at support.
Check your target host's current status before promising a launch date. That list moves quickly.
The SDK Pieces You Will Touch
Two package families do the work, and they fit together.
Package
Purpose
@modelcontextprotocol/ext-apps
Build interactive Views with the App class
@modelcontextprotocol/ext-apps/react
React hooks for Views
@modelcontextprotocol/ext-apps/app-bridge
Embed Views in a chat client
@modelcontextprotocol/ext-apps/server
Register tools and resources on your MCP server
@mcp-ui/server
createUIResource and helpers for Ruby and Python
@mcp-ui/client
AppRenderer and AppFrame for hosts
Server Side With ext-apps
For an MCP server, the install command from the repository looks like this:
The server package gives you two helpers, registerAppTool and registerAppResource, plus the RESOURCE_MIME_TYPE constant. One adds UI metadata to a tool, and the other serves the HTML bundle.
View Side With the App Class
The View is the page that runs inside the iframe. Its App class talks to the host through a PostMessageTransport. You create the app, set handlers such as ontoolresult, and call connect(). From there the View can call server tools with callServerTool and push notes back to the model with updateModelContext.
Host Side With AppRenderer
If you build your own chat client, AppRenderer from @mcp-ui/client is the high-level component. It needs an MCP client, a toolName, a sandbox URL, and the toolInput and toolResult of the call. Callbacks such as onOpenLink and onMessage let the host decide what a View may do. AppFrame is the lower-level option for HTML you fetched yourself.
Working Code Examples
A Tool That Returns the Time
This server code follows the official quickstart. A tool named get-time is linked to a ui:// resource, and the resource handler reads a bundled HTML file.
import { z } from "zod";
import fs from "node:fs/promises";
import path from "node:path";
import {
registerAppResource,
registerAppTool,
RESOURCE_MIME_TYPE,
} from "@modelcontextprotocol/ext-apps/server";
const DIST_DIR = path.join(process.cwd(), "dist");
const resourceUri = "ui://get-time/mcp-app.html";
registerAppTool(
server,
"get-time",
{
title: "Get Time",
description: "Returns the current server time.",
inputSchema: z.object({}),
_meta: { ui: { resourceUri } },
},
async () => {
const time = new Date().toISOString();
return { content: [{ type: "text", text: time }] };
},
);
registerAppResource(
server,
resourceUri,
resourceUri,
{ mimeType: RESOURCE_MIME_TYPE },
async () => {
const html = await fs.readFile(path.join(DIST_DIR, "mcp-app.html"), "utf-8");
return {
contents: [{ uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html }],
};
},
);
Notice how little there is: one tool, one resource and one metadata field tying them together.
The View That Calls It
The View receives the first result through ontoolresult and can ask the server for fresh data when the user clicks a button.
This one call is what turns a static widget into part of the conversation.
Which One Should You Pick
The honest answer is that most new projects should start from the MCP Apps standard and treat MCP-UI as a toolbox that sits beside it.
Choose the MCP Apps SDK when:
You are starting a new TypeScript project and want the official, host-neutral path.
You want one interface to render in several hosts, such as Claude, VS Code, Goose and ChatGPT.
You want the React hooks, or app-bridge to embed Views in your own chat client.
Your tool runs long jobs. Image and video generation is asynchronous: a tool starts a job, then something polls until it finishes. A View with a progress bar and a result gallery beats a text log every time.
Keep the MCP-UI helpers when:
Your server is written in Ruby or Python and you want mcp_ui_server or mcp-ui-server.
You already ship createUIResource output and it renders correctly in your hosts.
You want AppRenderer as a ready-made renderer inside a client you control.
A short migration checklist:
Add _meta.ui.resourceUri to every tool that has an interface.
Serve the HTML from a ui:// resource with the MIME type text/html;profile=mcp-app.
Replace embedded UI payloads in tool responses with resource pointers.
Move View logic onto the App class and read results in ontoolresult.
Test in at least two hosts before you release.
How to Use Sonnet 5 on PicassoIA
Views are mostly HTML, CSS and a thin layer of TypeScript, which is exactly the work a coding model handles well. Claude Sonnet 5 on Picasso IA is built for multi-step coding and tool-use tasks, reads screenshots and wireframes, and can draft a first version of a server, a View or a host wrapper from a plain request.
Fill the required field.prompt is the only required parameter. Try: "Write a TypeScript MCP server tool named show-chart that registers a ui:// resource, plus a View using the App class that renders a bar chart from the tool result."
Set the effort level. The default is low, which turns thinking off for the fastest answer. Raise it to high or max when the task touches several files, such as a server, a View and a build step together.
Add a system prompt. Fix a role once, for example: "You write MCP Apps code with @modelcontextprotocol/ext-apps and never inline secrets in HTML." It then applies across the session.
Attach an image if you have one. The optional image parameter accepts a wireframe or a screenshot, scaled by max_image_resolution to save time and money.
Generate and review. Output can run up to 8,192 tokens by default. Copy the code, then test it in a host.
Parameter
Required
Default
Use it for
prompt
Yes
None
The request itself
effort
No
low
How much the model thinks before answering
max_tokens
No
8192
Capping output length
system_prompt
No
Empty
Role and coding style
image
No
None
A wireframe or screenshot as context
max_image_resolution
No
0.5 megapixels
Scaling the image down before it is sent
💡 Tip: Paste the snippets from this article into your prompt as reference. The model then matches the real API names instead of guessing them.
Create Your Own Visuals Today
Every MCP App ends up needing pictures: a hero image for a landing page, product shots for a gallery View, a short clip for a demo. Picasso IA puts the models for all of that in one place, so you can test ideas before you wire anything into a server.
Start with stills from Seedream 5 Pro, and give the prompt a lens, a light direction and a texture to get a photographic result.
Turn the best frame into motion with Seedance 2.0, which pairs video with built-in audio.
Keep the code side moving with Claude Sonnet 5, using the steps above.
Pick one prompt, generate one image, and see how far a single idea goes. Then open the Picasso IA model collection and try a second model on the same prompt. The comparison alone will teach you what each one does best.