Labsco
arthjhon logo

Gmail Manager

from arthjhon

Gmail MCP server (33 tools) with optional recipient allowlist and local audit log

πŸ”₯πŸ”₯πŸ”₯βœ“ VerifiedAccount requiredAdvanced setup

mcp-gmail-manager

🌐 Leia em portuguΓͺs (pt-BR) β†’

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. See examples/config.with-allowlist.json to enable.

Tools (33)

GroupTools
Send / reply / forwardsend_email, reply_to_message, forward_message
Draftscreate_draft, list_drafts, send_draft, update_draft, delete_draft
Read / profileget_profile, get_message, search_threads, get_thread
Attachmentsget_message_attachments, download_attachment
Trashtrash_message, untrash_message, trash_thread, untrash_thread
Labelslist_labels, create_label, update_label, delete_label, label_message, unlabel_message, label_thread, unlabel_thread
Filterslist_filters, create_filter, delete_filter
Signatureget_signature, update_signature
Vacation responderget_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.json

Run the auth flow:

mcp-gmail-manager-auth

This 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:
    ssh -L 8765:localhost:8765 user@your-server
    Then run mcp-gmail-manager-auth inside 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:

SetupRefresh token lifetimeRe-auth required?
Internal (Google Workspace)No expirationNever (until user revokes)
External + Testing7 days (Google's policy for unverified apps)Yes β€” weekly
External + Production verifiedNo expirationNever, 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-auth

Takes ~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.modify requires 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-manager

If installed in a manual venv that isn't on $PATH:

claude mcp add gmail-manager -- ~/.venv-mcp-gmail/bin/mcp-gmail-manager

Restart 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-manager

Restart Claude Code. The tools appear under separate namespaces:

  • mcp__gmail-personal__send_email β†’ sends from the personal account
  • mcp__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.json is written chmod 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.json and 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.modify covers everything except permanent delete. If you only need to send, fork and replace the scope with gmail.send.
  • Permanent delete intentionally unsupported: we don't request https://mail.google.com/. Deletes go to Trash and can be undone with untrash_*.