← Alle Playbooks
Playbook· build

MCP App bauen: interaktive UI in deinem MCP-Tool statt Text-Wand

Wie du deinem MCP-Server ein Dashboard, ein Formular oder eine Karte gibst, das direkt im Chat rendert. Mit dem offiziellen ext-apps Package, Schritt für Schritt.

Dein MCP-Tool gibt Daten zurück, und der User will sie sortieren, filtern, durchklicken. Mit reinem Text heißt das: jede Interaktion ist ein neuer Prompt. "Zeig mir nur die von letzter Woche." "Sortier nach Umsatz." "Was steht in Zeile 47?" Das funktioniert, aber es ist zäh. Seit Januar 2026 gibt es dafür MCP Apps, die erste offizielle MCP-Extension. Dein Server kann jetzt eine echte UI zurückgeben, die direkt im Gespräch in einem Sandbox-iframe rendert. Claude unterstützt das, im Web und auf dem Desktop. In diesem Playbook baust du das in deinen bestehenden MCP-Server ein.

Schritt 1, kapier wofür MCP Apps gut sind und wofür nicht

MCP Apps schließen die Lücke zwischen dem, was dein Tool kann, und dem, was der User sieht. Vier Szenarien aus der offiziellen Doku, an denen du merkst ob du es brauchst: ein Sales-Dashboard zum Filtern nach Region, ein Konfigurations-Wizard mit abhängigen Feldern (wählst du "production", erscheinen Security-Optionen), ein Dokument-Review wo der User Klauseln anklickt und das Modell die Entscheidung in Echtzeit sieht, oder ein Live-Monitoring das sich aktualisiert ohne dass das Tool neu läuft.

Wenn dein Tool dagegen nur einen Wert ausspuckt oder einen Satz, lass es bei Text. UI lohnt sich erst wenn der User exploriert, manipuliert oder eine Auswahl trifft. Bau keine UI weil es schick aussieht. Bau sie weil ein Text-Hin-und-Her sonst fünf Prompts braucht.

Schritt 2, prüf ob dein Client es kann

MCP Apps brauchen einen Host der die Extension unterstützt. Stand Launch sind das vier: Claude (Web und Desktop, beide sofort verfügbar), Goose (die Referenz-Implementierung, sofort verfügbar), Visual Studio Code (in den Insiders, nicht im Stable), und ChatGPT. Der Vorteil am offenen Standard: du schreibst die UI einmal und sie läuft in allen unterstützten Clients, ohne eine Zeile client-spezifischen Code.

Wenn dein Zielpublikum auf einem Client sitzt der noch nicht dabei ist, halt den Server so dass er auch ohne UI funktioniert. Ein Tool das ein UI-Resource deklariert soll trotzdem ein sinnvolles Text-Ergebnis liefern, falls der Host die Extension nicht kennt.

Schritt 3, ext-apps installieren

Du brauchst einen bestehenden MCP-Server. Wenn du noch keinen hast, bau erst den (siehe Playbook unten). Dann installierst du das offizielle Package:

npm install @modelcontextprotocol/ext-apps

Aktuelle Version ist 1.7.3. Das Package liefert die App-Klasse für die Kommunikation zwischen deiner UI und dem Host. Auf der Server-Seite arbeitest du mit den MCP-Primitiven die du eh schon kennst, Tools und Resources. Neu ist nur, dass eine Resource jetzt HTML und JavaScript ausliefern kann statt nur Daten.

Schritt 4, eine UI-Resource unter ui:// anlegen

MCP Apps stehen auf zwei Säulen. Die erste ist eine UI-Resource: eine server-seitige Resource die über das ui://-Schema ausgeliefert wird und gebündeltes HTML plus JavaScript enthält. Das ist deine eigentliche Oberfläche, eine kleine Web-App.

Leg dir also eine Resource an deren URI mit ui:// beginnt, zum Beispiel ui://charts/interactive. Der Inhalt ist ein gebündeltes HTML-Dokument. Halt das Bundle klein und in sich geschlossen, denn der Host lädt es und rendert es in einem isolierten iframe. Kein Zugriff auf den Rest der Seite, nur das was du mitlieferst.

Schritt 5, das Tool mit der Resource verknüpfen

Die zweite Säule ist ein Tool mit UI-Metadaten. Du hängst deinem Tool ein _meta.ui.resourceUri-Feld an, das auf die UI-Resource aus Schritt 4 zeigt:

{
  name: "visualize_data",
  description: "Visualize data as an interactive chart",
  inputSchema: { /* ... */ },
  _meta: {
    ui: {
      resourceUri: "ui://charts/interactive"
    }
  }
}

Ruft das Modell jetzt visualize_data auf, sieht der Host die UI-Metadaten, holt sich die Resource und rendert sie im iframe statt einfach Text auszugeben. Achte darauf dass resourceUri exakt auf die URI deiner Resource matcht, ein Tippfehler hier ist der häufigste Grund warum nichts rendert.

Schritt 6, die App im iframe initialisieren

Jetzt zur UI-Seite. In deinem gebündelten HTML startest du die App-Klasse und verbindest dich mit dem Host:

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

const app = new App();
await app.connect();

// Tool-Ergebnisse vom Host empfangen
app.ontoolresult = (result) => {
  renderChart(result.data);
};

app.connect() baut die Verbindung zum Host auf. Der ontoolresult-Handler feuert, wenn das Tool ein Ergebnis liefert, und du rendert damit deine Oberfläche. Die ganze Kommunikation läuft über JSON-RPC über postMessage, du bist also an kein Framework gebunden. React, Vue, Vanilla-JS, alles geht solange es im iframe läuft.

Schritt 7, vom UI zurück zum Server rufen

Das Schöne ist die Zweibahn-Straße. Aus deiner UI kannst du Server-Tools aufrufen, ohne dass der User einen neuen Prompt tippt:

const response = await app.callServerTool({
  name: "fetch_details",
  arguments: { id: "123" },
});

Klickt der User in deinem Dashboard auf Zeile 47, ruft deine UI fetch_details mit der ID auf und zeigt die Details inline. Kein "Was steht in Zeile 47" mehr. Genau das macht den Unterschied zwischen einer Text-Antwort und einer echten App.

Schritt 8, das Modell im Loop halten

Eine UI die das Modell nicht mitkriegt ist nur die Hälfte wert. Mit updateModelContext schiebst du dem Modell still die Info zu was der User gerade gemacht hat:

await app.updateModelContext({
  content: [{ type: "text", text: "User selected option B" }],
});

Damit bleibt das Modell auf dem Laufenden und kann auf die Auswahl reagieren. Apps laufen innerhalb des Clients, deswegen können sie mehr als ein nackter iframe: Events fürs Debugging loggen, Links im Browser des Users öffnen, Follow-up-Nachrichten schicken die das Gespräch weitertreiben, oder eben leise den Modell-Kontext aktualisieren. Nutz das sparsam. Jedes updateModelContext kostet Tokens und zu viel Rauschen verwirrt das Modell.

Schritt 9, das Security-Modell verstehen

Du lässt Code aus einem MCP-Server in deinem Host laufen, also Code den du nicht geschrieben hast. MCP Apps fangen das auf vier Ebenen ab, und du als Server-Autor solltest wissen wogegen du arbeitest. Erstens Iframe-Sandboxing: alle UI läuft in Sandbox-iframes mit eingeschränkten Rechten. Zweitens vordeklarierte Templates: Hosts können das HTML prüfen bevor sie es rendern. Drittens auditierbare Nachrichten: die komplette UI-zu-Host-Kommunikation läuft über loggbares JSON-RPC. Viertens User-Consent: Hosts können explizite Zustimmung verlangen bevor ein UI-initiierter Tool-Call durchgeht.

Heißt für dich: bau so dass dein App auch funktioniert wenn der User einen Consent-Dialog wegklicken muss, und verstecke nichts in der Kommunikation, weil alles geloggt wird. Und sag deinen Usern weiterhin, dass sie MCP-Server gründlich prüfen sollen bevor sie sie verbinden, eine UI macht einen unseriösen Server nicht seriös.

Schritt 10, mit einem Beispiel starten statt bei null anzufangen

Schreib deine erste App nicht auf der grünen Wiese. Das ext-apps Repository hat lauffähige Beispiele die fast jeden Standardfall abdecken: threejs-server für 3D-Visualisierung, map-server für interaktive Karten, pdf-server fürs Dokumente-Anzeigen, system-monitor-server für Echtzeit-Dashboards und sheet-music-server für Notensatz. Such dir das raus das deinem Use-Case am nächsten kommt und bau von dort weiter.

Zum Testen lohnt sich ein Blick auf die MCPJam-Tutorials, die ein echtes App-Beispiel mit Code durchgehen. Und wenn du für Claude.ai baust und auf Probleme mit der Implementierung stößt, gibt es ein eigenes Repo für Bug-Reports unter github.com/anthropics/claude-ai-mcp. Fang klein an, ein einziges Tool mit einer einzigen UI-Resource, und erweiter erst wenn das sauber durch alle Clients läuft die du anvisierst.

Was als nächstes

Wenn du noch keinen MCP-Server hast, fang mit dem Erster MCP-Server in 90 Minuten an und komm dann hierher zurück. Hast du deine App fertig und willst sie verteilen, geht es mit MCP-Server publishen weiter. Und wer das ganze Build-Thema systematisch lernen will, ist in Level 6 mit den Lektionen ab MCP-Server planen richtig.

Source

  • MCP Apps Ankündigung (offiziell): https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps
  • Package: https://www.npmjs.com/package/@modelcontextprotocol/ext-apps (Version 1.7.3)
  • Beispiele und SDK: ext-apps Repository (modelcontextprotocol)