gmail-mcp
Gmail MCP server — scope-gated tools (readonly / send / modify), path jails for attachments + downloads, hardened OAuth credentials, Sigstore-signed releases.
README
gmail-mcp
Read, search, send, draft, label, filter, and thread Gmail from any MCP-enabled AI assistant. Wraps the Gmail API with scope-gated tools and in-process safeguards.
[!NOTE] This repository has not yet undergone a full independent third-party security review end-to-end. The hardening layer (path jails with
realpath+O_NOFOLLOW, CRLF sanitization on both email-assembly paths, OAuth scope filtering at startup, Zod bounds on every Gmail ID, crypto MIME boundary, credentials at0o600, opt-in redacted JSONL audit log (GMAIL_MCP_AUDIT_LOG), per-bucket daily+monthly write rate limits (send/delete/modify/drafts/labels/filters), Sigstore + SLSA + SBOM-signed releases, fast-check fuzz suite) is tested on every CI run. Against the two parent forks,klodr/gmail-mcpis already a meaningful step forward on prompt-injection and supply-chain posture. For mission-critical or high-sensitivity deployments, treat the server as carefully as any third-party MCP: prefer a narrowly-scoped OAuth token, enable human-in-the-loop confirmation on write tools, and track this repo's release notes for security-relevant updates. See SECURITY.md for the detailed threat model.
A Model Context Protocol (MCP) server that lets AI assistants (Claude Desktop, Claude Code, Cursor, Continue, OpenClaw…) read and manage a Gmail account through scope-gated tools. Exposes the Gmail v1 API surface you actually need (messages, threads, labels, filters, attachments, drafts, reply-all) behind a single npx install.
Why this MCP?
Comparison of the three maintained forks of the original Gmail MCP server, focusing on what an agent platform actually needs — prompt-injection safety, supply-chain integrity, and operational hygiene:
| Capability | GongRzhe/Gmail-MCP-Server (original, unmaintained) | ArtyMcLabin/Gmail-MCP-Server (intermediate fork) | klodr/gmail-mcp (this repo) |
|---|---|---|---|
| Core Gmail surface | |||
| Send / draft / read / search messages | ✅ | ✅ | ✅ |
| Label CRUD | ✅ | ✅ | ✅ |
| Filter CRUD | ⚠️ list_filters broken |
✅ fixed | ✅ |
| Batch modify / delete | ✅ | ✅ | ✅ |
Reply threading (In-Reply-To / References) |
❌ orphaned replies | ✅ | ✅ |
| Reply-all tool | ❌ | ✅ | ✅ |
Send-as alias (from parameter) |
❌ | ✅ | ✅ |
Thread-level tools (get_thread, list_inbox_threads, get_inbox_with_threads) |
❌ | ✅ | ✅ |
Download email to disk (json/eml/txt/html) |
❌ | ✅ | ✅ |
| Download attachment | ✅ | ✅ | ✅ |
| OAuth / authorization | |||
--scopes flag for least-privilege auth |
❌ | ✅ | ✅ |
| Tool list filtered by granted scopes | ❌ | ✅ | ✅ |
OAuth credentials file mode 0o600 |
❌ | ✅ | ✅ |
| Security — input handling | |||
CRLF header injection sanitization (\r\n\0) |
❌ | ⚠️ partial | ✅ |
Path traversal in download_attachment |
❌ | ✅ fixed | ✅ |
Attachment source jail (GMAIL_MCP_ATTACHMENT_DIR) blocks exfiltration of ~/.ssh/id_rsa etc. via prompt injection |
❌ | ❌ | ✅ |
Download destination jail (GMAIL_MCP_DOWNLOAD_DIR) |
❌ | ❌ | ✅ |
O_NOFOLLOW on leaf writes (pre-existing symlink at destination rejected) |
❌ | ❌ | ✅ |
Post-mkdir realpath re-verification (TOCTOU defense) |
❌ | ❌ | ✅ |
Zod bounds on maxResults / batchSize / messageIds length |
❌ | ❌ | ✅ |
Cryptographic MIME boundary (crypto.randomBytes, not Math.random) |
❌ | ❌ | ✅ |
| MCP protocol & tool surface | |||
| MCP SDK version | v0.4.x (outdated) | v1.27.x | v1.29.x |
Tool annotations (readOnlyHint / destructiveHint / idempotentHint) |
❌ | ✅ | ✅ |
llms-install.md (LLM-readable install guide) |
❌ | ❌ | ✅ |
| Publishing / discoverability | |||
| Published on npm | ✅ stale — no release since the fork diverged | ❌ (consumed as a GitHub install from the intermediate fork) | ✅ dedicated scoped package, signed releases |
| GitHub repo | GongRzhe/Gmail-MCP-Server | ArtyMcLabin/Gmail-MCP-Server | klodr/gmail-mcp |
| Active maintenance (last 30 d) | ❌ (dormant since Aug 2025) | ⚠️ sporadic | ✅ daily review cycle (CodeRabbit + human) |
| Supply-chain integrity | |||
| Node.js floor | ❌ >=14 (EOL April 2023) |
❌ >=14 (EOL April 2023) |
✅ >=22 (Active LTS, maintenance until 2027-04-30) |
CI: CodeQL Advanced (javascript-typescript + actions) |
❌ | ❌ | ✅ |
| CI: OpenSSF Scorecard (weekly scan + badge) | ❌ | ❌ | ✅ |
| CI: Socket Security supply-chain alerts | ❌ | ❌ | ✅ |
| CI: CodeRabbit assertive reviews on every PR | ❌ | ❌ | ✅ |
Release: Sigstore-signed dist/index.js + SLSA in-toto attestation |
❌ | ❌ | ✅ |
| Release: npm provenance statement | ❌ | ❌ | ✅ |
Release: single-file tsup ESM bundle (smaller tarball, easier to verify) |
❌ (multi-file tsc) |
❌ (multi-file tsc) |
✅ (target node22, ES2024) |
| Testing | |||
| Unit/property tests | ❌ (0 tests) | ⚠️ (97 tests) | ✅ (215 tests) |
Statement coverage across src/** |
0% | 16.14% | >45% |
| Fast-check property-based fuzz suite | ❌ | ❌ | ✅ |
| Hardening-specific test file (jails, CRLF, O_EXCL) | ❌ | ❌ | ✅ |
| CI/CD hardening | |||
| Shell-injection-safe GitHub Actions workflows | ❌ | ✅ | ✅ |
Workflows use least-privilege permissions: scopes |
❌ | ✅ | ✅ |
| All GitHub Actions pinned by full commit SHA | ❌ | ❌ | ✅ |
| Operational | |||
CHANGELOG.md (Keep-a-Changelog) |
❌ | ❌ | ✅ |
SECURITY.md (vulnerability reporting) |
❌ | ❌ | ✅ |
CONTRIBUTING.md |
❌ | ❌ | ✅ |
.github/FUNDING.yml |
❌ | ❌ | ✅ |
klodr/gmail-mcp is the only one of the three with (a) source-path jails that make prompt-injection attachment exfiltration inert, (b) a modern supply chain (Scorecard, Socket, Sigstore), and (c) an in-repo review policy (.coderabbit.yaml) that every PR must pass before merge.
Installation
npm install -g @klodr/gmail-mcp
Or directly via npx:
npx -y @klodr/gmail-mcp
Requires Node.js 22+.
Configuration
1. Google Cloud OAuth credentials
- Open the Google Cloud Console.
- Create a project and enable the Gmail API.
- Under APIs & Services → Credentials, create an OAuth 2.0 Client ID (Desktop or Web). For Web, add
http://localhost:3000/oauth2callbackto the authorised redirect URIs. - Download the JSON, rename it to
gcp-oauth.keys.json, place it at~/.gmail-mcp/gcp-oauth.keys.json(or override withGMAIL_OAUTH_PATH=/abs/path/gcp-oauth.keys.json).
2. Authenticate (once)
npx -y @klodr/gmail-mcp auth --scopes=gmail.readonly
Always pass --scopes with the minimum you actually need — the MCP filters the tool list at startup based on the granted scopes, so a read-only token doesn't expose write tools to the LLM. A browser opens for Google's consent flow; tokens are written to ~/.gmail-mcp/credentials.json (mode 0o600).
3. Register the server with your MCP client
{
"mcpServers": {
"gmail": {
"command": "npx",
"args": ["-y", "@klodr/gmail-mcp"]
}
}
}
Client-specific config file:
- Claude Code:
~/.claude.json - Claude Desktop:
~/Library/Application Support/Claude/claude_desktop_config.json(macOS) /%APPDATA%\Claude\claude_desktop_config.json(Windows) - Cursor:
~/.cursor/mcp.json - OpenClaw:
~/.openclaw/openclaw.json
See llms-install.md for an LLM-readable install guide.
OAuth scopes
| Scope shorthand | Full Gmail scope | What it grants |
|---|---|---|
gmail.readonly |
…/auth/gmail.readonly |
Read messages, threads, labels (filter tools require gmail.settings.basic) |
gmail.modify |
…/auth/gmail.modify |
Readonly + apply/remove labels, delete messages |
gmail.compose |
…/auth/gmail.compose |
Create drafts |
gmail.send |
…/auth/gmail.send |
Send messages |
gmail.labels |
…/auth/gmail.labels |
Manage labels only |
gmail.settings.basic |
…/auth/gmail.settings.basic |
Manage filters |
Recipes:
# Read-only browsing
npx @klodr/gmail-mcp auth --scopes=gmail.readonly
# Read + send (mailing-list bot)
npx @klodr/gmail-mcp auth --scopes=gmail.readonly,gmail.send
# Everything (default; explicit)
npx @klodr/gmail-mcp auth --scopes=gmail.modify,gmail.settings.basic
# Default + permanent delete (delete_email / batch_delete_emails)
# gmail.modify authorizes trash; mail.google.com is the only scope
# that authorizes purging from Trash. Both are listed because the
# tool gate does exact scope-name matching — a token holding only
# mail.google.com would not enable the gmail.modify-gated tools,
# even though Google's scope hierarchy would technically accept the
# same calls.
npx @klodr/gmail-mcp auth --scopes=gmail.modify,mail.google.com,gmail.settings.basic
Safeguards
| Knob | Env var | Default | Notes |
|---|---|---|---|
| Attachment jail | GMAIL_MCP_ATTACHMENT_DIR=/abs/path |
~/GmailAttachments/ (auto-created mode 0o700) |
Every attachment path (send_email, draft_email, reply_all) must live inside this directory after realpath canonicalization. Symlinks pointing outside are rejected. Blocks prompt-injected exfiltration of ~/.ssh/id_rsa, ~/.gmail-mcp/credentials.json, ~/.claude.json, etc. |
| Download jail | GMAIL_MCP_DOWNLOAD_DIR=/abs/path |
~/GmailDownloads/ (auto-created mode 0o700) |
download_email and download_attachment write exclusively here. The leaf is opened with O_NOFOLLOW; post-mkdir the resolved path is re-verified against the jail root (TOCTOU defense). |
| OAuth keys path | GMAIL_OAUTH_PATH=/abs/path/gcp-oauth.keys.json |
~/.gmail-mcp/gcp-oauth.keys.json |
Google Desktop/Web OAuth client credentials. |
| Credentials path | GMAIL_CREDENTIALS_PATH=/abs/path/credentials.json |
~/.gmail-mcp/credentials.json |
Access/refresh tokens. File mode 0o600. |
| Rate limit state dir | GMAIL_MCP_STATE_DIR=/abs/path |
~/.gmail-mcp/ |
Where the rolling call-history for rate limiting is persisted (ratelimit.json, mode 0o600). Same directory is reused for any future state files. |
| Rate limit overrides | GMAIL_MCP_RATE_LIMIT_<bucket>=D/day,M/month |
see below | Override the per-bucket daily/monthly caps. Buckets: send (400/6000), delete (200/2000), modify (500/5000), drafts (300/3000), labels (50/500), filters (20/200). The bucket name is lowercase and matches the tool family. Example: GMAIL_MCP_RATE_LIMIT_send=100/day,1500/month. |
| Rate limit disable | GMAIL_MCP_RATE_LIMIT_DISABLE=true |
unset (limiter active) | Kill-switch for the entire limiter. Use only for test suites or controlled batch operations. |
| Audit log | GMAIL_MCP_AUDIT_LOG=/abs/path/audit.jsonl |
unset (no audit trail) | Opt-in append-only JSONL log of every tool call (name, redacted args, outcome). File mode 0o600. Must be an absolute path; relative paths are rejected at startup. Redaction keeps structural keys and drops values under an allowlist. |
| Dry-run | GMAIL_MCP_DRY_RUN=true |
unset (real calls) | When "true" (strict match), every write tool (send_email, reply_all, draft_email, delete_email, modify_email, batch_modify_emails, batch_delete_emails, create_label, update_label, delete_label, get_or_create_label, create_filter, delete_filter, create_filter_from_template, modify_thread) short-circuits before reaching Gmail and returns the redacted payload it would have sent. Useful for CI smoke tests, agent debugging, and human-in-the-loop approval flows. Read tools ignore the flag (nothing to preview). Matches MERCURY_MCP_DRY_RUN / FAXDROP_MCP_DRY_RUN on the sibling servers. |
Tools
The exact set depends on the OAuth scopes granted at auth time. Full catalog:
- Messages —
send_email,draft_email,read_email,search_emails,modify_email,delete_email,download_email,download_attachment,batch_modify_emails,batch_delete_emails,reply_all - Threads —
get_thread,list_inbox_threads,get_inbox_with_threads,modify_thread - Labels —
list_email_labels,create_label,update_label,delete_label,get_or_create_label - Filters —
list_filters,get_filter,create_filter,delete_filter,create_filter_from_template
Every write tool is annotated with destructiveHint / readOnlyHint / idempotentHint per the MCP spec so policy-aware clients can gate on HITL confirmation.
search_emails query syntax
search_emails accepts Gmail's native search operators — from:, to:, subject:, has:attachment, after:YYYY/MM/DD, before:YYYY/MM/DD, is:unread, label:<name>, etc. They combine freely: from:alice@example.com after:2026/01/01 has:attachment. Full reference: Google's Gmail search operators cheat sheet.
Roadmap
See ROADMAP.md.
Ecosystem
The wider Gmail-MCP landscape — 29 standalone repositories and 323 forks of the original GongRzhe server — is reviewed in docs/COMPETITORS.md. That page covers which ideas we borrowed, which we chose not to, and where klodr/gmail-mcp sits on the maturity axes.
Contributing
See CONTRIBUTING.md for the test / build / lint checklist and release process.
Security
See SECURITY.md for the vulnerability-reporting process and the current security model, and ASSURANCE_CASE.md for the threat model, trust boundaries, and CWE/OWASP mitigation table.
Project continuity
See CONTINUITY.md for the handover plan if the maintainer becomes unavailable.
License
MIT — see LICENSE.
History
klodr/gmail-mcp is the maintenance fork of a two-step upstream chain:
- GongRzhe/Gmail-MCP-Server — the original server. Unmaintained since August 2025 (7+ months with zero maintainer activity and 72+ unmerged pull requests).
- ArtyMcLabin/Gmail-MCP-Server — Arty MacKiewicz's active fork, which merged a pile of long-pending community PRs: reply threading (#91), reply-all (#3 by @MaxGhenis),
list_filtersfix (#4 by @nicholas-anthony-ai),--scopesflag (#6 by @tansanDOTeth), CI/CD hardening (#9) + security hardening (#10) + dependency CVE fixes (#11) by @JF10R, tool annotations (#14 by @bryankthompson),download_email(#13 by @icanhasjonas).
klodr/gmail-mcp carries all of the above forward and adds the supply-chain / path-jail / review-policy layer (see comparison table above). Credit to every PR author along the chain.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。