关于 Mcp Emails
Mcp Emails 是面向 Agent 和 MCP 客户端的托管 MCP 服务,可操作已连接的邮箱。邮件按需从服务商实时读取且不留存,并支持按权限读取、整理、起草、发送和定时发送。
主要功能
- 01读取、搜索邮件及附件
- 02发送、回复和转发邮件
- 03整理邮件与文件夹
- 04创建草稿并定时发送
- 05按密钥配置细粒度权限
适用场景
- 01搜索收件箱并汇总匹配邮件
- 02批量移动或标记邮件
- 03准备草稿以供审核或发送
- 04安排邮件稍后发送
MCP 相关
通过托管 MCP 端点提供邮件工具和工作流提示词。客户端可使用 OAuth 或带权限范围的 API 密钥连接。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://mcpemails.com/api/mcpclaude mcp add --transport http MCPEmails https://mcpemails.com/api/mcp{"mcpServers":{"MCPEmails":{"type":"http","url":"https://mcpemails.com/api/mcp"}}}在 Cursor 中打开{"servers":{"MCPEmails":{"type":"http","url":"https://mcpemails.com/api/mcp"}}}在 VS Code 中打开{"mcpServers":{"MCPEmails":{"type":"http","url":"https://mcpemails.com/api/mcp"}}}{"mcpServers":{"MCPEmails":{"serverUrl":"https://mcpemails.com/api/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
MCPEmails
为你的 AI Agent 提供收件箱。 一个托管的 Model Context Protocol 服务,可让 Claude、Cursor 或任何兼容 MCP 的客户端通过你现有的邮箱读取、搜索、发送、整理和定时发送邮件,且绝不会存储你的邮件。
只需连接一次邮箱,将一个 URL 粘贴到你的 Agent 中,它就能实时处理收件箱。邮件按需获取,绝不保留;凭据以静态加密方式存储,只有在请求需要时才会在我们的服务器上解密。
🔗 mcpemails.com · 📚 文档 · 💳 定价
目录
工作原理
- 连接邮箱。 在 mcpemails.com 登录并连接 Outlook / Microsoft 365(使用 Microsoft 登录,通过 Microsoft Graph)、Gmail(通过 IMAP 使用 Google 应用专用密码),或任何 IMAP/SMTP 帐户(使用应用专用密码)。凭据在写入数据库前会使用 AES‑256‑GCM 加密。
- 获取访问权限。 支持 OAuth 的客户端(claude.ai、Claude Desktop、Cursor)通过 OAuth 2.0 + PKCE 一键连接。其他客户端则使用作用域受限的 API 密钥(
mcpe_…)。 - 将客户端指向服务。 MCP 端点是一个 URL:
https://mcpemails.com/api/mcp - 让你的 Agent 处理收件箱。 它会调用
inbox_list、email_read(action: "search")、email_compose(action: "send")和schedule(action: "create")等工具。每个请求都会从你的服务提供商实时获取数据——服务器端不会镜像或缓存任何内容。
权限按密钥划分作用域,因此你可以只授予 Agent read:email 权限,也可以授予发送和文件夹管理权限,而无需暴露删除权限。
快速开始(连接 Agent)
Claude Desktop / Cursor(OAuth): 添加一个指向 https://mcpemails.com/api/mcp 的远程 MCP 服务,并批准授权界面。选择 Agent 应拥有的作用域。
API 密钥(任何 MCP 客户端): 在控制面板中创建密钥,选择其作用域,并可选择将其限制为特定收件箱,然后将其作为 bearer token 发送:
// Example MCP client config
{
"mcpServers": {
"mcpemails": {
"url": "https://mcpemails.com/api/mcp",
"headers": { "Authorization": "Bearer mcpe_your_key_here" }
}
}
}
该协议使用 HTTP 上的 JSON‑RPC 2.0(MCP 2025-06-18,Streamable 传输)。每个会话都从 inbox_list 开始——它会返回该密钥可访问的收件箱、各服务提供商支持的功能,以及带版本号的兼容性配置文件。该配置文件会将标准化操作标记为 exact、different 或 unavailable,以便 Agent 保留服务提供商之间的差异,而不是悄悄降低请求的要求。
配置指南
每个客户端的复制粘贴式配置说明,包括各自配置文件的存放位置:mcpemails.com/docs/clients。
Claude · Claude Code · ChatGPT · Cursor · VS Code · Cline · Windsurf · Gemini CLI · Zed · JetBrains · Raycast · Warp · curl
功能
- 实时读取,绝不存储 — 每次调用都会直接从你的服务提供商读取邮件;不会保存邮件正文。
- 支持多种服务提供商 — 通过 Microsoft Graph 使用 Outlook / Microsoft 365(使用 Microsoft 登录),通过 IMAP 使用 Google 应用专用密码访问 Gmail,还可通过应用专用密码使用任何 IMAP/SMTP 邮箱(Fastmail、iCloud、Yahoo、Zoho、Yandex、可自托管邮箱等)。
- 由你的服务提供商发送 — 发出的邮件通过你的服务提供商的 SMTP/API 发送,使用你的真实地址。如果服务提供商拒绝来自云地址的连接,IMAP/SMTP 连接会通过我们自己的隧道(HTTP CONNECT 中继);TLS 仍会端到端连接到服务提供商,因此中继不会看到邮件或凭据。
- 细粒度权限范围 — 共 8 种权限范围,可针对每个 API 密钥和每个收件箱独立授予。
- 批量操作和搜索后执行 — 一次调用即可读取、移动、删除或标记数百封邮件,还可使用“搜索后移动/删除”组合操作。
- 草稿和定时发送 — 撰写草稿,并将邮件加入队列以便将来发送(由服务端分发)。
- 与服务提供商无关的搜索 — Gmail 语法、Microsoft Graph KQL 和 IMAP
SEARCH统一封装在一个email_read(action: "search")接口中。 - 适用于企业:Business 方案支持多个工作区、拥有角色的无限成员,以及由管理员审批暂缓发送的邮件。
工具
你可以直接调用 21 个工具。大多数工具面向资源,并接受一个用于选择具体操作的 action 参数(对于需要不同权限的操作,该参数还会指定所需的权限范围):
inbox_list- 列出密钥可访问的收件箱,以及每个收件箱支持的提供商功能。email_read- 分批列出、读取和搜索邮件,以及附件、提取的附件文本和原始.eml文件。email_organize- 按你指定的 ID 单独或分批移动、复制、标记和归档邮件。email_search_and_move- 将所有符合搜索条件的邮件移至某个文件夹。此工具单独列出,也是具有破坏性的工具,因为筛选条件有误会导致整个收件箱的邮件被移动。email_delete- 单独、分批或按搜索条件将邮件移至废纸篓或永久删除。email_compose- 通过你自己的提供商,使用你的真实地址发送、回复和转发邮件。folder_list- 列出文件夹(Gmail 中为标签),并显示提供商原生 ID 和邮件数量。只读。folder- 创建、重命名和删除文件夹(Gmail 中为标签)。draft_list- 列出收件箱中保存的草稿及其草稿 ID。只读。draft- 创建、更新、发送和删除草稿,包括使用提供商原生功能回复。schedule_list- 列出已排队等待未来发送的邮件。只读。schedule- 将邮件加入队列以便日后发送,并取消已排队的邮件。reminder_list- 列出服务端跟踪的跟进和延后提醒:已到期、即将到期或全部。只读。Pro 和 Business 版可用。reminder- 跟进无人回复的已发送邮件,并将邮件从收件箱中延后至你选择的时间。聊天关闭时也会在服务端运行。Pro 和 Business 版可用。signature_get- 读取收件箱中配置的签名和发件人姓名。只读。signature_set- 设置附加到外发邮件的签名和发件人姓名。automation_read- 列出分拣规则、读取单条规则、显示运行历史记录,并试运行筛选条件。只读。automation- 创建、更新、启用、停用和删除无人值守的分拣规则,无需大模型参与。contact_search- 实时扫描近期邮件查找联系人,不使用存储的通讯录。draft_read- 完整读取一封未发送的草稿,例如用户在草稿编辑器卡片中编辑后读取。只读。draft_editor_hide- 显示或隐藏某个收件箱或整个工作区的聊天内草稿编辑器卡片。仅为显示偏好设置。
| 工具 | 操作 | 范围 |
|---|---|---|
inbox_list | (单个操作) | read:email |
email_read | list、read、read_batch、search、attachment、extract、original | read:email(search 也接受 search:email) |
email_organize | move、move_batch、copy、copy_batch、flag、archive | manage:folders |
email_search_and_move | (单个操作) | manage:folders |
email_delete | delete、delete_batch、search_and_delete | delete:email |
email_compose | send、reply、forward | send:email |
folder_list | (单个操作) | read:email |
folder | create、rename、delete | manage:folders |
draft_list | (单个操作) | manage:drafts |
draft | create、reply、update、send、delete | manage:drafts(create/reply/update/delete),read:email(reply 也需要),send:email(send) |
schedule_list | (单个操作) | schedule:email |
schedule | create、cancel | schedule:email |
reminder_list | (单个操作) | read:email |
reminder | follow_up、snooze、done、cancel | manage:automations(snooze 和取消延后提醒的 cancel 也需要 manage:folders) |
signature_get | (单个操作) | read:email |
signature_set | (单个操作) | send:email |
automation_read | list、get、runs、preview | manage:automations |
automation | create、update、enable、disable、delete | manage:automations |
contact_search | (单个操作) | manage:contacts(也接受 read:email) |
draft_read | (单个操作) | manage:drafts 和 read:email |
draft_editor_hide | (单个操作) | manage:drafts |
拥有完整权限的密钥会在 tools/list 中看到 29 个工具:上面的 21 个,加上 8 个仅供应用使用的工具。这些工具用于驱动聊天内卡片,而非手动组合:approval_review、approval_decide、approval_update、approval_schedule(暂缓发送)、bulk_execute、bulk_cancel(预览批量操作)、draft_editor_save(草稿编辑器的 Save 按钮)和 card_automation(自动化卡片的 On/Off 开关)。6 个 approval_* 和 bulk_* 工具始终带有 _meta.ui.visibility: ["app"];草稿编辑器开启时,draft_editor_save 会带有此标记,而编辑器关闭时则会拒绝所有调用;只有卡片开启时,才会列出 card_automation。 |
prompts/list 中有 7 个由用户调用的工作流提示词(morning_inbox_triage、find_and_brief、follow_up_radar、decision_tracker、prepare_reply_drafts、clean_up_safely、review_scheduled_sends),每个提示词仅会列给拥有相应权限范围的密钥。
注意:
- 工具接受显式的
inbox_id(UUID)或inbox邮箱地址;单收件箱密钥会自动解析目标收件箱。 - 每次批量操作最多处理 50 条(
email_read的read_batch)到 500 条(移动/删除/标记)消息。 - 对于定向修改,先使用
email_read并设置action: "search",然后将返回的message_id或message_ids传给email_organize或email_delete。只有email_search_and_move和email_delete的search_and_delete操作接受搜索字段。 contact_search会实时扫描近期邮件,因此不会存储通讯录。email_read的original操作会将一封完整的、由服务提供方存储的 MIME 邮件作为可移植的.eml文件返回(最大 25 MB)。此操作为只读,且绝不会将邮件标记为已读。draft的send操作需要send:email,而非manage:drafts,因此仅能管理草稿的密钥无法借此绕过发送邮件的授权要求。draft的reply操作会在源会话中创建一封未发送的、由服务提供方原生支持的回复。此操作需要manage:drafts和read:email,且默认只回复发件人。- 只读部分(
folder_list、draft_list、schedule_list、signature_get、automation_read)已于 2026-09-09 从写入工具中拆分出来,因此只读密钥绝不会看到写入工具。对于已连接的客户端,旧的组合形式(folder的action: "list"、draft的action: "list"、schedule的action: "list"、signature的action: "get"/"set"、automation的action: "list"/"get"/"runs"/"preview")仍会通过线路协议接受,但不再公开列出。 automation用于管理无人值守的定时邮件分拣规则:存储一项搜索和一个固定操作,并按周期评估,不会有大模型参与其中。没有删除邮件的操作,forward始终需要人工批准,而draft_reply只会创建草稿。请参阅docs/automations-trust-boundary.md。- 对于 API 密钥,
tools/list只会返回该密钥权限范围允许使用的工具。OAuth 连接会列出所有工具;如果调用所需的权限范围未获授权,则会触发 MCP 升级验证质询(insufficient_scope)。
OAuth 权限范围
| 权限范围 | 授权内容 |
|---|---|
read:email | 列出收件箱和文件夹;列出、读取和搜索邮件;读取收件箱签名;查找联系人 |
search:email | 更窄的替代权限,仅授权 email_read 的 search 操作 |
send:email | 发送、回复和转发;设置签名和发件人名称;发送草稿也需要此权限 |
manage:folders | 创建/重命名/删除文件夹;移动、复制、标记和归档邮件 |
delete:email | 将邮件移至废纸篓或永久清除 |
manage:drafts | 创建、编辑和删除草稿(发送草稿还需要 send:email) |
manage:contacts | 从近期邮件中实时查找联系人 |
schedule:email | 将邮件加入队列以便日后发送 |
manage:automations | 创建和管理无人值守的定时邮件分拣规则(没有删除操作;转发始终需要批准) |
支持的提供商
| 提供商 | 连接方式 | 读取/搜索 | 发送 | 文件夹 | 永久删除 | 草稿 |
|---|---|---|---|---|---|---|
| Gmail / Google Workspace | 应用专用密码(IMAP/SMTP) | ✅ | ✅ | 标签 | ✅(遵循 Gmail 的 IMAP 清除设置) | ✅ |
| Fastmail | 应用专用密码(IMAP/SMTP) | ✅ | ✅ | ✅ | ✅ | ✅ |
| iCloud, Yahoo, AOL, GMX, Zoho, Yandex | 应用专用密码(IMAP/SMTP) | ✅ | ✅ | ✅ | ✅ | ✅ |
| IONOS, STRATO, One.com, OVHcloud, Namecheap Private Email, Hostinger, Infomaniak, Hetzner | 邮箱密码(IMAP/SMTP) | ✅ | ✅ | ✅ | ✅ | ✅ |
| cPanel, Plesk, SiteGround, Bluehost 及其他共享主机 | 邮箱密码(IMAP/SMTP) | ✅ | ✅ | ✅ | ✅ | ✅ |
| 任何其他 IMAP/SMTP 邮箱 | 应用专用密码或邮箱密码 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Outlook / Microsoft 365 | OAuth 2.0(Microsoft Graph) | ✅ | ✅ | ✅(嵌套) | ✅ | ✅ |
托管在网站主机上的自有域名邮箱,连接方式与任何 IMAP 邮箱相同;一个工作区可以包含多个此类邮箱(info@、sales@、support@)。100 家提供商的各主机设置和已知问题请参阅 mcpemails.com/connect。各提供商的功能支持情况见提供商兼容性矩阵;探测到的 IMAP/SMTP 主机、登录机制和大小限制可免费下载为开放的提供商数据集(JSON 和 CSV,CC BY 4.0)。
Outlook 使用 Microsoft Graph,并通过“使用 Microsoft 登录”,而非 IMAP。个人 Microsoft 账户(outlook.com、hotmail.com、live.com、msn.com)可直接连接。在工作或学校的 Microsoft 365 租户中,Microsoft 的默认许可策略会阻止员工自行批准邮件权限,因此需要 IT 管理员为组织批准一次该应用;控制面板会提供可分享的批准链接,供用户发送给管理员(
/auth/outlook/admin-consent),且管理员无需拥有 MCPEmails 账户。没有 Exchange Online 邮箱的 Microsoft 账户会被拒绝,并提示改用 IMAP。标签工具仅适用于 Gmail(Outlook 使用文件夹),但自动化中的标签操作会应用 Outlook 类别;此外,Graph 无法将文本搜索与未读、附件、已标记或日期筛选条件结合使用。
定价
价值指标是已连接的收件箱。免费版可连接 1 个邮箱,个人版最多可连接 3 个,专业版可为经营业务的个人连接最多 10 个,商业版包含 10 个邮箱,每增加 1 个邮箱每月收费 $3,并支持不限人数、设置角色,且为每位客户提供独立工作区。按年计费可节省约 20%。
| 免费版 | 个人版 | 专业版 | 商业版 | |
|---|---|---|---|---|
| 价格 | $0 | $9/月 · $86.40/年($7.20/月) | $15/月 · $144/年($12/月) | $39/月 · $374.40/年($31.20/月) |
| 已连接的收件箱 | 1 | 3 | 10 | 包含 10 个,之后每个 $3/月($28.80/年) |
| 每月邮件操作次数 | 150(前 3 天不计入) | 无月度上限(合理使用) | 无月度上限(合理使用) | 无月度上限(合理使用) |
| API 密钥 | 不限 | 不限 | 不限 | 不限 |
| 成员 | 1(仅所有者) | 1(仅所有者) | 1(仅所有者) | 不限,支持角色设置,不额外收费 |
| 合理使用速率限制 | 60 次请求/分钟 | 120 次请求/分钟 | 300 次请求/分钟 | 1,000 次请求/分钟 |
| 角色、管理员发送审批、多个工作区 | 否 | 否 | 否 | ✅ |
| 支持 | 社区 | 邮件 | 邮件 | 邮件 |
每个 API 密钥还会受到独立限制(100 次请求/分钟 · 1,000 次/小时 · 10,000 次/天)。速率限制可重试:超限时会返回 JSON-RPC 错误 -32003,并在 data.retry_after 中提供等待秒数。
免费工作区每个日历月(UTC)可进行150 次邮件操作。注册后的前 3 天不计入(2026-10-17 之前创建的工作区为 7 天),inbox_list 和仪表板永不计入。达到限额后,其他所有邮件操作都会被拒绝,直至下个月 1 日;无人值守的自动化流程会暂停,并在 1 日自动恢复;所有者会在使用量达到 80% 和 100% 时收到邮件通知。个人版、专业版和商业版没有月度上限,但须遵守合理使用规定(其上限是用于防止滥用的保护措施,并非套餐功能,且不会在任何位置显示)。操作被拒绝时不可重试,也不会返回 JSON-RPC 错误:它会作为普通工具结果返回,包含 isError: true,文本以使用次数和重置日期开头,并附带 _meta["com.mcpemails/usage_limit"] 区块,该区块会在 reset_at 所示时间清除。
内部套餐 ID 的命名早于对外名称:solo 对外称为专业版,pro 对外称为商业版(截至 2026-10-19,其名称为团队版)。较新的 personal ID 是唯一与其显示名称个人版一致的 ID。所有在 2026-08-19 调整价格前已存在的用户,永久保留免费的不限量收件箱;所有在 10 个收件箱上限推出时已使用专业版的工作区,均保留不限量收件箱;所有在 2026-09-12 推出操作次数限额前创建的工作区,都是早期成员,不会被计入该限额。请参阅 apps/web/src/lib/stripe/plans.ts。
架构
flowchart LR
Agent["MCP client<br/>(Claude, Cursor, …)"] -->|"JSON-RPC / OAuth or API key"| Web
subgraph Vercel["Vercel — Next.js 16"]
Web["/api/mcp route<br/>+ marketing site + dashboard"]
end
subgraph Supabase
Edge["mcp-server<br/>edge function (Deno)"]
DB[("Postgres<br/>RLS + encrypted creds")]
Cron["outlook-token-refresh<br/>edge function"]
end
Web -->|proxies| Edge
Edge -->|decrypt creds, fetch live| Providers["Email providers<br/>Gmail API · Microsoft Graph · IMAP/SMTP"]
Edge --> DB
Cron --> DB
Web --> Stripe[("Stripe<br/>billing")]
/api/mcp是一个精简的 Next.js 路由处理程序,用于代理到 Supabase Edge Functionmcp-server——真正的 MCP 实现,负责解密凭据并调用提供方。- Postgres 数据库用于存储工作区、成员、收件箱(加密的令牌/密码)、经过哈希处理的 API 密钥、OAuth 客户端、定时发送任务和活动日志——所有数据均受行级安全策略保护。
- Cron Edge Function(
outlook-token-refresh)会在 Outlook OAuth 令牌到期前刷新令牌。
技术栈: Next.js 16(App Router)· React 19 · next‑intl 4 · Supabase(Auth、Postgres、Edge Functions)· Stripe · Resend · TypeScript。邮件解析和清理在 Edge Functions 中运行(supabase/functions/mcp-server/mime.ts);签名 HTML 在浏览器中使用 DOMPurify 清理,在服务器端则使用无依赖的允许列表进行清理。
仓库布局
.
├── apps/
│ └── web/ # Next.js 16 app (marketing, dashboard, /api/mcp proxy)
│ ├── app/ # App Router routes ([locale], dashboard, api, auth)
│ ├── components/ # marketing/ + dashboard/ React components
│ ├── messages/ # next-intl translations (en, nb, es, fr, zh)
│ ├── src/lib/ # stripe/, supabase/, blog/, crypto helpers
│ └── proxy.ts # middleware: i18n + Supabase session + CDN cache
├── supabase/
│ ├── functions/
│ │ ├── mcp-server/ # the MCP server (tools, auth, scopes)
│ │ └── outlook-token-refresh/
│ └── migrations/ # SQL migrations (schema + RLS)
└── package.json # npm workspaces (apps/*)
本地开发
先决条件: Node.js 20+、npm,以及 Supabase CLI(用于迁移和 Edge Functions)。
# 1. Install (npm workspaces — run from the repo root)
npm install
# 2. Configure environment
cp .env.example apps/web/.env.local
# then fill in the values (see below) and generate the two secrets:
openssl rand -hex 32 # ENCRYPTION_KEY
openssl rand -hex 32 # CSRF_SECRET
# 3. Run the web app (http://localhost:3000)
npm run dev
# 4. Production build
npm run build
next.config.js会在构建/启动时验证必需的环境变量,并拒绝弱ENCRYPTION_KEY值,因此环境配置错误会立即暴露,而不是等到运行时才出现。
环境变量
复制 .env.example 并填入真实值。所有环境都必需:
| 变量 | 用途 |
|---|---|
NEXT_PUBLIC_SUPABASE_URL / NEXT_PUBLIC_SUPABASE_ANON_KEY | Supabase 客户端(公开) |
SUPABASE_SERVICE_ROLE_KEY | 服务端管理密钥(绕过 RLS)——机密 |
NEXT_PUBLIC_APP_URL | 规范基础 URL;用于 OAuth 重定向 URI |
GOOGLE_SITE_VERIFICATION (可选) | Google Search Console HTML 标签验证令牌;仅在生产环境中设置 |
ENCRYPTION_KEY | 用于静态凭据的 64 位十六进制 AES-256-GCM 密钥——机密 |
CSRF_SECRET | 用于 CSRF 令牌的 64 位十六进制 HMAC 密钥(与上面的密钥不同)——机密 |
取决于功能:
| 变量 | 用途 |
|---|---|
GMAIL_CLIENT_ID / GMAIL_CLIENT_SECRET | Gmail OAuth(gmail.readonly、gmail.send、gmail.modify) |
OUTLOOK_CLIENT_ID / OUTLOOK_CLIENT_SECRET / OUTLOOK_TENANT_ID | Outlook OAuth(Mail.ReadWrite、Mail.Send、offline_access、openid、profile、email)。OUTLOOK_TENANT_ID 为可选项,默认值为 common |
NEXT_PUBLIC_OAUTH_VERIFICATION_PENDING | 在 Google 验证完成前显示未验证应用警告(Microsoft 发布者已通过验证) |
STRIPE_SECRET_KEY / STRIPE_WEBHOOK_SECRET / NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | 计费 |
STRIPE_PRICE_PERSONAL_MONTHLY / _YEARLY、STRIPE_PRICE_SOLO_MONTHLY / _YEARLY、STRIPE_PRICE_PRO_MONTHLY / _YEARLY | 套餐价格 ID(personal = Personal,solo = Pro,pro = Business;当前的 Business 价格位于 STRIPE_PRICE_BUSINESS_* 中) |
STRIPE_WEBHOOK_PROXY_KEY | 可选。将 /api/stripe/webhook 限制为仅接受前置投递队列的请求。未设置 = 不限制。仅当队列已开始发送此密钥后再设置,否则每次投递都会返回 401 并进入死信队列。 |
STRIPE_WEBHOOK_TOLERANCE_SECONDS | 可选。Stripe 签名有效期上限,默认 7 天。设置较长是因为队列重放会携带原始签名;Stripe 自带的 300 秒默认值会拒绝所有暂存的重试请求。 |
Fastmail 和其他 IMAP 提供商通过应用专用密码连接,无需 OAuth 凭据。
Stripe webhook 通过队列投递。 Stripe 会向 Queuey 入口发送请求,该入口会转发到
/api/stripe/webhook。该队列有两项关键设置:有效负载必须为原始直通(签名针对精确字节计算),并且必须使用映射标头转发header:Stripe-Signature。如果没有映射标头,每次投递都会因Missing stripe-signature header.而失败。注意,STRIPE_WEBHOOK_SECRET必须是指向入口的 Stripe 端点的签名密钥,而不是任何较早的直连端点的密钥。
数据库与迁移
架构和行级安全策略位于 supabase/migrations/ 中。核心表:workspaces、workspace_members、inboxes(加密凭据,软删除)、api_keys(已哈希、限定作用域、限制收件箱)、oauth_clients、scheduled_sends、workspace_invites,以及按月分区的 activity_log。
# Apply one migration to the linked project, then record it in the history
npx supabase db query --linked -f supabase/migrations/<file>.sql
npx supabase migration repair --status applied <version> --linked
# Regenerate TypeScript types from the live schema
npm run gen:types
Supabase CLI 是此项目数据库变更的唯一事实来源。
apps/web/src/types/database.types.ts 是生成文件
此文件由 npm run gen:types(supabase gen types typescript --linked)完整写入,该命令读取的是已关联项目的实时数据,而不是迁移文件。
请勿手动编辑:手动添加的列会在下次重新生成时被静默删除;而手动添加但数据库中从未存在的列,则会通过编译,却在生产环境中导致 500 错误。应用迁移的同时重新生成此文件,并提交生成结果。
表、视图和 RPC 函数都已覆盖,而且 apps/web 中声明的每个 Supabase 客户端都位于 .ts/.tsx 文件中(这些文件构成了整个类型检查程序),类型均为 SupabaseClient<Database>,因此 .from()、.select()、.insert() 和 .rpc() 都会根据真实架构进行类型检查。如果某个表或列看起来缺失,解决方法是运行 npm run gen:types,而不是在 Supabase 客户端上局部使用 as any。保留下来的类型断言用于生成器确实无法表达的情况:jsonb 负载形状、可为 null 的函数参数,以及一个通过单一签名分派多个 RPC 的辅助函数。每处都附有说明原因的注释。
.ts/.tsx 这一限定至关重要。apps/web/tsconfig.json 未设置 checkJs,且其 include 为 **/*.ts 和 **/*.tsx,因此像 app/dashboard/[[...section]]/page.js 这样的 .js 文件完全不在程序范围内:其中的 JSDoc @param 类型只是文档,没有任何东西会验证它们。它们写作 SchemaTypedClient(一个指向 SupabaseClient<Database> 的 @typedef),这样文档至少与调用方传入的内容一致,但要保持其准确性仍需手动维护。
绝不要使用不带类型参数的 SupabaseClient。 如果没有类型参数,它会解析为 SupabaseClient<any, "public", any>,这就相当于一种 as any,用搜索 as any 的 grep 根本找不到:声明为 db: SupabaseClient 的函数完全不会检查列,.insert() 中不存在的列也能顺利编译。SupabaseClient<any> 是把同一个漏洞明说出来,SupabaseClient<any | Database> 和别名为 any 的 SupabaseClient<Alias> 也一样。因此,apps/web/eslint.config.mjs 不会搜索 any;它要求使用 Database,而且 npm run lint 会对任何未携带该类型的 SupabaseClient 类型引用报错,也会对未指定类型参数的 createServerClient(...) / createBrowserClient(...) 报错。
这些都是语法选择器(仓库不会运行类型感知 lint),因此它们会根据使用处的写法进行匹配;否则有三种情况可能直接绕过检查:import { SupabaseClient as SB }、先 import * as Supa 再使用 Supa.SupabaseClient,以及 const mk = createServerClient; mk(...)。任何选择器都无法追踪这些情况,因此配置会在上一层加以限制:重命名 SupabaseClient 导入,以及以命名空间方式导入 @supabase/ssr 或 @supabase/supabase-js,都会报错;no-restricted-imports 则禁止除 src/lib/supabase/ 中包装器以外的所有文件使用 createClient / createServerClient / createBrowserClient。只有这些包装器会创建客户端,并且始终传入 <Database>。其他所有内容都导入这些包装器。
这些规则没有限定于 **/*.ts(x),因此导入和调用限制也适用于 .js/.jsx/.mjs 文件。但它们无法读取这些文件中的 JSDoc 类型:语法选择器看不到对应的 AST 节点。这是上文所述的已知限制,并非规则假装能够覆盖的漏洞。
即使 tsc 通过,仍有两点无法由此得知:
--linked读取的是生产环境,而不是supabase/migrations/。 实际线上项目中的内容都会写入文件,差异也包括在内;本地存在但尚未推送的迁移对它不可见。重新生成需要关联项目的凭据,因此 CI 无法仅凭仓库内容重现此文件。在相信类型反映了迁移内容之前,请先运行supabase migration list --linked检查。截至 2026-09-16,该命令报告了八处双向不匹配。- 类型断言仍会关闭类型检查。
(row as any).some_column和client as unknown as SupabaseClient<Database>都会让任何写法通过编译。上面的 lint 规则会检查客户端的声明,但不会检查在调用处被断言为any的客户端;负责捕获这类问题的是@typescript-eslint/no-explicit-any,而对它使用eslint-disable是一种有意为之的选择,应该说明原因。
部署
Web 应用 → Vercel(项目 mcp-emails-web):
vercel --prod --yes
安全标头和函数超时在 vercel.json 中定义。营销页面路由使用可由 CDN 缓存的 Cache-Control(在 proxy.ts 中设置),因此爬虫和回访用户会命中边缘缓存;仪表板、身份验证和 API 路由则保持 no-store。
MCP 服务 → Supabase 边缘函数:
npx supabase functions deploy mcp-server --project-ref <your-project-ref> --no-verify-jwt
先迁移,再部署函数。 PostgREST 不会对它不认识的列返回
undefined,而是会报错;服务器共享的收件箱投影(INBOX_SELECT_COLUMNS)由所有邮件工具使用,而这些工具都会将查询错误解读为“找不到收件箱”。因此,在迁移之前部署函数,可能会导致整个邮件功能不可用,而不只是需要新增列的功能。新迁移的收件箱列会通过各自的小型查询(readSendReviewMode、readBulkReviewMode、readInboxDraftEditorHidden)单独读取,这样即使部署顺序颠倒,受影响的也只是对应功能,而不会导致所有功能都不可用——这是安全网,并不意味着可以跳过部署顺序。
自托管
不想把邮件交给托管服务?可以在自己的机器上运行同一个 MCP 服务。self-host/ 提供了一套容器化技术栈(Postgres + PostgREST + Deno 服务,不含 Supabase/Stripe/仪表板),因此你的凭据会使用只有你持有的密钥加密,并且只会在你自己的容器内解密。自托管指南介绍了它与托管服务的区别。
cd self-host
make setup # generate secrets (.env)
make up # build + start the stack
export IMAP_PASSWORD='your-app-password'
make provision [email protected] IMAP_HOST=imap.fastmail.com SMTP_HOST=smtp.fastmail.com SERVICE=fastmail
make key NAME="my agent" # mint an mcpe_ key, then point your client at http://localhost:8787
它以 IMAP/SMTP 为主(Fastmail、iCloud、Yahoo、Zoho、Yandex 和通用服务),通过应用密码连接;Gmail/Outlook OAuth 和 Web 仪表板仍仅由托管服务提供(Outlook 还需要你自行注册 Microsoft Entra 应用)。容器运行未经修改的 supabase/functions/mcp-server/;完整指南请参阅 self-host/README.md。
国际化
使用 next‑intl 构建(localePrefix: 'as-needed',localeDetection: false,以保证规范 URL 稳定)。英语使用 /;其他语言带有前缀(/nb、/es、/fr、/zh)。翻译文件位于 apps/web/messages/。
支持的语言:英语、挪威语博克马尔语、西班牙语、法语、简体中文。
安全模型
- 静态凭据使用 AES‑256‑GCM 加密;仅在服务器处理需要这些凭据的请求时解密(
mcp-server边缘函数,以及用于检查或测试连接的 Web API 路由)。 - 不存储邮件内容——邮件正文和附件均实时获取,绝不持久化。附件文本提取只在请求期间临时运行,不会返回原始附件字节。
- API 密钥经过哈希处理(仅存储用于显示的前缀),并按权限和收件箱分别限定范围,还可设置过期时间。
- 客户端授权使用 OAuth 2.0 + PKCE;MCP 客户端使用 Dynamic Client Registration(RFC 7591)。
- 行级安全性在数据库层隔离每个工作区的数据。
- 每个响应都设置了严格的 CSP、HSTS、
X-Frame-Options: DENY及相关标头。
许可证
MCPEmails 是基于 GNU Affero 通用公共许可证 v3.0(AGPL‑3.0)发布的开源软件。mcpemails.com 上的托管服务运行的就是同一服务器,你可以自行托管,阅读并验证代码,然后自己运行。信任模型请参阅 /security。
让任何 Agent 都能收发邮件。© MCPEmails,AGPL‑3.0。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。