PluginBench
Skill
Pass
Audit score 90

create-mcp-app

modelcontextprotocol/ext-apps

Build interactive UIs for MCP tools with React, Vue, Svelte, or vanilla JavaScript.

What is create-mcp-app?

Create MCP Apps that combine MCP tools with HTML resources to display rich, interactive content inside MCP-enabled hosts like Claude Desktop. Use this skill when scaffolding new MCP Apps, adding UIs to existing tools, or learning MCP Apps SDK patterns and lifecycle management.

  • Scaffold MCP Apps with tool + resource architecture linking LLM-callable tools to bundled HTML UIs
  • Provide framework templates (React with useApp hook, Vue, Svelte, Preact, Solid, vanilla JS) with working examples
  • Guide tool registration with UI metadata, resource serving, and host integration patterns
  • Document lifecycle handlers (ontoolinput, ontoolresult, onhostcontextchanged, onteardown) and event flow
  • Explain advanced patterns: polling, chunked responses, binary resources, CSP/CORS, host context, fullscreen mode, streaming input
  • Reference complete API documentation and type definitions from the SDK source

How to install create-mcp-app

npx skills add https://github.com/modelcontextprotocol/ext-apps --skill create-mcp-app
Prerequisites
  • Node.js and npm installed
  • Familiarity with TypeScript (recommended) or JavaScript
  • Understanding of MCP server basics (tools, resources, transports)
  • For React apps: basic React knowledge; for other frameworks: familiarity with that framework
Claude Code
Cursor
Windsurf
Cline

How to use create-mcp-app

  1. 1.Clone the SDK repository to access working templates: git clone --branch v$(npm view @modelcontextprotocol/ext-apps version) --depth 1 https://github.com/modelcontextprotocol/ext-apps.git /tmp/mcp-ext-apps
  2. 2.Choose a framework template from /tmp/mcp-ext-apps/examples/basic-server-{framework}/ (react, vue, svelte, preact, solid, or vanillajs)
  3. 3.Copy the template and install dependencies with npm install, ensuring you use npm install (not manual version numbers) for @modelcontextprotocol packages at ^2.0.0
  4. 4.Register handlers (ontoolinput, ontoolresult, onhostcontextchanged, onteardown) BEFORE calling app.connect()
  5. 5.Build with npm run build and test locally using basic-host: SERVERS='["http://localhost:3001/mcp"]' npm run start in /tmp/mcp-ext-apps/examples/basic-host/
  6. 6.Configure CSP and CORS in the _meta.ui object of resource contents if making network requests
  7. 7.Deploy your server and register it with an MCP-enabled host like Claude Desktop

Use cases

Good for
  • Building a dashboard MCP App that displays real-time data fetched by a tool
  • Adding an interactive UI to an existing MCP server tool without rewriting the backend
  • Creating a React-based form that collects user input and sends it to an MCP tool
  • Developing a Vue app that polls a tool endpoint and updates a live chart
  • Scaffolding a new MCP server with both CLI tools and a web-based UI component
Who it's for
  • MCP server developers building interactive applications
  • Teams familiar with React, Vue, Svelte, or vanilla JavaScript
  • Developers integrating MCP Apps into Claude Desktop or other MCP-enabled hosts
  • Engineers adding rich UIs to existing MCP tools without backend changes

create-mcp-app FAQ

What is the difference between a tool and a resource in an MCP App?

A tool is called by the LLM/host and returns data; a resource serves the bundled HTML UI that displays that data. The tool's _meta.ui.resourceUri references the resource's URI, linking them together.

Which framework should I choose for my MCP App?

React is best if your team is familiar with it (useApp hook provided); vanilla JS for simple apps with no build complexity; Vue, Svelte, Preact, or Solid based on framework preference. All require manual lifecycle management except React's useApp hook.

Why do I get CSP errors when my MCP App makes network requests?

MCP Apps HTML is served as an MCP resource with no same-origin server, so ALL network requests require CSP configuration. Set _meta.ui.csp and _meta.ui.domain in the contents[] objects returned by registerAppResource(), not in the config object.

How do I test my MCP App locally before deploying?

Use the basic-host example from the cloned SDK repo: build your server with npm run build, run it on localhost:3001, then run basic-host with SERVERS='["http://localhost:3001/mcp"]' npm run start and open http://localhost:8080.

What is the correct order for setting up an MCP App?

Create an App instance, register ALL handlers (ontoolinput, ontoolresult, onhostcontextchanged, onteardown) BEFORE calling app.connect(). Registering handlers after connect() will not work.

Full instructions (SKILL.md)

Source of truth, from modelcontextprotocol/ext-apps.


name: create-mcp-app description: This skill should be used when the user asks to "create an MCP App", "add a UI to an MCP tool", "build an interactive MCP View", "scaffold an MCP App", or needs guidance on MCP Apps SDK patterns, UI-resource registration, MCP App lifecycle, or host integration. Provides comprehensive guidance for building MCP Apps with interactive UIs.

Create MCP App

Build interactive UIs that run inside MCP-enabled hosts like Claude Desktop. An MCP App combines an MCP tool with an HTML resource to display rich, interactive content.

Core Concept: Tool + Resource

Every MCP App requires two parts linked together:

  1. Tool - Called by the LLM/host, returns data
  2. Resource - Serves the bundled HTML UI that displays the data

The tool's _meta.ui.resourceUri references the resource's URI.

Host calls tool → Host renders resource UI → Server returns result → UI receives result.

Quick Start Decision Tree

Framework Selection

FrameworkSDK SupportBest For
ReactuseApp hook providedTeams familiar with React
Vanilla JSManual lifecycleSimple apps, no build complexity
Vue/Svelte/Preact/SolidManual lifecycleFramework preference

Project Context

Adding to existing MCP server:

  • Import registerAppTool, registerAppResource from SDK
  • Add tool registration with _meta.ui.resourceUri
  • Add resource registration serving bundled HTML

Creating new MCP server:

  • Set up server with transport (stdio or HTTP)
  • Register tools and resources
  • Configure build system with vite-plugin-singlefile

Getting Reference Code

Clone the SDK repository for working examples and API documentation:

git clone --branch "v$(npm view @modelcontextprotocol/ext-apps version)" --depth 1 https://github.com/modelcontextprotocol/ext-apps.git /tmp/mcp-ext-apps

Framework Templates

Learn and adapt from /tmp/mcp-ext-apps/examples/basic-server-{framework}/:

TemplateKey Files
basic-server-vanillajs/server.ts, src/mcp-app.ts, mcp-app.html
basic-server-react/server.ts, src/mcp-app.tsx (uses useApp hook)
basic-server-vue/server.ts, src/App.vue
basic-server-svelte/server.ts, src/App.svelte
basic-server-preact/server.ts, src/mcp-app.tsx
basic-server-solid/server.ts, src/mcp-app.tsx

Each template includes:

  • server.ts with registerAppTool and registerAppResource
  • main.ts entry point with HTTP and stdio transport setup
  • Client-side app (e.g., src/mcp-app.ts, src/mcp-app.tsx) with lifecycle handlers
  • src/global.css with global styles and host style variable fallbacks
  • vite.config.ts using vite-plugin-singlefile
  • package.json with npm run scripts and required dependencies
  • .gitignore excluding node_modules/ and dist/

API Reference (Source Files)

Read JSDoc documentation directly from /tmp/mcp-ext-apps/src/:

FileContents
src/app.tsApp class, handlers (ontoolinput, ontoolresult, onhostcontextchanged, onteardown, etc.), lifecycle
src/server/index.tsregisterAppTool, registerAppResource, helper functions
src/spec.types.tsAll type definitions: McpUiHostContext, McpUiStyleVariableKey (CSS variable names), McpUiResourceCsp (CSP configuration), etc.
src/styles.tsapplyDocumentTheme, applyHostStyleVariables, applyHostFonts
src/react/useApp.tsxuseApp hook for React apps

Advanced Patterns

See /tmp/mcp-ext-apps/docs/patterns.md for detailed recipes:

  • App-only tools — visibility: ["app"], hiding tools from model
  • Polling — real-time dashboards, interval management
  • Chunked responses — large files, pagination, base64 encoding
  • Error handling — isError, informing model of failures
  • Binary resources — audio/video/etc via resources/read, blob field
  • Network requests — assets, fetch, CSP, _meta.ui.csp, CORS, _meta.ui.domain
  • Host context — theme, styling, fonts, safe area insets
  • Fullscreen mode — requestDisplayMode, display mode changes
  • Model context — updateModelContext, sendMessage, keeping model informed
  • View state — viewUUID, localStorage, state recovery
  • Visibility-based pause — IntersectionObserver, pausing animations/WebGL
  • Streaming input — ontoolinputpartial, progressive rendering

Reference Host Implementation

/tmp/mcp-ext-apps/examples/basic-host/ shows one way an MCP Apps-capable host could be implemented. Real-world hosts like Claude Desktop are more sophisticated—use basic-host for local testing and protocol understanding, not as a guarantee of host behavior.

Critical Implementation Notes

Adding Dependencies

Always use npm install to add dependencies rather than manually writing version numbers:

npm install @modelcontextprotocol/ext-apps @modelcontextprotocol/client@^2.0.0 @modelcontextprotocol/server@^2.0.0 @modelcontextprotocol/node@^2.0.0 @modelcontextprotocol/express@^2.0.0 zod@^4.2.0 express cors
npm install -D typescript vite vite-plugin-singlefile concurrently cross-env @types/node @types/express @types/cors

ext-apps 2.x requires the split base MCP SDK packages (@modelcontextprotocol/client, server, node, express) at ^2.0.0; @modelcontextprotocol/core comes in transitively. Do not add the legacy @modelcontextprotocol/sdk v1 package or substitute unpublished local packages.

TypeScript Server Execution

Unless the user has specified otherwise, use tsx for running TypeScript server files. For example:

npm install -D tsx

npm pkg set scripts.dev="cross-env NODE_ENV=development concurrently 'cross-env INPUT=mcp-app.html vite build --watch' 'tsx --watch main.ts'"

[!NOTE] The SDK examples use bun but generated projects should default to tsx for broader compatibility.

Handler Registration Order

Register ALL handlers BEFORE calling app.connect():

const app = new App({ name: "My App", version: "1.0.0" });

// Register handlers first
app.ontoolinput = (params) => { /* handle input */ };
app.ontoolresult = (result) => { /* handle result */ };
app.onhostcontextchanged = (ctx) => { /* handle context */ };
app.onteardown = async () => { return {}; };
// etc.

// Then connect
await app.connect();

Common Mistakes to Avoid

  1. No text fallback - Always provide content array for non-UI hosts
  2. Missing CSP configuration - MCP Apps HTML is served as an MCP resource with no same-origin server; ALL network requests—even to localhost—require a CSP configuration
  3. CSP or CORS config in wrong _meta object - _meta.ui.csp and _meta.ui.domain go in the contents[] objects returned by registerAppResource()'s read callback, not in registerAppResource()'s config object
  4. Handlers after app.connect() - Register ALL handlers BEFORE calling app.connect()
  5. No streaming for large inputs - Use ontoolinputpartial to show progress during input generation

Testing

Using basic-host

Test MCP Apps locally with the basic-host example:

# 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

Configure SERVERS with a JSON array of your server URLs (default: http://localhost:3001/mcp).

Debug with sendLog

Send debug logs to the host application (rather than just the iframe's dev console):

await app.sendLog({ level: "info", data: "Debug message" });
await app.sendLog({ level: "error", data: { error: err.message } });

Related skills

More from modelcontextprotocol/ext-apps and the wider catalog.

ADadd-app-to-server logo

add-app-to-server

modelcontextprotocol/ext-apps

This skill should be used when the user asks to "add an app to my MCP server", "add UI to my MCP server", "add a view to my MCP tool", "enrich MCP tools with UI", "add interactive UI to existing server", "add MCP Apps to my server", or needs to add interactive UI capabilities to an existing MCP server that already has tools. Provides guidance for analyzing existing tools and adding MCP Apps UI resources.

743 installs
COconvert-web-app logo

convert-web-app

modelcontextprotocol/ext-apps

This skill should be used when the user asks to "add MCP App support to my web app", "turn my web app into a hybrid MCP App", "make my web page work as an MCP App too", "wrap my existing UI as an MCP App", "convert iframe embed to MCP App", "turn my SPA into an MCP App", or needs to add MCP App support to an existing web application while keeping it working standalone. Provides guidance for analyzing existing web apps and creating a hybrid web + MCP App with server-side tool and resource registration.

610 installs
SEself-improvement logo

self-improvement

modelscope.cn

Captures learnings, errors, and corrections to enable continuous improvement. Use when: (1) A command or operation fails unexpectedly, (2) User corrects Claude ('No, that's wrong...', 'Actually...'), (3) User requests a capability that doesn't exist, (4) An external API or tool fails, (5) Claude realizes its knowledge is outdated or incorrect, (6) A better approach is discovered for a recurring task. Also review learnings before major tasks.

783 installsAudited
BA

bailian-cli

modelstudioai/cli

Aliyun Model Studio CLI (bl) — unified AI agent for text, vision, video, audio, search, and knowledge tasks.

18k installs
BA

bailian-finetune

modelstudioai/cli

Agent skill from modelstudioai/cli.

8.8k installs
BA

bailian-gen

modelstudioai/cli

Agent skill from modelstudioai/cli.

8.9k installs