Repository navigation
API Keys
MultiGPT ist nicht nur MCP-Client (siehe MCP-Server), sondern auch selbst MCP-Server: Andere Programme – n8n, Claude Desktop, Claude Code, eigene Agenten oder Skripte – steuern MultiGPT mit dem API-Key eines Kontos. Sie können Modelle fragen, Dokumente hochladen und durchsuchen, die Indexierung starten und überwachen, Verzeichnisquellen (Crawler) einlesen lassen und erzeugte Dateien abholen.
Der Grundsatz: Ein Key kann nie mehr als sein Konto. Es gelten Rolle, Freigaben der Sammlungen und Budgets des Kontos; Kosten gehen auf das Konto. Verwalterrechte (Konten, Rollen, Anbieter …) gibt es über Keys nicht.
https://<hostname>/mcp/ (auch ohne Schrägstrich: https://<hostname>/mcp)
Authorization: Bearer mgpt_…
- Transport: Streamable HTTP (POST, Antwort als JSON oder als SSE-Stream mit Fortschritt).
- Protokoll: 2026-07-28 (aktuelle Spezifikation, zustandslos) und die älteren Versionen
2025-03-26 bis 2025-11-25 mit
initialize-Handshake (n8n, Claude Desktop). Der Server vergibt keine Sitzungs-IDs; GET und DELETE ergeben 405. - Quellen: Streamable HTTP 2026-07-28, Transports 2025-11-25.
Manche Clients können nur den älteren Transport HTTP+SSE (Spezifikation
2024-11-05),
z. B. der n8n-Knoten „MCP Client Tool“ in Version 1 bzw. mit „Server Sent Events (Deprecated)“,
mcp-remote mit --transport sse-only oder ältere Desktop-Clients. Dafür gibt es zusätzlich:
GET https://<hostname>/mcp/sse (Event-Stream öffnen)
POST https://<hostname>/mcp/messages?session_id=… (Adresse liefert der Stream)
Authorization: Bearer mgpt_… (bei beiden)
Ablauf: Der Stream sendet zuerst event: endpoint mit der POST-Adresse samt Sitzungs-ID
(128 Bit Zufall), danach alle 15 s einen Keepalive. Jede Nachricht an diese Adresse bekommt
sofort nach der Verarbeitung 202; die Antwort kommt als event: message über den Stream
(bei ask mit progressToken vorher notifications/progress). Werkzeuge, Rechte, Drosselung
und Audit-Log sind dieselben wie bei /mcp/.
- Die Sitzung gehört zu dem Key, der den Stream geöffnet hat. Eine fremde, unbekannte oder beendete Sitzung ergibt 404 – dann neu verbinden.
- Höchstens 2 Streams je Key und 4 je gunicorn-Prozess (
MCP_SSE_PER_KEY,MCP_SSE_PER_PROCESS), sonst 503 mitRetry-After. Jeder offene Stream belegt einen Thread des Servers. - Ein Stream endet nach 30 Minuten (
MCP_SSE_MAX_MINUTES), bei einem Neustart des Dienstes und spätestens 15 s nach dem Widerruf des Keys. Clients verbinden sich dann neu. - Wo möglich Streamable HTTP (
/mcp/) nehmen: zustandslos, ohne Dauerverbindung.
Auf der Seite „API-Keys“ stehen unter SSE (ältere Clients …) JSON, claude mcp add und die
n8n-Felder für diesen Weg, z. B.
{"mcpServers": {"multigpt": {"type": "sse", "url": "https://nas.example/mcp/sse",
"headers": {"Authorization": "Bearer mgpt_…"}}}}claude mcp add --transport sse multigpt https://nas.example/mcp/sse --header "Authorization: Bearer mgpt_…"Im Browser: Einstellungen → „API-Keys (MCP-Zugang …)“ → Name, Rechte, Gültigkeit und
optional „Nur diese Sammlungen“ wählen; „Chats im Projekt „API“ sammeln“ ist vorgewählt
(siehe unten) → Key anlegen. Der Key erscheint genau einmal;
MultiGPT speichert nur einen Hash (SHA-256). Verloren = widerrufen und neu anlegen.
Unter dem Key-Feld stehen die Verbindungsdaten zum Kopieren: JSON (mcpServers) und
claude mcp add für Streamable HTTP, aufklappbar dieselben Angaben für SSE (ältere Clients,
n8n mit „Server Sent Events“).
Auf der Konsole (Betrieb):
sudo mgpt-ctl apikey create anna --name "n8n NAS" --scopes docs.read,docs.write,index.control --expires 365d
sudo mgpt-ctl apikey list
sudo mgpt-ctl apikey revoke mgpt_ab12cd34efDer Key steht auf stdout (z. B. > key.txt), die Hinweise auf stderr. Weitere Optionen:
mgpt-ctl.
Widerrufen wirkt sofort, ebenso das Ablaufdatum: Jeder Aufruf prüft Key, Konto und Rolle neu.
| Recht | Bedeutung | Werkzeuge |
|---|---|---|
chat.ask |
Einem Modell eine Aufgabe geben (Modell im Rahmen der Rolle, Budget des Kontos) |
ask, list_models
|
chat.read |
Eigene und mit dem Konto geteilte Chats auflisten und lesen (Verlauf, Werkzeugaufrufe, Fehler); fremde Chats nie, auch nicht für Verwalter |
list_chats, read_chat
|
docs.read |
Sammlungen und Dokumente auflisten, durchsuchen, lesen |
list_collections, search_documents, list_documents, document_info, read_document
|
docs.write |
Dateien hochladen, Dokumente löschen, neu indexieren (eigene bzw. schreibbare Sammlungen) und die Läufe dazu verfolgen |
upload_document, delete_document, reindex, run_status, list_runs
|
index.control |
Läufe überwachen, pausieren, fortsetzen und abbrechen; Verzeichnisquellen einlesen (nur Verwalter) |
run_status, list_runs, cancel_run, pause_run, resume_run, list_sources, start_scan
|
files.read |
Erzeugte Anhänge und Dokumente abholen | get_file |
tools.run |
Werkzeuge direkt aufrufen, mit denselben Rollenrechten und Budgets wie im Chat |
create_pdf, generate_image, run_python, fetch_url, web_search
|
usage.read |
Eigener Verbrauch und Budgetstand | usage |
Wirksam ist immer die Schnittmenge:
- Rechte des Keys,
- Höchstmenge der Rolle (Admin → Rollen → „API-Keys und MCP-Zugang“: Häkchen „API-Keys/MCP-Zugang“ und „Erlaubte API-Rechte“),
- die übrigen Rechte des Kontos auf das konkrete Objekt: Modellfreigabe, Lese- und Schreibrecht auf Sammlungen, „Dokumente hochladen“, „Websuche“, „Bilder“, „Berechnungen“, „Dokumente erzeugen“, Verwalter bei Verzeichnisquellen.
tools/list zeigt nur, was davon gerade wirksam ist. Ein Werkzeug außerhalb der Rechte gilt wie
ein unbekanntes. Zusätzlich: ask mit collections braucht docs.read, ask mit tools: true
braucht tools.run.
Startwerte: Verwalter und Erwachsene haben das Recht mit allen Scopes, Jugendliche und Gäste nicht.
| Werkzeug | Argumente | Ergebnis |
|---|---|---|
ask |
prompt, optional model, collections, web_search, tools, chat
|
Antworttext; strukturiert: chat_id, message_id, status, Tokens, cost_eur, sources
|
list_models |
– | erlaubte Chat-Modelle (ID, Name, Fähigkeiten, Budgetsperre) |
list_chats |
optional query (Titel), archived, include_shared (Standard ja), page, page_size (≤ 50) |
Chats mit chat_id, Titel, Projekt bzw. shared_by, letzter Änderung |
read_chat |
chat_id, optional page
|
angezeigter Verlauf als Markdown: Nachrichten mit ID, Verfasser/Modell, Zeit, Status, Werkzeugaufrufe (Argumente und Ergebnis gekürzt), Anhänge, Fehler; lange Chats seitenweise (30 000 Zeichen) |
list_collections |
– | Sammlungen mit Zahlen je Status |
search_documents |
query, optional collections
|
nummeriertes Quellmaterial mit Fundstellen |
list_documents, document_info, read_document
|
wie die Dokument-Werkzeuge im Chat | Liste, Angaben, Text mit Fundstellen |
upload_document |
collection, filename + content_base64 oder url
|
document_id, run_id
|
delete_document |
document_id |
– |
reindex |
collection oder document/documents
|
Lauf (id) |
run_status, list_runs
|
run_id bzw. open_only, limit
|
Status, Zähler, Fortschritt |
cancel_run |
run_id |
entfernte/markierte Aufträge |
pause_run |
run_id |
Zahl der Dokumente, die noch fertig werden |
resume_run |
run_id |
neuer Status |
list_sources, start_scan
|
– bzw. source
|
Verzeichnisquellen bzw. Lauf |
get_file |
attachment_id oder document_id
|
Datei als eingebettete Ressource (base64) |
create_pdf, generate_image, run_python, fetch_url, web_search
|
wie im Chat | Text wie für das Chatmodell, erzeugte Dateien direkt im Ergebnis (siehe unten) |
usage |
– | Verbrauch im laufenden Monat |
Hinweise:
-
asklegt je Aufruf einen Chat „API: …“ an, der im Konto sichtbar ist. Standardmäßig landet er im Projekt „API“ des Kontos (wird bei Bedarf angelegt; ein vorhandenes, nicht archiviertes Projekt dieses Namens wird genutzt) statt in der normalen Chatliste. Der Schalter gilt je Key: beim Anlegen, in der Liste „Deine Keys“ (Spalte „Projekt „API““, wirkt auf neue Chats) und auf der Konsole mit--no-project. Mitchat: <ID>geht es in einem eigenen bzw. schreibbar geteilten Chat weiter. Ohnetoolsbekommt das Modell keine Werkzeuge. Braucht ein Werkzeug eine Rückfrage, endetaskmit Statusawaiting_confirmation– bestätigen lässt sich das nur in MultiGPT. -
Lange Aufgaben (Indexierung, Verzeichnis einlesen) laufen im Worker. Das Werkzeug liefert
sofort eine Lauf-ID;
run_statuszeigt den Fortschritt, bisopenfalseist. -
Fortschritt per SSE: Schickt der Client
Accept: text/event-streamund einprogressTokenmit, sendetasknotifications/progress, bevor das Ergebnis kommt. Schließt der Client die Verbindung, wird die Antwort abgebrochen. -
Direkte Werkzeuge (
tools.run) erscheinen im Chat „API: – Werkzeuge“. Die Rückfrage, die der Verwalter fürgenerate_imagebzw.run_pythoneinstellen kann, gilt im Chat für Aufrufe eines Modells; über die API ruft das Programm des Key-Inhabers das Werkzeug selbst auf – dieser Aufruf ist die Bestätigung. -
Uploads: Typ und Größe wie in der Oberfläche (
DOCUMENT_MAX_UPLOAD_MB).urllädt nur über den geschützten Abruf der Websuche: keine Adressen im lokalen Netz, Weiterleitungen werden neu geprüft, Zeit- und Größengrenze. Dateien aus dem Heimnetz deshalb alscontent_base64.
Ein Ergebnis (tools/call) besteht aus Inhaltsblöcken nach der MCP-Spezifikation
(2025-11-25,
2026-07-28):
text, image, resource (eingebettete Datei, als Text oder base64) und resource_link
(Verweis). Der erste Block ist immer Text.
| Werkzeug | Inhalt |
|---|---|
run_python |
Text: Exit-Status, Laufzeit, stdout und stderr (wie für das Chatmodell). PNG, JPEG und WebP als image, SVG als resource mit mimeType image/svg+xml und dem SVG als Text (bereits auf dem Server bereinigt) – liegt ein PNG bei (eigenes oder Vorschau), nur als resource_link (mit get_file abholen), PDF als resource (base64) |
create_pdf |
Text mit Seitenzahl, das PDF als resource (application/pdf) |
generate_image |
Text, das Bild als image
|
fetch_url, web_search
|
Seiteninhalt bzw. Treffer als Text (Quellmaterial) |
get_file |
Datei als resource (base64) |
-
Diagramme: Am besten speichert der Code SVG (
plt.savefig('diagramm.svg')). Viele Clients zeigen SVG nicht als Bild. Speichert der Code nur SVG, legt MultiGPT über MCP deshalb aus den noch offenen matplotlib-Figuren zusätzlich ein PNG ab, das alsimagemitkommt. Ohne offene Figur (plt.close()am Ende oder selbst geschriebenes SVG) gibt es kein PNG; dann im Code zusätzlichplt.savefig('diagramm.png')aufrufen. -
Daten zum Weiterverarbeiten:
chat_id,message_id,attachments(ID, Name, Typ, Größe) und ggf.sourcesstehen bei Ergebnissen mit Dateien als JSON im letzten Textblock, nicht instructuredContent. Grund: Manche Clients (gemessen mit Claude Code) zeigen nurstructuredContent, sobald es da ist. Text und Bilder gingen dann verloren. Ergebnisse ohne Dateien haben weiterstructuredContent; ist der Text mehr als dieses JSON (Antwort vonask, Ausgabe vonrun_python, Treffer der Dokumentsuche), steht er dort zusätzlich alstext. -
Größe: Über eine JSON-Antwort betten die Werkzeuge bis zu 4 MB ein, über SSE (Antwort mit
progressTokenoder der Transport/mcp/sse) nur etwa 700 KB, weil der SSE-Client des MCP-SDK Events nur bis 1 MB liest. Bilder über 1600 Pixel Kantenlänge oder über der Grenze kommen verkleinert (PNG bzw. JPEG), mit Hinweis im Text. PDF und andere Dateien über 2 MB bzw. über der Grenze kommen nur alsresource_linkmiturimultigpt://attachment/<ID>. Das Original holtget_filemit dieserattachment_id. -
get_fileüber SSE: Passt die Datei nicht in ein Event, kommt einresource_linkmit dem Hinweis, sie über Streamable HTTP (/mcp/) oder in MultiGPT zu holen. - Die Adressen
multigpt://…benennen Anhang bzw. Dokument. MultiGPT bietet keinresources/readan, abgeholt wird mitget_file.
KEY=mgpt_…
curl -s https://nas.example/mcp/ -H "Authorization: Bearer $KEY" \
-H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
curl -s https://nas.example/mcp/ -H "Authorization: Bearer $KEY" \
-H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"ask","arguments":{"prompt":"Fasse die Heizungsanleitung zusammen.",
"collections":["Haus"]}}}'Claude Desktop spricht HTTP-Server über mcp-remote an:
{
"mcpServers": {
"multigpt": {
"command": "npx",
"args": ["mcp-remote", "https://nas.example/mcp/", "--header", "Authorization:${AUTH_HEADER}"],
"env": { "AUTH_HEADER": "Bearer mgpt_…" }
}
}
}Bei einem selbstsignierten Zertifikat (snakeoil) braucht Node zusätzlich
NODE_EXTRA_CA_CERTS=/pfad/zum/zertifikat.pem – besser ein eigenes Zertifikat einspielen
(siehe nginx und TLS).
-
Keys stehen nur als Hash in der Datenbank, nie im Klartext in Logs. In Listen erscheint nur
das Präfix (
mgpt_ab12cd34ef…). Verwalter sehen im Admin unter „Knoten“ nur Metadaten. -
Keine Cookies:
/mcp/wertet weder Sitzung noch Login-Cookie aus, nur den Bearer-Key. Deshalb gilt der CSRF-Schutz dort nicht. EinOrigin-Header aus einem fremden Host wird abgewiesen (Schutz gegen DNS-Rebinding). -
Drosselung: nach
API_FAILURE_LIMIT(10) ungültigen Keys inAPI_FAILURE_WINDOW_MINUTES(15) sperrt/mcp/die IP-Adresse (HTTP 429), auch für gültige Keys; je Key höchstensAPI_RATE_LIMIT_PER_MINUTE(120) Aufrufe je Minute. Siehe Konfiguration. - Fehler ohne Details: fehlender, falscher, abgelaufener oder widerrufener Key → 401 ohne Inhalt; Konto bzw. Rolle ohne API-Recht → 403 ohne Inhalt.
-
Audit-Log: Jeder Aufruf wird mit Key, Methode, Werkzeug, Status, Dauer, Größen und
IP-Adresse protokolliert – ohne Inhalte. Das Mitglied sieht die letzten 50 auf der Seite
„API-Keys“, Verwalter alle im Admin unter „Knoten › API-Aufrufe“. Aufbewahrung
API_AUDIT_DAYS(90 Tage). -
Prompt-Injection: Was über die API hereinkommt (Prompts, Dateien, URLs) und was
zurückgeht (Modellantworten, Dokument- und Webtext), ist Material, keine Anweisung. Für
Werkzeuge mit Rückfrage gibt es über
askkeine Abkürzung. - Budgets gelten unverändert: Ein ausgeschöpftes Budget sperrt die betroffenen Modelle auch über die API.
| Meldung | Ursache |
|---|---|
| HTTP 401 | Key falsch, abgelaufen, widerrufen oder Konto gesperrt. |
| HTTP 403 | Rolle ohne „API-Keys/MCP-Zugang“ bzw. Key ohne wirksame Rechte; oder fremder Origin. |
| HTTP 429 | Zu viele Fehlversuche von dieser IP oder zu viele Aufrufe mit diesem Key. |
| HTTP 413 | Anfrage zu groß (Upload über DOCUMENT_MAX_UPLOAD_MB). |
HTTP 404 an /mcp/messages
|
SSE-Sitzung unbekannt, beendet oder von einem anderen Key – Stream neu öffnen. |
HTTP 503 an /mcp/sse
|
Zu viele offene SSE-Streams (je Key bzw. Serverprozess); Retry-After abwarten oder Streamable HTTP nutzen. |
Unknown tool |
Werkzeug gibt es nicht oder der Key hat das Recht nicht. |
isError: true |
Das Werkzeug lehnt ab (z. B. „Sammlung nicht gefunden.“, „Diese Sammlung darf nur gelesen werden.“). |
Nur {"chat_id": …, "message_id": …} sichtbar, keine Ausgabe |
Server vor 0.3.3: Der Client zeigte nur structuredContent. Ab 0.3.3 kommen Text und Dateien direkt (siehe „Was Werkzeuge zurückgeben“). |
| „… als Vorschau verkleinert“ bzw. „nicht eingebettet“ | Bild bzw. Datei zu groß für die Verbindung; Original mit get_file holen, bei SSE besser Streamable HTTP. |
MultiGPT-Wiki
- Startseite
- Konfiguration (.env)
- nginx und TLS
- Chat-Bedienung (Zitieren, Kontextmenü, Scrollen, Tasten)
- Chat-Einstellungen (Grundregeln, Kreativität, Denktiefe)
- Projekte
- Chats teilen
- Anbieter und Modelle
- MCP-Server
- API-Keys (MultiGPT als MCP-Server)
- n8n
- Bilder erzeugen
- Berechnungen
- Runner (Arbeitsumgebung)
- Blätter und Dokumente (PDF)
- Kosten und Budgets
- mgpt-ctl (Verwaltungsbefehle)
Dokumente (RAG)
Websuche
Projekt