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: Gmail MCP Connector
部署
大约十分钟。你需要一个 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 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,因此日文、中文和表情符号都能完好传输。
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 流程在一个 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 按位置维护此计数,因此从两个地区连接的账户在每个地区大约可获得该次数。一次广泛读取会消耗多次: |
|
|
| 一个地址在该窗口内可进行的客户端注册次数。客户端注册一次并保留其获得的 ID,因此正常使用远不会接近此值;设置上限是因为注册不需要凭据,且每次注册都会写入 KV。 |
在 Workers 免费计划上还适用一个更高的上限:每次调用最多 50 个出站请求。一次大范围读取每条消息会消耗一次请求,因此 search_messages 和 list_drafts 需要将 maxResults 设置为 45 或以下;超过该数值的部分会以单条消息错误的形式返回,而不是作为结果返回。付费计划允许 1000。
调高上限然后重新部署。Cloudflare 的速率限制器(rate limiter)会在构建时从其绑定上读取上限,所以二者各自的 simple.limit 是唯一需要修改它的地方。单用户部署可以完全不管这两项——普通规格的助手使用量远低于这些上限。
安全
自托管只是转移信任问题,而不是消除它,因此这里说明各项安全机制的具体位置。
你的令牌始终属于你。 刷新令牌在 OAuth 授权中被加密,并存储在你自己的 KV 命名空间中。一个会话的 Durable Object 保存着存活一小时的访问令牌,而 MCP 代理框架会在该对象存续期间保留一份授权副本,包括刷新令牌。这两个存储都是你自己的 Cloudflare 账户,落盘时已加密。邮件从不存储——它只是透传。
一个会话,一个邮箱。 MCP 会话绑定的是开通它的账户,因此一个邮箱的授权不能通过借用的会话 ID 作用于另一个邮箱。
范围最小化。
gmail.modify涵盖读取、发送、标签和垃圾箱操作。它不包含永久删除以及所有gmail.settings.*权限,因此自动转发规则和过滤器数据外泄——这些经典的邮箱后门——落在任何被窃取的授权可做的范围之外。与之并行的还有两个只读范围:userinfo.sign-in和userinfo.profile:它们用于允许列表和会话绑定知道是哪个账户签入了,并且不涉及任何邮件内容。头部参数无法助词夹带,每个出站头部参数值只要包含 CR、LF 或 NUL 就会被拒绝,因此任何实参都不能逃逸出自己的字段去追加额外字段——例如,在主题行中夹带一个
Bcc。媒体类型(Media Type)会被验证,引用的历史内容会进行 HTML 转义。这不涉及对参数本身的核查:bcc是一个真实存在的参数,因此模型如果根据邮件正文中隐藏的指令行事,仍然可以填入该参数,而你客户端的批准提示就会是对此的最后一道检查。访问可以被收回。 缩窄
ALLOWED_EMAILS范围会阻止新的登录。单个账户的访问可以在 myaccount.google.com/connections 撤销。更换 Google client secret 会让所有授权一次性失效。
Worker 在服务请求时会在内存中解密邮件,这与任何托管中继都必须做的一样。如果这对于某个特定邮箱来说不可接受,可以为该邮箱单独运行一个本地 MCP 服务器。
测试发生了什么事
253 个单元测试涵盖了消息构造(MIME 嵌套、RFC 2047 折叠、RFC 2231 文件名、CR/LF 拒绝、base64 换行)、跨字符集的正文提取、回复和转发的组合、Google 令牌流程、登录允许列表、保护登录浏览器端的 CSRF 和 state 绑定检查,以及与一个替身 Gmail 对接的工具本身——会话归属、收件人组合、附件选择,以及部分失败的读取会返回什么。
在这之外,每个工具都在真实 Gmail 账户上运行过,还有单独的一个账户检查实际收到的内容:
区域 | 结果 |
编码 | 日文主题在 encoded words 中正确折叠;emoji、ZWJ 序列、阿拉伯语 RTL、组合音符和罕见 CJK 字符往返保持不变 |
附件 | 一个名为 |
线程处理 | " |
双账户 | 两个账户同时连接同一个原有部署;来自一个账户的一个消息 ID 在另一个账户上返回 |
整理 | 一个嵌套 CJK 标签被创建、重命名、批量应用后删除;线程与消息的 trash 操作都能正确恢复 |
规模 | 对包含 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问题和 bug
请打开一个 issue。
许可证
Copyright © 2026 mkpoli。在 MIT 许可证 下发布。
src/workers-oauth-utils.ts 直接源自 cloudflare/ai 仓库中的 remote-mcp-github-oauth demo,Copyright © 2025 Cloudflare, Inc.,按 MIT 许可证使用。参见 THIRD-PARTY.md。
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables interaction with Gmail through the MCP protocol, supporting sending, reading, searching, replying, forwarding, managing drafts and labels, and saving attachments.123MIT
- AlicenseNot gradedqualityBmaintenanceA 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.231MIT
- AlicenseNot gradedqualityCmaintenancegmail-mcp is a remote MCP server that exposes Gmail as a set of tools — search, read, label, draft, send — over streamable HTTP with OAuth 2.1. It runs on Cloudflare Workers under your own domain.2317MIT
- AlicenseNot gradedqualityCmaintenanceA Gmail MCP server that lets AI assistants search, read, send, and manage email across multiple Google accounts, deployed on Cloudflare Workers.231MIT
Related MCP Connectors
Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.
Manage Gmail end-to-end: search, read, send, draft, label, and organize threads. Automate workflow…
Manage Gmail messages, threads, labels, drafts, and settings from your workflows. Send and organiz…
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Skraelingen/gmail-mcp-kevin'
If you have feedback or need assistance with the MCP directory API, please join our Discord server