关于 gmail-mcp
gmail-mcp 通过部署在操作者 Cloudflare 账户中的 Worker,将 Gmail 接入 Claude 和其他 MCP 客户端。它支持多个绑定账户的连接,并提供邮件读取、发送、回复、转发、附件、草稿、标签和会话管理。
主要功能
- 01多个绑定账户的连接
- 02搜索和读取邮件
- 03发送、回复和转发邮件
- 04处理附件与内嵌图片
- 05管理草稿、标签和会话
适用场景
- 01分别访问个人与工作邮箱
- 02通过 MCP 客户端发送或回复邮件
- 03读取附件和较长的邮件会话
- 04使用标签整理 Gmail 邮件
MCP 相关
Cloudflare Worker 在 MCP 端点公开 Gmail 工具,并支持 MCP 客户端 OAuth 注册。每个连接认证到一个 Google 账户,刷新令牌保存在操作者的 Cloudflare 账户中。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
gmail-mcp 可将 Gmail 接入 Claude 及任何其他 MCP 客户端。它可以搜索和阅读邮件、发送邮件并回复所有人(附带引用的历史邮件)、转发邮件、处理附件和内嵌图片,并管理草稿、标签和邮件会话——支持同时使用多个 Google 账号。
它以远程服务的形式运行在你自己的 Cloudflare Worker 上,因此同一个连接可供笔记本电脑上的 Claude Code、浏览器中的 claude.ai 和手机上的 Claude 使用。每个连接只登录一个 Google 账号,Google 刷新令牌则保存在你自己的 Cloudflare 账号中。
人们通常是出于两方面原因来这里。Claude 和 Google 内置的 Gmail 连接器可以读取邮件和撰写草稿,但无法发送邮件,而且每个助手账号只能连接一个 Google 账号。能发送邮件的服务通常是本地进程——在桌前使用没问题,但手机上无法访问。
对比
更详细的对比 — 六个项目,十二项对比
| gmail-mcp | Claude · Google 内置 | taylorwilsdon/ google_workspace_mcp | ArtyMcLabin/ Gmail-MCP-Server | shinzo-labs/ gmail-mcp | aaronsb/ google-workspace-mcp | |
|---|---|---|---|---|---|---|
| 运行位置 | Cloudflare Workers | 供应商托管 | 你的服务端或本地 | 本地 | 本地 | 本地 |
| 可通过手机访问 | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| 同时使用多个邮箱 | ✅ 每个连接绑定一个邮箱 | ❌ | ✅ 每次调用时选择 | ❌ 仅支持别名 | ❌ | ✅ 每次调用时选择 |
| 发送邮件 | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
附件 · 内嵌 cid: 图片 | ✅ | 未注明 | ✅ | ✅ | ❌ | ✅ |
| 回复所有人并引用历史记录 | ✅ | ❌ | 仅草稿 | 不引用 | ❌ | ✅ |
| 转发 | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ |
| 遵循各部分的字符集 | ✅ | — | ❌ 假定为 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 以附件数据块形式存储的长邮件,返回时正文会是空的。
部署
大约需要十分钟。你需要一个 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.com
Google 没有为接下来的两个步骤提供 API,因此需要在 Cloud 控制台中完成:
- OAuth 同意屏幕 → 选择 External,然后在 Audience 下点击 Publish app。如果仍处于 Testing 状态,Google 会在 7 天后使所有刷新令牌过期,每个连接也会随令牌一同失效。发布后,应用会在登录时显示“应用未经验证”警告,并最多可服务 100 个账户。
- Credentials → Create credentials → OAuth client ID → 选择 Web application,并将
https://<your-host>/callback设为授权重定向 URI。保存客户端 ID 和密钥。
<your-host> 是你指向 Worker 的域名;如果没有域名,则是 Worker 获得的 workers.dev 主机名。也可以先部署,再回来填写此项——Worker 在 / 提供的指南会显示确切值。
2 · 部署 Worker
该按钮会将仓库复制到你的 GitHub 账户,创建 KV 命名空间和 Durable Object,并提示你填写四个密钥。它会部署到 workers.dev;之后可在 Settings → Domains & Routes 下绑定自定义域名。
也可以通过终端操作:
git clone https://github.com/mkpoli/gmail-mcp && cd gmail-mcp
bun install
bun run setup
bun 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 Code 中运行 /mcp,将每个连接登录到其 Google 账户。在 claude.ai 中,使用相同的 URL 前往 Settings → Connectors → Add custom connector。/mcp/ 后可使用任意单段标签,这样一个部署就能为拒绝两个服务器共用同一 URL 的客户端提供多个邮箱。
你的部署会在 https://<your-host>/ 提供本指南。
功能一览
| 📖 读取 | ✍️ 写入 | 🏷 整理 |
|---|---|---|
|
|
|
|
邮件会像邮件客户端发送邮件那样发出:纯文本附带 HTML 备选内容、文件附件,以及通过 cid: 引用的内嵌图片,嵌套结构为 multipart/mixed › multipart/related › multipart/alternative。主题和显示名称使用 RFC 2047,文件名使用 RFC 2231,因此日文、中文和表情符号都能正常传递。
reply_all 会读取原邮件的 Reply-To、From、To 和 Cc,移除你自己的地址以及你代为发送邮件的任何地址,从发件人写信的地址回复,保留 References 链,并在你发送的各部分引用原邮件。forward_message 会还原转发邮件的封套信息,并可重新附上原邮件的文件;如果无法全部附上,就不会发送任何内容。
使用 replyToMessageId 调用 create_draft,可将回复写为草稿,以便发送前编辑:它会加入原邮件所在的会话,保留 In-Reply-To 和 References,生成“回复全部”的收件人和 Re: 主题,并引用原邮件。update_draft 只会修改你提供的字段;收件人、文本、通过任意客户端手动添加的文件,以及草稿所回复的会话,都会被读取并保留。若文件的 base64 内容无法通过工具参数传递,则可先暂存:stage_attachment_begin 会返回一个上传 URL,可通过一次 curl -T 上传原始字节;stage_attachment_append 可分块接收 base64;每个 attachments 字段都接受生成的 stagingId。
读取内容会有意受到限制:邮件和会话正文设有字符数预算,整个响应设有字节数上限,附件只有足够小才会以内联形式返回。较长的邮件列表会话会被截断,并附上说明,而不会塞满助手的上下文。较大的文件会以下载链接形式返回,只要会话保持开启,该链接一小时内有效;使用 curl -o 可将文件保存到磁盘,无需让文件字节经过对话。
工作原理
两个 OAuth 流程在一个 Worker 中交汇。MCP 客户端向 Worker 进行身份验证;Worker 代表你向 Google 进行身份验证。双方都不会持有对方的凭据。
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 | workers-oauth-provider | 动态客户端注册、PKCE、存储在 KV 中且将 Google 令牌密封其中的授权 |
| 🔗 Google 侧 OAuth | src/google-handler.ts | 带离线访问权限的授权码、绑定到浏览器会话的一次性状态、双重提交 CSRF,以及针对已验证邮箱的允许列表 |
| 🤖 Agent | src/index.ts | 每个 MCP 会话对应一个 Durable Object,并绑定到启动该会话的账号;单航班令牌刷新、限流扇出 |
| ✉️ 邮件 | src/gmail.ts | RFC 822 构造、MIME 树遍历、字符集解码、回复和转发内容编写 |
构建技术
- TypeScript 和 Cloudflare Workers — Durable Objects 各自持有一个 MCP 会话,KV 存储 OAuth 授权
- Hono — 为 OAuth 端点、Google 回调和位于
/的设置页面提供路由 @cloudflare/workers-oauth-provider— 供 MCP 客户端注册的 OAuth 2.1 服务端agents—McpAgent,通过 Durable Objects 实现的 MCP 传输@modelcontextprotocol/sdk和 Zod — 工具定义和参数验证- Bun、Biome、Wrangler — 安装、测试、代码检查、部署
Gmail 通过普通的 fetch 调用REST API。官方的 googleapis SDK 假定运行环境是 Node,且包含的内容远超 Worker 所需,因此邮件构建、MIME 解析和令牌刷新由 src/gmail.ts 和 src/utils.ts 负责。
端点
| 路径 | 用途 |
|---|---|
/mcp | MCP 端点 |
/mcp/<label> | 使用任意单段标签访问同一服务,适用于拒绝两个服务共用一个 URL 的客户端 |
/ | 本设置指南 |
/authorize · /token · /register · /callback | OAuth 机制 |
谁可以登录
ALLOWED_EMAILS 决定谁可以登录;系统会将其与 Google 报告为已验证的地址进行核对,核对发生在用户同意之后、创建任何授权之前。
| 值 | 可登录对象 |
|---|---|
| (空) | 无人 |
[email protected], [email protected] | 这些账号 |
*@company.com | 该域名下的任何人 |
* | 任何已验证的 Google 账号 |
每项授权只能访问完成身份验证的邮箱,因此扩大此列表不会扩大对已连接邮箱的访问权限。设置为 * 会让陌生人使用你的部署和 Google 客户端配额来收发他们自己的邮件。
限制
以下两个上限都在 wrangler.jsonc 中设置,可避免共享部署的资源被耗尽:
| 设置 | 位置 | 默认值 | 限制范围 |
|---|---|---|---|
MAX_ACCOUNTS | vars | 25 | 大致限制可以完成登录的不同 Google 账号数量。达到上限后,已连接的账号仍可继续使用;新账号将无法登录。多个登录请求同时到达时,每个请求都会在任何请求被记录前读取计数,因此最终总数可能略高于此值。Google 对未经验证的应用设有 100 位用户的上限,因此应留出余量。 |
RATE_LIMITER.simple.limit | unsafe.bindings | 每 60s 为 120 | 一个账号在该时间窗口内可发起的 Gmail 调用次数,按其所有会话累计。Cloudflare 按位置分别计数,因此一个账号从两个区域连接时,每个区域大约都能获得这么多次调用。一次大范围读取会消耗多次调用:search_messages 返回 50 条结果时会发起 51 次调用。 |
REGISTER_LIMITER.simple.limit | unsafe.bindings | 每 60s 为 10 | 一个地址在该时间窗口内可发起的客户端注册次数。客户端只需注册一次并保留分配到的 ID,因此正常使用远达不到此上限;设置此上限是因为注册无需凭据,而且每次注册都会写入 KV。 |
Workers 免费计划还受另一项上限限制:每次调用最多发出 50 个出站请求。一次大范围读取会对每条消息发出一个请求,因此该计划下,search_messages 和 list_drafts 的 maxResults 应设为 45 或更低;超过此值的部分不会作为结果返回,而会逐条返回错误。付费计划允许 1000 个请求。
提高任一上限后重新部署。Cloudflare 的速率限制器在构建时从绑定中读取上限,因此,只有对应项的 simple.limit 可以更改上限。单用户部署无需更改这两项——正常的助手使用量远低于上限。
安全性
自托管只是转移了信任问题,并未消除它。以下说明各项数据的存放位置。
- 令牌由你保管。 刷新令牌在 KV 命名空间中的 OAuth 授权信息内加密存储。会话的 Durable Object 会保存有效期为一小时的访问令牌;只要该对象存在,MCP Agent 框架也会在其中保留一份授权信息副本,包括刷新令牌。这两个存储都属于你自己的 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 服务。
测试方式
260 项单元测试覆盖了消息构造(MIME 嵌套、RFC 2047 折行、RFC 2231 文件名、拒绝 CR/LF、Base64 换行)、跨字符集的正文提取、回复和转发的撰写、Google 令牌流程、登录允许列表、保护浏览器端登录的 CSRF 和状态绑定检查,以及针对模拟 Gmail 的工具测试——包括会话所有权、收件人撰写、附件选择,以及读取部分失败时的返回结果。
此外,每项工具都在真实 Gmail 账户上运行过,并由另一个独立账户检查实际收到的内容:
| 领域 | 结果 |
|---|---|
| 编码 | 日文主题跨编码字词折行;表情符号、ZWJ 序列、从右向左书写的阿拉伯文、组合字符和罕见 CJK 字符往返传输后均保持不变 |
| 附件 | 名为 請求書.csv 的 CSV 文件发送、送达并下载回来,字节完全一致;收件人成功显示了内嵌的 cid: 图片;通过下载链接获取的 2 MB zip 文件大小与声明一致,且可以打开 |
| 线程 | reply_all 向发件人发送回复,保留第三方 Cc,移除自己的地址,并在同一线程中引用原始邮件 |
| 两个账户 | 两个账户同时连接到同一部署;一个账户的邮件 ID 在另一个账户上返回 404 |
| 整理 | 创建、重命名、批量应用并删除嵌套的 CJK 标签;线程和邮件的移至垃圾箱操作都可撤销 |
| 规模 | 使用 Gmail 运算符和分页搜索包含 15,000 封邮件的邮箱,未触发速率限制 |
开发
bun run dev # wrangler dev on :8788
bun run check # biome + tsc
bun test # 260 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 demo,版权所有 © 2025 Cloudflare, Inc.,根据 MIT License 使用。请参阅 THIRD-PARTY.md。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。