Add RESOURCE_MIME_TYPE constant (#108)

* Add RESOURCE_MIME_TYPE constant

* Update app-bridge.ts

* update syntax
This commit is contained in:
Olivier Chafik 2025-12-09 19:10:56 +01:00 • committed by GitHub
commit 3ac7c7935b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 24 additions and 20 deletions

View file

@ -1,5 +1,4 @@
import { RESOURCE_URI_META_KEY, type McpUiSandboxProxyReadyNotification } from "@modelcontextprotocol/ext-apps"; import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY, type McpUiSandboxProxyReadyNotification, AppBridge, PostMessageTransport } from "@modelcontextprotocol/ext-apps/app-bridge";
import { AppBridge, PostMessageTransport } from "@modelcontextprotocol/ext-apps/app-bridge";
import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import type { CallToolResult, Tool } from "@modelcontextprotocol/sdk/types.js"; import type { CallToolResult, Tool } from "@modelcontextprotocol/sdk/types.js";
@ -111,7 +110,7 @@ async function getUiResourceHtml(serverInfo: ServerInfo, uri: string): Promise<s
// Per the MCP App specification, "text/html;profile=mcp-app" signals this // Per the MCP App specification, "text/html;profile=mcp-app" signals this
// resource is indeed for an MCP App UI. // resource is indeed for an MCP App UI.
if (content.mimeType !== "text/html;profile=mcp-app") { if (content.mimeType !== RESOURCE_MIME_TYPE) {
throw new Error(`Unsupported MIME type: ${content.mimeType}`); throw new Error(`Unsupported MIME type: ${content.mimeType}`);
} }

View file

@ -5,7 +5,7 @@ import cors from "cors";
import express, { type Request, type Response } from "express"; import express, { type Request, type Response } from "express";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import path from "node:path"; import path from "node:path";
import { RESOURCE_URI_META_KEY } from "../../dist/src/app"; import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "../../dist/src/app";
const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001; const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001;
const DIST_DIR = path.join(import.meta.dirname, "dist"); const DIST_DIR = path.join(import.meta.dirname, "dist");
@ -50,7 +50,7 @@ const server = new McpServer({
contents: [ contents: [
// Per the MCP App specification, "text/html;profile=mcp-app" signals // Per the MCP App specification, "text/html;profile=mcp-app" signals
// to the Host that this resource is indeed for an MCP App UI. // to the Host that this resource is indeed for an MCP App UI.
{ uri: resourceUri, mimeType: "text/html;profile=mcp-app", text: html }, { uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html },
], ],
}; };
}, },

View file

@ -5,7 +5,7 @@ import cors from "cors";
import express, { type Request, type Response } from "express"; import express, { type Request, type Response } from "express";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import path from "node:path"; import path from "node:path";
import { RESOURCE_URI_META_KEY } from "../../dist/src/app"; import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "../../dist/src/app";
const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001; const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001;
const DIST_DIR = path.join(import.meta.dirname, "dist"); const DIST_DIR = path.join(import.meta.dirname, "dist");
@ -50,7 +50,7 @@ const server = new McpServer({
contents: [ contents: [
// Per the MCP App specification, "text/html;profile=mcp-app" signals // Per the MCP App specification, "text/html;profile=mcp-app" signals
// to the Host that this resource is indeed for an MCP App UI. // to the Host that this resource is indeed for an MCP App UI.
{ uri: resourceUri, mimeType: "text/html;profile=mcp-app", text: html }, { uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html },
], ],
}; };
}, },

4
examples/budget-allocator-server/server.ts Normal file → Executable file
View file

@ -16,7 +16,7 @@ import express, { type Request, type Response } from "express";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import path from "node:path"; import path from "node:path";
import { z } from "zod"; import { z } from "zod";
import { RESOURCE_URI_META_KEY } from "../../dist/src/app"; import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "../../dist/src/app";
const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001; const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001;
const DIST_DIR = path.join(import.meta.dirname, "dist"); const DIST_DIR = path.join(import.meta.dirname, "dist");
@ -286,7 +286,7 @@ server.registerResource(
); );
return { return {
contents: [ contents: [
{ uri: resourceUri, mimeType: "text/html;profile=mcp-app", text: html }, { uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html },
], ],
}; };
}, },

View file

@ -7,7 +7,7 @@ import express, { type Request, type Response } from "express";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import path from "node:path"; import path from "node:path";
import { z } from "zod"; import { z } from "zod";
import { RESOURCE_URI_META_KEY } from "../../dist/src/app"; import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "../../dist/src/app";
const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001; const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001;
const DIST_DIR = path.join(import.meta.dirname, "dist"); const DIST_DIR = path.join(import.meta.dirname, "dist");
@ -196,7 +196,7 @@ const server = new McpServer({
contents: [ contents: [
{ {
uri: resourceUri, uri: resourceUri,
mimeType: "text/html;profile=mcp-app", mimeType: RESOURCE_MIME_TYPE,
text: html, text: html,
}, },
], ],

View file

@ -10,7 +10,7 @@ import express, { type Request, type Response } from "express";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import path from "node:path"; import path from "node:path";
import { z } from "zod"; import { z } from "zod";
import { RESOURCE_URI_META_KEY } from "../../dist/src/app"; import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "../../dist/src/app";
import { import {
generateCustomers, generateCustomers,
generateSegmentSummaries, generateSegmentSummaries,
@ -95,7 +95,7 @@ const server = new McpServer({
contents: [ contents: [
{ {
uri: resourceUri, uri: resourceUri,
mimeType: "text/html;profile=mcp-app", mimeType: RESOURCE_MIME_TYPE,
text: html, text: html,
}, },
], ],

View file

@ -10,7 +10,7 @@ import express, { type Request, type Response } from "express";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import path from "node:path"; import path from "node:path";
import { z } from "zod"; import { z } from "zod";
import { RESOURCE_URI_META_KEY } from "../../dist/src/app"; import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "../../dist/src/app";
const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001; const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001;
const DIST_DIR = path.join(import.meta.dirname, "dist"); const DIST_DIR = path.join(import.meta.dirname, "dist");
@ -299,7 +299,7 @@ const server = new McpServer({
contents: [ contents: [
{ {
uri: resourceUri, uri: resourceUri,
mimeType: "text/html;profile=mcp-app", mimeType: RESOURCE_MIME_TYPE,
text: html, text: html,
}, },
], ],

View file

@ -12,7 +12,7 @@ import os from "node:os";
import path from "node:path"; import path from "node:path";
import si from "systeminformation"; import si from "systeminformation";
import { z } from "zod"; import { z } from "zod";
import { RESOURCE_URI_META_KEY } from "../../dist/src/app"; import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "../../dist/src/app";
const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001; const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001;
@ -167,7 +167,7 @@ const server = new McpServer({
contents: [ contents: [
{ {
uri: resourceUri, uri: resourceUri,
mimeType: "text/html;profile=mcp-app", mimeType: RESOURCE_MIME_TYPE,
text: html, text: html,
}, },
], ],

View file

@ -12,7 +12,7 @@ import express, { type Request, type Response } from "express";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import path from "node:path"; import path from "node:path";
import { z } from "zod"; import { z } from "zod";
import { RESOURCE_URI_META_KEY } from "../../dist/src/app"; import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "../../dist/src/app";
const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001; const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3001;
const DIST_DIR = path.join(import.meta.dirname, "dist"); const DIST_DIR = path.join(import.meta.dirname, "dist");
@ -176,7 +176,7 @@ const server = new McpServer({
contents: [ contents: [
{ {
uri: resourceUri, uri: resourceUri,
mimeType: "text/html;profile=mcp-app", mimeType: RESOURCE_MIME_TYPE,
text: html, text: html,
}, },
], ],

View file

@ -60,7 +60,7 @@ import {
McpUiSizeChangedNotificationSchema, McpUiSizeChangedNotificationSchema,
} from "./types"; } from "./types";
export * from "./types"; export * from "./types";
export { RESOURCE_URI_META_KEY } from "./app"; export { RESOURCE_URI_META_KEY, RESOURCE_MIME_TYPE } from "./app";
export { PostMessageTransport } from "./message-transport"; export { PostMessageTransport } from "./message-transport";
/** /**

View file

@ -76,6 +76,11 @@ export * from "./types";
*/ */
export const RESOURCE_URI_META_KEY = "ui/resourceUri"; export const RESOURCE_URI_META_KEY = "ui/resourceUri";
/**
* MIME type for MCP UI resources.
*/
export const RESOURCE_MIME_TYPE = "text/html;profile=mcp";
/** /**
* Options for configuring App behavior. * Options for configuring App behavior.
* *