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 存储为附件 blob 的长消息会返回空正文。
Related MCP server: multiGmailMCP
部署
大约十分钟。你需要一个 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 的域名,或者 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 Code 中运行 /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 会重现转发的信封,并可以重新附加原始邮件的文件。
使用 replyToMessageId 的 create_draft 会将回复写为草稿,以便在发送前编辑:它会加入原始邮件的线程,携带 In-Reply-To 和 References,推导出回复全部收件人和 Re: 主题,并引用原始内容。update_draft 仅更改给定的字段;收件人、文本、在任何客户端中手动添加的文件以及草稿回复的线程都会被读回并保留。如果文件的 base64 无法通过工具参数传递,则可以分阶段上传:stage_attachment_begin 返回一个上传 URL,该 URL 通过一次 curl -T 接收原始字节;stage_attachment_append 分块接收 base64;每个 attachments 字段都接受生成的 stagingId。
读取操作有意设置了限制:消息和线程正文有字符预算,整个响应有字节上限,附件仅在其足够小以便读取时才以内联方式返回。长邮件列表线程或大文件会被截断并附带说明,而不会填满助手的上下文。
工作原理
两个 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 | 动态客户端注册、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—McpAgent,基于 Durable Objects 的 MCP 传输@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 按位置统计此计数,因此从两个区域连接的账户大致在每个区域获得该次数。一次广泛读取会消耗多次:返回 50 条结果的 |
|
| 每 | 一个地址在该窗口内可以进行的客户端注册次数。客户端注册一次并保留其获得的 ID,因此正常使用永远不会接近此限制;设置此上限是因为注册不需要凭据,并且每次注册都会写入 KV。 |
在 Workers 免费计划中还有一个上限:每次调用最多 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 账户运行过,并使用另一个账户检查收到的内容:
区域 | 结果 |
编码 | 日语主题跨编码词折叠;表情符号、ZWJ 序列、从右到左的阿拉伯语、组合标记和罕见 CJK 字符往返不变 |
附件 | 一个名为 |
线程 |
|
两个账户 | 两个账户同时连接到一个部署;来自一个账户的消息 ID 在另一个账户上返回 |
组织管理 | 创建、重命名、批量应用并删除嵌套的 CJK 标签;线程和消息的垃圾箱操作均被撤销 |
规模 | 使用 Gmail 运算符和分页搜索 15,000 条消息的邮箱,未触发速率限制 |
开发
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 许可证 发布。
src/workers-oauth-utils.ts 衍生自 remote-mcp-github-oauth 演示,位于 cloudflare/ai,版权所有 © 2025 Cloudflare, Inc.,根据 MIT 许可证使用。请参阅 THIRD-PARTY.md。
Related MCP Connectors
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Email for AI agents: read, search and send from your Gmail, Outlook, Yahoo, iCloud or IMAP inbox.
Connect any mailbox to Claude, ChatGPT & AI: read, send, reply, schedule & search emails.
Your mailboxes in ChatGPT and Claude: Gmail, iCloud, Fastmail, any IMAP. Passwords stay yours.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI agents to search, read, send, and organize Gmail emails via MCP protocol.22161 npm2MIT
- AlicenseAqualityBmaintenanceConnects AI assistants to multiple Gmail accounts simultaneously, enabling search, read, draft, send, and reply operations with per-account permission controls.54ISC
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with Gmail through a standardized MCP server interface, allowing for natural language email management and automation.-
- AlicenseBqualityDmaintenanceMulti-account Gmail integration for AI assistants via the Model Context Protocol (MCP).35161 npmMIT