### Running Basic-Host Example Source: https://apps.extensions.modelcontextprotocol.io/api/media/SKILL-1.md Instructions for building and running your server, then starting the basic-host example to test your migrated app. Ensure the SERVERS environment variable is correctly set. ```bash npm run build && npm run serve cd /tmp/mcp-ext-apps/examples/basic-host npm install SERVERS='["http://localhost:3001/mcp"]' npm run start # Open http://localhost:8080 ``` -------------------------------- ### Clone and Run the Test Host Source: https://apps.extensions.modelcontextprotocol.io/api/documents/quickstart.html Commands to clone the ext-apps repository, install dependencies, and start the basic host example. This is typically run in the second terminal. ```bash git clone https://github.com/modelcontextprotocol/ext-apps.git cd ext-apps npm install cd examples/basic-host npm start ``` -------------------------------- ### Build and Run Examples Source: https://apps.extensions.modelcontextprotocol.io/api/media/CONTRIBUTING.md Execute this command to build the examples and then run them. This is useful for testing the final build output. ```bash npm run examples:start ``` -------------------------------- ### Run MCP Apps Examples Locally Source: https://apps.extensions.modelcontextprotocol.io/api/index.html Clone the MCP Apps repository and install dependencies to run all examples locally using the basic-host implementation. Access the examples via http://localhost:8080/. ```bash git clone https://github.com/modelcontextprotocol/ext-apps.git cd ext-apps npm install npm start ``` -------------------------------- ### Clone and Install Dependencies for basic-host Source: https://apps.extensions.modelcontextprotocol.io/api/documents/Testing_MCP_Apps.html Clone the MCP Apps repository and install necessary dependencies to set up the `basic-host` example for local development. ```bash git clone https://github.com/modelcontextprotocol/ext-apps.git cd ext-apps npm install cd examples/basic-host ``` -------------------------------- ### Example: Discover and List Video Resources Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.App.html This example demonstrates how to list server resources, filter for video resources, and populate a select element with them. It includes error handling for the API call. ```javascript try { const result = await app.listServerResources(); const videoResources = result.resources.filter((r) => r.mimeType?.startsWith("video/"), ); videoResources.forEach((resource) => { const option = document.createElement("option"); option.value = resource.uri; option.textContent = resource.description || resource.name; selectElement.appendChild(option); }); } catch (error) { console.error("Failed to list resources:", error); } ``` -------------------------------- ### Start basic-host with Local MCP Server Source: https://apps.extensions.modelcontextprotocol.io/api/documents/Testing_MCP_Apps.html Start the `basic-host` reference implementation, configuring it to connect to a local MCP server. This is useful for local development and testing. ```bash SERVERS='["http://localhost:3001/mcp"]' npm start ``` -------------------------------- ### MCP Server Setup Code Source: https://apps.extensions.modelcontextprotocol.io/api/media/SKILL-3.md Create a server.ts file to set up the MCP server, register tools and resources, and start the server. Ensure CSP domains are added if needed. ```typescript import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; import fs from "node:fs/promises"; import path from "node:path"; import { z } from "zod"; const server = new McpServer({ name: "my-app", version: "1.0.0" }); const resourceUri = "ui://my-app/mcp-app.html"; // Register the tool — inputSchema maps to the app's data sources registerAppTool(server, "show-app", { description: "Displays the app with the given parameters", inputSchema: { query: z.string().describe("The search query") }, _meta: { ui: { resourceUri } }, }, async (args) => { // Process args server-side if needed return { content: [{ type: "text", text: `Showing app for: ${args.query}` }], structuredContent: { query: args.query }, }; }); // Register the HTML resource registerAppResource(server, { uri: resourceUri, name: "My App UI", mimeType: RESOURCE_MIME_TYPE, // Add CSP domains from Step 2 if needed: // _meta: { ui: { connectDomains: ["api.example.com"], resourceDomains: ["cdn.example.com"] } }, }, async () => { const html = await fs.readFile( path.resolve(import.meta.dirname, "dist", "mcp-app.html"), "utf-8", ); return { contents: [{ uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html }] }; }); // Start the server const transport = new StdioServerTransport(); await server.connect(transport); ``` -------------------------------- ### Install Dependencies Source: https://apps.extensions.modelcontextprotocol.io/api/documents/quickstart.html Install the necessary dependencies for your MCP App, including SDKs and development tools. ```bash npm init -y npm install @modelcontextprotocol/ext-apps @modelcontextprotocol/sdk express cors npm install -D typescript vite vite-plugin-singlefile @types/express @types/cors @types/node tsx concurrently cross-env Copy ``` -------------------------------- ### Complete Hybrid Example with MCP App Initialization Source: https://apps.extensions.modelcontextprotocol.io/api/media/SKILL-3.md A comprehensive example demonstrating hybrid app initialization, including MCP-specific handlers for tool input, theme, styles, fonts, and safe area insets. It also includes a fallback for standalone web apps. Requires imports for App, PostMessageTransport, and theming/styling utilities. ```typescript import { App, PostMessageTransport, applyDocumentTheme, applyHostStyleVariables, applyHostFonts } from "@modelcontextprotocol/ext-apps"; const isMcpApp = window.location.origin === "null"; async function initMcpApp(): Promise> { const app = new App({ name: "My App", version: "1.0.0" }); // Register ALL handlers BEFORE connect() const params = await new Promise>((resolve) => { app.ontoolinput = (input) => resolve(input.arguments ?? {}); }); app.onhostcontextchanged = (ctx) => { if (ctx.theme) applyDocumentTheme(ctx.theme); if (ctx.styles?.variables) applyHostStyleVariables(ctx.styles.variables); if (ctx.styles?.css?.fonts) applyHostFonts(ctx.styles.css.fonts); if (ctx.safeAreaInsets) { const { top, right, bottom, left } = ctx.safeAreaInsets; document.body.style.padding = `${top}px ${right}px ${bottom}px ${left}px`; } }; app.onteardown = async () => { return {}; }; await app.connect(new PostMessageTransport()); return params; } async function initStandaloneApp(): Promise> { return Object.fromEntries(new URL(location.href).searchParams); } async function main() { const params = isMcpApp ? await initMcpApp() : await initStandaloneApp(); renderApp(params); // Same rendering logic — no fork needed } main().catch(console.error); ``` -------------------------------- ### Start basic-host with Multiple Local MCP Servers Source: https://apps.extensions.modelcontextprotocol.io/api/documents/Testing_MCP_Apps.html Configure and start the `basic-host` reference implementation to connect to multiple local MCP servers simultaneously. This allows testing interactions with several backend services. ```bash SERVERS='["http://localhost:3001/mcp", "http://localhost:3002/mcp"]' npm start ``` -------------------------------- ### Clone and Install MCP Extensions Repository Source: https://apps.extensions.modelcontextprotocol.io/api/media/CONTRIBUTING.md Clone the repository and install its dependencies to set up your local development environment. ```bash git clone https://github.com/modelcontextprotocol/ext-apps.git cd ext-apps npm install ``` -------------------------------- ### Example Resource URI for Weather Tool Source: https://apps.extensions.modelcontextprotocol.io/api/interfaces/app.McpUiToolMeta.html Provides an example of a resource URI that can be used to display a UI for a tool. This is typically a path to an HTML file. ```string "ui://weather/view.html" ``` -------------------------------- ### Create Project Directory Source: https://apps.extensions.modelcontextprotocol.io/api/documents/quickstart.html Start by creating a project directory for your MCP App. ```bash mkdir my-mcp-app && cd my-mcp-app Copy ``` -------------------------------- ### Example Domain: URL-derived Subdomain Source: https://apps.extensions.modelcontextprotocol.io/api/interfaces/app.McpUiResourceMeta.html An example of a URL-derived subdomain format for a dedicated origin. ```string "www-example-com.oaiusercontent.com" ``` -------------------------------- ### Install MCP Apps SDK Dependencies Source: https://apps.extensions.modelcontextprotocol.io/api/media/SKILL-2.md Install the MCP Apps SDK and Vite for building the application. Framework-specific dependencies may also be required. ```bash npm install @modelcontextprotocol/ext-apps npm install -D vite vite-plugin-singlefile ``` -------------------------------- ### PostMessageTransport Constructor: View Example Source: https://apps.extensions.modelcontextprotocol.io/api/classes/message-transport.PostMessageTransport.html Example demonstrating the instantiation of PostMessageTransport from the view's perspective, targeting the parent window. ```typescript const transport = new PostMessageTransport(window.parent, window.parent); ``` -------------------------------- ### Start Development Environment with Hot Reloading Source: https://apps.extensions.modelcontextprotocol.io/api/media/CONTRIBUTING.md Use this command to start the development server with hot reloading enabled for faster iteration during development. ```bash npm run examples:dev ``` -------------------------------- ### Configure package.json Scripts Source: https://apps.extensions.modelcontextprotocol.io/api/documents/Quickstart.html Set up build and start scripts in your package.json for development and production builds. ```bash npm pkg set type=module npm pkg set scripts.build="tsc --noEmit && tsc -p tsconfig.server.json && cross-env INPUT=mcp-app.html vite build" npm pkg set scripts.start='concurrently "cross-env NODE_ENV=development INPUT=mcp-app.html vite build --watch" "tsx watch main.ts"' ``` -------------------------------- ### Download via resource link (host fetches) Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.App.html This example shows how to download content by providing a resource link, allowing the host to fetch the content. ```APIDOC ## Download via resource link (host fetches) ### Description Downloads content by providing a resource link, which the host will fetch. ### Method ```javascript app.downloadFile ``` ### Parameters #### Request Body - **contents** (array) - Required - An array of content objects to download. - **type** (string) - Required - The type of content, must be "resource_link". - **uri** (string) - Required - The URI of the resource link. - **name** (string) - Optional - The name of the resource. - **mimeType** (string) - Optional - The MIME type of the resource. ### Request Example ```json { "contents": [ { "type": "resource_link", "uri": "https://api.example.com/reports/q4.pdf", "name": "Q4 Report", "mimeType": "application/pdf" } ] } ``` ### Response #### Success Response (200) - **isError** (boolean) - Indicates if an error occurred during the download. ``` -------------------------------- ### Example Domain: Hash-based Subdomain Source: https://apps.extensions.modelcontextprotocol.io/api/interfaces/app.McpUiResourceMeta.html An example of a hash-based subdomain format for a dedicated origin. ```string "a904794854a047f6.claudemcpcontent.com" ``` -------------------------------- ### PostMessageTransport Constructor: Host Example Source: https://apps.extensions.modelcontextprotocol.io/api/classes/message-transport.PostMessageTransport.html Example showing how a host initializes PostMessageTransport to communicate with an iframe, using the iframe's content window. ```typescript const iframe = document.getElementById("app-iframe") as HTMLIFrameElement; const transport = new PostMessageTransport( iframe.contentWindow!, iframe.contentWindow!, ); ``` -------------------------------- ### Server-Side Migration: Before (OpenAI) Source: https://apps.extensions.modelcontextprotocol.io/api/documents/migrate-openai-app.html Example of registering a tool and a UI resource using the OpenAI Apps SDK with its specific metadata structure. ```typescript import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from "zod"; function createServer() { const server = new McpServer({ name: "shop", version: "1.0.0" }); // Register tool with OpenAI metadata server.registerTool( "shopping-cart", { title: "Shopping Cart", description: "Display the user's shopping cart", inputSchema: { userId: z.string() }, annotations: { readOnlyHint: true }, _meta: { "openai/outputTemplate": "ui://view/cart.html", "openai/toolInvocation/invoking": "Loading cart...", "openai/toolInvocation/invoked": "Cart ready", "openai/widgetAccessible": true, }, }, async (args) => { const cart = await getCart(args.userId); return { content: [{ type: "text", text: JSON.stringify(cart) }], structuredContent: { cart }, }; }, ); // Register UI resource server.registerResource( "Cart View", "ui://view/cart.html", { mimeType: "text/html+skybridge" }, async () => ({ contents: [ { uri: "ui://view/cart.html", mimeType: "text/html+skybridge", text: getCartHtml(), _meta: { "openai/widgetCSP": { resource_domains: ["https://cdn.example.com"], connect_domains: ["https://api.example.com"], frame_domains: ["https://embed.example.com"], }, }, }, ], }), ); return server; } ``` -------------------------------- ### Install Project Dependencies Source: https://apps.extensions.modelcontextprotocol.io/api/documents/Quickstart.html Install the required npm packages for your MCP App, including SDKs and development tools. ```bash npm init -y npm install @modelcontextprotocol/ext-apps @modelcontextprotocol/sdk express cors npm install -D typescript vite vite-plugin-singlefile @types/express @types/cors @types/node tsx concurrently cross-env ``` -------------------------------- ### start Source: https://apps.extensions.modelcontextprotocol.io/api/classes/message-transport.PostMessageTransport.html Initiates message listening from the event source by registering a message event listener. This must be called before receiving messages. ```APIDOC ## Methods ### `start(): Promise` Begins listening for messages from the event source. Registers a message event listener on the window. Must be called before messages can be received. #### Returns * `Promise`: A promise that resolves when message listening has started. ``` -------------------------------- ### PostMessageTransport: Start Method Source: https://apps.extensions.modelcontextprotocol.io/api/classes/message-transport.PostMessageTransport.html Invoke the `start` method to begin receiving messages. This action registers a message event listener on the window, which is necessary for message reception. ```typescript start(): Promise ``` -------------------------------- ### Install MCP Apps Skills via Vercel Skills CLI Source: https://apps.extensions.modelcontextprotocol.io/api/documents/Agent_Skills.html Install the MCP Apps skills across different AI coding agents using the Vercel Skills CLI. ```bash npx skills add modelcontextprotocol/ext-apps ``` -------------------------------- ### Manually Install MCP Apps Skills Source: https://apps.extensions.modelcontextprotocol.io/api/documents/Agent_Skills.html Clone the repository to manually install the MCP Apps skills. Copy the skills from the specified directory to your agent's skills directory. ```bash git clone https://github.com/modelcontextprotocol/ext-apps.git ``` -------------------------------- ### Check Host Capabilities After Connection Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.App.html After establishing a connection, check the host's capabilities. This example specifically checks for 'serverTools' support. ```javascript await app.connect(); if (app.getHostCapabilities()?.serverTools) { console.log("Host supports server tool calls"); } ``` -------------------------------- ### Project Directory Structure Source: https://apps.extensions.modelcontextprotocol.io/api/documents/quickstart.html Shows the expected file and directory layout for the MCP application after initial setup. ```plaintext my-mcp-app/ ├── main.ts ├── mcp-app.html ├── package.json ├── server.ts ├── src/ │ └── mcp-app.ts ├── tsconfig.json ├── tsconfig.server.json └── vite.config.ts ``` -------------------------------- ### Install MCP App Dependencies with npm Source: https://apps.extensions.modelcontextprotocol.io/api/media/SKILL.md Use `npm install` to add necessary MCP app and SDK dependencies. Avoid manually specifying version numbers to ensure npm resolves the latest compatible versions. ```bash npm install @modelcontextprotocol/ext-apps @modelcontextprotocol/sdk zod express cors npm install -D typescript vite vite-plugin-singlefile concurrently cross-env @types/node @types/express @types/cors ``` -------------------------------- ### Run Unit Tests with Bun Source: https://apps.extensions.modelcontextprotocol.io/api/media/CONTRIBUTING.md Execute unit tests for the project using Bun. Ensure you have Bun installed and the project dependencies are met. ```bash npm test ``` -------------------------------- ### Configure package.json Scripts Source: https://apps.extensions.modelcontextprotocol.io/api/documents/quickstart.html Configure the scripts in your package.json file for building and starting the MCP App development server. ```bash npm pkg set type=module npm pkg set scripts.build="tsc --noEmit && tsc -p tsconfig.server.json && cross-env INPUT=mcp-app.html vite build" npm pkg set scripts.start='concurrently --raw "cross-env NODE_ENV=development INPUT=mcp-app.html vite build --watch" "tsx watch main.ts"' Copy ``` -------------------------------- ### Use with CSS Selectors Source: https://apps.extensions.modelcontextprotocol.io/api/functions/app.applyDocumentTheme.html Example CSS demonstrating how to use the `data-theme` attribute to apply different styles for dark and light themes. ```css [data-theme="dark"] { --bg-color: #1a1a1a; } [data-theme="light"] { --bg-color: #ffffff; } ``` -------------------------------- ### connect Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.ProtocolWithEvents.html Attaches to a given transport, starts it, and begins listening for messages. This method assumes ownership of the transport and replaces any existing callbacks. ```APIDOC ## connect * connect(transport: Transport): Promise Attaches to the given transport, starts it, and starts listening for messages. The Protocol object assumes ownership of the Transport, replacing any callbacks that have already been set, and expects that it is the only user of the Transport instance going forward. #### Parameters * transport: Transport #### Returns Promise ``` -------------------------------- ### Apply Host Fonts from Host Context Source: https://apps.extensions.modelcontextprotocol.io/api/functions/app.applyHostFonts.html This example shows how to apply fonts when the host context changes or after initial connection. It checks for the presence of `ctx.styles.css.fonts` before calling `applyHostFonts`. ```javascript // Apply when host context changes app.onhostcontextchanged = (ctx) => { if (ctx.styles?.css?.fonts) { applyHostFonts(ctx.styles.css.fonts); } }; // Apply initial fonts after connecting app.connect().then(() => { const ctx = app.getHostContext(); if (ctx?.styles?.css?.fonts) { applyHostFonts(ctx.styles.css.fonts); } }); ``` -------------------------------- ### App Class Initialization and Connection Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.App.html Demonstrates how to instantiate the App class and establish a connection to the host. It also shows how to register event handlers before connecting to ensure no events are missed. ```APIDOC ## App Class Usage ### Description Instantiate the `App` class with your app's information and capabilities, then call `connect()` to establish communication with the host. It's recommended to register event handlers before calling `connect()` to avoid missing any initial events. ### Constructor ```javascript new App(info: AppInfo, capabilities: AppCapabilities) ``` ### Methods - `connect()`: Establishes the transport and performs the handshake with the host. ### Event Handlers - `ontoolinput`: Handler for receiving tool input parameters from the host. - `ontoolinputpartial`: Handler for receiving streaming partial tool arguments. - `ontoolresult`: Handler for receiving tool execution results. - `ontoolcancelled`: Handler for notifications that a tool execution was cancelled. - `onhostcontextchanged`: Handler for changes in the host context (e.g., theme, locale). ### Example ```javascript const app = new App( { name: "WeatherApp", version: "1.0.0" }, {} ); app.ontoolinput = (params) => { console.log("Tool arguments:", params.arguments); }; await app.connect(); ``` ``` -------------------------------- ### Fetch updated weather data Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.App.html Example of how to call a server-side tool to get updated weather data for a specified location. ```APIDOC ## Fetch updated weather data ### Description Example of how to call a server-side tool to get updated weather data for a specified location. ### Code Example ```javascript try { const result = await app.callServerTool({ name: "get_weather", arguments: { location: "Tokyo" }, }); if (result.isError) { console.error("Tool returned error:", result.content); } else { console.log(result.content); } } catch (error) { console.error("Tool call failed:", error); } ``` ``` -------------------------------- ### Basic App Initialization and Connection Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.App.html Instantiate the App with basic information and connect to the host. Register handlers before connecting to ensure no notifications are missed. ```javascript const app = new App( { name: "WeatherApp", version: "1.0.0" }, {}, // capabilities ); // Register handlers before connecting to ensure no notifications are missed app.ontoolinput = (params) => { console.log("Tool arguments:", params.arguments); }; await app.connect(); ``` -------------------------------- ### Client-Side Migration Example: Before (OpenAI) Source: https://apps.extensions.modelcontextprotocol.io/api/documents/migrate-openai-app.html This snippet demonstrates typical usage of the OpenAI Apps SDK for applying themes, logging tool inputs/outputs, calling tools, sending messages, reporting height, and opening external links. ```javascript // OpenAI Apps SDK applyTheme(window.openai.theme); console.log("Tool args:", window.openai.toolInput); console.log("Tool result:", window.openai.toolOutput); // Call a tool const result = await window.openai.callTool("get_weather", { city: "Tokyo" }); // Send a message await window.openai.sendFollowUpMessage({ prompt: "Weather updated!" }); // Report height window.openai.notifyIntrinsicHeight(400); // Open link await window.openai.openExternal({ href: "https://example.com" }); ``` -------------------------------- ### Client-Side Migration Example: After (MCP Apps) Source: https://apps.extensions.modelcontextprotocol.io/api/documents/migrate-openai-app.html This snippet shows the equivalent functionality using the MCP Apps SDK. It includes initializing the App, registering event handlers before connecting, connecting to the host, accessing context, calling server tools, sending messages, and opening links. ```javascript import { App } from "@modelcontextprotocol/ext-apps"; const app = new App({ name: "MyApp", version: "1.0.0" }); // Register handlers BEFORE connect (events may occur immediately after connect) app.ontoolinput = (params) => { console.log("Tool args:", params.arguments); }; app.ontoolresult = (params) => { console.log("Tool result:", params.structuredContent); }; app.onhostcontextchanged = (ctx) => { if (ctx.theme) applyTheme(ctx.theme); }; // Connect (auto-detects OpenAI vs MCP) await app.connect(); // Access context applyTheme(app.getHostContext()?.theme); // Call a tool const result = await app.callServerTool({ name: "get_weather", arguments: { city: "Tokyo" }, }); // Send a message await app.sendMessage({ role: "user", content: [{ type: "text", text: "Weather updated!" }], }); // Open link (note: url not href) await app.openLink({ url: "https://example.com" }); ``` -------------------------------- ### Test MCP Apps with basic-host Source: https://apps.extensions.modelcontextprotocol.io/api/media/SKILL.md Instructions for testing MCP Apps locally using the `basic-host` example. This involves running your server in one terminal and the `basic-host` in another, configuring the server URL via the `SERVERS` environment variable. ```bash # Terminal 1: Build and run your server npm run build && npm run serve # Terminal 2: Run basic-host (from cloned repo) cd /tmp/mcp-ext-apps/examples/basic-host npm install SERVERS='["http://localhost:3001/mcp"]' npm run start # Open http://localhost:8080 ``` -------------------------------- ### Install MCP Apps Skills via Claude Code Plugin Source: https://apps.extensions.modelcontextprotocol.io/api/documents/Agent_Skills.html Use these commands to install the MCP Apps skills using the Claude Code plugin marketplace. ```bash /plugin marketplace add modelcontextprotocol/ext-apps ``` ```bash /plugin install mcp-apps@modelcontextprotocol-ext-apps ``` -------------------------------- ### Check for MCP Apps support in server initialization Source: https://apps.extensions.modelcontextprotocol.io/api/functions/server-helpers.getUiCapability.html This example demonstrates how to check for MCP Apps support during server initialization. It registers an app-enhanced tool if the client capabilities include the necessary MIME type, otherwise, it falls back to a text-only handler. ```javascript server.server.oninitialized = () => { const clientCapabilities = server.server.getClientCapabilities(); const uiCap = getUiCapability(clientCapabilities); if (uiCap?.mimeTypes?.includes(RESOURCE_MIME_TYPE)) { // App-enhanced tool registerAppTool( server, "weather", { description: "Get weather information with interactive dashboard", _meta: { ui: { resourceUri: "ui://weather/dashboard" } }, }, weatherHandler, ); } else { // Text-only fallback server.registerTool( "weather", { description: "Get weather information", }, textWeatherHandler, ); } }; ``` -------------------------------- ### Install MCP Apps SDK with npm Source: https://apps.extensions.modelcontextprotocol.io/api/index.html Install the MCP Apps SDK as a dependency for your project using npm. This package provides the necessary tools for building interactive Views. ```bash npm install -S @modelcontextprotocol/ext-apps ``` -------------------------------- ### connect Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.App.html Establishes a connection with the host and performs an initialization handshake. ```APIDOC ## connect ### Description Establish connection with the host and perform initialization handshake. This method performs the following steps: 1. Connects the transport layer 2. Sends `ui/initialize` request with app info and capabilities 3. Receives host capabilities and context in response 4. Sends `ui/notifications/initialized` notification 5. Sets up auto-resize using `setupSizeChangedNotifications` if enabled (default) If initialization fails, the connection is automatically closed and an error is thrown. ### Method `connect(transport?: Transport, options?: RequestOptions): Promise` ### Parameters #### Path Parameters * **transport** (Transport) - Required - Transport layer (typically `PostMessageTransport`). * **options** (RequestOptions) - Optional - Request options for the initialize request. ### Returns A promise that resolves when the connection is established. ### Throws If initialization fails or connection is lost. ### Example ```javascript const app = new App({ name: "MyApp", version: "1.0.0" }, {}); try { await app.connect(new PostMessageTransport(window.parent, window.parent)); console.log("Connected successfully!"); } catch (error) { console.error("Failed to connect:", error); } ``` ### See Also * `McpUiInitializeRequest` for the initialization request structure * `McpUiInitializedNotification` for the initialized notification * `PostMessageTransport` for the typical transport implementation ``` -------------------------------- ### Apply Style Variables from Host Context Source: https://apps.extensions.modelcontextprotocol.io/api/functions/app.applyHostStyleVariables.html This example shows how to use CSS variables in your application's styles and how to apply them when the host context changes or after connecting to the host. ```javascript // Use CSS variables in your styles document.body.style.background = "var(--color-background-primary)"; // Apply when host context changes app.onhostcontextchanged = (ctx) => { if (ctx.styles?.variables) { applyHostStyleVariables(ctx.styles.variables); } }; // Apply initial styles after connecting app.connect().then(() => { const ctx = app.getHostContext(); if (ctx?.styles?.variables) { applyHostStyleVariables(ctx.styles.variables); } }); ``` -------------------------------- ### Basic useApp Hook Usage with Event Handlers Source: https://apps.extensions.modelcontextprotocol.io/api/functions/_modelcontextprotocol_ext-apps_react.useApp.html Demonstrates how to use the useApp hook to create an MCP App and attach common event handlers. The hook manages connection state and provides the app instance. Options are only used on initial mount. ```javascript function MyApp() { const [hostContext, setHostContext] = useState( undefined ); const { app, isConnected, error } = useApp({ appInfo: { name: "MyApp", version: "1.0.0" }, capabilities: {}, onAppCreated: (app) => { app.ontoolinput = (input) => { console.log("Tool input:", input); }; app.ontoolresult = (result) => { console.log("Tool result:", result); }; app.ontoolcancelled = (params) => { console.log("Tool cancelled:", params.reason); }; app.onerror = (error) => { console.log("Error:", error); }; app.onhostcontextchanged = (ctx) => { setHostContext((prev) => ({ ...prev, ...ctx })); }; }, }); if (error) return
Error: {error.message}
; if (!isConnected) return
Connecting...
; return
Theme: {hostContext?.theme}
; } ``` -------------------------------- ### transport Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.ProtocolWithEvents.html Gets the underlying transport layer for the protocol. ```APIDOC ## transport ### Description Gets the underlying transport layer for the protocol. ### Accessor `get transport(): Transport | undefined` ### Returns `Transport | undefined` - The transport layer, or undefined if not available. ``` -------------------------------- ### Build the View using npm Source: https://apps.extensions.modelcontextprotocol.io/api/documents/quickstart.html Command to bundle the View's HTML and TypeScript assets for deployment. This command should be run from the project's root directory. ```bash npm run build ``` -------------------------------- ### transport getter Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.App.html Gets the transport instance associated with the app. ```APIDOC ## transport ### Description Gets the transport instance associated with the app. ### Returns Transport | undefined ``` -------------------------------- ### Start MCP Server with Streamable HTTP Transport (main.ts) Source: https://apps.extensions.modelcontextprotocol.io/api/documents/quickstart.html Starts an MCP server using Streamable HTTP transport in stateless mode. It handles requests on a specified port and includes CORS middleware. Errors during request handling are logged and result in a 500 JSON-RPC error response. ```typescript import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import cors from "cors"; import type { Request, Response } from "express"; import { createServer } from "./server.js"; /** * Starts an MCP server with Streamable HTTP transport in stateless mode. * * @param createServer - Factory function that creates a new McpServer instance per request. */ export async function startStreamableHTTPServer( createServer: () => McpServer, ): Promise { const port = parseInt(process.env.PORT ?? "3001", 10); const app = createMcpExpressApp({ host: "0.0.0.0" }); app.use(cors()); app.all("/mcp", async (req: Request, res: Response) => { const server = createServer(); const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, }); res.on("close", () => { transport.close().catch(() => {}); server.close().catch(() => {}); }); try { await server.connect(transport); await transport.handleRequest(req, res, req.body); } catch (error) { console.error("MCP error:", error); if (!res.headersSent) { res.status(500).json({ jsonrpc: "2.0", error: { code: -32603, message: "Internal server error" }, id: null, }); } } }); const httpServer = app.listen(port, (err) => { if (err) { console.error("Failed to start server:", err); process.exit(1); } console.log(`MCP server listening on http://localhost:${port}/mcp`); }); const shutdown = () => { console.log("\nShutting down..."); httpServer.close(() => process.exit(0)); }; process.on("SIGINT", shutdown); process.on("SIGTERM", shutdown); } /** * Starts an MCP server with stdio transport. * * @param createServer - Factory function that creates a new McpServer instance. */ export async function startStdioServer( createServer: () => McpServer, ): Promise { await createServer().connect(new StdioServerTransport()); } async function main() { if (process.argv.includes("--stdio")) { await startStdioServer(createServer); } else { await startStreamableHTTPServer(createServer); } } main().catch((e) => { console.error(e); process.exit(1); }); ``` -------------------------------- ### Verify build output Source: https://apps.extensions.modelcontextprotocol.io/api/documents/quickstart.html Command to list the contents of the distribution directory, confirming that the bundled HTML file has been created. ```bash $ ls dist/ ``` -------------------------------- ### HTML Entry Point for MCP App Source: https://apps.extensions.modelcontextprotocol.io/api/media/SKILL-3.md Create an mcp-app.html file as the entry point for the MCP App build. This file includes basic HTML structure and points to the main application script. ```html MCP App
``` -------------------------------- ### App Constructor Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.App.html Creates a new MCP App instance with specified application information, capabilities, and options. ```APIDOC ## constructor new App ### Description Create a new MCP App instance. ### Parameters * `_appInfo`: { description?: string; icons?: { mimeType?: string; sizes?: string[]; src: string; theme?: "light" | "dark"; }[]; name: string; title?: string; version: string; websiteUrl?: string; } App identification (name and version) * `_capabilities`: McpUiAppCapabilities = {} Features and capabilities this app provides * `options`: AppOptions = ... Configuration options including `autoResize` behavior ### Returns App ### Example ```typescript const app = new App( { name: "MyApp", version: "1.0.0" }, { tools: { listChanged: true } }, // capabilities { autoResize: true }, // options ); ``` ``` -------------------------------- ### oncreatesamplingmessage Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app-bridge.AppBridge.html Handles the creation of sampling messages. This is an example of how to forward requests to an LLM provider. ```APIDOC ## oncreatesamplingmessage ### Description Handles the creation of sampling messages, allowing for custom logic such as rate limiting, user approval, and cost controls before forwarding to an LLM provider. ### Example ```javascript bridge.oncreatesamplingmessage = async (params, extra) => { // Apply rate limiting, user approval, cost controls here return await myLlmProvider.complete(params, { signal: extra.signal }); }; ``` ### See * `CreateMessageRequest` from @modelcontextprotocol/sdk for the request type * `CreateMessageResult` / `CreateMessageResultWithTools` from @modelcontextprotocol/sdk for result types ``` -------------------------------- ### listTasks Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.ProtocolWithEvents.html Lists tasks, optionally starting from a pagination cursor. Use `client.experimental.tasks.listTasks()` to access this method. ```APIDOC ## listTasks(params?: { cursor?: string }, options?: RequestOptions): Promise<{ _meta?: { "io.modelcontextprotocol/related-task"?: { taskId: string }; progressToken?: string | number; [key: string]: unknown; }; nextCursor?: string; tasks: { createdAt: string; lastUpdatedAt: string; pollInterval?: number; status: "working" | "input_required" | "completed" | "failed" | "cancelled"; statusMessage?: string; taskId: string; ttl: number | null; }[]; [key: string]: unknown; }> ### Description Lists tasks, optionally starting from a pagination cursor. ### Parameters #### Path Parameters * **params** (object) - Optional - * **cursor** (string) - Optional - * **options** (RequestOptions) - Optional - ### Returns Promise<{ _meta?: { "io.modelcontextprotocol/related-task"?: { taskId: string }; progressToken?: string | number; [key: string]: unknown; }; nextCursor?: string; tasks: { createdAt: string; lastUpdatedAt: string; pollInterval?: number; status: "working" | "input_required" | "completed" | "failed" | "cancelled"; statusMessage?: string; taskId: string; ttl: number | null; }[]; [key: string]: unknown; }> ``` -------------------------------- ### Project Directory Structure Source: https://apps.extensions.modelcontextprotocol.io/api/documents/quickstart.html This shows the expected file structure for your project. Ensure these files are present. ```bash my-mcp-app/ ├── main.ts ├── package.json ├── server.ts ├── tsconfig.json ├── tsconfig.server.json └── vite.config.ts ``` -------------------------------- ### Example Usage of onAppCreated Source: https://apps.extensions.modelcontextprotocol.io/api/interfaces/_modelcontextprotocol_ext-apps_react.UseAppOptions.html Demonstrates how to use the `onAppCreated` callback to register an event handler for tool results. ```APIDOC ## Example: Register an event handler ```javascript useApp({ appInfo: { name: "MyApp", version: "1.0.0" }, capabilities: {}, onAppCreated: (app) => { app.ontoolresult = (result) => { console.log("Tool result:", result); }; }, }); ``` ``` -------------------------------- ### Server Listening Message Source: https://apps.extensions.modelcontextprotocol.io/api/documents/quickstart.html Indicates that the MCP server has successfully started and is listening for connections on the specified address. ```plaintext MCP server listening on http://localhost:3001/mcp ``` -------------------------------- ### fallbackNotificationHandler Source: https://apps.extensions.modelcontextprotocol.io/api/classes/app.App.html A handler to invoke for any notification types that do not have their own specific handler installed. It receives a notification object and returns a Promise. ```APIDOC ## `Optional` fallbackNotificationHandler fallbackNotificationHandler?: ( notification: { method: string; params?: { _meta?: { "io.modelcontextprotocol/related-task"?: { taskId: string }; progressToken?: string | number; [key: string]: unknown; }; [key: string]: unknown; }; }, ) => Promise A handler to invoke for any notification types that do not have their own handler installed. ```