Gmail MCP Gateway
Gmail MCP Gateway
Ein MCP-Server, der KI-Agenten vollständigen Lese- und Organisationszugriff auf mehrere Gmail-Konten gewährt – aber keine Möglichkeit, E-Mails zu senden, zu löschen oder in den Papierkorb zu verschieben.
Gmail MCP Gateway
ALLOWED FORBIDDEN
─────── ─────────
Search Send
Read messages Send draft
Read threads Trash
Read attachments Delete
Create drafts Mark spam
Edit drafts Gmail settings
Archive Forwarding rules
Read / unread Arbitrary API calls
LabelsDie Garantie wird im Anwendungscode durchgesetzt, nicht durch Anweisungen an den Client. Ein fehlerhafter, kompromittierter oder per Prompt-Injection angegriffener MCP-Client kann über dieses Gateway keine E-Mails senden, da kein Codepfad existiert, der dies erlauben würde.
Inhalt
Schnellstart – vom Klonen bis zum funktionierenden System in fünf Schritten
Umgebungsvariablen – was zu setzen ist und wie man es generiert
Ausführen – stdio, HTTP, systemd, Docker
Related MCP server: imap-mcp
Schnellstart
Erfordert Python 3.11+. Fünf Schritte, etwa zehn Minuten, die meiste Zeit in der Google-Konsole.
1. Installieren
git clone <this-repo> gmail-mcp-gateway
cd gmail-mcp-gateway
uv sync # or: python -m venv .venv && .venv/bin/pip install -e .
.venv/bin/gmail-mcp-gateway --versionOptional: Legen Sie es in Ihrem PATH ab, damit die folgenden Beispiele natürlicher lesbar sind:
export PATH="$PWD/.venv/bin:$PATH"2. Einen Google OAuth-Client erstellen
Einmalig, kostenlos und für jedes später hinzugefügte Konto gemeinsam nutzbar.
Erstellen Sie ein Projekt unter https://console.cloud.google.com/.
APIs & Services → Bibliothek → aktivieren Sie die Gmail API.
APIs & Services → OAuth-Zustimmungsbildschirm → Extern, füllen Sie die erforderlichen Felder aus, fügen Sie Ihr eigenes Google-Konto unter Testbenutzer hinzu.
App veröffentlichen (es ist noch keine Überprüfung erforderlich, solange Sie der einzige Benutzer sind). Wenn Sie dies überspringen, bleibt die App im Status "Test", und Google läuft Refresh-Tokens nach 7 Tagen ab. Sie müssten dann jede Woche neu autorisieren.
Anmeldedaten → Anmeldedaten erstellen → OAuth-Client-ID → Desktop-App → JSON herunterladen.
Hier wählen Sie keine Scopes aus. Das Gateway fordert bei der Autorisierung genau das an, was es benötigt, und lehnt Anfragen außerhalb von Gmail ab.
3. Den OAuth-Client installieren
install -Dm600 ~/Downloads/client_secret_*.json \
~/.local/share/gmail-mcp-gateway/secrets/oauth_client.jsonDas ist die einzige Datei, die Sie manuell platzieren müssen. Der Verschlüsselungsschlüssel wird beim ersten Start für Sie generiert.
4. Ein Konto autorisieren
gmail-mcp-gateway accounts add personalEin Browser öffnet sich; genehmigen Sie die angeforderten Berechtigungen, lassen Sie jedes Kästchen aktiviert (das Gateway meldet einen Fehler, anstatt nur teilweise zu funktionieren, wenn eine Berechtigung verweigert wird). Ein Refresh-Token wird verschlüsselt gespeichert, und ab hier läuft das Gateway unbeaufsichtigt.
Fügen Sie so viele hinzu, wie Sie möchten – jedes erhält seine eigene Zustimmung, seinen eigenen Refresh-Token, Verschlüsselungsschlüssel, Rate-Limit-Bucket und Prüfpfad:
gmail-mcp-gateway accounts add work
gmail-mcp-gateway accounts add newsletters --read-only # Google itself refuses writes5. Überprüfen
gmail-mcp-gateway health # exit 0 = ready, 2 = something is wrong[ok ] directories config=/home/you/.config/gmail-mcp-gateway ...
[ok ] database /home/you/.local/share/gmail-mcp-gateway/gateway.db
[ok ] master_key loaded
[ok ] oauth_client configured
[ok ] accounts 1/1 authorized
gmail-mcp-gateway 1.0.0: healthyRichten Sie dann Ihren MCP-Client darauf aus – siehe Einen MCP-Client verbinden – oder testen Sie ihn zuerst:
uv run python scripts/try-it.py --account personalUmgebungsvariablen
Für eine normale lokale Installation benötigen Sie keine davon. Der obige Schnellstart setzt null Umgebungsvariablen. Standardmäßig werden Konfigurationen in ~/.config, Daten und Geheimnisse in ~/.local/share abgelegt, und der Verschlüsselungsschlüssel generiert sich selbst.
Diese existieren für Container, systemd-Einheiten und Secret-Manager – Orte, an denen eine Datei auf der Festplatte der falsche Mechanismus ist.
Variable | Erforderlich? | Standard | Zweck |
| nein¹ | — | Google OAuth-Client-ID |
| nein¹ | — | Google OAuth-Client-Geheimnis |
| nein² | automatisch generiert | base64 32-Byte-Schlüssel zur Verschlüsselung von Anmeldedaten |
| nein |
|
|
| nein |
|
|
| nein |
| Schlüssel, OAuth-Client, Anmeldedaten |
| nein |
| HTTP-Bind-Adresse |
| nein |
| HTTP-Bind-Port |
| nein |
| HTTP-Transport über Konfiguration aktivieren |
| nein |
| Nicht-Loopback-Bind zulassen |
| nein |
|
|
¹ Alternative zu secrets/oauth_client.json. Geben Sie entweder die Datei oder das Paar an.
² Nicht gesetzt bedeutet, dass das Gateway beim ersten Start secrets/master.key (Modus 0600) erstellt.
Umgebungsvariablen überschreiben config.toml, welches die Standardwerte überschreibt.
Jeden Wert generieren
OAuth-Client-ID und -Geheimnis – aus der JSON-Datei, die Sie in Schritt 2 des Schnellstarts heruntergeladen haben. Um Umgebungsvariablen anstelle der Datei zu verwenden:
jq -r '.installed.client_id' ~/Downloads/client_secret_*.json
jq -r '.installed.client_secret' ~/Downloads/client_secret_*.jsonMaster-Schlüssel – 32 zufällige Bytes, base64:
openssl rand -base64 32
# or, without openssl:
python3 -c "import base64,secrets; print(base64.b64encode(secrets.token_bytes(32)).decode())"Dieser Schlüssel entschlüsselt Ihre gespeicherten Refresh-Tokens. Wenn Sie ihn ändern, nachdem Sie Konten hinzugefügt haben, werden deren Anmeldedaten unlesbar, und jedes Konto benötigt
accounts reauth. Sichern Sie ihn dort, wo Sie auch das Datenverzeichnis sichern.
Gateway-Bearer-Token – keine Umgebungsvariable. Es wird von einem MCP-Client über den HTTP-Transport gesendet und hat nichts mit Google-Anmeldedaten zu tun. Die CLI erstellt es und speichert nur einen SHA-256-Hash:
gmail-mcp-gateway token create my-agentDer Klartext wird einmal ausgegeben und kommt in die Client-Konfiguration.
Verwendung einer env-Datei
Das Gateway liest .env nicht automatisch – ein Sicherheitstool sollte nicht stillschweigend Geheimnisse aus dem Verzeichnis aufnehmen, in dem es gestartet wurde. Kopieren Sie .env.example, das jede Variable dokumentiert, und laden Sie es explizit:
cp .env.example .env # already covered by .gitignore
$EDITOR .env
set -a && source .env && set +a
gmail-mcp-gateway healthsystemd verwendet EnvironmentFile=; Docker Compose verwendet env_file:.
Ausführen
stdio – die übliche Wahl
Der Client startet das Gateway als Kindprozess und kommuniziert über Pipes. Kein Port, kein Token, keine Netzwerkexposition. Google-Anmeldedaten bleiben im Gateway-Prozess; der Client sieht nur Tool-Aufrufe.
gmail-mcp-gateway serve --transport stdioWenn Sie es von Hand ausführen, scheint es zu hängen – das ist korrekt, es wartet auf JSON-RPC auf stdin. Normalerweise startet Ihr MCP-Client es für Sie.
Streamable HTTP – eigenständiger Dienst
Für einen langlebigen Dienst oder einen Client, der keine Prozesse starten kann.
gmail-mcp-gateway token create my-agent # once; save the printed token
gmail-mcp-gateway serve --transport http --host 127.0.0.1 --port 8765Der Endpunkt bindet loopback, erfordert einen Bearer-Token und hat einen DNS-Rebinding-Schutz. GET /healthz ist nicht authentifiziert und meldet nur die Lebendigkeit.
Das Binden einer Nicht-Loopback-Adresse erfordert GMAIL_MCP_ALLOW_REMOTE_BIND=true, und selbst dann wird eine internetroutbare Adresse abgelehnt. Für einen entfernten Client: Tunnel:
ssh -L 8765:127.0.0.1:8765 gateway-hostsystemd
deploy/gmail-mcp-gateway.service läuft als dedizierter Systembenutzer in einer gehärteten Sandbox – ProtectSystem=strict, leere CapabilityBoundingSet, seccomp-Filter, NoExecPaths über dem Datenverzeichnis. Die Installationsschritte befinden sich im Kopf der Unit. Autorisieren Sie Konten einmal interaktiv als Service-Benutzer, bevor Sie ihn starten.
Docker
deploy/Dockerfile und
deploy/docker-compose.yml laufen nicht-root und schreibgeschützt, alle Capabilities entfernt, Port nur auf Loopback veröffentlicht. Das Image enthält keine Anmeldedaten; sie befinden sich im /secrets-Volume.
docker compose -f deploy/docker-compose.yml up -dDie einmalige Autorisierungssequenz – Platzieren des OAuth-Clients, Ausführen des Zustimmungsflusses mit veröffentlichtem Redirect-Port, Erstellen eines Tokens – befindet sich in den Kopfkommentaren der Compose-Datei.
Einen MCP-Client verbinden
stdio
{
"mcpServers": {
"gmail": {
"command": "/absolute/path/to/gmail-mcp-gateway/.venv/bin/gmail-mcp-gateway",
"args": ["serve", "--transport", "stdio"]
}
}
}Claude Code:
claude mcp add gmail -- /absolute/path/to/.venv/bin/gmail-mcp-gateway serve --transport stdioHTTP
{
"mcpServers": {
"gmail": {
"type": "http",
"url": "http://127.0.0.1:8765/mcp",
"headers": { "Authorization": "Bearer <token from `token create`>" }
}
}
}Clients mounten oder greifen niemals auf Google-Anmeldedateien zu. Bei stdio spricht der Client mit einer Pipe; bei HTTP hält er ein Gateway-Token, das nichts mit Google-Anmeldedaten zu tun hat.
Tool-Referenz
Jedes Tool akzeptiert einen account-Alias – es gibt kein Standardkonto. Verändernde Tools akzeptieren optional eine client_request_id für Idempotenz: Das Wiederholen eines Aufrufs mit derselben ID und denselben Argumenten gibt das erste Ergebnis zurück, anstatt ein zweites Mal auszuführen.
Tool | Was es tut |
| Aliase, Adressen, Status, gewährte Berechtigungen. Keine Anmeldedaten. |
| Live-Autorisierungsprüfung pro Konto, plus Postfachsummen. |
| Gmail-Suchsyntax; |
| Eine Nachricht: Absender, An, CC, BCC, Betreff, Zeitstempel, Labels, Lesestatus, Text, Anhangsinventar. |
| Eine ganze Unterhaltung in der richtigen Reihenfolge, mit Teilnehmern. |
| Anhangsinventar. Lädt nichts herunter. |
| Bytes abrufen: inline base64 bei kleinen Anhängen, sonst in das eigene Verzeichnis des Gateways geschrieben. |
| Alle Labels mit Zählern und ob das Gateway jedes ändern wird. |
| Labels nach ID oder Name anwenden. Lehnt |
| Labels nach ID oder Name entfernen. Lehnt |
|
|
|
|
|
|
| Gespeicherte Entwürfe mit Empfängern, Betreff, Textausschnitt. |
| Einen vollständigen Entwurf. |
| Neuen Klartext-Entwurf. Gespeichert, niemals gesendet. |
| Antwortentwurf in einem bestehenden Thread, mit korrektem |
| Entwurf bearbeiten; weggelassene Felder behalten ihre Werte, Threading bleibt erhalten. |
Mutationen arbeiten an einzelnen Nachrichten oder Threads und an Batches (Standard-Limit 100 IDs). Labels können als IDs (Label_7) oder Anzeigenamen (Receipts) angegeben werden.
Lesen und Schreiben werden asymmetrisch behandelt, wo es darauf ankommt: gmail_search filtert bereitwillig nach TRASH oder setzt include_spam_trash, weil das Überprüfen dessen, was bereits vorhanden ist, ein Lesevorgang ist. Das Anwenden dieser Labels wird abgelehnt, weil dies E-Mails in den Papierkorb verschieben oder als Spam melden würde.
Fehler
Fehler werden als MCP-Tool-Fehler mit isError: true und einer strukturierten Nutzlast sowohl im Textblock als auch im strukturierten Inhalt zurückgegeben:
{"error": {
"code": "forbidden_label",
"message": "refusing to add label 'TRASH': moving messages to Trash is a forbidden capability of this gateway",
"retryable": false
}}Codes umfassen invalid_input, unknown_account, not_found, too_large, batch_too_large, rate_limited, forbidden_operation, forbidden_label, account_read_only, needs_reauth, upstream_rate_limited, upstream_unavailable, network_error, timeout und internal_error. Interne Ausnahmen werden serverseitig protokolliert und als einfaches internal_error gemeldet – Clients erhalten niemals einen Traceback oder einen internen Pfad.
Administration
gmail-mcp-gateway accounts list
gmail-mcp-gateway accounts status # live Gmail check per account
gmail-mcp-gateway accounts auth <alias>
gmail-mcp-gateway accounts reauth <alias> # after a revoked or expired grant
gmail-mcp-gateway accounts remove <alias> --yes # revokes at Google, deletes locally
gmail-mcp-gateway token create <name>
gmail-mcp-gateway token list
gmail-mcp-gateway token revoke <name>
gmail-mcp-gateway audit --limit 50 # recent state-changing operations
gmail-mcp-gateway audit --account work --since-hours 24
gmail-mcp-gateway audit --outcome denied --json
gmail-mcp-gateway prune # expired audit rows, dedup keys, attachments
gmail-mcp-gateway health --jsonAuf einem hostlosen Rechner autorisieren Sie mit dem umgeleiteten Port:
# on the server
gmail-mcp-gateway accounts add work --no-browser --port 8899
# on your laptop
ssh -L 8899:127.0.0.1:8899 server
# then open the printed URL locallyDas Audit-Protokoll zeichnet Konto, Zeitstempel, Vorgang, betroffene IDs, Ergebnis, Fehlercode, Dauer und aufrufenden Prinzipal auf – sowohl für Erfolge, Fehlschläge als auch Verweigerungen. Es zeichnet niemals Token, Nachrichteninhalte, Betreffe oder Anhänge auf. Die Administration erfolgt ausschließlich über die CLI: Ein kompromittierter MCP-Client kann kein Konto hinzufügen, keinen Zustimmungsvorgang auslösen, kein Token ausstellen oder das Audit-Protokoll lesen.
Verzeichnisstruktur
Konfiguration, Daten und Geheimnisse sind getrennt und können separat überschrieben werden, sodass jede Gruppe einen anderen Speicherort haben kann:
Rolle | Variable | Standard | Inhalt |
Konfig |
|
|
|
Daten |
|
|
|
Geheim |
|
|
|
config.toml ist optional; siehe
deploy/config.example.toml für alle Schlüssel –
Stapelgrenzen, Seitengrößen, Größenbegrenzungen für Nachrichten und Anhänge,
Ratenbegrenzungen, Wiederholungsrichtlinie und Idempotenzfenster – mit Standardwerten.
Wie die Grenze durchgesetzt wird
Vier unabhängige Schichten. Jede einzelne würde das Senden blockieren; alle vier müssen versagen, damit eine Nachricht das System verlässt.
1. Die Werkzeugoberfläche. Es gibt achtzehn Werkzeuge. Es gibt kein gmail_send,
kein gmail_trash, kein gmail_raw_request und kein Werkzeug, das eine URL, einen Pfad,
eine HTTP-Methode oder einen Endpunktnamen akzeptiert. Ein generischer Gmail-Proxy ist für
den Client nicht erreichbar, weil er nicht geschrieben wurde.
mcpsrv/server.py
2. Die Endpunkt-Erlaubnisliste. Jede HTTP-Anfrage an Gmail muss einen der vierzehn
Endpoint-Konstanten nennen. users.messages.send, users.drafts.send,
users.messages.trash, users.messages.delete und alles unter
users.settings fehlen schlichtweg. Pfadparameter werden gegen ein strenges
ID-Muster validiert und mit einem leeren Satz sicherer Zeichen URL-kodiert,
sodass kein Wert ein / einführen und einen anderen Endpunkt erreichen kann.
Eine Verbotsliste prüft die aufgelöste Methode und den Pfad unmittelbar vor dem
Absenden der Anfrage erneut, unabhängig davon, wie sie erstellt wurde. DELETE und
PATCH können gar nicht ausgegeben werden.
gmail/allowlist.py
3. Die Bezeichner-Richtlinie. Dies schließt die Hintertür, die die Erlaubnisliste
offen lässt. users.messages.modify ist erlaubt – es wird für Archivierung und
Lesestatus benötigt – aber Gmail behandelt TRASH und SPAM als gewöhnliche
Bezeichner, sodass das Anwenden eines davon eine Nachricht in den Papierkorb verschiebt
oder als Spam meldet. Jeder Bezeichner in einer Mutation wird in beide Richtungen
ohne Berücksichtigung der Groß-/Kleinschreibung geprüft, und der zusammengestellte
Anfragetext wird vor der Übertragung erneut geprüft.
gmail/labels.py
4. Der OAuth-Bereich. Konten werden mit gmail.modify und nichts anderem
autorisiert. Dieser Bereich kann keine Nachricht endgültig löschen (messages.delete
erfordert https://mail.google.com/) und kann keine Gmail-Einstellung ändern,
sodass Weiterleitungsregeln, Filter, POP/IMAP-Konfiguration und dauerhaftes Löschen
auf der Autorisierungsebene von Google unmöglich sind und nicht nur hier blockiert
werden. Google veröffentlicht keinen Bereich, der das Erstellen von Entwürfen ohne
Senden erlaubt, daher wird das Senden durch die Schichten 1–2 blockiert. Mit
--read-only hinzugefügte Konten erhalten gmail.readonly, und Google selbst
lehnt dann jeden Schreibvorgang ab.
Sicherheitsmodell
E-Mail-Inhalte sind nicht vertrauenswürdig. Texte, Betreffe, Absendernamen und
Anhangsdateinamen werden von Dritten geschrieben und können Anweisungen enthalten, die
an das sie lesende Modell gerichtet sind. Das Gateway markiert jedes Leseergebnis mit
content_is_untrusted: true, und die Serveranweisungen teilen dem Client mit, E-Mails
als Daten und nicht als Anweisungen zu behandeln. Noch hilfreicher: Die Fähigkeiten,
die eingeschleuste Anweisungen anfordern würden, existieren nicht.
HTML wird niemals ausgeführt und niemals als Auszeichnung zurückgegeben. <script>,
<style>, <iframe> und ähnliche Elemente werden mitsamt ihrem Inhalt verworfen; alle
anderen Tags werden entfernt. Das Ergebnis ist einfacher Text.
Unsichtbare Unicode-Zeichen werden entfernt. Nullbreitenzeichen, bidirektionale
Überschreibungen und Unicode-Tag-Zeichen ermöglichen es einem Angreifer, einem Menschen
etwas anderes zu zeigen, als ein LLM liest. Sie werden entfernt und die Anzahl als
removed_hidden_characters gemeldet.
Anhänge werden gespeichert, niemals geöffnet. Das Gateway parst, rendert oder
führt Anhänge nicht aus. Ein Client kann einen Dateinamen vorschlagen, aber niemals
einen Pfad: Das Ziel ist immer
<attachments_dir>/<account>/<message_id>/<sanitized-name>, aufgelöst und erneut auf
Einschluss geprüft, mit O_NOFOLLOW und Modus 0600 geschrieben.
Anmeldedaten erreichen niemals den Client. Aktualisierungstoken, Zugriffstoken und
das OAuth-Clientgeheimnis existieren nur innerhalb des Gateway-Prozesses. Die
Anmeldedaten jedes Kontos werden mit AES-256-GCM unter einem pro Konto abgeleiteten
Schlüssel (HKDF-SHA256(master, "…account:<id>")) versiegelt, wobei die Konto-ID als
zugehörige Daten dient – sodass der Schlüssel eines Kontos kein anderes öffnet und eine
zwischen Konten verschobene Anmeldedatendatei nicht entschlüsselt werden kann. Dateien
haben Modus 0600 in einem Verzeichnis mit Modus 0700; das Gateway weigert sich, einen
gruppen- oder weltweit lesbaren Schlüssel zu lesen.
Ehrlicher Umfang: Die Verschlüsselung im Ruhezustand schützt vor Backups, verirrten Kopien und Datenträgerabbildern. Sie schützt nicht vor einem Angreifer, der bereits Code als der Benutzer des Gateways ausführt – dieser Angreifer kann den Hauptschlüssel lesen. Dateisystemberechtigungen bleiben die primäre Grenze.
Protokolle können keine Geheimnisse preisgeben. Jeder Protokolleintrag durchläuft einen Bereinigungsfilter, der alles umschreibt, was wie ein Google-Zugriffs- oder -Aktualisierungstoken, Clientgeheimnis, Bearer-Header, JWT oder ein nach Anmeldedaten benanntes Feld aussieht – in der Nachricht, den Argumenten und dem Ausnahmetext. Bei Stdio gehen Protokolle nach stderr, da stdout der MCP-Draht ist.
Eingaben werden validiert. Entwurfsempfänger müssen bloße Adressen sein, die einem
strengen Muster entsprechen; jedes CR, LF oder NUL in einem Header-Wert wird als
versuchte Header-Injektion zurückgewiesen. Entwürfe werden aus typisierten Feldern
zusammengebaut – das Gateway akzeptiert niemals rohes RFC 5322 von einem Client.
Stapel, Seitengrößen, Textlängen, Anhangsgrößen und Empfängeranzahlen sind alle
begrenzt, und ein pro Konto vorhandener Token-Eimer schlägt schnell mit einem
retry_after_seconds-Hinweis fehl, anstatt zu warten.
Wogegen dies nicht schützt
Ein Betreiber, der Code als Gateway-Benutzer ausführen kann.
Ein Client, der legitime Fähigkeiten missbraucht – z. B. Massenarchivierung oder das Verfassen eines irreführenden Entwurfs. Archivierung und Bezeichnung sind umkehrbar und werden geprüft; Entwürfe erfordern weiterhin einen Menschen zum Senden.
Kompromittierung auf Google-Seite oder eine bösartige OAuth-Clientkonfiguration.
Abfangen des Datenverkehrs, wenn Sie den HTTP-Transport ohne TLS verfügbar machen. Belassen Sie es auf Loopback oder setzen Sie einen TLS-terminierenden Proxy davor.
Zuverlässigkeit
Token-Aktualisierung: automatisch, mit einer Sperre pro Konto, sodass gleichzeitige Aufrufe nur einmal aktualisieren. Ein
401löst genau eine Aktualisierung mit Wiederholung aus.Aktualisierungsfehler:
invalid_grantmarkiert das Konto alsneeds_reauthund gibt einen strukturierten Fehler zurück, der den CLI-Befehl zur Behebung nennt.Ratenbegrenzungen und 5xx: exponentielles Backoff mit vollständigem Jitter unter Berücksichtigung von
Retry-After, bis zumax_attempts.Netzwerkfehler und Zeitüberschreitungen: werden wiederholt, dann als
network_errorodertimeoutohne interne Details gemeldet.Seitennummerierung:
next_page_tokenwird an den Client zurückgegeben, sodass kein Cursor-Status auf dem Server verbleibt.Doppelte Anfragen:
client_request_idunterdrückt Wiederholungen für 24 Stunden. Gleichzeitige Wiederholungen werden innerhalb des Prozesses serialisiert; die Wiederverwendung einer ID mit anderen Argumenten ist ein Fehler, keine stille falsche Antwort.Gegendruck: Gmail-Aufrufe teilen sich einen konfigurierbaren Parallelitätssemaphor, und jedes Konto hat einen unabhängigen Token-Eimer. Eine große Suche oder ein ausgelastetes Konto kann daher keine unbegrenzte nachgelagerte Parallelität erzeugen.
Skalierung und Bereitstellungstopologie
Führen Sie einen Gateway-Prozess für ein bestimmtes Daten- und Geheimnisverzeichnis aus. SQLite-Zustand, Anmeldedatendateien, Token-Aktualisierungssperren und die Koordinierung der laufenden Idempotenz sind absichtlich lokal; das Ausrichten mehrerer Replikate auf dasselbe Volume bietet keinen sicheren Active-Active-Betrieb.
Für eine größere Installation verteilen Sie Konten auf unabhängige Gateway-Instanzen,
jede mit eigener Konfiguration, Daten, Geheimnissen, Bearer-Tokens und Loopback-Port.
Dies hält Fehler, Ratenbegrenzungen, Audit-Pfade und Anmeldedaten isoliert, während
jede Instanz dennoch gleichzeitige Clients bedienen kann. Erhöhen Sie
limits.max_concurrency erst, nachdem Sie die Gmail-Kontingentnutzung und die
Hostkapazität beobachtet haben; der Standardwert von 8 ist konservativ. Setzen Sie
eine TLS-authentifizierte Routing-Schicht davor, wenn Clients eine gemeinsame
Netzwerkadresse benötigen, und leiten Sie jeden Kontoalias an seine eigene Instanz.
Active-Active-Replikate für dasselbe Konto würden erfordern, SQLite und den lokalen Anmeldedaten-/Idempotenzzustand durch koordinierte externe Speicher zu ersetzen. Dies liegt außerhalb des aktuellen Sicherheitsmodells dieses Gateways; skalieren Sie es nicht durch bloßes Hinzufügen von Arbeitern oder gemeinsame Nutzung seines Volumes.
Tests
uv sync --all-extras
uv run pytest -q # 334 tests, no Google account needed
uv run pytest tests/test_security_boundary.py -v # just the guaranteetest_security_boundary.py treibt jeden unterstützten Vorgang durch einen simulierten
Gmail an, der fehlschlägt, wenn eine verbotene URL jemals angefordert wird, und
versucht dann, über jeden verfügbaren Weg in den Papierkorb zu verschieben, als Spam zu
melden und zu senden.
Sobald ein Konto autorisiert ist, testen Sie es gegen ein echtes Postfach. Das Skript verbindet sich genau wie ein MCP-Client über Stdio, führt eine reine Leserunde durch und bestätigt dann, dass die verbotenen Vorgänge abgelehnt werden:
uv run python scripts/try-it.py --account personal
uv run python scripts/try-it.py --account personal --draft # also drafts a reply
uv run python scripts/try-it.py --account personal --archive # archive round tripSchreibgeschützt, es sei denn, Sie übergeben ein Mutations-Flag, und jede von ihm durchgeführte Mutation ist umkehrbar. Der von ihm erstellte Entwurf muss von Ihnen gelöscht werden – das Gateway kann das nicht.
Um interaktiv herumzuklicken:
npx @modelcontextprotocol/inspector .venv/bin/gmail-mcp-gateway serve --transport stdioAnordnung
src/gmail_mcp_gateway/
├── mcpsrv/server.py the tool surface — the complete client-facing API
├── mcpsrv/http.py Streamable HTTP transport, bearer auth, bind safety
├── service.py the supported operations, and nothing else
├── gmail/allowlist.py the endpoint allowlist ← security boundary
├── gmail/labels.py label policy (blocks TRASH/SPAM) ← security boundary
├── gmail/client.py the only code that talks to Gmail
├── gmail/parse.py MIME → structured data, sanitization
├── gmail/compose.py draft assembly from typed fields
├── security/ validation, rate limiting, path confinement
├── auth/oauth.py OAuth 2.0 + PKCE, refresh, revoke
├── accounts.py account registry
├── crypto.py envelope encryption for credentials
├── audit.py audit log
└── cli.py administrationDas Hinzufügen eines unterstützten Vorgangs bedeutet: einen Endpoint in
allowlist.py, eine Methode in service.py, ein Werkzeug in mcpsrv/server.py,
einen Eintrag in EXPOSED_TOOLS und Tests. EXPOSED_TOOLS und FORBIDDEN_TOOLS
werden gegen den laufenden Server geprüft, sodass das Hinzufügen eines Werkzeugs ohne
Deklaration – oder das Hinzufügen eines verbotenen – die Suite fehlschlagen lässt.
Halten Sie das Gateway auf Gmail fokussiert; ein anderes Google-Produkt gehört in einen
separaten MCP-Dienst, nicht in breitere Bereiche hier.
Fehlerbehebung
no OAuth client configured – Schnellstart Schritt 3. Platzieren Sie entweder
secrets/oauth_client.json (Modus 0600) oder setzen Sie GMAIL_MCP_OAUTH_CLIENT_ID und
GMAIL_MCP_OAUTH_CLIENT_SECRET.
Google did not return a refresh token – Sie haben diese App bereits autorisiert.
Entfernen Sie ihren Zugriff unter https://myaccount.google.com/permissions und führen Sie
accounts auth <alias> erneut aus.
consent screen did not grant every required permission – Ein Berechtigungsfeld
wurde nicht angehakt. Führen Sie die Autorisierung erneut durch und lassen Sie alle
angehakt. Das Gateway schlägt hier absichtlich fehl, anstatt ein Konto zu hinterlassen,
das nur halb funktioniert.
Konto wird jede Woche zu needs_reauth – Die OAuth-App befindet sich noch im
"Test"-Modus, in dem Google Aktualisierungstoken nach 7 Tagen ablaufen lässt.
Veröffentlichen Sie sie (Schnellstart Schritt 2.4).
stored credential failed authentication – GMAIL_MCP_MASTER_KEY wurde geändert
oder die Schlüsseldatei wurde ersetzt. Stellen Sie den Originalschlüssel wieder her oder
führen Sie für jedes Konto accounts reauth <alias> aus.
<file> is accessible to other users – Das Gateway weigert sich, ein gruppen- oder
weltweit lesbares Geheimnis zu lesen. Führen Sie chmod 600 für die genannte Datei aus.
refusing to bind …: it is not a loopback address – Beabsichtigt. Binden Sie
127.0.0.1 und verwenden Sie einen SSH-Tunnel, oder setzen Sie
GMAIL_MCP_ALLOW_REMOTE_BIND=true, wenn es sich wirklich um eine vertrauenswürdige
private Schnittstelle handelt. Internet-routbare Adressen werden unabhängig davon
abgelehnt.
serve --transport stdio scheint zu hängen – Richtig; es wartet auf JSON-RPC auf
stdin. Lassen Sie Ihren MCP-Client es starten, oder verwenden Sie scripts/try-it.py.
Etwas hat die Mailbox geändert und ich möchte wissen, was — gmail-mcp-gateway audit --limit 50. Jede Statusänderung ist dort, Ablehnungen inbegriffen.
Lizenz
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
- Alicense-qualityAmaintenanceAn open-source MCP server that provides AI agents with secure access to read, search, and manage emails via Microsoft 365 and Gmail. It features security-first defaults like recipient allowlists and markdown content conversion to facilitate safe agent interaction with mailboxes.4Apache 2.0
- Alicense-qualityBmaintenanceRead-only MCP server for IMAP email access, enabling AI agents to read, search, and monitor email without sending or deleting messages.47MIT
- AlicenseCqualityCmaintenanceMulti-account Gmail MCP server that lets assistants scan inbox, read threads, draft and send emails only after human approval, and manage follow-up reminders.4268MIT
- Flicense-qualityDmaintenanceEnables AI agents to interact with Gmail through a standardized MCP server interface, allowing for natural language email management and automation.
Related MCP Connectors
Hosted email MCP for AI agents with inboxes, send/receive, memory, recovery, and credits.
Shipmail MCP server for AI agent custom-domain email inboxes with REST API and webhooks.
Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.
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/systheno/gmail-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server