Agent skill

Create MCP App

by sammcj in sammcj/agentic-coding

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", or needs guidance on MCP Apps SDK patterns, UI-resource registration…

Apache-2.0Auto-check passedAgent Workflows

Install Create MCP App

skills CLI
$ npx skills add sammcj/agentic-coding --skill create-mcp-app -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install sammcj/agentic-coding create-mcp-app --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/sammcj/agentic-coding.git skills-src && mkdir -p .claude/skills && cp -r skills-src/Skills_disabled/create-mcp-app .claude/skills/create-mcp-app && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
create-mcp-app
GitHub stars
162
Token cost
~3k tokens
SKILL.md length
734 words
Files
1
Skills in repo
64
Repo updated
First seen
Licence
Apache-2.0

At a glance

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", or needs guidance on MCP Apps SDK patterns, UI-resource registration…

  • Works in 3 steps: Tool - Called by the LLM/host, returns… → Resource - Serves the bundled HTML UI… → Link - The tool's _meta.ui.resourceUri…
  • Asks to create an MCP App
  • SKILL.md covers Core Concept: Tool + Resource, Quick Start Decision Tree, Getting Reference Code and Critical Implementation Notes, plus 2 more sections
  • Calls npm and git; reaches github.com

What it does

Create MCP App is an agent skill from sammcj/agentic-coding. 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", or needs guidance on MCP Apps SDK patterns, UI-resource registration, MCP App lifecycle, or host integration. Provides guidance for building MCP Apps with interactive UIs.

Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Agent Workflows, covering MCP servers. It works with Model Context Protocol, React, Svelte and Vue.js. The repository describes itself as: Agentic Coding Rules, Templates etc... The licence is Apache-2.0.

When your agent uses it

  • Asks to create an MCP App
  • Add a UI to an MCP tool
  • Build an interactive MCP View
  • Needs guidance on MCP Apps SDK patterns

Example prompts

  • “create an MCP App”
  • “add a UI to an MCP tool”
  • “build an interactive MCP View”
  • “/create-mcp-app”

Requirements

  • Node.js

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. Tool - Called by the LLM/host, returns data
  2. Resource - Serves the bundled HTML UI that displays the data
  3. Link - The tool's _meta.ui.resourceUri references the resource

What it can do on your machine

Read from SKILL.md and the folder at commit 2f25ced. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npm
    • git

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • github.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Create MCP App loads about 3k tokens when it runs. Until then it costs about 79 tokens; SKILL.md has 734 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~79
When it runs · the whole SKILL.md, loaded when a task matches
~3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from sammcj/agentic-coding at commit 2f25ced, republished under its Apache-2.0 licence (© sammcj). 734 words, ~3,000 tokens.

Download SKILL.mdSave it as .claude/skills/create-mcp-app/SKILL.md (or your agent's skills folder).
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", or needs guidance on MCP Apps SDK patterns, UI-resource registration, MCP App lifecycle, or host integration. Provides 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
  3. Link - The tool's _meta.ui.resourceUri references the resource
Host calls tool → Server returns result → Host renders resource UI → 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

Note that if the user prefers to write MCP Servers in Golang or Rust you should ask the user if they have a specific framework in mind for that language and if not help them search for a suitable framework / library that supports MCP Apps.

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:

bash
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:

  • Complete server.ts with registerAppTool and registerAppResource
  • Client-side app with all lifecycle handlers
  • vite.config.ts with vite-plugin-singlefile
  • package.json with all 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), lifecycle
src/server/index.tsregisterAppTool, registerAppResource, tool visibility options
src/spec.types.tsAll type definitions: McpUiHostContext, CSS variable keys, display modes
src/styles.tsapplyDocumentTheme, applyHostStyleVariables, applyHostFonts
src/react/useApp.tsxuseApp hook for React apps
src/react/useHostStyles.tsuseHostStyles, useHostStyleVariables, useHostFonts hooks
Advanced Examples
ExamplePattern Demonstrated
examples/shadertoy-server/Streaming partial input + visibility-based pause/play (best practice for large inputs)
examples/wiki-explorer-server/callServerTool for interactive data fetching
examples/system-monitor-server/Polling pattern with interval management
examples/video-resource-server/Binary/blob resources
examples/sheet-music-server/ontoolinput - processing tool args before execution completes
examples/threejs-server/ontoolinputpartial - streaming/progressive rendering
examples/map-server/updateModelContext - keeping model informed of UI state
examples/transcript-server/updateModelContext + sendMessage - background context updates + user-initiated messages
examples/basic-host/Reference host implementation using AppBridge

Critical Implementation Notes

Adding Dependencies

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

bash
npm install @modelcontextprotocol/ext-apps @modelcontextprotocol/sdk zod

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

TypeScript Server Execution

Use tsx as a devDependency for running TypeScript server files:

bash
npm install -D tsx
json
"scripts": {
  "serve": "tsx server.ts"
}

Note: The SDK examples use bun but generated projects should use tsx for broader compatibility.

Show full SKILL.md (294 more words)Show less
Handler Registration Order

Register ALL handlers BEFORE calling app.connect():

typescript
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 {}; };

// Then connect
await app.connect();
Tool Visibility

Control who can access tools via _meta.ui.visibility:

typescript
// Default: visible to both model and app
_meta: { ui: { resourceUri, visibility: ["model", "app"] } }

// UI-only (hidden from model) - for refresh buttons, form submissions
_meta: { ui: { resourceUri, visibility: ["app"] } }

// Model-only (app cannot call)
_meta: { ui: { resourceUri, visibility: ["model"] } }
Host Styling Integration

Vanilla JS - Use helper functions:

typescript
import { applyDocumentTheme, applyHostStyleVariables, applyHostFonts } from "@modelcontextprotocol/ext-apps";

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);
};

React - Use hooks:

typescript
import { useApp, useHostStyles } from "@modelcontextprotocol/ext-apps/react";

const { app } = useApp({ appInfo, capabilities, onAppCreated });
useHostStyles(app); // Injects CSS variables to document, making var(--*) available

Using variables in CSS - After applying, use var():

css
.container {
  background: var(--color-background-secondary);
  color: var(--color-text-primary);
  font-family: var(--font-sans);
  border-radius: var(--border-radius-md);
}
.code {
  font-family: var(--font-mono);
  font-size: var(--font-text-sm-size);
  line-height: var(--font-text-sm-line-height);
  color: var(--color-text-secondary);
}
.heading {
  font-size: var(--font-heading-lg-size);
  font-weight: var(--font-weight-semibold);
}

Key variable groups: --color-background-*, --color-text-*, --color-border-*, --font-sans, --font-mono, --font-text-*-size, --font-heading-*-size, --border-radius-*. See src/spec.types.ts for full list.

Safe Area Handling

Always respect safeAreaInsets:

typescript
app.onhostcontextchanged = (ctx) => {
  if (ctx.safeAreaInsets) {
    const { top, right, bottom, left } = ctx.safeAreaInsets;
    document.body.style.padding = `${top}px ${right}px ${bottom}px ${left}px`;
  }
};
Streaming Partial Input

For large tool inputs, use ontoolinputpartial to show progress during LLM generation. The partial JSON is healed (always valid), enabling progressive UI updates.

Spec: ui/notifications/tool-input-partial

typescript
app.ontoolinputpartial = (params) => {
  const args = params.arguments; // Healed partial JSON - always valid, fields appear as generated
  // Use args directly for progressive rendering
};

app.ontoolinput = (params) => {
  // Final complete input - switch from preview to full render
};

Use cases:

PatternExample
Code previewShow streaming code in <pre>, render on complete (examples/shadertoy-server/)
Progressive formFill form fields as they stream in
Live chartAdd data points to chart as array grows
Partial renderRender incomplete structured data (tables, lists, trees)

Simple pattern (code preview):

typescript
app.ontoolinputpartial = (params) => {
  codePreview.textContent = params.arguments?.code ?? "";
  codePreview.style.display = "block";
  canvas.style.display = "none";
};
app.ontoolinput = (params) => {
  codePreview.style.display = "none";
  canvas.style.display = "block";
  render(params.arguments);
};
Visibility-Based Resource Management

Pause expensive operations (animations, WebGL, polling) when view scrolls out of viewport:

typescript
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      animation.play(); // or: startPolling(), shaderToy.play()
    } else {
      animation.pause(); // or: stopPolling(), shaderToy.pause()
    }
  });
});
observer.observe(document.querySelector(".main"));
Fullscreen Mode

Request fullscreen via app.requestDisplayMode(). Check availability in host context:

typescript
let currentMode: "inline" | "fullscreen" = "inline";

app.onhostcontextchanged = (ctx) => {
  // Check if fullscreen available
  if (ctx.availableDisplayModes?.includes("fullscreen")) {
    fullscreenBtn.style.display = "block";
  }
  // Track current mode
  if (ctx.displayMode) {
    currentMode = ctx.displayMode;
    container.classList.toggle("fullscreen", currentMode === "fullscreen");
  }
};

async function toggleFullscreen() {
  const newMode = currentMode === "fullscreen" ? "inline" : "fullscreen";
  const result = await app.requestDisplayMode({ mode: newMode });
  currentMode = result.mode;
}

CSS pattern - Remove border radius in fullscreen:

css
.main { border-radius: var(--border-radius-lg); overflow: hidden; }
.main.fullscreen { border-radius: 0; }

See examples/shadertoy-server/ for complete implementation.

Common Mistakes to Avoid

  1. Handlers after connect() - Register ALL handlers BEFORE calling app.connect()
  2. Missing single-file bundling - Must use vite-plugin-singlefile
  3. Forgetting resource registration - Both tool AND resource must be registered
  4. Missing resourceUri link - Tool must have _meta.ui.resourceUri
  5. Ignoring safe area insets - Always handle ctx.safeAreaInsets
  6. No text fallback - Always provide content array for non-UI hosts
  7. Hardcoded styles - Use host CSS variables for theme integration
  8. No streaming for large inputs - Use ontoolinputpartial to show progress during generation

Testing

Using basic-host

Test MCP Apps locally with the basic-host example:

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

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):

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

© sammcj, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in Skills_disabled/create-mcp-app of sammcj/agentic-coding.

Open the folder on GitHubat commit 2f25ced

Compare with similar skills

Create MCP App next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Create MCP App compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Create MCP App this skillsammcj/agentic-coding162—~3kAutomated safety check: PassApache-2.0
Domscribepatchorbit/domscribe194—~3.3kAutomated safety check: NotesMIT
Databuddydatabuddy-analytics/Databuddy1.2k—~2.1kAutomated safety check: PassAGPL-3.0
MCP Server Builder with mcp-usemcp-use/mcp-use11k—~923Automated safety check: PassApache-2.0
Chatgpt App Builderalpic-ai/skybridge2.1k—~1kAutomated safety check: PassMIT
Local DevSmilyOrg/photofield608—~2.4kAutomated safety check: PassMIT

Similar skills

  • Domscribe

    patchorbit/domscribe

    Work with Domscribe — the pixel-to-code bridge. An agent skill from patchorbit/domscribe.

    194 GitHub stars~3.3k tokensUpdated 2 mo ago
    Agent WorkflowsAuto-check: notes
  • Databuddy

    databuddy-analytics/Databuddy

    Integrate Databuddy analytics using the SDK, REST API, or MCP.

    1.2k GitHub stars~2.1k tokensUpdated today
    Backend & APIsAuto-check passed
  • Builds, modifies, debugs, migrates and verifies TypeScript MCP servers and MCP Apps with the mcp-use framework, treating the installed package's types as the source of truth.

    11k GitHub stars~923 tokensUpdated today
    Agent WorkflowsAuto-check passed
  • Chatgpt App Builder

    alpic-ai/skybridge

    Guide developers through creating and updating ChatGPT plugins.

    2.1k GitHub stars~1k tokensUpdated yesterday
    Agent WorkflowsAuto-check passed
  • Local Dev

    SmilyOrg/photofield

    Run, test, and debug the photofield server locally. An agent skill from SmilyOrg/photofield.

    608 GitHub stars~2.4k tokensUpdated 1 mo ago
    Agent WorkflowsAuto-check passed
  • MCP App Builder

    alpic-ai/skybridge

    Guide developers through creating and updating MCP Apps. An agent skill from alpic-ai/skybridge.

    2.1k GitHub stars~906 tokensUpdated yesterday
    Agent WorkflowsAuto-check passed

More from sammcj/agentic-coding

All 64 skills in this repo
  • Yue2 Music

    sammcj/agentic-coding

    A skill your agent uses when generating songs with YuE2, covering a recording via SheetSage2 audio-to-ABC, editing a score or lyrics with melody preservation, or building a reproducible listening…

    162 GitHub stars~2.3k tokensUpdated today
    Auto-check passed
  • Bento Slides

    sammcj/agentic-coding

    A skill your agent uses when creating or editing Bento (.bento.html) slide decks, including any request for a single-file HTML slide deck.

    162 GitHub stars~2.9k tokensUpdated today
    Auto-check passed
  • Idrive Backup

    sammcj/agentic-coding

    A skill your agent uses whenever the user wants you to manage, discuss or diagnose iDrive Backup configuration on macOS

    162 GitHub stars~1.7k tokensUpdated today
    Auto-check: notes
  • Piper Tts Training

    sammcj/agentic-coding

    Train custom TTS voices for Piper (ONNX format) using fine-tuning or from-scratch approaches.

    162 GitHub stars~1.4k tokensUpdated today
    Auto-check passed
  • PPTX To Md

    sammcj/agentic-coding

    Convert a PPTX slide deck into per-slide markdown that preserves both the verbatim text and the meaning of embedded screenshots, diagrams and charts in their original layout positions.

    162 GitHub stars~1.8k tokensUpdated today
    Auto-check passed
  • Skill Creator Primer

    sammcj/agentic-coding

    You MUST load this skill before the skill-creator skill AND before making ANY change to, or conducting a review of ANY Agent Skill.

    162 GitHub stars~9.8k tokensUpdated today
    Auto-check passed

Categories

Questions about Create MCP App

What does Create MCP App do?

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", or needs guidance on MCP Apps SDK patterns, UI-resource registration…. Create MCP App is an agent skill from sammcj/agentic-coding. 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", or needs guidance on MCP Apps SDK patterns, UI-resource registration, MCP App lifecycle, or host integration.

When should I use Create MCP App?

Create MCP App fits situations like: asks to create an MCP App; add a UI to an MCP tool; build an interactive MCP View; needs guidance on MCP Apps SDK patterns.

How do I install Create MCP App in Claude Code?

Run `npx skills add sammcj/agentic-coding --skill create-mcp-app -a claude-code`. Or copy the skill folder (Skills_disabled/create-mcp-app in sammcj/agentic-coding) into .claude/skills/create-mcp-app in your project. Claude Code loads it when a task matches its description.

How do I install Create MCP App in Codex?

Run `npx skills add sammcj/agentic-coding --skill create-mcp-app -a codex`. Or copy the skill folder (Skills_disabled/create-mcp-app in sammcj/agentic-coding) into .agents/skills/create-mcp-app in your project. Codex loads it when a task matches its description.

Can I use Create MCP App in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add sammcj/agentic-coding --skill create-mcp-app -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/create-mcp-app, .gemini/skills/create-mcp-app, .github/skills/create-mcp-app and .opencode/skills/create-mcp-app in your project.

What does Create MCP App need to run?

Going by SKILL.md and its folder, Create MCP App needs the command-line tools its instructions call (npm and git). Our summary lists: Node.js.

Does Create MCP App access the network?

SKILL.md names 1 domain. In commands or code: github.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.

Is Create MCP App safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Create MCP App use?

Create MCP App is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Create MCP App use?

About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Create MCP App?

Skills that share tags, products or a category with Create MCP App: Domscribe (patchorbit/domscribe, 194 stars), Databuddy (databuddy-analytics/Databuddy, 1.2k stars), MCP Server Builder with mcp-use (mcp-use/mcp-use, 11k stars) and Chatgpt App Builder (alpic-ai/skybridge, 2.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Create MCP App?

sammcj (a GitHub user) maintains it in sammcj/agentic-coding, which has 162 GitHub stars. The repository holds 64 skills in this directory. The repository was last updated on October 9, 2026.

Source: sammcj/agentic-coding on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.