gmail-mcp
为你的 AI 助手提供 Gmail——同时管理多个账户,运行在你自己的服务器上。
gmail-mcp 将 Gmail 连接到 Claude 和任何其他 MCP 客户端。它可以搜索和阅读邮件、发送和全部回复(带引用历史)、转发、处理附件和内联图片,并管理草稿、标签和线程——同时支持多个 Google 账户。
它作为远程服务器运行在你自己的 Cloudflare Worker 上,因此同一个连接可以从笔记本电脑上的 Claude Code、浏览器中的 claude.ai 以及手机上的 Claude 访问。每个连接登录一个 Google 账户,Google 刷新令牌保存在你的 Cloudflare 账户中。
有两件事促使人们选择这里。Claude 和 Google 内置的 Gmail 连接器可以阅读邮件和撰写草稿,但无法发送,而且每个助手账户只能绑定一个 Google 账户。能够发送邮件的服务器通常是本地进程——在办公桌前没问题,但从手机上看不到。
对比
gmail-mcp | ||||||
运行位置 | Cloudflare Workers | 供应商托管 | 你的服务器或本地 | 本地 | 本地 | 本地 |
可从手机访问 | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
同时管理多个邮箱 | ✅ 按连接绑定 | ❌ | ✅ 每次调用选择 | ❌ 仅别名 | ❌ | ✅ 每次调用选择 |
发送邮件 | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
附件 · 内联 | ✅ | 未记录 | ✅ | ✅ | ❌ | ✅ |
带引用历史的全部回复 | ✅ | ❌ | 仅草稿 | 无引用 | ❌ | ✅ |
转发 | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ |
尊重每个部分的字符集 | ✅ | — | ❌ 假定 UTF-8 | ❌ 假定 UTF-8 | ❌ | ❌ |
拒绝 CRLF 头注入 | ✅ | — | ✅ 框架级 | ✅ 剥离 | ❌ 无防护 | ✅ |
邮箱设置(过滤器、假期回复) | ❌ 超出范围 | ❌ | 过滤器 | 过滤器 | ✅ | ❌ |
工具数量 | 24 | 11–16 | 14 (Gmail) | 30 | 64 | 11 |
谁持有你的刷新令牌 | 你 | 供应商 | 你 | 你 | 你 | 你 |
google_workspace_mcp 是这里最完整的项目。它覆盖了整个 Workspace 而不仅仅是 Gmail,并且它会附加你的 Gmail 签名、直接从 URL 拉取附件,这两点 gmail-mcp 都不做。shinzo-labs/gmail-mcp 通过其 64 个工具支持假期回复、委托和 S/MIME;这些工具位于 gmail.settings.* 之下,这是 gmail-mcp 从不请求的作用域,因此无论授权如何变化,它们都超出其能力范围。
其余大部分差异由两个设计决策决定。通过调用参数路由账户,让一个授权可以访问所有已连接的邮箱;而将邮箱绑定到连接,则意味着错误的参数不会触及任何内容。在读取方面,本地服务器将每个部分都解码为 UTF-8:ISO-2022-JP 和 Shift_JIS 邮件会乱码,而 Gmail 以附件块形式存储的长邮件会返回空正文。
Related MCP server: gmail-mcp
部署
大约十分钟。你需要一个 Cloudflare 账户、bun 和一个 Google 账户。Cloudflare 账户上的域名是可选的——没有域名时 Worker 会在 workers.dev 上响应。
1 · 创建 Google OAuth 客户端
PROJECT="gmail-mcp-$(openssl rand -hex 3)"
gcloud auth login
gcloud projects create "$PROJECT" --name="gmail-mcp"
gcloud config set project "$PROJECT"
gcloud services enable gmail.googleapis.comGoogle 没有为接下来的两步提供 API,因此它们需要在 Cloud 控制台 中完成:
OAuth 同意屏幕 → 外部,然后在 受众群体 下按 发布应用。如果保持 测试 状态,Google 会在 7 天后使每个刷新令牌过期,每次连接都会随之失效。发布后,应用在登录时会显示未经验证警告,并且最多可服务 100 个账户。
凭据 → 创建凭据 → OAuth 客户端 ID → Web 应用,并将
https://<your-host>/callback设为已授权的重定向 URI。请妥善保存客户端 ID 和客户端密钥。
<your-host> 是您指向 Worker 的域名,或者是它默认获得的 workers.dev 主机名。先部署再回来填写也可以——Worker 在 / 路径提供的指南会显示确切的值。
2 · 部署 Worker
点击按钮会将仓库复制到您的 GitHub 账户,创建 KV 命名空间和 Durable Object,并要求您提供四个密钥。它会部署到 workers.dev;之后您可以在 设置 → 路由 下添加自定义域名。
或者使用终端:
git clone https://github.com/mkpoli/gmail-mcp && cd gmail-mcp
bun install
bun run setupbun run setup 会询问要使用哪个域名,创建或复用 OAUTH_KV 命名空间,接收客户端 ID 和密钥,生成 cookie 密钥,然后执行部署。前两个回答会写入 wrangler.local.jsonc,该文件已被 git 忽略——wrangler.jsonc 不包含任何账户命名空间或域名信息,因此克隆后可以在任何地方部署。重新运行 setup 来轮换单个密钥也是安全的。
3 · 连接客户端
将客户端 ID 和密钥字段留空——MCP 客户端会自行完成注册。
claude mcp add --transport http gmail-personal https://<your-host>/mcp
claude mcp add --transport http gmail-work https://<your-host>/mcp/work在 Claude 中运行 /mcp,每个连接都会登录到各自的 Google 账户。在 claude.ai 中,路径为 设置 → 连接器 → 添加自定义连接器,使用相同的 URL。/mcp/ 后面的任何单段标签都可以使用,这样同一个部署可以为多个邮箱提供服务,也能兼容那些拒绝两个服务器共享同一 URL 的客户端。
您的部署会在 https://<your-host>/ 提供本指南。
功能
whoami
search_messages
get_message
get_thread
get_attachment
send_message
reply_all
forward_message
create_draft
update_draft
send_draft
delete_draft
list_drafts
stage_attachment_begin
stage_attachment_append
stage_attachment_finish
list_labels
create_label
update_label
delete_label
modify_labels
modify_thread_labels
batch_modify_messages
trash_message · untrash_message
trash_thread · untrash_thread
消息的发送方式与邮件客户端一致:纯文本配 HTML 备用版本,文件作为附件,内嵌图片通过 cid: 引用,整体结构为 multipart/mixed › multipart/related › multipart/alternative。主题和显示名称使用 RFC 2047 编码,文件名使用 RFC 2231 编码,因此日文、中文和 emoji 都能完好传输。
reply_all 会读取原邮件的 Reply-To、From、To 和 Cc 字段,剔除您自己的地址以及您用作发件人的任何地址,从原发件人写下的内容中提取引用,保留 References 链,并仅引用您选择回复的部分。forward_message 会重新生成原始信封,并可重新附带原邮件的附件。
create_draft 配合 replyToMessageId 可以将回复写成草稿供后续编辑:它会加入原邮件的线程,保留 In-Reply-To 和 References,推导出回复全部收件人及 Re: 主题,并引用原邮件。update_draft 只修改提供的字段;收件人、主题、正文和附件均可独立更新。草稿回复会保留原邮件的引用和线程信息。当文件体积过大无法通过工具参数传递 base64 时,可改用分块上传:stage_attachment_begin 返回一个上传 URL,curl -T 可将原始字节一次性上传,stage_attachment_append 则分块接收 base64,所有 attachments 字段都接受返回的 stagingId。
读取操作有意设置了上限:消息和线程正文有字符数限制,整个响应有字节数上限,附件只有在体积足够小的情况下才会内联返回。过长的邮件线程或过大的文件会附带说明被截断返回,而不会填满助手的上下文。
工作原理
两种 OAuth 流程在此交汇。MCP 客户端通过 workers-oauth-provider 向 Worker 进行身份验证;Worker 则通过 Google 的授权码流程(含 PKCE)代表用户访问 Gmail。客户端持有自己的令牌,Worker 持有用户的令牌——任何一方都不会接触到另一方的凭据。
sequenceDiagram
autonumber
participant C as MCP client<br/>(Claude Code · claude.ai)
participant W as Worker<br/>(OAuthProvider + McpAgent)
participant G as Google<br/>(OAuth + Gmail API)
C->>W: POST /register (dynamic client registration)
C->>W: GET /authorize (PKCE challenge)
W->>C: approval dialog
C->>G: consent screen — pick the account
G->>W: GET /callback?code=…
W->>W: allowlist check on the verified email
W->>G: exchange code → access + refresh token
W->>C: MCP access token (Google tokens sealed inside the grant)
C->>W: POST /mcp — tools/call
W->>G: Gmail REST (token refreshed as needed)
G->>W: message / thread / label data
W->>C: tool result层 | 文件 | 作用 |
🔐 MCP 端 OAuth | 动态客户端注册、PKCE、KV 中的授权授予,Google 令牌在其中加密保存 | |
🔗 Google 端 OAuth |
| 授权码、离线访问、一次性状态绑定到浏览器会话、双重提交 CSRF 防护、基于已验证邮箱的允许列表 |
🤖 代理 |
| 每个 MCP 会话一个 Durable Object,绑定到打开它的账户;单飞令牌刷新、限流扇出 |
✉️ 邮件 |
| RFC 822 构建、MIME 树遍历、字符集解码、回复与转发构造 |
技术栈
TypeScript + Cloudflare Workers — Durable Objects 各自持有一个 MCP 会话,KV 保存 OAuth 授权
Hono — 处理 OAuth 端点、Google 回调以及
/路径的设置页面@cloudflare/workers-oauth-provider— MCP 客户端所对接的 OAuth 2.1 服务器agents— 基于 Durable Objects 的McpAgentMCP 传输层@modelcontextprotocol/sdk+ Zod — 工具定义与参数校验
Gmail 本身通过普通的 fetch 调用 REST API。官方的 googleapis SDK 假定运行在 Node 环境中,体积远超 Worker 应承载的范围,因此消息构建、MIME 解析和令牌刷新都实现在 src/gmail.ts 和 src/utils.ts 中。
端点
路径 | 用途 |
| MCP 端点 |
| 同一服务器在任何单段标签下可用,适用于拒绝两个服务器共享同一 URL 的客户端 |
| 本设置指南 |
| OAuth 机制 |
谁可以登录
ALLOWED_EMAILS 决定访问权限,检查标准是 Google 报告的已验证地址——在用户同意之后、任何授权创建之前进行。
值 | 允许谁进入 |
(空) | 没有人 |
| 这些账户 |
| 该域名的任何人 |
| 任何经过验证的 Google 账户 |
每个授权只能访问完成身份验证的那个邮箱,因此扩大此列表绝不会扩大对已连接邮箱的访问范围。设置为 * 会让陌生人使用您的部署以及您的 Google 客户端配额来处理他们自己的邮件。
限制
两个上限用于防止共享部署被耗尽,均在 wrangler.jsonc 中设置:
设置 | 位置 | 默认值 | 限制内容 |
|
|
| 大致上,有多少个不同的 Google 账户可以完成登录。达到上限后,已连接的账户仍可继续使用;新账户将被拒绝。同时到达的登录请求各自在记录之前读取计数,因此总数可能略高于此值。Google 将未经验证的应用限制为 100 个用户,请留出余量。 |
|
| 每 | 一个账户在该时间窗口内可发起的 Gmail 调用次数,涵盖其所有会话。Cloudflare 按地理位置分别计数,因此从两个地区连接的账户大约在每个地区各获得该次数。一次广泛读取会消耗多次调用: |
|
| 每 | 一个地址在该时间窗口内可发起的客户端注册次数。客户端只注册一次并保留获得的 ID,因此正常使用远不会触及此限制;设置上限是因为注册无需凭据且每次都会写入 KV。 |
在 Workers Free 套餐上还有一层上限:每次调用最多 50 个出站请求。一次广泛读取每条消息消耗一次请求,因此 search_messages 和 list_drafts 中的 maxResults 需要设为 45 或以下;超出部分会以逐条错误而非结果的形式返回。付费套餐允许 1000。
要提高任一上限,重新部署即可。Cloudflare 的速率限制器在构建时从绑定读取上限,因此每个上的 simple.limit 是唯一可修改它的地方。单用户部署可以两者都不改——正常使用助手的流量远低于这些限制。
安全性
自托管只是转移了信任问题,而非消除它,因此这里说明一切的位置。
你的令牌始终是你的。 刷新令牌在其 OAuth 授权中被加密,存储在你的 KV 命名空间中。会话的 Durable Object 持有有效期一小时的访问令牌,MCP 智能体框架在该对象存续期间保留一份授权副本,包含刷新令牌。两个存储都是你自己的 Cloudflare 账户,静态加密。邮件从不存储——只经过转发。
一个会话,一个邮箱。 MCP 会话绑定到打开它的账户,因此一个邮箱的授权无法通过借用会话 id 作用于另一个邮箱。
最小化权限范围。
gmail.modify涵盖读取、发送、标签和回收站。它排除了永久删除以及所有gmail.settings.*,使自动转发规则和过滤器外泄——经典的邮箱后门——超出任何被盗授权可做的事。另有随附请求的两个只读范围,userinfo.email和userinfo.profile:允许列表和会话绑定正是通过它们得知登录的是哪个账户,且它们不接触任何邮件。请求头无法被走私。 每个出站请求头值若包含 CR、LF 或 NUL 都会被拒绝,因此任何参数都无法跳出自身字段来追加另一个字段——例如在主题行内夹带
Bcc。媒体类型经过校验,引用的历史内容经过 HTML 转义。这不约束参数本身:bcc是真实参数,因此模型依据隐藏在消息正文中的指令仍可能填入该参数,而你客户端的批准提示仍是对此的检查。可以撤销访问。 收窄
ALLOWED_EMAILS可阻止新的登录。单个账户的访问可在 myaccount.google.com/connections 撤销。轮换 Google 客户端密钥会一次性使所有授权失效。
Worker 在处理请求期间会在内存中解密邮件,任何托管中继都必须如此。如果这对某个特定邮箱不可接受,可为该邮箱运行本地 MCP 服务器。
测试方式
253 个单元测试覆盖了消息构造(MIME 嵌套、RFC 2047 折行、RFC 2231 文件名、CR/LF 拒绝、base64 换行)、跨字符集的正文提取、回复与转发组合、Google 令牌流程、登录允许列表、保护登录浏览器端的 CSRF 和状态绑定检查,以及针对模拟 Gmail 的工具本身——会话所有权、收件人组合、附件选择,以及部分失败读取的返回内容。
在此之外,每个工具都针对真实 Gmail 账户运行过测试,并用另一个账户检查收到的内容:
领域 | 结果 |
编码 | 日文主题跨编码词折叠;emoji、ZWJ 序列、RTL 阿拉伯文、组合记号及罕见 CJK 字符往返不变 |
附件 | 发送名为 |
线程 |
|
双账户 | 两个账户同时连接到一个部署;一个账户的消息 id 在另一个账户上返回 |
整理 | 嵌套 CJK 标签被创建、重命名、批量应用并删除;线程和消息的垃圾箱操作均可撤销 |
规模 | 对 15,000 封邮件的邮箱使用 Gmail 运算符和分页进行搜索,未触发速率限制 |
开发
bun run dev # wrangler dev on :8788
bun run check # biome + tsc
bun test # 253 unit tests
bun run assets # regenerate the light and dark diagrams
bun run deploy问题与缺陷
请通过 issue 提交。
许可证
版权所有 © 2026 mkpoli。以 MIT License 发布。
src/workers-oauth-utils.ts 衍生自 cloudflare/ai 中的 remote-mcp-github-oauth 演示,版权 © 2025 Cloudflare, Inc.,依据 MIT License 使用。参见 THIRD-PARTY.md。
Related MCP Connectors
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Remote streamable-HTTP MCP server running on a single Cloudflare Worker. Your assistant gets live Airbnb, Amazon, Booking.com, Google Flights, Maps and Reddit data, social search on X, Instagram and TikTok, the Meta Ad Library, and image/video generation without any keys. Connect your own accounts to let it send WhatsApp or Telegram messages, work an IMAP inbox, manage Meta Ads campaigns and publish to X and LinkedIn. OAuth 2.1 with PKCE; stored credentials are AES-256-GCM encrypted.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
A MCP server for Gmail that lets you search, read, and draft emails and replies.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA Gmail MCP server running on Cloudflare Workers that enables reading, searching, labeling, drafting, sending, and managing Gmail messages, including fetching raw attachment bytes, with per-user OAuth authorization.371 npm1MIT
- AlicenseNot gradedqualityCmaintenanceA Gmail MCP server that lets AI assistants search, read, send, and manage email across multiple Google accounts, deployed on Cloudflare Workers.371 npmMIT
- AlicenseNot gradedqualityCmaintenanceAn MCP server that connects Gmail to AI assistants, enabling search, read, send, reply-all, forward, attachment handling, and draft management across multiple Google accounts, deployable on your own Cloudflare Worker.371 npmMIT
- AlicenseNot gradedqualityCmaintenanceDeployable MCP server on Cloudflare Workers that connects Gmail to AI assistants, enabling search, read, send, reply-all, forward, attachment handling, and label/thread management across multiple Google accounts simultaneously.371 npmMIT