Dashboard Builder MCP server
Dashboard Builder MCP server
Ermöglicht einem KI-Client, Ihre Datensätze zu entdecken und Dashboards in Dashboard Builder zu erstellen.
Er kommuniziert über HTTP als gewöhnlicher API-Client mit der Next.js-App, sodass alle Berechtigungsprüfungen, Abhängigkeitsrichtlinien und Validierungsregeln in der App weiterhin gelten. An der Hauptanwendung ändert sich nichts.
Sie können ihn auf zwei Arten ausführen:
Wer ihn ausführt | Identität | Benutzer benötigen | |
Gehostet | ein Server, gesamte Organisation | das eigene Konto jeder Person, einmal an ihren Schlüssel gebunden | eine URL und einen Schlüssel |
Lokal | jede Person, eigener Rechner | das eigene Konto dieser Person | Node und eine Kopie dieses Ordners |
Gehostet ist die normale Bereitstellung und wird in diesem Dokument behandelt. Der lokale Modus dient der Entwicklung des Servers selbst oder für eine benutzerspezifische Identität und ist in DEVELOPMENT.md beschrieben.
Für Benutzer: Verbindung zu einem gehosteten Server
Sie benötigen zwei Dinge von der Person, die ihn bereitgestellt hat: die URL und Ihren Gate-Key. Nichts zu klonen, keine Dateien, auf die Sie verweisen müssen, keine .env.
Fügen Sie dies zu claude_desktop_config.json (Claude Desktop) oder .mcp.json (Claude Code) hinzu:
{
"mcpServers": {
"dashboard-builder": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://mcp.yourcompany.com/mcp",
"--header", "Authorization: Bearer YOUR_KEY_HERE",
"--header", "X-Dashboard-Username: you",
"--header", "X-Dashboard-Password: your-dashboard-password"
]
}
}
}mcpServers ist ein Top-Level-Schlüssel, ein Geschwister von preferences – nicht darin verschachtelt. Beenden Sie Claude Desktop über das System-Tray und öffnen Sie es erneut; das Schließen des Fensters reicht nicht aus.
Mit den beiden X-Dashboard-*-Headern meldet sich der Server bei der ersten Verwendung automatisch als Sie an und erneut, wenn die Sitzung abläuft – sonst ist nichts weiter zu tun, und jeder Aufruf handelt als Sie: Ihre Berechtigungen, Ihr Audit-Trail. Der Kompromiss ist, dass Ihr Dashboard-Passwort in dieser Konfigurationsdatei liegt und mit jeder Anfrage (über HTTPS) übertragen wird. Wenn das Passwort Zeichen außerhalb von ASCII enthält, verwenden Sie stattdessen die curl-Bindung unten – HTTP-Header übertragen diese nicht zuverlässig.
Alternative: Einmal mit curl binden, das Passwort aus der Konfiguration heraushalten
Lassen Sie die beiden X-Dashboard-*-Header weg und binden Sie stattdessen Ihren Schlüssel einmal – das Passwort wird für diesen einzelnen Login verwendet und nirgendwo gespeichert; der Server behält nur die resultierenden Sitzungstokens, genau wie ein Browser Cookies speichert:
curl -X POST https://mcp.yourcompany.com/auth/bind \
-H "Authorization: Bearer YOUR_KEY_HERE" \
-H "content-type: application/json" \
-d '{"username":"you","password":"your-dashboard-password"}'Der Unterschied zur Header-Methode: Wenn die Sitzungskette schließlich abläuft, führen Sie diesen Befehl erneut aus, während die Header automatisch neu binden. DELETE /auth/bind mit demselben Authorization-Header meldet den Schlüssel in beiden Fällen ab.
Alice's Claude ──[gate key]──> MCP server ──[Alice's session cookies]──> Dashboard API
^ ^
client config bound via credential headers or
POST /auth/bind; refreshed
automatically after thatAnmeldedaten | Lebt in | Beantwortet |
Gate-Key | in der Client-Konfiguration jedes Benutzers | Darf diese Person den MCP-Server verwenden? |
Sitzungstokens | auf dem Server, eine Datei pro Schlüssel | Als welche Identität handelt dieser Schlüssel? |
Wenn ein Schlüssel nie gebunden wird, schlagen Tool-Aufrufe mit einem Fehler fehl, der den Bindungsschritt erklärt – oder, wenn der Server mit einem Legacy-Dienstkonto konfiguriert ist, fallen sie auf diese gemeinsame Identität zurück.
mcp-remote ist eine kleine Brücke, die lokal läuft und an den Server weiterleitet, daher muss Node auf dem Rechner des Benutzers installiert sein. Um auch das zu vermeiden, akzeptiert Claude Desktops Einstellungen → Connectors → Benutzerdefinierten Connector hinzufügen eine URL direkt ohne lokale Komponenten – dieser Pfad erwartet OAuth anstelle eines statischen Schlüssels, und die Verfügbarkeit variiert je nach Desktop-Version.
Related MCP server: MCP SQL Server Data Warehouse Connector
Bereitstellung des Servers
server.js ist die Startdatei. Sie lauscht auf PORT wie ein Next.js-server.js und setzt ein API-Key-Gate vor jede MCP-Anfrage, sodass nicht authentifizierte Aufrufer abgewiesen werden, bevor etwas das Dashboard-System erreicht.
Endpunkte: POST /mcp (geschützt), POST /auth/bind und DELETE /auth/bind (geschützt – bindet oder entbindet die Dashboard-Identität des aufrufenden Schlüssels) und GET /health (offen, für den Plattform-Health-Check). Alles andere gibt 404 zurück.
Umgebungsvariablen
Erforderlich – der Server startet nicht ohne diese
Variable | Wert |
|
|
|
|
Generieren Sie Schlüssel mit openssl rand -hex 24. Das Label vor dem Doppelpunkt erscheint in Logs und Rate-Limit-Buckets; das Geheimnis selbst wird nie protokolliert. Entziehen Sie einer Person den Zugriff, indem Sie ihren Eintrag entfernen und neu starten – und löschen Sie ihre Sitzungsdatei unter ~/.dashboard-mcp/sessions/, um auch die gebundene Identität zu entfernen.
Jeder Schlüssel wird dann von seinem Inhaber über POST /auth/bind an ein Dashboard-Konto gebunden – siehe den Benutzerabschnitt oben. Keine Dashboard-Anmeldedaten liegen in der Umgebung des Servers.
Optionaler Legacy-Fallback – ein gemeinsames Dienstkonto
Variable | Wert |
| ein Dienstkonto |
| das Passwort dieses Kontos |
Wenn gesetzt, agieren Schlüssel, die nicht gebunden wurden, als dieses gemeinsame Konto, anstatt zu fehlschlagen – ebenso wie ein Schlüssel, dessen Bindung abgelaufen ist, bis er neu gebunden wird. Nützlich während der Migration; für neue Bereitstellungen überspringen, damit jeder Aufrufer seine eigene Identität hat.
Stark empfohlen
Variable | Wert | Warum |
|
| mit schreibgeschütztem Zugriff starten, bis Identitäten gebunden sind |
|
| aktiviert DNS-Rebinding-Schutz |
| Ihre Client-Origin | dasselbe |
Lassen Sie DASHBOARD_MCP_PERSIST_SESSION auf dem Standardwert (true): Bindungen werden als eine Datei pro Schlüssel gespeichert und überleben Neustarts. Wenn Sie es auf false setzen, bleiben Bindungen nur im Speicher, sodass jeder Neustart – und jeder Worker in einem Multi-Worker-Host – eine eigene Neubindung benötigt.
MCP_ALLOWED_HOSTS und MCP_ALLOWED_ORIGINS sind optional – der Server läuft ohne sie, und das API-Key-Gate gilt weiterhin. Das Setzen einer der beiden aktiviert den DNS-Rebinding-Schutz des Transports. Lassen Sie beide ungesetzt, und das Startprotokoll sagt dies explizit.
Optional
Variable | Standard |
| 3001 |
|
|
| 120 Anfragen pro Schlüssel pro Fenster |
| 60000 |
Weitere Tuning-Variablen – Sitzungsdateipfad, Anfragetimeout, Antwortlimits und die Überschreibung der Dashboard-Kind-ID – sind inline in .env.example dokumentiert, das nach Modus organisiert ist und jede Variable auflistet, die der Server liest.
Hinweis zu mehreren Workern
Bindungen sind eine Datei pro Schlüssel, und ein Worker, dessen In-Memory-Token von einem anderen Worker rotiert wurde, erholt sich, indem er diese Datei erneut liest, die der gewinnende Worker bereits aktualisiert hat. Das Fehlerfenster besteht darin, dass zwei Worker dasselbe Token gleichzeitig aktualisieren; der Verlierer erholt sich beim nächsten Versuch, und im schlimmsten Fall muss der Schlüssel neu gebunden werden. Der MCP-Transport selbst ist zustandslos, sodass Anfragen auf jedem Worker landen können.
Plesk-Einrichtung
Einstellung | Wert |
Anwendungsstammverzeichnis | das |
Anwendungsstartdatei |
|
Anwendungsmodus | Produktion |
Umgebungsvariablen | die obigen Tabellen, im Node.js-Panel |
Vor dem Start |
|
Fügen Sie zu den Zusätzlichen nginx-Direktiven der Domain hinzu:
proxy_buffering off;
proxy_read_timeout 300s;MCP antwortet als Server-Sent Events, und nginx puffert standardmäßig proxierte Antworten. Ohne proxy_buffering off scheinen Anfragen zu hängen, anstatt zu fehlschlagen – eine verwirrende Art, einen Nachmittag zu verlieren.
Halten Sie den Node-Port von der öffentlichen Firewall fern. Plesks nginx proxyt zu ihm und setzt X-Forwarded-For, was die protokollierten Client-IPs vertrauenswürdig macht.
Zugriff versus Identität
Der Gate-Key kontrolliert den Zugriff; die Identität stammt aus der Bindung. Der Schlüssel bringt einen Aufrufer am Gate vorbei, und die an diesen Schlüssel gebundene Sitzung entscheidet, wen das Dashboard sieht – ihre Berechtigungen, ihren Audit-Trail. Die beiden sind bewusst getrennt: Das Rotieren des Geheimnisses eines Schlüssels verwirft seine Bindung (die Sitzung wird unter dem Digest des Schlüssels abgelegt), und das Entziehen eines Schlüssels entfernt den Zugriff, ohne das Konto zu berühren.
Die Bindung funktioniert wie ein Browser-Login. POST /auth/bind führt das echte /api/auth/login der App einmal aus, das Passwort wird nach dem Austausch verworfen, und nur die rotierende Refresh-Token-Sitzung wird aufbewahrt – eine Datei pro Schlüssel, Modus 0600. Da die App das Refresh-Token bei jeder Verwendung rotiert, stirbt eine geleakte Sitzungsdatei schnell; da das Passwort nie gespeichert wird, gibt es nichts Langlebiges zu leaken. Der Kompromiss: Wenn eine Refresh-Kette abläuft oder bricht, bindet sich dieser Schlüssel mit einem curl neu.
Eine stabile, pro Anfrage gültige Anmeldeinformation (ApiKey im Hauptsystem oder OAuth) würde sogar diese Neubindung überflüssig machen, erfordert aber Änderungen in der Hauptanwendung. Dieses Design benötigt bewusst keine.
Lokale Entwicklung oder Ausführung
Das Ausführen des Servers auf Ihrem eigenen Rechner – für die Entwicklung oder für eine benutzerspezifische Identität ohne Hosting – ist separat in DEVELOPMENT.md dokumentiert.
Tools
Die Kette ist: Datenquelle (HTTP-API oder Excel-Upload) → Datensatz (eine geformte Ansicht mit einem Transformations-Workflow) → Dashboard-Widgets. Die Tools decken alle drei Stufen ab.
Tool | Mode | Purpose |
| read | Datenquellen-IDs, Bezeichnungen, Arten (http/excel) und Ziele |
| read | Struktur einer Quelle: Parameter, Antwortpfad, Spalten — niemals Anmeldedaten |
| read | Live-Zeilen aus einer Quelle; listet mögliche Antwortpfade auf, wenn einer fehlschlägt |
| read | Datensatz-IDs, Bezeichnungen und Bereiche |
| read | Exakte Feldnamen, abgeleitete Typen, jeweils ein Beispielwert |
| read | Eine begrenzte Stichprobe echter Zeilen |
| read | Vollständige Datensatzdefinition: Quelle, Materialisierung, Workflow-Zusammenfassung oder roher Envelope |
| read | Workflow-Entwurf gegen echte Daten ausführen, ohne zu speichern; Diagnose pro Schritt |
| read | Dashboard-IDs, Bezeichnungen und Bereiche |
| read | Dashboard-Details plus eine Zeile pro Widget; eine Konfiguration auf Anfrage |
| read | Die erstellbaren Widget-Arten |
| read | Konfigurationsvertrag für eine Art, plus ein reales Beispiel aus deinem Arbeitsbereich |
| write | HTTP-Endpunkt-Konfiguration testen; nichts wird gespeichert, Spalten und Pfade werden abgeleitet |
| write | HTTP-Datenquelle erstellen; der Server prüft die URL und legt einen Standarddatensatz an |
| write | Teile einer HTTP-Quelle ändern; wird mit der gespeicherten Konfiguration zusammengeführt |
| write | Datensatz erstellen; der Server erstellt den Standard-Workflow, wenn keiner angegeben ist |
| write | Teilweises Update: Bezeichnung, Quelle, Limits, Materialisierung oder Workflow ersetzen |
| write | Snapshot-materialisierten Datensatz erneut ausführen oder letzten Refresh melden |
| write | Dashboard erstellen und seine Datensätze anhängen |
| write | Datensatzliste des Dashboards ersetzen |
| write | Ein Widget hinzufügen, automatisch im Raster platziert |
| write | Titel, Datensatz oder Konfigurationsschlüssel ändern |
| write | Ein Widget entfernen |
| write | Raster neu packen oder explizite Positionen anwenden |
test_datasource steht im write-Set, weil die App es hinter der Berechtigung zum Erstellen/Bearbeiten von Datenquellen absichert und es den vorgelagerten Endpunkt aufruft — es speichert jedoch nichts.
Design-Hinweise
Kontext-Disziplin. Die gesamte Tool-Oberfläche kostet etwa 7 KB — 24 Beschreibungen plus die Server-Anweisungen — und bleibt damit günstig im Speicher. Antworten sind kompakter Text statt rohem JSON, und jede Liste ist mit einem expliziten Hinweis darauf begrenzt, was ausgelassen wurde. get_dashboard lässt Widget-Konfigurationen bewusst aus; du fragst ein Widget per ID an, wenn du seine Konfiguration brauchst.
Progressive Offenlegung. Eine Chart-Konfiguration hat etwa 59 Felder. Das in eine Tool-Beschreibung zu packen würde den Kontext des Clients bei jeder Anfrage dominieren, also liefert describe_widget_kind den Vertrag stattdessen auf Abruf: Feldnamen, Typen, Hinweise, ein minimales funktionierendes Beispiel und — der nützliche Teil — eine echte Konfiguration, die aus einem bestehenden Widget dieser Art in deinem eigenen Arbeitsbereich gewonnen wurde. Eine Form zu kopieren, die bereits rendert, ist besser, als eine aus Feldnamen zu erfinden.
Der Server übernimmt die Geometrie. Modelle sind bei 2D-Packing unzuverlässig. add_widget nimmt einen size-Hinweis (small, medium, large, full) und findet selbst die erste freie, nicht überlappende Zelle im 12-Spalten-Raster. arrange_dashboard im auto-Modus packt ein gesamtes Dashboard neu.
Vor der API scheitern, nicht danach. Widget-Konfigurationen werden von der App als undurchsichtiges JSON gespeichert, sodass ein falsch geschriebener Schlüssel ein leeres Widget statt eines Fehlers erzeugt. add_widget validiert die Konfiguration zuerst gegen den Vertrag der Art — erforderliche Schlüssel, gültige Aggregationsnamen, field vorhanden, wenn die Aggregation eines benötigt — und gibt eine konkrete Liste dessen zurück, was fehlt.
Widgets entsprechen dem, was die UI erstellen würde. Die Palette der App versorgt jedes neue Widget mit der defaultConfig der Art aus der Registry (config === undefined ? def.defaultConfig : config). add_widget spiegelt das wider: Die Standardwerte der Art werden unter das gelegt, was der Aufrufer liefert, sodass ein MCP-erstellter Chart dieselbe paginationMode- und maxPoints-Basis hat wie ein manuell erstellter — statt einer spärlichen Konfiguration, auf die der Renderer zurückfallen müsste. Das zusammengeführte Objekt ist es, das validiert wird.
Zusammenführen statt erneut senden. PATCH /widgets/:id ersetzt das Konfigurationsobjekt vollständig. update_widget führt standardmäßig deine Schlüssel in die bestehende Konfiguration zusammen, sodass das Ändern einer Einstellung nicht bedeutet, alles erneut zu senden.
Fail-closed beim Start. Der HTTP-Server weigert sich zu starten, wenn nicht mindestens ein MCP_API_KEYS-Eintrag vorhanden ist, und lehnt Schlüssel unter 24 Zeichen ab. Ein unauthentifizierter MCP-Endpunkt sollte nie versehentlich möglich sein. Schlüssel werden als SHA-256-Digests mit timingSafeEqual verglichen, und nur Bezeichnungen werden protokolliert.
Geheimnisse bleiben serverseitig. describe_datasource liest den /schema-Endpunkt der App, der niemals Anmeldedaten enthält. update_datasource benötigt die vollständige gespeicherte Konfiguration zum Zusammenführen — sie wird innerhalb des Tool-Laufs abgerufen und das zusammengeführte Ergebnis zurückgesendet, ohne jemals authConfig, gespeicherte Header oder Body in den Kontext des Modells zu rendern.
Vor dem Speichern validieren. Workflow-Envelopes sind leicht subtil falsch zu bekommen, also ist der Ablauf: einen funktionierenden Envelope mit get_dataset includeWorkflow kopieren, bearbeiten, validate_dataset_workflow ausführen (das ihn serverseitig ausführt und pro Schritt Zeilenzahlen, Ausgabefelder und Null-Zählungen meldet, ohne etwas zu speichern), dann mit update_dataset speichern.
Bekannte Grenzen
Der Widget-Arten-Katalog ist eine Kopie.
src/catalog/widget-kinds.tsspiegeltsrc/features/dashboard/widgets/registry.ts— einschließlich derdefaultConfigjeder Art — und die Konfigurationsschnittstellen pro Art. Die Registry der App ist eine Client-Komponente und importiert React, kann also hier nicht importiert werden. Wenn eine Widget-Art ein Feld bekommt oder sich eindefaultConfig-Wert ändert, muss auch der Katalog aktualisiert werden, sonst weichen MCP-erstellte Widgets von UI-erstellten ab.Die Katalogabdeckung ist hoch, aber nicht vollständig. Dokumentierte vs. tatsächliche Konfigurationsfelder: table 18/21, stat 22/25, chart 39/59, select 9/12, text 16/17. Was weggelassen wird, sind meist kosmetische Varianten (Kreis-/Linien-/Balken-Stiloptionen, Overrides für die rechte Achse) und veraltete Interaktionsschlüssel, die durch
highlightBindingsersetzt wurden. Das Live-Beispiel, dasdescribe_widget_kindzurückgibt, ist die Referenz dafür. Felder sind in Kern / Anzeige / Interaktion gruppiert, sodass der Datenvertrag zuerst gelesen wird.Bindings laufen mit der Refresh-Kette ab. Die Sitzung eines Schlüssels dauert so lange, wie die App ihr rotierendes Refresh-Token am Leben hält. Wenn es abläuft, schlagen Aufrufe mit einem Fehler fehl, der die Lösung nennt, und der Inhaber des Schlüssels bindet mit einem curl neu. Eine nie ablaufende Identität erfordert, dass
ApiKeyinsrc/lib/api-guard.tsim Hauptsystem verdrahtet wird, was nicht geschehen ist.Schreibvorgänge sind direkt. Die App hat einen Änderungsentwurfs- und Genehmigungsworkflow (
ChangeDraft,ApprovalRequest). Diese Tools schreiben direkt mit den Berechtigungen des angemeldeten Kontos. Wenn KI-erstellte Dashboards vor der Veröffentlichung überprüft werden sollen, leite die Schreib-Tools stattdessen über/api/change-draftsund halte die Berechtigungen des Kontos schreibgeschützt.Excel-Datenquellen sind hier schreibgeschützt. Das Erstellen oder Aktualisieren einer solchen erfordert einen Multipart-Datei-Upload, der nicht in den MCP-Textfluss passt. Sie erscheinen weiterhin in
list_datasources,describe_datasourceundpreview_datasource; erstelle und aktualisiere sie in der UI.Keine Lösch-Tools. Das Löschen einer Datenquelle kaskadiert ein Soft-Delete auf jeden darauf aufgebauten Datensatz, daher bleiben Löschungen eine menschliche Aktion in der UI.
delete_widgetist das einzige destruktive Tool, das verfügbar ist.
This server cannot be deployed
Maintenance
Related MCP Connectors
- Muvia BIOAuthcom.muviabi
Company and industrial data for AI assistants: datasets, SQL, dashboards, alarms, with approvals.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Query your warehouse or a CSV with Claude/ChatGPT over MCP, governed by table-level ACL + audit.
Ask your organization's connected business data in plain language, with each person's permissions.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables secure querying of analytics data stored in AWS Athena/S3 through natural language, with multiple security layers including query validation, resource limits, and automatic PII redaction to prevent data breaches and destructive operations.-
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with SQL Server Data Warehouses using natural language for automatic schema discovery and report generation. It ensures security by restricting operations to read-only SELECT queries through both code validation and database permissions.-
- AlicenseNot gradedqualityDmaintenanceEnables natural language querying and management of Apache Superset dashboard metadata, including user activity, data lineage, and change tracking.504 PyPI4MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI applications to interact with Tableau for querying data, exploring content, and retrieving views through natural language.26,488 npmApache 2.0