
mcp-gmail-manager
A comprehensive Gmail Model Context Protocol server: 33 tools covering send, reply, forward, drafts, search, read, attachments, trash, labels, filters, signature, and vacation responder.
Two optional features that distinguish it from other Gmail MCPs:
- Local audit log (on by default) β every write/send/modify/download appends a JSON line to
audit.jsonl. Metadata only (no body content). Compliance trail without third-party services. - Recipient allowlist (off by default) β when enabled, every outbound operation (
send_email,create_draft,reply_to_message,forward_message) checks recipients against configured domains and explicit addresses. Useful for institutional / compliance contexts. Seeexamples/config.with-allowlist.jsonto enable.
Tools (33)
| Group | Tools |
|---|---|
| Send / reply / forward | send_email, reply_to_message, forward_message |
| Drafts | create_draft, list_drafts, send_draft, update_draft, delete_draft |
| Read / profile | get_profile, get_message, search_threads, get_thread |
| Attachments | get_message_attachments, download_attachment |
| Trash | trash_message, untrash_message, trash_thread, untrash_thread |
| Labels | list_labels, create_label, update_label, delete_label, label_message, unlabel_message, label_thread, unlabel_thread |
| Filters | list_filters, create_filter, delete_filter |
| Signature | get_signature, update_signature |
| Vacation responder | get_vacation_responder, set_vacation_responder |
OAuth scopes requested: gmail.modify + gmail.settings.basic. Does not request the https://mail.google.com/ superuser scope β permanent delete is intentionally unsupported.
First-time auth
Move your credentials into the config directory (default ~/.config/mcp-gmail-manager/):
mkdir -p ~/.config/mcp-gmail-manager
mv ~/Downloads/client_secret_*.json ~/.config/mcp-gmail-manager/credentials.json
chmod 600 ~/.config/mcp-gmail-manager/credentials.jsonRun the auth flow:
mcp-gmail-manager-authThis binds to localhost:8765 and prints a Google authorisation URL. Open it in a browser on a machine that can reach localhost:8765 on the auth host:
- Local desktop: the printed URL works directly.
- Remote / headless server: forward the port from your laptop first:
Then run
ssh -L 8765:localhost:8765 user@your-servermcp-gmail-manager-authinside that SSH session.
Authorise with the Google account that will own outbound mail. On success the script writes token.json and exits.
Token expiration
The refresh token's lifetime depends on how the OAuth consent screen is configured:
| Setup | Refresh token lifetime | Re-auth required? |
|---|---|---|
| Internal (Google Workspace) | No expiration | Never (until user revokes) |
| External + Testing | 7 days (Google's policy for unverified apps) | Yes β weekly |
| External + Production verified | No expiration | Never, but verification requires a paid Google security assessment |
When the refresh token expires in Testing mode you'll see invalid_grant or Token has been expired or revoked errors. To recover:
rm ~/.config/mcp-gmail-manager/token.json
mcp-gmail-manager-authTakes ~30 seconds. Your credentials.json is not affected β only the user's token.
How to avoid the weekly rotation
- Workspace users: configure the consent screen as Internal instead of External. Token never expires.
- Personal Gmail users: weekly re-auth is the only practical option today. Production verification for
gmail.modifyrequires a Google security assessment (paid, weeks of process) β not feasible for most personal projects. - Set a calendar reminder or a cron job to nudge you weekly. A future release may add proactive in-tool warnings before expiry.
Register with Claude Code
If installed via pipx:
claude mcp add gmail-manager -- mcp-gmail-managerIf installed in a manual venv that isn't on $PATH:
claude mcp add gmail-manager -- ~/.venv-mcp-gmail/bin/mcp-gmail-managerRestart your Claude Code session so the new tool schemas load.
Multiple Gmail accounts
Each MCP instance handles one Gmail account. To use several accounts from the same Claude Code session (e.g. personal + work), register the MCP once per account with a distinct GMAIL_MCP_CONFIG_DIR. Each instance gets its own credentials, token, audit log, and config β fully isolated.
Setup per account
# 1. Dedicated config directory
mkdir -p ~/.config/mcp-gmail-<name> && chmod 700 ~/.config/mcp-gmail-<name>
# 2. Reuse the same OAuth client (one credentials.json works for any user in the same GCP project)
cp ~/.config/mcp-gmail-<other>/credentials.json ~/.config/mcp-gmail-<name>/
chmod 600 ~/.config/mcp-gmail-<name>/credentials.json
# 3. Authenticate with the target Gmail account
GMAIL_MCP_CONFIG_DIR=$HOME/.config/mcp-gmail-<name> mcp-gmail-manager-auth
# 4. Register with the env override
claude mcp add gmail-<name> -s user \
-e GMAIL_MCP_CONFIG_DIR=$HOME/.config/mcp-gmail-<name> \
-- mcp-gmail-managerRestart Claude Code. The tools appear under separate namespaces:
mcp__gmail-personal__send_emailβ sends from the personal accountmcp__gmail-work__send_emailβ sends from the work account
You can prompt Claude with "send via gmail-work" and it picks the right namespace.
Per-account configuration
Each <config_dir>/config.json is independent. Useful patterns:
// ~/.config/mcp-gmail-work/config.json β strict allowlist
{
"allowlist": {
"enabled": true,
"domains": ["yourcompany.com"]
}
}// ~/.config/mcp-gmail-personal/config.json β silence the audit log
{
"audit_log": { "enabled": false }
}Compromise of one account's token does not leak the other β each lives in a separate directory with chmod 600.
Security notes
- Token storage:
token.jsonis writtenchmod 600. Treat it as a password β anyone with read access can act as your Gmail account. - No remote attestation: this server runs entirely on your machine. No telemetry, no third-party calls beyond
googleapis.com. - Allowlist is defence in depth, not perimeter security: an attacker who compromises your machine can read
token.jsonand call the Gmail API directly, bypassing the MCP entirely. The allowlist defends against the LLM being tricked or hallucinating malicious recipients, not against host compromise. - OAuth scope is broad:
gmail.modifycovers everything except permanent delete. If you only need to send, fork and replace the scope withgmail.send. - Permanent delete intentionally unsupported: we don't request
https://mail.google.com/. Deletes go to Trash and can be undone withuntrash_*.
pipx install mcp-gmail-managerBefore it works, you'll need: GMAIL_MCP_TOKEN
Requirements
- Python β₯ 3.10
- A Google Cloud project with the Gmail API enabled and an OAuth 2.0 client (Desktop type)
- A way to forward
localhost:8765to your auth host (typicallyssh -L 8765:localhost:8765 user@host)
Install
Recommended β pipx (installs in an isolated venv, exposes the entry points on $PATH):
pipx install mcp-gmail-managerIf pipx is missing:
sudo apt install pipx # Debian / Ubuntu / Mint
brew install pipx # macOS
pipx ensurepath # makes ~/.local/bin available, may need shell restartAlternative β manual venv:
python3 -m venv ~/.venv-mcp-gmail
~/.venv-mcp-gmail/bin/pip install mcp-gmail-manager
# Use the absolute path when registering with Claude Code (see below)Why not plain pip install system-wide? On modern Debian-based distros it fails with error: externally-managed-environment (PEP 668) β the OS protects its Python. The two methods above are the canonical workarounds.
From source:
git clone https://github.com/arthjhon/mcp-gmail-manager.git
cd mcp-gmail-manager
pipx install .Google Cloud setup (one-time, ~10 minutes)
- Go to Google Cloud Console and create a new project (or pick an existing one).
- Enable the Gmail API (not "Gmail MCP API" β that's Google's own remote MCP; not what we want).
- Configure the OAuth consent screen:
- User type: Internal if your account is part of a Google Workspace (no token expiration); otherwise External in Testing mode (up to 100 users, refresh tokens expire every 7 days β see Token expiration below).
- Scopes: add
https://www.googleapis.com/auth/gmail.modifyandhttps://www.googleapis.com/auth/gmail.settings.basic. Do not add anything else. - Test users (External only): add the Gmail address you'll authenticate with.
- Create an OAuth Client ID:
- Application type: Desktop app
- Download the JSON. Save it as
credentials.json.
Configuration
~/.config/mcp-gmail-manager/config.json is optional β if it doesn't exist, sensible defaults apply (no allowlist, audit log enabled). Two ready-to-copy examples are provided:
examples/config.example.jsonβ minimal, no allowlist (default behaviour). Use this if you want the MCP to send to any address.examples/config.with-allowlist.jsonβ institutional setup with allowlist enforced.
Schema reference:
{
"allowlist": {
"enabled": false,
"domains": [],
"emails": []
},
"audit_log": {
"enabled": true,
"path": null
},
"attachments": {
"max_total_bytes": 20971520
}
}| Field | Default | Meaning |
|---|---|---|
allowlist.enabled | false | When false, any recipient is accepted. Enable explicitly for institutional use. |
allowlist.domains | [] | Lower-case domain suffixes accepted as recipients. |
allowlist.emails | [] | Explicit lower-case email addresses accepted regardless of domain. |
audit_log.enabled | true | Append every write/modify/send to JSONL. |
audit_log.path | null | null β <config_dir>/audit.jsonl. Override to centralise logs. |
attachments.max_total_bytes | 20971520 (20 MB) | Combined size cap per send. Gmail's hard limit is 25 MB raw. |
Environment variable overrides
| Variable | Default |
|---|---|
GMAIL_MCP_CONFIG_DIR | $XDG_CONFIG_HOME/mcp-gmail-manager or ~/.config/mcp-gmail-manager |
GMAIL_MCP_CREDENTIALS | <config_dir>/credentials.json |
GMAIL_MCP_TOKEN | <config_dir>/token.json |
Limitations
- OAuth "Production" verification for
gmail.modifyrequires a paid Google security assessment. Stay in "Internal" (Workspace, no expiration) or "Testing" (β€ 100 users, 7-day refresh token rotation β see Token expiration) to avoid this. - HTML email body composition is not exposed as a first-class field. Send via
create_draft+ manual HTML editing in the Gmail UI, or extend_build_mimein a fork. - Push notifications (Pub/Sub
watch/stop) not implemented β out of scope.
Licensed under MITβ you can use, modify, and redistribute it under that license's terms.
License
MIT β see LICENSE.