Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/simple-host/src/app-host-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export async function readToolUiResourceHtml(
}
const content = resource.contents[0];
let html: string;
const isHtml = (t?: string) => t === "text/html+mcp";
const isHtml = (t?: string) => t === "text/html;profile=mcp-app";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: spaces are allowed before / after the ; and the profile value can be quoted (see spec) so in theory we should test w/ t.match(/text\/html\s*;\s*profile=(mcp-app|"mcp-app")/)


if (
"text" in content &&
Expand Down
6 changes: 3 additions & 3 deletions examples/simple-server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const getServer = async () => {
uri: "ui://raw",
title: "Raw UI Template",
description: "A simple raw HTML UI",
mimeType: "text/html+mcp",
mimeType: "text/html;profile=mcp-app",
},
rawHtml,
);
Expand Down Expand Up @@ -99,7 +99,7 @@ const getServer = async () => {
uri: "ui://vanilla",
title: "Vanilla UI Template",
description: "A simple vanilla JS UI",
mimeType: "text/html+mcp",
mimeType: "text/html;profile=mcp-app",
},
vanillaHtml,
);
Expand Down Expand Up @@ -130,7 +130,7 @@ const getServer = async () => {
uri: "ui://react",
title: "React UI Template",
description: "A React-based UI",
mimeType: "text/html+mcp",
mimeType: "text/html;profile=mcp-app",
},
reactHtml,
);
Expand Down
24 changes: 12 additions & 12 deletions specification/draft/apps.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

## Abstract

This SEP proposes an extension (per SEP-1724) to MCP that enables servers to deliver interactive user interfaces to hosts. MCP Apps introduces a standardized pattern for declaring UI resources via the `ui://` URI scheme, associating them with tools through metadata, and facilitating bidirectional communication between the UI and the host using MCP's JSON-RPC base protocol. This extension addresses the growing community need for rich, interactive experiences in MCP-enabled applications, maintaining security, auditability, and alignment with MCP's core architecture. The initial specification focuses on HTML resources (`text/html+mcp`) with a clear path for future extensions.
This SEP proposes an extension (per SEP-1724) to MCP that enables servers to deliver interactive user interfaces to hosts. MCP Apps introduces a standardized pattern for declaring UI resources via the `ui://` URI scheme, associating them with tools through metadata, and facilitating bidirectional communication between the UI and the host using MCP's JSON-RPC base protocol. This extension addresses the growing community need for rich, interactive experiences in MCP-enabled applications, maintaining security, auditability, and alignment with MCP's core architecture. The initial specification focuses on HTML resources (`text/html;profile=mcp-app`) with a clear path for future extensions.

## Motivation

Expand Down Expand Up @@ -43,7 +43,7 @@ MCP Apps extends the Model Context Protocol to enable servers to deliver interac
- **Bidirectional Communication:** UI iframes communicate with hosts using standard MCP JSON-RPC protocol
- **Security Model:** Mandatory iframe sandboxing with auditable communication

This specification focuses on HTML content (`text/html+mcp`) as the initial content type, with extensibility for future formats.
This specification focuses on HTML content (`text/html;profile=mcp-app`) as the initial content type, with extensibility for future formats.

As an extension, MCP Apps is optional and must be explicitly negotiated between clients and servers through the extension capabilities mechanism (see Capability Negotiation section).

Expand Down Expand Up @@ -87,11 +87,11 @@ interface UIResource {
/**
* MIME type of the UI content
*
* SHOULD be `text/html+mcp` for HTML-based UIs in the initial MVP.
* SHOULD be `text/html;profile=mcp-app` for HTML-based UIs in the initial MVP.
* Other content types are reserved for future extensions.
*
* @example
* "text/html+mcp"
* "text/html;profile=mcp-app"
*/
mimeType: string;

Expand Down Expand Up @@ -168,7 +168,7 @@ The resource content is returned via `resources/read`:
{
contents: [{
uri: string; // Matching UI resource URI
mimeType: "text/html+mcp"; // MUST be "text/html+mcp"
mimeType: "text/html;profile=mcp-app"; // MUST be "text/html;profile=mcp-app"
text?: string; // HTML content as string
blob?: string; // OR base64-encoded HTML
_meta?: {
Expand All @@ -188,7 +188,7 @@ The resource content is returned via `resources/read`:
#### Content Requirements:

- URI MUST start with `ui://` scheme
- `mimeType` MUST be `text/html+mcp` (other types reserved for future extensions)
- `mimeType` MUST be `text/html;profile=mcp-app` (other types reserved for future extensions)
- Content MUST be provided via either `text` (string) or `blob` (base64-encoded)
- Content MUST be valid HTML5 document

Expand Down Expand Up @@ -216,14 +216,14 @@ Example:
"uri": "ui://weather-server/dashboard-template",
"name": "weather_dashboard",
"description": "Interactive weather dashboard widget",
"mimeType": "text/html+mcp"
"mimeType": "text/html;profile=mcp-app"
}

// Resource content with metadata
{
"contents": [{
"uri": "ui://weather-server/dashboard-template",
"mimeType": "text/html+mcp",
"mimeType": "text/html;profile=mcp-app",
"text": "<!DOCTYPE html><html>...</html>",
"_meta": {
"ui" : {
Expand Down Expand Up @@ -919,7 +919,7 @@ Clients advertise MCP Apps support in the initialize request using the extension
"capabilities": {
"extensions": {
"io.modelcontextprotocol/ui": {
"mimeTypes": ["text/html+mcp"]
"mimeTypes": ["text/html;profile=mcp-app"]
}
}
},
Expand All @@ -933,7 +933,7 @@ Clients advertise MCP Apps support in the initialize request using the extension

**Extension Settings:**

- `mimeTypes`: Array of supported content types (REQUIRED, e.g., `["text/html+mcp"]`)
- `mimeTypes`: Array of supported content types (REQUIRED, e.g., `["text/html;profile=mcp-app"]`)

Future versions may add additional settings:

Expand All @@ -946,7 +946,7 @@ Servers SHOULD check client (host would-be) capabilities before registering UI-e

```typescript
const hasUISupport =
clientCapabilities?.extensions?.["io.modelcontextprotocol/ui"]?.mimeTypes?.includes("text/html+mcp");
clientCapabilities?.extensions?.["io.modelcontextprotocol/ui"]?.mimeTypes?.includes("text/html;profile=mcp-app");

if (hasUISupport) {
// Register tools with UI templates
Expand Down Expand Up @@ -1030,7 +1030,7 @@ This proposal synthesizes feedback from the UI CWG and MCP-UI community, host im

#### 3. Support Raw HTML Content Type

**Decision:** MVP supports only `text/html+mcp` (rawHtml), with other types explicitly deferred.
**Decision:** MVP supports only `text/html;profile=mcp-app` (rawHtml), with other types explicitly deferred.

**Rationale:**

Expand Down