Die Integration von KI-gestützten Assistenten verändert die Art und Weise, wie Nutzer mit Anwendungen interagieren. Doch traditionelle MCP-Server liefern oft nur unstrukturierte JSON-Antworten – ein Problem, das MCP-Apps elegant lösen. Diese Technologie ermöglicht die Entwicklung von eigenständigen, interaktiven Benutzeroberflächen, die direkt in Gesprächen mit KI-Assistenten angezeigt werden. Im Gegensatz zu herkömmlichen Lösungen sind diese UIs plattformunabhängig und funktionieren in jedem MCP-kompatiblen Host, sei es ein Desktop-Client wie Claude Desktop oder ein benutzerdefinierter KI-Assistent.
Mit Angular lassen sich solche MCP-Apps besonders effizient umsetzen. Dieser Leitfaden zeigt, wie Sie eine MCP-App mit Angular entwickeln – von der Einrichtung des Servers bis zur Erstellung zweier verschiedener UIs, die auf einem gemeinsamen Codebase basieren. Sie erfahren zudem, wie Sie Ihre Angular-Anwendung in eine einzige HTML-Datei bündeln, um sie ohne zusätzliche Abhängigkeiten in allen MCP-unterstützten Umgebungen auszuführen.
Architektur: Wie MCP-Apps Server und UI verbinden
MCP-Apps basieren auf einer schlanken Kommunikationsschicht zwischen dem MCP-Server und der Angular-Oberfläche. Die Architektur besteht aus drei zentralen Komponenten:
- MCP-Server: Registriert Tools und Ressourcen und verknüpft jedes Tool mit einem spezifischen UI-Endpunkt.
- Host (AppBridge): Lädt die UI-Ressource und rendert sie in einem sandboxierten iframe innerhalb der Chat-Oberfläche.
- Angular-View: Läuft innerhalb des iframes und nutzt die Bibliothek
@modelcontextprotocol/ext-apps, um bidirektional mit dem Host zu kommunizieren.
Der entscheidende Schritt ist die Bündelung der Anwendung. Mit Vite und dem Plugin vite-plugin-singlefile wird die gesamte Angular-Anwendung in eine einzige HTML-Datei kompiliert. Der Host muss nicht wissen, dass es sich um eine Angular-Anwendung handelt – er lädt einfach die HTML-Datei, wodurch die UI universell mit jedem MCP-konformen System kompatibel wird.
Projektstruktur: Eine minimalistische Angular-MCP-App
Für die Umsetzung empfiehlt sich eine modulare Projektstruktur, die gemeinsame Logik zentralisiert, während spezialisierte UIs für verschiedene Tools ermöglicht werden. Die folgende Ordnerstruktur dient als Ausgangspunkt:
angular-mcp-app/
├── ui-get-time.html # UI-Einstieg für das Tool "Aktuelle Zeit"
├── ui-greeting.html # UI-Einstieg für das Tool "Begrüßung"
├── src/
│ ├── main.ts # Angular-Bootstrap für das Tool "Aktuelle Zeit"
│ ├── app.component.ts # Kernkomponente für Zeitanzeige
│ ├── greeting-main.ts # Angular-Bootstrap für das Tool "Begrüßung"
│ ├── greeting.component.ts # Komponente für personalisierte Begrüßungen
│ ├── shared/
│ │ └── mcp-setup.ts # Gemeinsame Initialisierung und thematische Anpassungen
│ └── global.css # Host-übergreifende Stilvariablen
├── server.ts # MCP-Server mit registrierten Tools und Ressourcen
├── main.ts # Server-Einstiegspunkt (HTTP + stdio)
└── vite.config.ts # Vite-Konfiguration für die Single-File-BündelungDiese Struktur ermöglicht Code-Wiederverwendung, während gleichzeitig klare Trennungen zwischen verschiedenen UI-Workflows erhalten bleiben.
Schritt 1: MCP-Server konfigurieren
Der Server fungiert als Brücke zwischen Ihren Tools und deren zugehörigen UIs. Beginnen Sie mit der Initialisierung eines grundlegenden MCP-Servers und registrieren Sie Tools mit ihren jeweiligen Ressourcen-URIs:
// server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
import fs from "node:fs/promises";
import path from "node:path";
import {
registerAppTool,
registerAppResource,
RESOURCE_MIME_TYPE,
} from "@modelcontextprotocol/ext-apps/server";
const server = new McpServer({
name: "Angular MCP App Server",
version: "1.0.0",
});
// Tool "Aktuelle Zeit" registrieren und mit UI verknüpfen
registerAppTool(server, "get-time", {
title: "Aktuelle Zeit abrufen",
description: "Ruft die aktuelle Serverzeit im ISO-8601-Format ab.",
inputSchema: {},
_meta: {
ui: {
resourceUri: "ui://get-time/ui-get-time.html" // Verknüpft Tool mit UI
}
}
}, async (): Promise<CallToolResult> => {
const time = new Date().toISOString();
return {
content: [{ type: "text", text: time }]
};
});
// UI-Ressource für das Tool registrieren
registerAppResource(
server,
"ui://get-time/ui-get-time.html",
"ui://get-time/ui-get-time.html",
{ mimeType: RESOURCE_MIME_TYPE },
async (): Promise<ReadResourceResult> => {
const html = await fs.readFile(
path.join(DIST_DIR, "ui-get-time.html"),
"utf-8"
);
return {
contents: [{
uri: "ui://get-time/ui-get-time.html",
mimeType: RESOURCE_MIME_TYPE,
text: html
}]
};
}
);Das Feld _meta.ui.resourceUri ist entscheidend, da es dem MCP-Host mitteilt, welche HTML-Datei geladen werden soll, wenn dieses Tool aufgerufen wird. Dies ermöglicht eine nahtlose Integration der Benutzeroberfläche.
Schritt 2: Angular-Einstiegspunkt für die UI erstellen
Jede UI benötigt eine dedizierte HTML-Datei im Projektstammverzeichnis. Diese Datei dient als Bündelungseinstiegspunkt für Vite und muss die Laufzeitabhängigkeiten von Angular enthalten:
<!-- ui-get-time.html -->
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>Aktuelle Zeit</title>
<link rel="stylesheet" href="/src/global.css">
</head>
<body>
<app-root></app-root>
<script type="module" src="/src/main.ts"></script>
</body>
</html>Diese minimale Vorlage verzichtet auf externe Abhängigkeiten und stellt sicher, dass die gebündelte Datei leichtgewichtig und portabel bleibt.
Schritt 3: Angular-Anwendung initialisieren
Angular 19+ vereinfacht diesen Prozess durch zoneless Change Detection, was die Leistung in eingebetteten Kontexten verbessert. Initialisieren Sie Ihre Anwendung mit einem optimierten Setup:
// src/main.ts
import "@angular/compiler";
import { bootstrapApplication } from "@angular/platform-browser";
import { provideZonelessChangeDetection } from "@angular/core";
import { AppComponent } from "./app.component";
import "./global.css";
bootstrapApplication(AppComponent, {
providers: [provideZonelessChangeDetection()],
}).catch((err) => console.error("Bootstrap fehlgeschlagen:", err));Die Komponente selbst integriert sich mit dem MCP-Host über die App-Klasse aus @modelcontextprotocol/ext-apps. Sie kommuniziert über das MessagePort-Protokoll mit dem Host und ermöglicht so eine reibungslose Interaktion zwischen Benutzer und Tool.
Vorteile und Ausblick: Warum Angular für MCP-Apps ideal ist
Die Kombination aus Angular und MCP-Apps bietet mehrere entscheidende Vorteile:
- Plattformunabhängigkeit: Die gebündelte HTML-Datei funktioniert in jedem MCP-kompatiblen System, ohne dass zusätzliche Abhängigkeiten erforderlich sind.
- Wiederverwendbarer Code: Durch die modulare Struktur können Entwickler gemeinsame Logik zentral pflegen und gleichzeitig unterschiedliche UIs für verschiedene Tools erstellen.
- Interaktive Nutzererfahrung: Im Gegensatz zu statischen JSON-Antworten ermöglichen MCP-Apps eine dynamische und ansprechende Nutzerinteraktion direkt im Chatfenster.
Die Technologie befindet sich noch in einer frühen Phase, doch die wachsende Akzeptanz von MCP und die Leistungsfähigkeit moderner Frontend-Frameworks wie Angular deuten auf ein großes Potenzial hin. In Zukunft könnten MCP-Apps noch stärker in den Alltag integriert werden – von personalisierten Assistenten bis hin zu spezialisierten Entwicklungstools. Für Entwickler, die ihre KI-Integration auf das nächste Level heben möchten, ist Angular ein starker Kandidat für die Umsetzung.
Die Kombination aus Angulars robuster Architektur und der Flexibilität von MCP-Apps eröffnet neue Möglichkeiten für die Erstellung intelligenter, interaktiver Anwendungen, die sich nahtlos in bestehende KI-Ökosysteme einfügen.
KI-Zusammenfassung
MCP standartlarına uyumlu yapay zeka asistanlarında etkileşimli Angular arayüzleri nasıl oluşturabilirsiniz? Tüm bağımlılıkları tek bir HTML dosyasına paketlemenin püf noktalarını keşfedin.