fix: use profile parameter for MIME type instead of suffix (#75)

Change MIME type from `text/html+mcp` to `text/html;profile=mcp-app`
to follow RFC 6838 recommendations for custom media types.

The `+suffix` format (like `text/html+mcp`) is intended for structured
syntax suffixes (e.g., `+json`, `+xml`) that describe the underlying
format. Since MCP Apps doesn't define a new syntax but rather a profile
of HTML, using a profile parameter is more semantically correct.

Fixes #59

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Anton Pidkuiko 2025-12-04 18:28:58 +00:00 • committed by GitHub
commit 0af15322af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 16 additions and 16 deletions

View file

@ -89,7 +89,7 @@ export async function readToolUiResourceHtml(
} }
const content = resource.contents[0]; const content = resource.contents[0];
let html: string; let html: string;
const isHtml = (t?: string) => t === "text/html+mcp"; const isHtml = (t?: string) => t === "text/html;profile=mcp-app";
if ( if (
"text" in content && "text" in content &&

View file

@ -68,7 +68,7 @@ const getServer = async () => {
uri: "ui://raw", uri: "ui://raw",
title: "Raw UI Template", title: "Raw UI Template",
description: "A simple raw HTML UI", description: "A simple raw HTML UI",
mimeType: "text/html+mcp", mimeType: "text/html;profile=mcp-app",
}, },
rawHtml, rawHtml,
); );
@ -99,7 +99,7 @@ const getServer = async () => {
uri: "ui://vanilla", uri: "ui://vanilla",
title: "Vanilla UI Template", title: "Vanilla UI Template",
description: "A simple vanilla JS UI", description: "A simple vanilla JS UI",
mimeType: "text/html+mcp", mimeType: "text/html;profile=mcp-app",
}, },
vanillaHtml, vanillaHtml,
); );
@ -130,7 +130,7 @@ const getServer = async () => {
uri: "ui://react", uri: "ui://react",
title: "React UI Template", title: "React UI Template",
description: "A React-based UI", description: "A React-based UI",
mimeType: "text/html+mcp", mimeType: "text/html;profile=mcp-app",
}, },
reactHtml, reactHtml,
); );

View file

@ -7,7 +7,7 @@
## Abstract ## 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 ## Motivation
@ -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 - **Bidirectional Communication:** UI iframes communicate with hosts using standard MCP JSON-RPC protocol
- **Security Model:** Mandatory iframe sandboxing with auditable communication - **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). 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).
@ -87,11 +87,11 @@ interface UIResource {
/** /**
* MIME type of the UI content * 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. * Other content types are reserved for future extensions.
* *
* @example * @example
* "text/html+mcp" * "text/html;profile=mcp-app"
*/ */
mimeType: string; mimeType: string;
@ -168,7 +168,7 @@ The resource content is returned via `resources/read`:
{ {
contents: [{ contents: [{
uri: string; // Matching UI resource URI 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 text?: string; // HTML content as string
blob?: string; // OR base64-encoded HTML blob?: string; // OR base64-encoded HTML
_meta?: { _meta?: {
@ -188,7 +188,7 @@ The resource content is returned via `resources/read`:
#### Content Requirements: #### Content Requirements:
- URI MUST start with `ui://` scheme - 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 provided via either `text` (string) or `blob` (base64-encoded)
- Content MUST be valid HTML5 document - Content MUST be valid HTML5 document
@ -216,14 +216,14 @@ Example:
"uri": "ui://weather-server/dashboard-template", "uri": "ui://weather-server/dashboard-template",
"name": "weather_dashboard", "name": "weather_dashboard",
"description": "Interactive weather dashboard widget", "description": "Interactive weather dashboard widget",
"mimeType": "text/html+mcp" "mimeType": "text/html;profile=mcp-app"
} }
// Resource content with metadata // Resource content with metadata
{ {
"contents": [{ "contents": [{
"uri": "ui://weather-server/dashboard-template", "uri": "ui://weather-server/dashboard-template",
"mimeType": "text/html+mcp", "mimeType": "text/html;profile=mcp-app",
"text": "<!DOCTYPE html><html>...</html>", "text": "<!DOCTYPE html><html>...</html>",
"_meta": { "_meta": {
"ui" : { "ui" : {
@ -919,7 +919,7 @@ Clients advertise MCP Apps support in the initialize request using the extension
"capabilities": { "capabilities": {
"extensions": { "extensions": {
"io.modelcontextprotocol/ui": { "io.modelcontextprotocol/ui": {
"mimeTypes": ["text/html+mcp"] "mimeTypes": ["text/html;profile=mcp-app"]
} }
} }
}, },
@ -933,7 +933,7 @@ Clients advertise MCP Apps support in the initialize request using the extension
**Extension Settings:** **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: Future versions may add additional settings:
@ -946,7 +946,7 @@ Servers SHOULD check client (host would-be) capabilities before registering UI-e
```typescript ```typescript
const hasUISupport = 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) { if (hasUISupport) {
// Register tools with UI templates // Register tools with UI templates
@ -1030,7 +1030,7 @@ This proposal synthesizes feedback from the UI CWG and MCP-UI community, host im
#### 3. Support Raw HTML Content Type #### 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:** **Rationale:**