PluginBench
Skill
Review
Audit score 70

create-mcp-app

modelcontextprotocol/ext-apps

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

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 (tool called by LLM, resource serves bundled HTML UI)
  • Provide framework templates for React (with useApp hook), Vue, Svelte, Preact, Solid, and vanilla JS
  • Guide handler registration, lifecycle management (ontoolinput, ontoolresult, onhostcontextchanged, onteardown)
  • Support advanced patterns: polling, chunked responses, binary resources, streaming input, fullscreen mode, host context integration
  • Configure CSP and CORS for network requests in MCP resource contexts
  • Enable local testing via basic-host example and debug logging with sendLog

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 and your chosen UI framework (React, Vue, Svelte, etc.)
  • Understanding of MCP server basics (tools, resources, transport)
  • For testing: ability to run local HTTP servers
Claude Code
Cursor
Windsurf
Cline

How to use create-mcp-app

  1. 1.Clone the SDK repository to access templates and API docs: 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, vanillajs, preact, or solid)
  3. 3.Copy the template and install dependencies with npm install
  4. 4.Register your tool with registerAppTool and resource with registerAppResource, linking them via _meta.ui.resourceUri
  5. 5.Implement lifecycle handlers (ontoolinput, ontoolresult, onhostcontextchanged, onteardown) BEFORE calling app.connect()
  6. 6.Build with npm run build and test locally using basic-host (SERVERS='["http://localhost:3001/mcp"]' npm run start from /tmp/mcp-ext-apps/examples/basic-host)
  7. 7.Configure CSP in resource _meta.ui.csp if making network requests; use sendLog for debug output to the host

Use cases

Good for
  • Building a dashboard MCP App that polls data and updates in real-time
  • Adding an interactive UI to an existing MCP tool without rewriting the server
  • Creating a file browser or data visualization tool that streams large responses
  • Integrating theme and styling from the host (Claude Desktop) into your MCP App UI
  • Testing MCP Apps locally before deploying to production hosts
Who it's for
  • Developers building MCP servers with interactive frontends
  • Teams familiar with React, Vue, Svelte, or vanilla JavaScript
  • MCP tool authors wanting to add rich UIs without host-specific code
  • Engineers integrating MCP Apps into Claude Desktop or custom MCP hosts

create-mcp-app FAQ

What's 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, creating the link between them.

Which framework should I use?

React with the useApp hook is recommended for teams familiar with React. Vanilla JS is best for simple apps with no build complexity. Vue, Svelte, Preact, and Solid are supported if you prefer those frameworks.

Why do I need CSP configuration?

MCP Apps HTML is served as an MCP resource with no same-origin server. All network requests—even to localhost—require CSP configuration in _meta.ui.csp within the resource's returned contents.

How do I test my MCP App locally?

Use the basic-host example from the cloned SDK repo. Run your server (npm run build && npm run serve), then in another terminal run basic-host with SERVERS='["http://localhost:3001/mcp"]' npm run start and open http://localhost:8080.

What if I need to show progress during long operations?

Use ontoolinputpartial to handle streaming input and show progressive rendering. For large responses, implement chunked responses with pagination or base64 encoding as documented in /tmp/mcp-ext-apps/docs/patterns.md.

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 toolsvisibility: ["app"], hiding tools from model
  • Polling — real-time dashboards, interval management
  • Chunked responses — large files, pagination, base64 encoding
  • Error handlingisError, 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 moderequestDisplayMode, display mode changes
  • Model contextupdateModelContext, sendMessage, keeping model informed
  • View stateviewUUID, localStorage, state recovery
  • Visibility-based pause — IntersectionObserver, pausing animations/WebGL
  • Streaming inputontoolinputpartial, 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/sdk zod express cors
npm install -D typescript vite vite-plugin-singlefile concurrently cross-env @types/node @types/express @types/cors

This lets npm resolve the latest compatible versions. Never specify version numbers from memory.

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.

2.6k installs
BAbailian-docs-llm-wiki logo

bailian-docs-llm-wiki

modelstudioai/skills

Aliyun Bailian platform technical documentation knowledge base with structured model data, wiki synthesis layer, and raw docs.

1.6k installsAudited
BAbailian-model-recommend logo

bailian-model-recommend

modelstudioai/skills

>-

604 installs