#601

Globales Ranking · von 601 Skills

mcp-apps AI Agent Skill

Quellcode ansehen: b-open-io/prompts

Medium

Installation

npx skills add b-open-io/prompts --skill mcp-apps

10

Installationen

MCP Apps

MCP Apps is the first official MCP extension (spec 2026-01-26, co-authored by Anthropic and OpenAI). It enables interactive HTML UIs rendered in sandboxed iframes inside MCP hosts. Extension ID: io.modelcontextprotocol/ui. npm package: @modelcontextprotocol/ext-apps.

MCP Apps bridge the gap between LLM tool calls and rich visual interfaces — the model sees text, users see interactive UIs.

Quick Start

The fastest path is the official create-mcp-app skill from the ext-apps repo:

npx skills add modelcontextprotocol/ext-apps --skill create-mcp-app

Then ask the agent: "Create an MCP App that displays a color picker." For manual setup, see references/build-guide.md.

Architecture

Three layers:

  1. Server — Exposes tools and ui:// resources. Tools declare a _meta.ui.resourceUri pointing to the UI. Resources serve HTML via RESOURCE_MIME_TYPE.
  2. Host — The MCP client (Claude Desktop, ChatGPT, VS Code Copilot). Renders iframes, proxies tool calls from the View, enforces the security sandbox.
  3. View — The HTML app running inside the sandboxed iframe. Uses the App class from @modelcontextprotocol/ext-apps to communicate with the Host.

The View is intentionally thin. All tool calls go through the Host proxy — the View never reaches the network or the MCP server directly.

Server Pattern

Install the package:

npm install @modelcontextprotocol/ext-apps

Register tools and resources using the helper functions:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import {
  registerAppTool,
  registerAppResource,
  RESOURCE_MIME_TYPE,
} from "@modelcontextprotocol/ext-apps/server";
import { readFile } from "fs/promises";

const server = new McpServer({ name: "my-app", version: "1.0.0" });

// Register a tool that exposes a UI
registerAppTool(
  server,
  "my-tool",
  {
    description: "Does something useful",
    inputSchema: { type: "object", properties: {} },
    _meta: {
      ui: { resourceUri: "ui://myapp/index.html" },
    },
  },
  async (args) => ({
    content: [{ type: "text", text: "Model sees this text" }],
    structuredContent: { data: "UI gets this rich data" },
  })
);

// Register the HTML resource
registerAppResource(
  server,
  "ui://myapp/index.html",
  "ui://myapp/index.html",
  { mimeType: RESOURCE_MIME_TYPE },
  async () => ({
    contents: [
      {
        uri: "ui://myapp/index.html",
        mimeType: RESOURCE_MIME_TYPE,
        text: await readFile("dist/index.html", "utf-8"),
      },
    ],
  })
);

ui:// resources use the MIME type text/html;profile=mcp-app. They must be predeclared in the server manifest — dynamic resource generation is not permitted (security requirement for pre-scanning).

View Pattern

The View is the HTML app. Install the client package:

npm install @modelcontextprotocol/ext-apps
import { App } from "@modelcontextprotocol/ext-apps";

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

// CRITICAL: Set handlers BEFORE calling connect()
app.ontoolresult = (result) => {
  // result.structuredContent has rich data for the UI
  // result.content has text (what model sees)
  renderData(result.structuredContent ?? result.content);
};

app.onhostcontextchanged = (ctx) => {
  // Apply host theme, locale, timezone
  applyTheme(ctx.theme);
};

// Connect after handlers are set
await app.connect();

Set ontoolresult before or immediately after connect(). The initial tool result is buffered, so either order works, but setting handlers first is safer to avoid race conditions.

Lifecycle

  1. Discovery — Host reads server manifest, finds io.modelcontextprotocol/ui in experimental capabilities.
  2. Init — Host sends ui/initialize. Server responds with supported UI version.
  3. Data — Model calls tool → Host forwards ui/notifications/tool-input to View → Tool executes → Host forwards ui/notifications/tool-result to View.
  4. Interactive — View calls tools via app.callServerTool(). Host proxies them. Results flow back via ontoolresult.
  5. Teardown — Host sends ui/notifications/resource-teardown when the iframe is destroyed.

Tool Visibility

Control which audience sees each tool:

_meta: {
  ui: {
    resourceUri: "ui://myapp/index.html",
    visibility: ["app"],  // UI-only, hidden from the model
  }
}
Visibility Default Behavior
["model", "app"] Yes Both model and UI can call the tool
["app"] No UI-only tool, hidden from LLM
["model"] No LLM-only, View cannot call it

Use ["app"] for tools that only make sense as UI interactions (pagination, sorting, drill-down).

Build

MCP App Views must be compiled to a single self-contained HTML file. Use Vite with vite-plugin-singlefile:

bun add -d vite vite-plugin-singlefile
// vite.config.ts
import { defineConfig } from "vite";
import { viteSingleFile } from "vite-plugin-singlefile";

export default defineConfig({
  plugins: [viteSingleFile()],
  build: {
    rollupOptions: { input: "src/views/mcp-app.html" },
    outDir: "dist",
    emptyOutDir: false,
  },
});

Any framework works: React, Vue, Svelte, Preact, Solid, or vanilla JS/HTML. The View is just HTML — no special runtime.

CRITICAL: Why bundling is mandatory

Views render inside srcdoc iframes. This means:

  • Bare module imports failimport { App } from "@modelcontextprotocol/ext-apps" cannot resolve without a bundler
  • CDN <script src=""> tags fail — external script tags don't work in srcdoc iframes
  • ALL dependencies must be inlined — JS, CSS, everything bundled into one HTML file
  • Install deps as npm packages (e.g., bun add leaflet), import them in your view TS file, and let Vite bundle them

Tool result viewUUID

Tool results MUST include _meta.viewUUID for the host to create a UI instance:

return {
  content: [{ type: "text", text: "Summary for the model" }],
  structuredContent: { data: richData },
  _meta: { viewUUID: randomUUID() },
};

Theming

The Host provides context via app.onhostcontextchanged:

interface HostContext {
  theme: "light" | "dark" | "system";
  locale: string;          // e.g. "en-US"
  timezone: string;        // e.g. "America/New_York"
  displayMode: "inline" | "fullscreen" | "pip";
  containerDimensions: { width: number; height: number };
  platform: "desktop" | "web" | "mobile";
}

CSS variables provided by the Host sandbox:

:root {
  --color-background-primary: /* host bg */;
  --color-text-primary:       /* host text */;
  --color-border:             /* host border */;
  --color-accent:             /* host accent */;
}

Always include default values — not all hosts provide all CSS variables:

body {
  background: var(--color-background-primary, #ffffff);
  color: var(--color-text-primary, #000000);
}

Display Modes

Mode Use Case
inline Default. Embedded in the chat thread. Good for results, cards, small visualizations.
fullscreen Editors, dashboards, complex tools. Occupies the full panel.
pip Picture-in-picture. Persistent widget that survives scrolling (calendars, timers, music players).

Declare the preferred display mode in _meta.ui:

_meta: {
  ui: {
    resourceUri: "ui://myapp/index.html",
    displayMode: "fullscreen",
  }
}

Progressive Enhancement

Tools degrade gracefully on hosts without UI support. Always populate both content (text for the model) and structuredContent (rich data for the View):

async (args) => ({
  content: [
    { type: "text", text: `Found ${results.length} items: ${summary}` }
  ],
  structuredContent: { items: results, total: results.length },
})

Non-UI hosts display content. UI hosts pass structuredContent to the View. This is the key design principle: MCP Apps are an enhancement, not a replacement.

Capability Negotiation

Declare the extension in the server capabilities:

const server = new McpServer({
  name: "my-app",
  version: "1.0.0",
  capabilities: {
    experimental: {
      "io.modelcontextprotocol/ui": { version: "0.1" },
    },
  },
});

Hosts that do not support MCP Apps ignore this capability and fall back to standard tool behavior.

Reference Files

Detailed protocol and integration documentation:

  • references/protocol.md — JSON-RPC methods, capability negotiation, message schemas
  • references/security.md — Sandbox model, CSP, permissions, audit logging
  • references/patterns.md — App-only tools, streaming, multi-tool calls, state management
  • references/host-integration.md — AppBridge, @mcp-ui/client, AppRenderer, AppFrame
  • references/client-matrix.md — Host support (points to canonical source at modelcontextprotocol.io)
  • references/build-guide.md — Complete project setup, configuration files, testing with Claude and basic-host
  • references/draft-spec-details.md — Draft spec additions: new CSS variables (70+), container dimensions, sandbox proxy, device capabilities, Vercel deployment

Installationen

Installationen 10
Globales Ranking #601 von 601

Sicherheitsprüfung

ath Safe
socket Safe
Warnungen: 0 Bewertung: 90
snyk Medium
EU EU-Hosted Inference API

Power your AI Agents with the best open-source models.

Drop-in OpenAI-compatible API. No data leaves Europe.

Explore Inference API

GLM

GLM 5

$1.00 / $3.20

per M tokens

Kimi

Kimi K2.5

$0.60 / $2.80

per M tokens

MiniMax

MiniMax M2.5

$0.30 / $1.20

per M tokens

Qwen

Qwen3.5 122B

$0.40 / $3.00

per M tokens

So verwenden Sie diesen Skill

1

Install mcp-apps by running npx skills add b-open-io/prompts --skill mcp-apps in your project directory. Führen Sie den obigen Installationsbefehl in Ihrem Projektverzeichnis aus. Die Skill-Datei wird von GitHub heruntergeladen und in Ihrem Projekt platziert.

2

Keine Konfiguration erforderlich. Ihr KI-Agent (Claude Code, Cursor, Windsurf usw.) erkennt installierte Skills automatisch und nutzt sie als Kontext bei der Code-Generierung.

3

Der Skill verbessert das Verständnis Ihres Agenten für mcp-apps, und hilft ihm, etablierte Muster zu befolgen, häufige Fehler zu vermeiden und produktionsreifen Code zu erzeugen.

Was Sie erhalten

Skills sind Klartext-Anweisungsdateien — kein ausführbarer Code. Sie kodieren Expertenwissen über Frameworks, Sprachen oder Tools, das Ihr KI-Agent liest, um seine Ausgabe zu verbessern. Das bedeutet null Laufzeit-Overhead, keine Abhängigkeitskonflikte und volle Transparenz: Sie können jede Anweisung vor der Installation lesen und prüfen.

Kompatibilität

Dieser Skill funktioniert mit jedem KI-Coding-Agenten, der das skills.sh-Format unterstützt, einschließlich Claude Code (Anthropic), Cursor, Windsurf, Cline, Aider und anderen Tools, die projektbezogene Kontextdateien lesen. Skills sind auf Transportebene framework-agnostisch — der Inhalt bestimmt, für welche Sprache oder welches Framework er gilt.

Data sourced from the skills.sh registry and GitHub. Install counts and security audits are updated regularly.

EU Made in Europe

Chat with 100+ AI Models in one App.

Use Claude, ChatGPT, Gemini alongside with EU-Hosted Models like Deepseek, GLM-5, Kimi K2.5 and many more.

App herunterladen:

Kundensupport