Gmail Model Context Protocol server with recipient allowlist and local audit log.
Project description
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.
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
pip install mcp-gmail-manager
Or from source:
git clone https://github.com/arthjhon/mcp-gmail-manager.git
cd mcp-gmail-manager
pip 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; otherwise External in Testing mode (limited to 100 users, tokens expire every 7 days — fine for individuals).
- 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.
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 runmcp-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.
Register with Claude Code
claude mcp add gmail-manager -- mcp-gmail-manager
Or, if you installed inside a virtualenv that isn't on $PATH:
claude mcp add gmail-manager -- /path/to/venv/bin/mcp-gmail-manager
Restart your Claude Code session so the new tool schemas load.
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 |
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_*.
Limitations
- OAuth "Production" verification for
gmail.modifyrequires a Google security assessment (paid, weeks of process). Stay in "Internal" (Workspace) or "Testing" (≤ 100 users, 7-day token refresh) modes 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.
Contributing
Issues and PRs welcome. Keep changes scoped, document any new tool with a schema example, and add an audit-log entry for anything that mutates state.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_gmail_manager-0.1.0.tar.gz.
File metadata
- Download URL: mcp_gmail_manager-0.1.0.tar.gz
- Upload date:
- Size: 18.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a73aeb4dee8d71bd583e6413506861ef5497533a32f9a6f99abcd27883671806
|
|
| MD5 |
0f0e60ec3677c36c131b54cd943cecc9
|
|
| BLAKE2b-256 |
73c9dca1bd7a95c89aa3783407f730b78662d5036dbbc3a65ee468c8489a204e
|
File details
Details for the file mcp_gmail_manager-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcp_gmail_manager-0.1.0-py3-none-any.whl
- Upload date:
- Size: 16.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82a7096c44d255a342de1b0c9acefe7b044b4a253c52891d9452e5dcd410333e
|
|
| MD5 |
cb256590b00fdcee5451e60799c5b5d1
|
|
| BLAKE2b-256 |
eef00fbe2d3a8c3adc1776dc7c7cef4e4a1aae3d0eb671e84815394f09af80c9
|