|
| 1 | +# MCP Apps SDK |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +MCP Apps SDK (`@modelcontextprotocol/ext-apps`) enables MCP servers to display interactive UIs in conversational clients. |
| 6 | + |
| 7 | +Key abstractions: |
| 8 | + |
| 9 | +- **View** - UI running in an iframe, uses `App` class with `PostMessageTransport` to communicate with host |
| 10 | +- **Host** - Chat client embedding the iframe, uses `AppBridge` class to proxy MCP requests |
| 11 | +- **Server** - MCP server that registers tools/resources with UI metadata |
| 12 | + |
| 13 | +Specification (stable): `specification/2026-01-26/apps.mdx` |
| 14 | + |
| 15 | +## Commands |
| 16 | + |
| 17 | +```bash |
| 18 | +# Install dependencies |
| 19 | +npm install |
| 20 | + |
| 21 | +# Build the SDK only (generates schemas + bundles, does not build examples) |
| 22 | +npm run build |
| 23 | + |
| 24 | +# Build everything (SDK + all examples) |
| 25 | +npm run build:all |
| 26 | + |
| 27 | +# Type check + build a single example |
| 28 | +npm run --workspace examples/<example-name> build |
| 29 | + |
| 30 | +# Run all examples (starts server at http://localhost:8080) |
| 31 | +npm start |
| 32 | + |
| 33 | +# Run E2E tests (primary testing mechanism - starts examples server automatically) |
| 34 | +npm run test:e2e |
| 35 | + |
| 36 | +# Run unit tests (E2E tests have broader coverage; unit tests cover specific modules) |
| 37 | +npm test |
| 38 | + |
| 39 | +# Check JSDoc comment syntax and `{@link}` references |
| 40 | +npm exec typedoc -- --treatValidationWarningsAsErrors --emit none |
| 41 | + |
| 42 | +# Regenerate package-lock.json (especially on setups w/ custom npm registry) |
| 43 | +rm -fR package-lock.json node_modules && \ |
| 44 | + docker run --rm -it --platform linux/amd64 -v $PWD:/src:rw -w /src node:latest npm i && \ |
| 45 | + rm -fR node_modules && \ |
| 46 | + npm i --cache=~/.npm-mcp-apps --registry=https://registry.npmjs.org/ |
| 47 | +``` |
| 48 | + |
| 49 | +## Architecture |
| 50 | + |
| 51 | +### SDK Entry Points |
| 52 | + |
| 53 | +- `@modelcontextprotocol/ext-apps` - Main SDK for Apps (`App` class, `PostMessageTransport`) |
| 54 | +- `@modelcontextprotocol/ext-apps/react` - React hooks (`useApp`, `useHostStyleVariables`, etc.) |
| 55 | +- `@modelcontextprotocol/ext-apps/app-bridge` - SDK for hosts (`AppBridge` class) |
| 56 | +- `@modelcontextprotocol/ext-apps/server` - Server helpers (`registerAppTool`, `registerAppResource`) |
| 57 | + |
| 58 | +### Key Source Files |
| 59 | + |
| 60 | +- `src/app.ts` - `App` class extends MCP Protocol, handles guest initialization, tool calls, messaging |
| 61 | +- `src/app-bridge.ts` - `AppBridge` class for hosts, proxies MCP requests, sends tool input/results to guests |
| 62 | +- `src/server/index.ts` - Helpers for MCP servers to register tools/resources with UI metadata |
| 63 | +- `src/types.ts` - Protocol types re-exported from `spec.types.ts` and Zod schemas from `generated/schema.ts` (auto-generated during build) |
| 64 | +- `src/message-transport.ts` - `PostMessageTransport` for iframe communication |
| 65 | +- `src/react/` - React hooks: `useApp`, `useHostStyles`, `useAutoResize`, `useDocumentTheme` |
| 66 | + |
| 67 | +### Protocol Flow |
| 68 | + |
| 69 | +``` |
| 70 | +View (App) <--PostMessageTransport--> Host (AppBridge) <--MCP Client--> MCP Server |
| 71 | +``` |
| 72 | + |
| 73 | +1. Host creates iframe with view HTML |
| 74 | +2. View creates `App` instance and calls `connect()` with `PostMessageTransport` |
| 75 | +3. View sends `ui/initialize` request, receives host capabilities and context |
| 76 | +4. Host sends `sendToolInput()` with tool arguments after initialization |
| 77 | +5. View can call server tools via `app.callServerTool()` or send messages via `app.sendMessage()` |
| 78 | +6. Host sends `sendToolResult()` when tool execution completes |
| 79 | +7. Host calls `teardownResource()` before unmounting iframe |
| 80 | + |
| 81 | +## Documentation |
| 82 | + |
| 83 | +JSDoc `@example` tags should pull type-checked code from companion `.examples.ts` files (e.g., `app.ts` → `app.examples.ts`). Use ` ```ts source="./file.examples.ts#regionName" ` fences referencing `//#region regionName` blocks; region names follow `exportedName_variant` or `ClassName_methodName_variant` pattern (e.g., `useApp_basicUsage`, `App_hostCapabilities_checkAfterConnection`). For whole-file inclusion (any file type), omit the `#regionName`. Run `npm run sync:snippets` to sync. |
| 84 | + |
| 85 | +Standalone docs in `docs/` (listed in `typedoc.config.mjs` `projectDocuments`) can also have type-checked companion `.ts`/`.tsx` files using the same pattern. |
| 86 | + |
| 87 | +## Full Examples |
| 88 | + |
| 89 | +Uses npm workspaces. Full examples in `examples/` are separate packages: |
| 90 | + |
| 91 | +- `basic-server-*` - Starter templates (vanillajs, react, vue, svelte, preact, solid). Use these as the basis for new examples. |
| 92 | +- `basic-host` - Reference host implementation |
| 93 | +- Other examples showcase specific features (charts, 3D, video, etc.) |
| 94 | + |
| 95 | +## Claude Code Plugin |
| 96 | + |
| 97 | +The `plugins/mcp-apps/` directory contains a Claude Code plugin distributed via the plugin marketplace. It provides the following Claude Code skills files: |
| 98 | + |
| 99 | +- `plugins/mcp-apps/skills/create-mcp-app/SKILL.md` — for creating an MCP App |
| 100 | +- `plugins/mcp-apps/skills/migrate-oai-app/SKILL.md` — for migrating an app from the OpenAI Apps SDK to the MCP Apps SDK |
0 commit comments