Skip to main content
Glama
askie

cloudflare-email

by askie

cloudflare-email (已迁移)

这个仓库已废弃,不再更新。 项目整体搬到了 askie/cfmail,请去那边看代码、提 issue、拉最新版本。

git clone 本仓库地址依然能拉到最后的历史,但后续开发都在新仓库进行。


cloudflare-email · 给 Agent 一个自己能收发邮件的邮箱

这是什么

目标很直接:让 Agent 自己收邮件、自己发邮件,中间不用人转发、不用人审批、不用人点发送。 搭在 Cloudflare 上,没有网页界面——这不是给你自己翻邮件用的收件箱,是给 AI/程序当成自己的邮箱在用的。

发到 任意名字@你的域名 的邮件会被自动收下来存好;Agent 自己去搜、自己读全文、自己回信、自己转发附件——你不用把邮件转发给它,它也不用等你点确认才能发出去。

起步几乎零成本,Cloudflare 和 Resend 的免费额度就够用,两边都不用绑信用卡:

环节

免费额度

收信(Cloudflare Email Routing)

不限量,本来就免费

跑服务(Cloudflare Workers)

每天 10 万次请求

存邮件正文/索引(Cloudflare D1)

5 GB,每天 500 万次读

存附件原文(Cloudflare R2)

10 GB/月

发信(Resend,默认后端)

每月 3000 封、每天 100 封

一个小项目、一个人或几个 Agent 用,这些额度基本用不完;真的跑量大了再考虑升级也不迟。

有两种用法,按需选一种(也可以都用):

用法

怎么接

适合

直接接 MCP

把服务地址配进支持 MCP 的 AI 客户端

只想让某个 AI 客户端能查邮件,接一次就行

命令行 cfmail + 技能

装一个 CLI,给 Agent 配一份「技能」

要脚本化、要本地归档/提醒、要一台机器管多个邮箱

它适合这些场景:

  • 给 Agent 一个真正属于它自己的邮箱,让它独立完成「收信→读懂→回复/转发」的全流程,中间没有人工环节。

  • 用一个自己的域名收验证码、通知、账单、发票等邮件,让 AI 统一帮你查找和整理。

  • 不想登录邮箱一封封翻,想用「问一句、答一句」的方式查邮件。

  • 想把邮件连正文带附件定期同步到本机磁盘存一份,新邮件来了直接推送到聊天里,点开就是本地文件。

Related MCP server: io.github.p-w-4-z/inbox-mcp

它能做什么

  • 📥 自动收信:发到你域名下任意地址的邮件,全部收下并存档(正文 + 附件都留着)。

  • 🔎 AI 可查询:AI 能搜索关键词、按发件人/时间筛选、读邮件全文、下载附件。

  • 🈶 中文也能搜:中文主题和正文都能搜到。

  • 📤 能发信、能回信、能带附件:AI 可以用你的地址发邮件(走 Resend,也可用 Cloudflare 自带发信),对着某封邮件直接回复(自动带上原主题和会话线索),还能把收到的附件直接转发出去。

  • 💻 命令行工具 cfmail(可选):不接 MCP 也能用,脚本、定时任务、多个 Agent 各管各的邮箱都靠它。

  • 📁 本地归档(可选):新邮件按邮箱、按天同步到本机磁盘,正文自动存成纯文本/Markdown,附件原样落盘,可定时清理旧的。

  • 🔔 新邮件提醒(可选):每来一封新邮件自动推送到聊天或你自己的程序,本地归档的那种推送还带可点击的本地文件链接

  • 🔐 有访问密码:接口由一个密钥保护,只有持密钥的人/AI 才能查。

它是怎么跑的(一张图)

别人给你发邮件 ──▶ Cloudflare 收下 ──▶ 自动解析、存进数据库和文件存储
                                                  │
你 / 你的 AI 助手 ──问问题──▶ 这个服务的接口 ──查询──┘

技术细节(数据库表、检索原理、组件划分)见 ARCHITECTURE.md


快速部署到 Cloudflare(约 10 分钟)

全部在你自己的 Cloudflare 账号里完成,邮件只存在你自己的账号下,别人碰不到。

你需要准备

  1. 一个 Cloudflare 账号(免费版即可)。

  2. 一个已经添加到这个账号里的域名(用来收邮件,也用来访问服务)。

  3. 本机装好 Node.js 18 以上

第 0 步:拿到代码、登录、建本地配置

git clone <this-repo> && cd cloudflare-email
npm install
npx wrangler login                       # 浏览器里登录你的 Cloudflare 账号
cp wrangler.jsonc wrangler.local.jsonc   # 你的私有配置,不会被上传到代码仓库

你的域名、数据库编号这些「跟你账号绑定」的信息,都填在 wrangler.local.jsonc 里。它已被忽略,不会进代码仓库;后面的命令会自动用它。

第 1 步:创建数据库(存邮件的元信息和正文)

npx wrangler d1 create email_db

命令会输出一个 database_id,把它复制到 wrangler.local.jsoncd1_databases[0].database_id 那一行。

第 2 步:创建文件存储(存邮件原文和附件)

npx wrangler r2 bucket create email-store

第 3 步:填好你的域名

打开 wrangler.local.jsonc,把 routes[0].pattern 改成你想用的子域名,例如 mail.yourdomain.com(必须是你 Cloudflare 上的域名)。这个地址将来就是 AI 访问服务的入口。

第 4 步:建表 + 设访问密码 + 部署

npm run db:remote                        # 在数据库里建好表
npx wrangler secret put MCP_TOKEN        # 设一个访问密码(见下方提示)
npm run deploy                           # 部署上线

访问密码:执行上面那条命令后,粘贴一段足够长的随机字符串作为密码。可以先用 openssl rand -hex 32 生成一个。这个密码 AI 接入时要用,不要泄露

第 5 步:把「收到的邮件」转给这个服务

让发到你域名的所有邮件都进入这个服务(一次性配置):

# 把 <ZONE_ID> 换成你域名的 Zone ID;<API_TOKEN> 换成一个有 “Email Routing 编辑” 权限的 Cloudflare API Token
curl -X PUT "https://api.cloudflare.com/client/v4/zones/<ZONE_ID>/email/routing/rules/catch_all" \
  -H "Authorization: Bearer <API_TOKEN>" -H "Content-Type: application/json" \
  --data '{"enabled":true,"name":"catch-all to worker","matchers":[{"type":"all"}],"actions":[{"type":"worker","value":["cloudflare-email"]}]}'

不想敲命令也可以在网页里点:Cloudflare 控制台 → 你的域名 → Email Routing → Catch-all → 动作选 “Send to a Worker” → 选 cloudflare-email

如果这个域名以前没开过 Email Routing,先在控制台点一下开启(它会自动帮你加好收信需要的 DNS 记录)。

完成! 现在发到 任意@你的域名 的邮件都会被收下来,服务地址是 https://你的子域名


让 AI 用起来

把下面信息给到你的 AI 客户端即可:

  • 接口地址:https://你的子域名/mcp

  • 访问密码(放在请求头里):Authorization: Bearer 你设置的密码

用 Claude Code,一行命令接入:

claude mcp add --transport http email https://你的子域名/mcp \
  --header "Authorization: Bearer 你设置的密码"

其他 MCP 客户端,用配置文件:

{
  "mcpServers": {
    "email": {
      "url": "https://你的子域名/mcp",
      "headers": { "Authorization": "Bearer 你设置的密码" }
    }
  }
}

接好之后,直接用大白话问 AI 就行,例如:

  • 「搜一下含‘发票’的邮件」

  • 「看看最近 10 封邮件」

  • 「打开第一封,把附件下载下来」

  • 「上个月有没有来自某某的邮件」

背后 AI 会用到这些能力:搜索 search_emails、列表 list_emails、读单封 get_email、取附件 get_attachment、统计 stats、发信 send_email,以及设置新邮件提醒 set_webhook / 查看 get_webhook。你不用记这些名字,AI 会自己选。


用「技能」让 Agent 上手(可移植,推荐)

上面那种方式要把整个服务当 MCP 服务器接进客户端。如果你想让某个 AI Agent(Claude Code、或任何支持 skill 的 Agent)直接「会收发邮件、会开通邮箱」,用 skills/ 目录下这两份技能更省事——它们教 Agent 用下面这个 cfmail 命令干活,所以先装 CLI(需要 Node 20+),再把技能目录拷过去。

skills/
  email-inbox/   普通用户:用绑定的 Key 收取最新未读邮件
  email-admin/   管理员:开通邮箱、签发/吊销 Key、配置新邮件提醒

两者配套:管理员email-admin 为某个邮箱地址签发一把 Key,用户把这把 Key 配进 email-inbox 就能收信。

第 0 步:装上 cfmail 命令行工具

技能靠这个工具干活,先装(需要 Node 20+):

npm install -g cfmail
cfmail --help

想跑仓库里最新未发布的代码,从源码装:

git clone https://github.com/askie/cloudflare-email.git
cd cloudflare-email/cli && npm i -g $(npm pack | tail -1)

从源码装时别用 npm i -g ./cli:那样装的是指向源码目录的符号链接,仓库一移动 就坏,外置卷上的定时任务还会因访问不到而报 EPERM。先 npm pack 再装是真正的复制。

装完之后 cfmail 在任何目录都能用。它把这个服务的全部能力做成了子命令——收信、搜索、发信、回信、附件、管理密钥,详见 cli/README.md

不用技能、直接命令行用也完全可以:

cfmail setup --base https://你的子域名 --email you@你的域名 --key <你的Key>
cfmail unread
cfmail send --to someone@example.com --subject "标题" --text "正文"

第 1 步:把技能放进 Agent 的技能目录

把需要的技能整个目录拷过去即可。以 Claude Code 为例,技能目录是 .claude/skills/

# 拷贝(任选其一或两个都拷)
cp -r skills/email-inbox  你的项目/.claude/skills/
cp -r skills/email-admin  你的项目/.claude/skills/

也可以软链接整个 skills/ln -s /路径/cloudflare-email/skills 你的项目/.claude/skills。Agent 启动后会读取每个技能里的 SKILL.md,在合适的时候自动调用。

第 2 步(管理员):开通一个邮箱

# 一次性配置:服务地址 + 管理员密钥(部署时设置的 MCP_TOKEN)
cfmail admin setup --base https://你的子域名 --key <管理员MCP_TOKEN>
# 给某个地址开通邮箱,会打印一把明文 Key(只显示一次)
cfmail admin create-key alice@你的域名

其它管理命令:cfmail admin list-keys(看已开通的邮箱)、delete-key <邮箱>(吊销)、webhook [--set <url>|--clear](新邮件提醒)。

第 3 步(用户):用 Key 收发邮件

# 一次性配置:服务地址 + 自己的邮箱 + 上一步拿到的 Key
cfmail setup --base https://你的子域名 --email alice@你的域名 --key <你的Key>
# 收取最新未读邮件(首次给最近的存量,之后只给新到的)
cfmail unread
# 发一封邮件
cfmail send --to someone@example.com --subject "标题" --text "正文"
# 回复某封邮件(收件人、主题、会话线索自动推导)
cfmail reply <邮件id> --text "回复内容"

配好之后,对 Agent 说「看看有没有新邮件」「找一下验证码邮件」「回复一下那封发票邮件」,它就会自己选合适的命令,按需读全文、取附件、回信。

发信用的是 Key 绑定的那个地址,改不了——服务端强制的,所以拿到 Key 的人发不出别人的地址。

第 4 步(可选):同步到本地磁盘、加新邮件提醒

不想每次都问 AI,想让邮件自己定期落到本机磁盘、来新邮件就推一条消息?

cfmail sync --dir ~/cfmail            # 第一次指定目录,正文+附件按邮箱、按天存下来
cfmail sync                           # 之后只同步新邮件,重复跑很便宜
cfmail sync --notify whk_你的key      # 顺手推到聊天里,消息带本地文件的可点击链接
cfmail prune --older-than 90d --yes   # 定期清理旧归档,只删本地文件,服务器上的邮件不动

放进 launchd/cron 让 sync 每分钟跑一次,通知就跟同步一样快。目录结构、去重规则、prune 的安全设计都在 cli/README.md 里说明。

这是「本地推」;下面「新邮件提醒」一节还有一种不用先装 CLI 的「服务端推」,两者选一种即可,同时开会收到两条重复通知。

配置存哪、怎么改

  • 连接信息(含 Key)只存在运行 Agent 的本机

    • 用户端:~/.config/email-inbox/config.json

    • 管理端:~/.config/email-admin/config.json(与用户端分开,管理员密钥不会和普通 Key 放一起)

  • 可用环境变量覆盖文件:EMAIL_INBOX_CONFIG 换配置文件(一份配置 = 一个邮箱,这也是多邮箱和多程序并行的做法),EMAIL_INBOX_BASE / EMAIL_INBOX_KEY 覆盖凭据(管理端同理 EMAIL_ADMIN_*)。不确定当前连的是哪个邮箱,cfmail config 看一眼(不会打印 Key)。

  • 「未读」由本机游标记录(服务端不分已读/未读):cfmail unread --peek 只看不标记、--all 看最近全部、--reset 全部标为已读。

  • 发信:--attach ./file.pdf 附上本地文件、--forward-attachment <附件id> 直接转发收到的附件(不用先下载)、--text-file 从文件读长正文。

  • 任何命令加 --json 得到机器可读输出,失败时也是 JSON 且退出码非 0。

安全:email-admin 用的是最高权限的管理员密钥,只配在管理员自己机器上,绝不要交给普通用户;普通用户只该拿到 email-inbox 用的、绑定到自己邮箱的 Key。


试一下(30 秒跑通)

第 1 步:发一封测试邮件。 两种方式任选其一:

  • 用你的手机或任意邮箱,给 test@你的域名 发一封邮件,主题、正文随便写。

  • 或者用项目自带的自测脚本一键发送(会发一封带中文正文和 PDF 附件的样例邮件):

    node scripts/send-test-email.mjs test@你的域名

第 2 步:让 AI 查出来。 对接好的 AI 说一句「帮我查最新的邮件」,它就能查到刚发的那封。AI 拿到的内容大致长这样:

{
  "emails": [
    {
      "from": "selftest@你的域名",
      "subject": "测试邮件 发票 E2E",
      "date": 1781421031676,
      "has_attachments": true,
      "snippet": "你好,这是一封测试邮件,发票金额 8888 元。..."
    }
  ]
}

接着你就可以说「打开它」「把里面的附件下载下来」。

还没接 AI 也能验证:npx wrangler tail cloudflare-email 看是否收到,或直接查数据库: npx wrangler d1 execute email_db --remote --command "SELECT subject,from_addr FROM emails ORDER BY date DESC LIMIT 3"


发邮件(可选)

服务不只收信,也能用你的地址把邮件发出去。接好之后直接对 AI 说:

  • 「用我的邮箱给 xxx@xx.com 发一封邮件,主题是……」

  • 「回复刚才那封发票邮件,告诉对方已收到」——会自动带上原主题(Re: …)和会话线索,收件人那边能看到是同一串对话。

走哪条通道

有两个后端,默认用 Resend,没配 Resend 时自动退回 Cloudflare 自带的发信:

Resend(默认,推荐)

Cloudflare Email Sending(回退)

发给外部收件人

免费档 3000 封/月、100 封/天

要 Workers 付费计划 + 域名 onboarding

发给自己已验证的地址

同上,计入额度

免费,不计配额

退信/打开率统计

有面板

没有

怎么启用

设一个 secret(见下)

send_email binding

两个都没配的话,发信会返回一句「没有可用的发信后端」并告诉你怎么配,收信和查询不受影响。

配置 Resend(约 5 分钟)

1. 在 Resend 注册,添加你的域名——直接用根域 yourdomain.com 就行,不用退到子域。

2. 在 Cloudflare DNS 里加它给的三条记录:

类型

名称

代理

MX

send

Resend 给的地址,优先级 10

TXT

send

v=spf1 include:amazonses.com ~all

TXT

resend._domainkey

Resend 给的 DKIM 公钥

DNS Only(关橙云)

不会和收信打架:这条 MX 挂在 send.yourdomain.com 上(Resend 用它收退信),根域的 MX 仍然归 Email Routing。所以你可以用 me@yourdomain.com 发信,对方回过来又被这个服务收下——收发闭环在同一个地址上。

DKIM 那条一定要关橙云代理,开着会验不过。

3. 把 key 设成 secret:

npx wrangler secret put RESEND_API_KEY -c wrangler.local.jsonc

设完就能发了。

想用 Cloudflare 自带的发信

不设 RESEND_API_KEY,改成确认 wrangler.local.jsonc 里有这一行(wrangler.jsonc 模板里已经带了):

"send_email": [{ "name": "EMAIL" }],

然后去 Cloudflare 后台 Email → Email Sending 给域名做一次 onboarding。只发给自己在 Email Routing → Destination addresses 里验证过的地址的话,这步可以跳过,直接就能发且免费。

带附件

两种发法,直接说话就行:

  • 「把刚才那封邮件的发票附件转发给会计」——AI 用 forward_attachment_ids 直接从存储里取,不用先下载再上传,大文件也不占对话

  • 「把这份报告作为附件发出去」——AI 自己生成文件内容附上去

能带多大:Resend 单封 40 MB,Cloudflare 5 MiB,两家都最多 32 个附件。

注意附件在邮件里是 base64 编码传输的,会膨胀约 1/3。所以走 Cloudflare 时,5 MiB 的限额换算成实际文件大概是 3.6 MB 左右;走 Resend 则是 29 MB 左右。中文正文同样会被编码放大,也一并算在内。服务按编码后的真实大小在发送前就检查,超了会直接告诉你,不会等发出去才失败。

转发别人邮箱里的附件是转不了的——和读邮件同一套权限。

小提示:文本附件每经一次收发往返,末尾会多一个换行。这是邮件格式(MIME)本身的规定造成的,不是出错了。

发件人是谁

  • 用普通 Key 的用户:只能用自己 Key 绑定的那个地址发信,改不了,也发不出别人的地址。

  • 管理员:没有绑定地址,发信时要自己指定 from

发失败时工具会把错误码和该怎么处理一并返回,AI 能直接读懂告诉你。比如 validation_error 一般是域名还没在 Resend 验证通过。


新邮件提醒(可选)

想让新邮件来的时候自动通知你?有两条完全独立的路:

这一节:cfmail admin webhook

本地同步的 cfmail sync --notify(「新邮件推送到 Grix」一节)

谁配

管理员,服务端全局一份

每个用户各自在自己机器上配

要不要装 CLI

不用,服务端直接推

要,靠本机 sync 定时跑

附件

只报文件名和大小

带可点击的本地文件链接,点开就是已经下载好的文件

时效

邮件一到就推

跟着 sync 的频率,一般设成每分钟

两者选一种即可,同时开会收到两条重复通知。不装 CLI、只想要一个最省事的即时提醒,用这一节;想要点开就是本地文件,用 cfmail sync --notify(上面「同步到本地磁盘、加新邮件提醒」那步)。

推到 Grix 聊天里(只要一个 key):

cfmail admin webhook --set whk_你的key

之后每来一封邮件,Grix 里就会收到一条消息,长这样:

📬 新邮件(含附件)
发件人: 张三 <zhangsan@example.com>
收件人: you@你的域名
主题: 8 月账单

附件 2 个:
  · 账单.pdf  240 KB
  · 明细.xlsx  18 KB

账单已生成,请查收附件……

附件只列文件名和大小,不塞文件内容——要拿文件用 cfmail read <邮件id> 找到附件 id,再 cfmail attachment <附件id> --out <路径> 下载。

POST 给你自己的程序

cfmail admin webhook --set https://你的接收地址

这种方式发的是原始 JSON 事件(含发件人、主题、摘要,以及完整的附件元信息数组),适合自己写处理逻辑。注意 JSON 事件里的附件是全量列出的,而 Grix 消息里最多列 10 个——前者给程序消费,不怕长。

关掉:cfmail admin webhook --clear。查看当前设置:cfmail admin webhook

服务靠值的形态自动判断:whk_ 开头当作 Grix key,http(s):// 开头当作普通 URL,其它一律拒绝。

推送是「尽力而为」的——通知失败只记日志,绝不会影响邮件本身的接收和存档。


日常维护

npx wrangler tail cloudflare-email        # 实时看收信和报错日志
npx wrangler secret put MCP_TOKEN         # 换访问密码(换完旧密码立即失效)
# 直接翻看最近 10 封邮件
npx wrangler d1 execute email_db --remote \
  --command "SELECT id,subject,from_addr,date FROM emails ORDER BY date DESC LIMIT 10"

提示:wrangler.local.jsonc 只存在你本机,记得别误删;删了就照「第 0 步」重新 cp 一份再把你的数据库编号和域名填回去。


给开发者:本地运行与自检

cp .dev.vars.example .dev.vars                 # 填一个本地访问密码
npm run db:local                               # 建本地数据库表
npm run dev                                     # 本地启动,:8787
MCP_TOKEN=本地密码 node scripts/mcp-smoke.mjs    # 连本地接口自检
npm test                                        # 单元测试
npm run typecheck                               # 类型检查

线上自检:BASE="https://你的子域名" TOKEN="你的密码" node scripts/remote-check.mjs


安全说明

  • 访问密码以 Cloudflare 加密保管(MCP_TOKEN),不在代码里、不会进代码仓库

  • 别把密码贴进代码或公开分享;要换随时 wrangler secret put MCP_TOKEN

  • 你的真实域名、数据库编号写在 wrangler.local.jsonc,本地保存、不入库。

常见问题

  • 服务地址打不开 / 连接被重置:别用默认的 *.workers.dev(部分地区会被阻断),用你自己的域名(本项目默认就是这么做的)。

  • 自己测试发邮件被退回(550 SPF):这是发件方校验问题;用正常邮箱(Gmail/QQ/Outlook 等)发信不受影响。

  • 刚发的邮件查不到:收信到入库有几秒延迟,稍等再查,或用 wrangler tail 看是否收到。

  • 提示 401 没权限:检查 Authorization: Bearer 密码 是否填对。

许可

MIT — 可自由使用、修改、分发。

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server enabling AI assistants to manage Gmail through natural language, including sending, reading, searching, labeling, and handling attachments with auto authentication.
    1
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Provider-agnostic email MCP server that connects any IMAP mailbox to AI assistants, enabling email management through natural language.
    8
    AGPL 3.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that gives AI assistants comprehensive access to Apple Mail accounts, enabling email discovery, reading, flag management, and server-side message retrieval.
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    An MCP server that gives AI assistants full access to Apple Mail -- read, search, compose, organize, and analyze emails via natural language.
    38
    MIT