multi-gmail-cowork-mcp
multi-gmail-cowork-mcp
一个自托管的小型 MCP 服务器,允许 一个 Claude 自定义连接器 在 多个、独立认证的 Gmail 账户 中搜索、读取、编写和发送。 它可以由任何人部署到自己的 Google Cloud 项目中,没有共享的基础设施, 也不需要针对每次部署修改任何代码。
Claude Cowork
|
v
Your private Multi-Gmail MCP (your own Cloud Run project)
|
+-- Gmail account: "personal"
+-- Gmail account: "work"
+-- Gmail account: "billing"
+-- ...more, added any time via the admin page你可以向 Claude 提出这样的请求:
"搜索我的工作 Gmail 中来自 David 的邮件。"
"搜索所有已连接的 Gmail 账户,查找包含 'ACCP 4831' 的内容。"
"读取来自 ACH Works 的最新邮件,无论哪个账户收到。"
"我哪个 Gmail 账户昨天收到过 John 的邮件?"
每个结果都会明确注明它来自哪个账户别名和邮件地址。 如果你请求一个未连接的账户,或授权已过期的账户,你会收到明确错误信息 —— 本服务器绝不会静默使用其他账户代替。
它不是什么
仅支持 Gmail。没有 Calendar、Drive、Docs、Sheets 或 Contacts。没有永久删除工具。没有共享后端, 没有中心账户,没有遥测数据。
Related MCP server: Gmail MCP
隐私模型 —— 谁可以看到你的邮件
Google <-> Your Google Cloud deployment <-> Claude / Anthropic你 把这个项目部署到 你自己的 Google Cloud 项目中,使用 你自己的 Google OAuth 客户端和 你自己的 Cloud Run 服务。
Google 可以授予或撤销 OAuth 授权;它能看到的只是正常的 OAuth 流量。
你的部署环境 是唯一保存 Gmail 刷新令牌的地方。
Claude/Anthropic 在你的 Claude 调用工具时,看到的只是工具返回的数据(与任何其他 MCP 工具一样)——没有更多内容,且你不使用它时什么都看不到。
此代码库的作者永远不会看到你的任何邮件。没有共享服务器。你的部署和你兄弟姐妹的部署之间,除了源代码之外没有任何共同之处。
阅读 SECURITY.md 可以了解完整的信任边界和设计原理说明—— 包括认证为什么采用现在这种方式,以及本项目已知的限制。这个 README 不重复这些内容。
架构概览
语言/运行时: 在 Node.js 20+ 上使用 TypeScript,基于官方
@modelcontextprotocol/sdk和 Google 的google-auth-library。传输层: Streamable HTTP(当前 MCP 推荐的远程传输方式),无状态——每个请求独立处理,因此可以在 Cloud Run 上平滑伸缩,无需会话亲和性支持。
Claude <-> 服务器认证: MCP OAuth 2.1 授权码流程,搭配 PKCE/S256、动态客户端注册、短生命周期访问令牌、轮换刷新令牌,以及 Secret Manager 中部署本地的授权状态。
服务器 <-> Google 认证: 标准的 OAuth 2.0 配合 PKCE,每个已连接的 Gmail 账户一个授权,scope 为
gmail.modify(读取、编写、发送和邮箱修改;没有永久删除)。账户存储: 一个 Google Secret Manager 的 secret,保存一个小型 JSON 数组(别名、邮件、刷新令牌),无数据库。
管理界面: 几个无法样式的 HTML 页面,放在 HTTP Basic Auth 之后——足以连接或断开账户。
前置条件
需要一个 Google 账户和一个已启用结算的 Google Cloud 项目(如果未启用结算,bootstrap 脚本会打印确切的结算页面)。
一个支持自定义连接器的 Claude 套餐(用于连接 Cowork/claude.ai)。
部署不需要其他任何东西:Google Cloud Shell 已经包含
gcloud、curl、openssl和jq。
费用与计费
Cloud Run 需要启用结算项目。此部署按个人小型业务使用设计: 最小实例数 0(空闲时缩放到 0)和 最大实例数为 3。正常使用——每天少量搜索、读取和发送——都在 Google Cloud 的 Cloud Run Always Free 用量范围内,因此实际长期成本通常是 0 美元。这不是一种保证:如果持续突发流量超出了免费额度, 会产生正常的 Cloud Run 费用。bootstrap 会在有任何支出前,可选地打印一个 budget-alert 链接。
快速地 Cloud Shell 设置(推荐)
使用上方的按钮在 Google Cloud Shell 中打开此仓库(或使用 GitHub 上的 Open in Cloud Shell)。
在 Cloud Shell 中根据提示进行身份验证,然后运行:
./scripts/bootstrap.sh脚本会要求你选择一个项目(或创建一个),检查计费,启用必要的 APIs,创建专用的 Cloud Run 运行时服务账号,分配它需要的 Secret Manager 角色,创建全部 secrets,部署 Cloud Run,并输出 PASS/FAIL 检查项。运行是安全的: 现有的 secrets、账户记录、OAuth 凭据和 Cloud Run 服务都会被保留。
脚本永远不会打印密码、OAuth 客户端密钥、刷新令牌、账户存储 JSON 或 MCP OAuth 令牌。Secret 值会以精确字节写入(不会出现 trailing-newline 导致的凭据问题)。使用 ./scripts/bootstrap.sh --check 进行只读的 Cloud Shell 前置条件检查。
最后一个不可替代的自定义浏览器步骤
Google 不针对通用 Web 提供安全且受支持的 API/CLI 创建 OAuth 客户端的方式。当 bootstrap 要求时,打开它显示的 Google Auth Platform 页面,并执行以下操作:
将应用配置为 External,添加 scope
https://www.googleapis.com/groups.google.com/,将其简单表述完整,并将要使用的测试用户 Gmail 地址添加为测试用户。创建 application type 为 Web application 的 OAuth 客户端。
输入脚本明确打印的回调 URI:
https://<your-cloud-run-host>/oauth/google/callback。将生成的 Client ID 和 Client Secret 粘贴到 Cloud Shell 中的隐藏提示中。
如果 Google 显示 “验证尚未导入” 之类的提示,这是个人部署时预期出现的。如果希望刷新令牌的 7 天有限期限外仍然有效,请将同意屏幕发布到 In production;个人/小型部署不需要 Google verification。
在最后,bootstrap 会打印 Admin URL、准确的 Google OAuth 回调 URL、MCP URL 以及下一步需要人工进行的操作。Claude 会通过其受支持的 OAuth 流程对 MCP 端点进行认证;没有要复制到静态 URL 的连接器头。
连接 Gmail 账户
用 bootstrap 末尾打印的命令来获取管理密码(bootstrap 生成,从不打印):
gcloud secrets versions access latest --secret=admin-password --project=YOUR_PROJECT_ID然后打开发出的 Admin URL,使用用户名
admin和该密码登录。输入一个简短的别名,如
personal或work,点击 Add Gmail Account,并完成 Google 的授权。授权 URL 会请求consent select_account,因此每次往返都会出现 Google 的账户选择器。回调后显示的地址是Google 实际授权的“地址”,不是从别名数据中获取的。重复上述操作,你可以连接任意多个 Gmail 账户。每个别名都是独立的,所有结果都会被标记为别名和验证过的 Gmail 地址。
连接 Claude Cowork
在 Claude 中,打开 Settings → Connectors → Add custom connector 并输入以下内容:
Connector name:
Multi GmailRemote MCP URL: 打印的以
/claude-mcp结尾的 URLOAuth Client ID: 留空(服务器支持 Dynamic Client Registration)
OAuth Client Secret: 留空
/mcp 路径继续保留给现有客户端使用;对于新的 Claude 连接器,请使用 /claude-mcp,这些连接器的身份可以独立记录到之前的连接器记录。
点击 Add,然后 Connect。Claude 会通过发现 MCP 授权元数据,注册自己,并打开部署的 Authorize MCP access 页面。在那里使用用户名 admin 登录,密码是你自己的 admin-password Secret Manager 中保存的管理密码,然后再批准。Claude 会通过其回调 https://claude.ai/api/mcp/auth_callback 进行跳转,保存 OAuth 令牌,并重新连接。不要在 Claude 中输入 Gmail 的 OAuth Client ID 或 ClientSecret——这些信息只属于 Google Gmail 设置。
连接完成后,请让 Claude 调用 list_accounts,然后为每个账户执行特定的别名搜索以及 search_all_accounts 搜索,以验证结果归属。
验证你的部署
scripts/acceptance_test.mjs 会证明每个工具在你的部署中端到端都生效——包括账户隔离、错误别名的 fallback、草稿和发送是否到达,以及 From 身份。该脚本会像真实客户端一样执行完整的 MCP OAuth 流程,并且从不打印令牌:
MCP_BASE_URL=https://your-service.run.app \
MCP_ADMIN_PASSWORD='...' # Secret Manager -> admin-password
node scripts/acceptance_test.mjs发送测试会发送一封账户 A → 账户 B 的邮件以及一封 B → A 的邮件,所以收件者始终是谁自己也拥有的账户。设置 SKIP_SEND=1 可忽略发送。
本地开发(可选)
仅适用于源码开发:安装 Node.js 20+,运行 npm install,将 .env.example 复制为 .env,设置 TOKEN_STORE=file,并使用 npm run dev。本地使用 Gmail OAuth 需要单独的 OAuth 客户端回调,例如 http://localhost:8080/oauth/google/callback;不要复用生产环境的 secret 或将其提交到仓库。Windows 用户可一次使用 scripts/setup.ps1 和 scripts/deploy.ps1 来替代 CloudShell 引导。
重新授权 / 撤销账户
当你从早期只读版本升级后,每个现有账户都会被标记为需要 Gmail 权限升级。打开 /admin,单击同一别名的 Reauthorize,并完成 Google 的 cons exc 也会由 redirect。回调会验证 Google 确实授予了 https://www.googleapis.com/auth/gmail.modify,然后才替换该别名的存储刷新令牌。在此之前,读取工具仍可通过旧授权继续运行,而写入工具则明确返回要求重新授权的消息;绝不会使用其他别名。
如需移除访问权限,点击对应账户旁边的 Disconnect。这会在 Google 端撤销授权(尽力而为)并立即把账户脱离通过——之后 Claude 在请求此别名时会看到明确的“未连接”错误,而不是静默回退。
如果在 Google 端已撤销之前授权过的同一别名,可以使用 Connect account 并输入相同别名重新连接——只有成功执行 Google 授权后,服务才会覆盖旧记录。
写入工具和安全
部署的服务器中公开了 create_draft 和 send_email。两者需要明确指定已连接的账户别名,且都不会 fallback。send_email 总是锁定所选的 Gmail 身份来发送;结果中包含该已验证的地址。工具使用 gmail.modify,而不是范围更大的 mail.google.com scope,且没有永久删除工具。Claude 连接器的权限设置应允许自动响应读取工具,同时将 create_draft 和 send_email 设置为 Needs approval。
更新与轮换
更新部署: 修改源码或要获取新的 secret 版本时,重新运行
./scripts/bootstrap.sh(幂等——保留账户、令牌和 OAuth client),或在 Windows 上使用脚本scripts/deploy.ps1。已连接的 Gmail 账户和 Claude 连接不受影响。轮换管理员密码: 为
admin-password添加新的 Secret Manager 版本,重新部署。已验证的 Claude connector 的令牌会继续有效(不由 admin 密码派生);只有后续 MCP 授权批准,才会用新密码。轮换
oauth-state-secret: 它会用于签发每个 MCP OAuth 令牌,因此轮换会使已验证 Claude 连接器现有令牌失效——完成后还需要重新连接 Claude。在途 Gmail 链接中的 state token(10 分钟有效)也会失效;已连接的 Gmail 账户不受影响。轮换 Gmail 账户的授权: 从管理员页面重新连接该别名(请参阅重新授权 / 撤销账户)。
如何删除所有内容
移除 Gmail 访问权限: 在
/admin中对每个账号断开连接,或直接在 https://myaccount.google.com/permissions 撤回访问权限。拆除部署:
gcloud run services delete multi-gmail-mcp --region us-central1 gcloud secrets delete mcp-oauth-state admin-password oauth-state-secret google-client-id google-client-secret gmail-mcp-accounts gcloud iam service-accounts delete multi-gmail-mcp-run@YOUR_PROJECT_ID.iam.gserviceaccount.com删除 OAuth 客户端: Cloud Console -> APIs & Services -> Credentials -> 删除 OAuth 客户端 ID,并可选地删除 OAuth 同意屏幕配置。
或者最简单:删除整个 Google Cloud 项目。
故障排除
“账号需要重新连接”错误: 存储的刷新令牌被 Google 拒绝(已被吊销、已过期, 或同意屏幕卡在“Testing”——请见下文)。请在
/admin中重新连接。刷新令牌大约 7 天后死亡: 你的 OAuth 同意屏幕仍是“Testing”发布状态。请将其 发布到“In production”(见第 3 个步骤)——即使不通过验证也可以,个人使用完全没问题。
Claude 无法连接连接器 / 连接静默失败: 请确认服务 URL 能通过纯 HTTPS 正常解析, 不会重定向到其他主机;然后打开
/claude-mcp结尾的 MCP URL 与 Connect 重新连接。 服务器在无访问令牌调用时必须返回 OAuth 元数据和 401 质询;无需设置静态请求头。gcloud run deploy在未启用 API 时失败: 重新运行scripts/setup.ps1,或运行gcloud services enable run.googleapis.com cloudbuild.googleapis.com artifactregistry.googleapis.com secretmanager.googleapis.com gmail.googleapis.com iam.googleapis.com。本地开发环境无法通过 HTTPS 访问 Google(证书错误): 这几乎总是本地机器问题 (企业代理或企业杀毒软件进行 TLS 中间拦截),不是本项目的 bug——请检查受信任的根证书。
Google OAuth Testing 与长期使用
Google Cloud OAuth 客户端最初是 Testing 状态。处于 Testing 时,敏感/受限范围
(包括 gmail.modify)的刷新令牌会在 7 天后过期,无论你有多少用户——如果保持现状,
这个连接器每周都会静默失效。
解决方案不是 Google 验证(那是面向公开 SaaS 的多月流程)。更简单的做法:
点击 Publish app,将同意屏幕改为 In production。如果你的应用只请求
gmail.modify 并保持连接账号总数不足 100 个,官方文档会认为这是个人/小规模正常使用,
无需验证。唯一可见的影响是每个新连接用户在同意前,会看到一次
“Google hasn't verified this app”的点击提示。这属正常,不意味着配置有误。
底层规则与来源见 SECURITY.md。
仓库布局
src/ TypeScript source (server, MCP tools, admin/setup UI, OAuth flows)
scripts/ bootstrap.sh (Cloud Shell), setup.ps1/deploy.ps1 (Windows),
acceptance_test.mjs (verify any deployment end-to-end)
.env.example Local-dev configuration template (placeholders only)
SECURITY.md Trust model, design rationale, known limitations许可证
MIT——见 LICENSE.
This server cannot be installed
Maintenance
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 gradedqualityFmaintenanceServer for Gmail integration in Claude Desktop with auto authentication support. This server enables AI assistants to manage Gmail through natural language interactions.26,6781,165MIT
- AlicenseNot gradedqualityDmaintenanceA server that allows Claude to search and retrieve emails from your Gmail account, supporting functions like searching emails, retrieving full content of specific emails, and listing recent messages.7Apache 2.0
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that enables Claude AI to interact with Gmail, supporting email sending, reading, searching, labeling, draft management, and batch operations through natural language commands.2MIT
- -licenseNot gradedqualityNot gradedmaintenanceA Model Context Protocol server that enables Claude to interact with Gmail through a secure OAuth2 connection, providing email management capabilities like listing, sending, deleting, and organizing emails.
Related MCP Connectors
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…
Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.
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/reconexus/multi-gmail-cowork-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server