mcp-a2ui-vega
mcp-a2ui-vega
Eine MCP-App, deren UI A2UI ist und deren Diagramme Vega-Lite sind.
Bitte Claude um das Ticketverkaufs-Dashboard und es erscheint im Gespräch: Kennzahlen, Diagramme, eine Tabelle der neuesten Bestellungen, eine Ablagefläche für eine CSV. Bitte dann um Änderungen — mach aus dem Verkaufsdiagramm ein Liniendiagramm und zeige die heutigen Verkäufe in Grün, füge eine Heatmap hinzu, wann Leute kaufen — und das Dashboard wird direkt an Ort und Stelle bearbeitet, nicht neu gezeichnet. Lege eine CSV hinein oder füge Zeilen per Skript hinzu, und jedes Diagramm aktualisiert sich von selbst.
Das Dashboard ist kein Bild, das das Modell erzeugt hat. Es ist ein Komponentenbaum, den der Agent aus einem typisierten Katalog zusammengestellt hat, gezeichnet von Googles eigenem A2UI-Renderer (@a2ui/react), gebunden an einen Datensatz, der Änderungen an das Dashboard weitergibt.
Woraus es besteht
Bestandteil | Funktion |
Der A2UI-Katalog – Komponenten-APIs, Funktionen und das daraus erzeugte JSON-Schema-Dokument. Der Vertrag zwischen Agent und Renderer. | |
Die MCP-App-Ansicht: React + | |
Ein Cloudflare Worker: der MCP-Server, der Datensatzspeicher, die Bibliothek für gespeicherte Widgets und die | |
Der Datensatz, basierend auf den realen wöchentlichen Broadway-Einnahmen. | |
Das Skill, das einem Agenten beibringt, diese Dashboards gut zu erstellen und umzugestalten. | |
Datensatz-Builder, Live-Append-Feed, Host-Harness, End-to-End-Test. |
Keine API-Schlüssel. Es gibt kein Modell in diesem Repository. Der Agent ist der jeweilige MCP-Host, der sich verbindet; der Server speichert Zeilen und stellt JSON zusammen; der Renderer ist deterministisch. Die einzigen beteiligten Zugangsdaten sind die Cloudflare-Zugangsdaten, die du zum Bereitstellen des Workers benötigst.
Related MCP server: vegalite-viewer
Was das ist, in A2UIs eigenen Worten
Googles Beitrag A2UI and MCP Apps nennt drei Arten, wie die beiden Protokolle zusammenwirken. Dieses Repository ist Pattern 3: A2UI in MCP Apps – das MCP-App-Bundle bringt seinen eigenen A2UI-Renderer mit, wodurch ein Host, der noch nie von A2UI gehört hat (heute Claude), trotzdem eine vom Agenten zusammengestellte Oberfläche anzeigen kann.
Es ist echtes A2UI, keine Nachahmung. Der Renderer ist @a2ui/react, das den MessageProcessor von @a2ui/web_core steuert – Googles Pakete, unverändert. Das Übertragungsformat sind A2UI-v0.9-Nachrichten: createSurface, updateComponents, updateDataModel. Der Katalog erweitert A2UIs eigenen Basiskatalog, anstatt ihn zu ersetzen, sodass Column, Card und ChoicePicker von ihnen stammen und VegaChart von uns – unter einer gemeinsamen Katalog-ID.
Es implementiert außerdem Pattern 1: A2UI über MCP als zweiten Pfad – dasselbe Dashboard wird als application/a2ui+json unter a2ui://dashboard/ticket_sales ausgeliefert, sodass ein Host mit eigenem A2UI-Renderer (Flutter, Angular, ein nativer Client) es ganz ohne iframe zeichnen kann. Dieses Payload ist das portable Artefakt; die MCP-App ist der Weg, wie alle anderen es zu sehen bekommen.
Wie ein Dashboard live bleibt
agent ──render_dashboard──▶ server ──A2UI messages in _meta──▶ view
┌──────── change stream (SSE) ────────┐
server ──────────────┘ "ticket_sales moved" ▼
▲ view
└── get_dataset_rows, through the host's tool proxy ──── │
│
updateDataModel ──┘ every chart,
tile and table
re-rendersVier Entscheidungen leisten den Großteil der Arbeit:
Zeilen wandern nie durch das Modell. render_dashboard gibt ein Layout und eine Zeilenanzahl zurück. Die Ansicht holt Zeilen selbst mit get_dataset_rows, einem Tool, dessen _meta.ui.visibility auf ["app"] gesetzt ist, sodass es nie in der Tool-Liste des Agents erscheint. Zwölftausend Bestellungen gehören in ein Diagramm, nicht in ein Kontextfenster.
Ein Dashboard ist Komponenten, kein Bild. Eine Diagrammänderung ist ein update_dashboard, das eine ID nennt. Die Filter, die Sortierreihenfolge und die Scrollposition des Nutzers bleiben erhalten, weil nichts anderes angefasst wurde.
Ein Update muss in einer Ansicht rendern, die das Dashboard noch nie gesehen hat. Ein Host kann für jedes Tool-Ergebnis eine neue Ansicht öffnen, anstatt es in die laufende zu lenken – und ein Payload aus reinen updateComponents hat dort nichts zu aktualisieren: A2UI lehnt es mit surface not found ab, und der Nutzer bekommt ein leeres Panel, wo er eine Änderung erbeten hat. Deshalb merkt sich der Server den zusammengesetzten Baum, und jedes Update reist in zwei Formen: _meta['a2ui/messages'] baut die gesamte Oberfläche aus dem Nichts neu auf, _meta['a2ui/patch'] trägt nur das Delta. Die Ansicht wendet an, was zu dem passt, was sie bereits enthält, sodass der Server nie raten muss, mit welcher Ansicht er spricht.
Der Server bestimmt das Wann, der Host trägt weiterhin das Was. MCP hat keinen Server→View-Kanal, deshalb hält die Ansicht einen Änderungsstream direkt zum Worker offen – das Eine, was die App-Ressource in csp.connectDomains erlaubt. Was darüber ankommt, ist eine Benachrichtigung, nie Daten: Die Zeilen werden weiterhin über den Tool-Proxy des Hosts geholt, sodass jedes Datenbyte nachvollziehbar bleibt. Ein untätiges Dashboard stellt überhaupt keine Anfragen, und eine Änderung erreicht es in etwa einer Sekunde.
Jedes Diagramm, auch solche, die der Katalog nie benannt hat
VegaChart akzeptiert eine vollständige Vega-Lite-Spec als Eigenschaft. Eine Heatmap, ein Boxplot, ein facettiertes Small-Multiple – keines davon ist im Katalog, und alle funktionieren, weil die Grenze des Katalogs Arten von Komponenten sind, nicht Arten von Diagrammen.
Wenn dem Nutzer eines gefällt, speichert save_widget es unter seinem Namen, und render_dashboard({widgets: ["sales_by_hour_heatmap"]}) holt es in einem späteren Gespräch zurück – weiterhin an den Live-Datensatz gebunden, sodass es sich wie alles andere aktualisiert.
Die Daten
data/ticket_sales.csv enthält eine Zeile pro Ticketbestellung aus zwölf Broadway-Shows. Die Shows, ihre Theater, Saalgrößen, Woche-für-Woche-Auslastung und Preisniveaus sind echt, aus dem Broadway weekly grosses dataset (Playbill, über TidyTuesday). Die einzelnen Bestellungen sind aus diesen Zahlen modelliert, da die Quelle wöchentlich und aggregiert ist. data/README.md sagt genau, welche Teile was sind.
npm run data:build # rebuild, 90 days ending now
npm run data:append -- --watch 10 # a live feed: new orders every 10sRichte das mit --url https://your-worker.workers.dev auf eine Bereitstellung und beobachte, wie sich das Dashboard bewegt, während du es dir ansiehst – innerhalb einer Sekunde nach jedem Append, weil der Server es ihm sagt.
Ausführen
npm install
npm run data:build # build the dataset (downloads the source CSV once)
npm run build # catalog → renderer → single-file app → worker
npm run dev -w @mcp-a2ui-vega/serverÖffne dann http://localhost:8788/app.html für das Dashboard allein oder http://localhost:8788/ für die Verbindungsanleitung.
In Claude installieren
Stelle zuerst bereit (weiter unten) – auf einen benutzerdefinierten Connector wird aus der Cloud von Anthropic zugegriffen, nicht von deinem Rechner; localhost reicht nicht.
Claude Code, direkt aus diesem Repository:
/plugin marketplace add vpm238/mcp-a2ui-vega
/plugin install a2ui-vega-dashboards@mcp-a2ui-vegaDas installiert den MCP-Server und das Skill zusammen. Die Server-URL steht in .claude-plugin/plugin.json – wenn du deinen eigenen Worker bereitstellst, ändere diese eine Zeile und führe /plugin marketplace update mcp-a2ui-vega aus.
Claude Web oder Desktop: Einstellungen → Connectors → Benutzerdefinierten Connector hinzufügen und füge https://your-worker.workers.dev/mcp ein. Es gibt kein OAuth und keinen Schlüssel. Füge dann das Skill hinzu: Packe den Ordner skills/a2ui-dashboards als Zip – der Ordner selbst muss im Root des Zip liegen – und lade ihn unter Einstellungen → Fähigkeiten → Skills hoch.
Das Skill ist in beiden Fällen optional: Der Server sendet Nutzungshinweise im MCP-Handshake. Es ist das, was die Folgefragen gut macht – eine Komponente zu bearbeiten, statt alles neu zu zeichnen, und sich Diagramme zu merken, die dir gefallen haben.
Bitte dann um das Ticketverkaufs-Dashboard.
Bereitstellen
Der Worker ist das Einzige, das gehostet werden muss. GitHub Pages bekommt die eigenständige Demo.
npx wrangler login
npm run deploy -w @mcp-a2ui-vega/serverDas erstellt den KV-Namespace, falls er noch nicht existiert, schreibt seine ID in wrangler.toml, bündelt die App und die Seed-Daten und führt den Deploy aus.
Oder füge zwei Repository-Secrets hinzu und pushe auf main – der Workflow erledigt alles, einschließlich des Erstellens des Namespace, und überspringt den Deploy mit einer Warnung, anstatt einen Fehler zu werfen, während die Secrets fehlen:
Secret | Was es ist |
| Ein Token aus der Vorlage Edit Cloudflare Workers |
| Deine Account-ID, aus dem Workers-Dashboard |
Derselbe Workflow veröffentlicht die eigenständige Demo auf GitHub Pages, sobald Pages unter Einstellungen → Pages mit der Quelle GitHub Actions aktiviert ist. Solange das nicht der Fall ist, weist der Workflow in einer Warnung darauf hin und bleibt grün.
Test
npm test # dataset and catalog checks
npm run dev -w @mcp-a2ui-vega/server # terminal 1
python3 -m http.server 8479 # terminal 2, at the repo root
node tools/e2e.mjs # a real browser, the real protocolUm dieselbe Testsuite gegen eine Bereitstellung statt gegen einen lokalen Worker auszuführen:
node tools/relay.mjs https://your-worker.workers.dev # terminal 3
SERVER_URL=http://localhost:8790 node tools/e2e.mjsDas Relay existiert, weil ein Browser hinter einem restriktiven Proxy Cloudflare möglicherweise nicht erreicht, während Node es kann; jedes Byte stammt trotzdem aus der echten Bereitstellung. Es puffert Antworten, trägt also keinen Änderungsstream – eine Ansicht dahinter fällt auf Polling zurück, was ebenfalls zu testen lohnt.
tools/e2e.mjs steuert tools/harness.html – einen handgeschriebenen MCP-Apps-Host mit ~120 Zeilen, der bewusst keinen Code mit der App teilt, damit ein Protokollfehler nicht in beiden unbemerkt durchgehen kann. Es prüft die Dinge, die ein Typprüfer nicht prüfen kann: dass das Dashboard gezeichnet wird, dass das Neuzusammenstellen eine Kachel einfärbt, ohne den Rest zu stören, dass angehängte Zeilen unaufgefordert eintreffen, dass ein Filter die Kennzahlen und die Tabelle gemeinsam bewegt und dass ein gespeichertes Widget zurückkommt.
tools/push-latency.mjs misst das, was die Architektur behauptet: Ein untätiges Dashboard stellt keine Anfragen, und eine Änderung erreicht es in etwa einer halben Sekunde mit genau einem Fetch.
node tools/push-latency.mjs https://your-worker.workers.devLizenz
MIT.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables business intelligence chart creation and visualization using Vega-Lite, with data loading and processing capabilities.13Apache 2.0
- AlicenseAqualityCmaintenanceMCP server for creating interactive Vega-Lite data visualizations that render inline in chat via MCP Apps.21MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to compose and edit dashboards through MCP tools, allowing them to manage tabs, widgets, layout, and data bindings via a unified control plane.9MIT
- FlicenseAqualityBmaintenanceMCP server that lets agents create, display, and export rich UI widgets (cards, dashboards, charts, forms) inline in conversations, with interactive iframe support in MCP Apps hosts and PNG image fallback for other clients.3
Related MCP Connectors
Create, browse, remix, collaborate on, and run durable AI workflow nodes from MCP hosts.
Build, deploy, and operate hosted web apps on VibeKit (vibekit.bot) from any MCP client.
MCP Hub: AI service discovery, per-user OAuth, and multi-service workflow orchestration
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/vpm238/mcp-a2ui-vega'
If you have feedback or need assistance with the MCP directory API, please join our Discord server