内容
<div align="center">
<img src="public/agentbox.png" alt="AgentBox" width="96" height="96" />
# AgentBox
**自主工作流的代理原生收件箱**
轻量级、开源、自主托管的收件箱,适用于由 **Cloudflare** 提供的 AI 代理。按需创建收件箱,接收一次性密码和验证电子邮件,并使用您自己的域名。
<p>
<img alt="Next.js" src="https://img.shields.io/badge/Next.js_16-000000?logo=nextdotjs&logoColor=white" />
<img alt="React" src="https://img.shields.io/badge/React_19-20232A?logo=react&logoColor=61DAFB" />
<img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white" />
<img alt="Tailwind CSS" src="https://img.shields.io/badge/Tailwind_v4-06B6D4?logo=tailwindcss&logoColor=white" />
<img alt="shadcn/ui" src="https://img.shields.io/badge/shadcn%2Fui-000000?logo=shadcnui&logoColor=white" />
<img alt="Cloudflare" src="https://img.shields.io/badge/Cloudflare-F38020?logo=cloudflare&logoColor=white" />
<img alt="License" src="https://img.shields.io/badge/License-MIT-22C55E" />
</p>
</div>
---
代理可以通过 `POST /v1/inboxes` 生成一个新的地址 (`swift-fox-ab12@yourdomain.com`),使用它注册,然后通过 `GET /v1/inboxes/<id>/messages?wait=30` 读取验证电子邮件 — 所有操作都通过简单的 REST API 或内置的 **MCP 服务器** 进行,供 MCP 原生代理和代理框架使用。
<img src="images/inboxes.png" alt="AgentBox" />
<img src="images/apikey.png" alt="AgentBox" />
<img src="images/settings.png" alt="AgentBox" />
<img src="images/claude-code.png" alt="AgentBox" />
## 目录
- [部署到 Vercel](#deploy-to-vercel)
- [工作原理](#how-it-works)
- [多域名支持](#multi-domain-support)
- [存储](#storage)
- [需求](#requirements)
- [设置](#setup)
- [Docker](#docker)
- [代理 API (`/v1`)](#agent-api-v1)
- [MCP 服务器](#mcp-server)
- [仪表盘](#dashboard)
- [清理 / 出厂重置](#cleanup--factory-reset)
- [备注和限制](#notes--limits)
- [技术栈](#stack)
- [项目结构](#project-structure)
## 部署到 Vercel
最快的开始方式 — 一键部署,零本地设置:
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fmastomii%2Fagentbox&env=CF_API_TOKEN,AGENTBOX_SECRET&envDescription=CF_API_TOKEN%3A%20Cloudflare%20API%20token%20(Workers%2BD1%2BEmail%20Routing).%20AGENTBOX_SECRET%3A%20run%20%60openssl%20rand%20-hex%2032%60.&envLink=https%3A%2F%2Fgithub.com%2Fmastomii%2Fagentbox%23creating-the-cloudflare-api-token&project-name=agentbox&repository-name=agentbox)
您将被提示输入两个环境变量:
| 变量 | 如何获取 |
|---|---|
| `CF_API_TOKEN` | [创建 Cloudflare API token](#creating-the-cloudflare-api-token) ,具有 Workers、D1、账户设置和电子邮件路由权限 |
| `AGENTBOX_SECRET` | 运行 `openssl rand -hex 32` |
部署后,打开应用程序 → 创建管理员账户 → 设置 → 添加域名 → 预置 → [手动启用电子邮件路由](#setup) → 完成。
## 工作原理
```
inbound email
│
▼
Cloudflare 电子邮件路由 每个收件箱一个规则 (you@yourdomain → worker)
│
▼
电子邮件工作流 由 AgentBox 解析的 MIME
│
├──▶ Cloudflare D1 消息行 + 附件元数据
│
└──▶ Cloudflare R2 附件二进制文件 (可选,需要 CC)
│
▼
AgentBox 仪表盘 / 代理 API 通过 Cloudflare REST API 读取
```
- **仪表盘(此 Next.js 应用程序)** — 登录、设置、真正的收件箱 UI 和 API 密钥。完全响应式(桌面 3 窗格,移动抽屉 + 单窗格)。
- **控制平面** — Cloudflare API token 位于 `CF_API_TOKEN` 环境变量中。您选择您的域名,点击 **预置**,AgentBox 使用 Cloudflare REST API:创建 D1 数据库(+ 架构)并上传绑定到它的电子邮件工作流。**注意:** 必须在 Cloudflare 仪表盘中为每个域名手动启用电子邮件路由(API token 无法切换此设置)。启用后,每个您创建的收件箱都会自动注册自己的地址路由规则到工作流中。**无需 `wrangler` 。**
- **存储** — 所有内容(用户、设置、API 密钥、收件箱、邮件)都存储在一个 Cloudflare **D1 数据库** (`agentbox`) 中。无需本地磁盘,因此可以直接部署到 **Vercel / Cloudflare Pages** (无服务器)。
## 多域名支持
AgentBox 可以同时路由多个域的邮件。每个域必须是您的 Cloudflare 账户中的一个区域。 在 **设置** 中添加域名 — 收件箱可以使用其中任何一个域名。添加的第一个域名成为默认域名(用于预置共享的 D1 + 工作流)。额外的域名重用相同的工作流;每个收件箱都会在其所属区域中创建一个路由规则。
您可以随时切换默认域名,并在侧边栏中按域名筛选收件箱。
## 存储
状态存储在 **Cloudflare D1** (无服务器 SQLite)中 — 免费,无需信用卡。电子邮件工作流通过绑定 D1 原生写入入站邮件,而仪表盘(在 Cloudflare 外运行)通过 D1 REST API 读取/写入。真正的 SQL 意味着未读计数、列表和搜索都是单个索引查询,而不是键扫描,因此它始终保持在免费配额内。
**附件** 存储在 **Cloudflare R2** (S3 兼容的对象存储)中。R2 在设置期间自动预置,如果 API token 具有 `Workers R2 Storage` 权限,并且 Cloudflare 账户有信用卡记录。R2 的免费层是 10 GB 存储 + 10M 读取/月 — 足够代理收件箱使用。如果 R2 不可用,AgentBox 仍然正常工作,但附件不会存储。设置页面显示一个徽章,指示附件是否启用或禁用。
API token 是唯一必须存储在数据库外部的密钥(您需要它才能从无状态的无服务器函数访问 D1)。账户 ID 和数据库 ID 从 token 中自动发现并缓存。
## 需求
- **Node 22+** (或 18+;Docker 中使用 22-alpine)
- **Cloudflare 上的域名** (由 Cloudflare 管理 DNS — 即域名在您的 Cloudflare 账户中处于活动状态)
- **Cloudflare API token** (见下文)
所有使用的 Cloudflare 产品(Workers、D1、电子邮件路由)都在 **免费层** ,无需信用卡。R2(附件存储)是可选的,需要在 Cloudflare 账户上记录信用卡(免费高达 10 GB/月)。
### 创建 Cloudflare API token
AgentBox 使用一个 token 来完成所有操作 — 基础设施预置 *和* 运行时数据读写。一次性创建:
1. 前往 **[dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens)**。
2. 点击 **创建 Token** → 向下滚动 → **创建自定义 Token** → **开始**。
3. 命名,例如 `agentbox`。
4. 在 **权限** 下,添加这四行(每个点击 **+ 添加更多**):
| # | 类型 | 资源 | 访问权限 |
|---|---------|--------------------------|----------|
| 1 | 账户 | **Workers 脚本** | **编辑** |
| 2 | 账户 | **D1** | **编辑** |
| 3 | 账户 | **账户设置** | **读取** |
| 4 | 区域 | **电子邮件路由规则**¹ | **编辑** |
| 5 | 账户 | **Workers R2 存储**² | **编辑** |
¹ 在区域下拉菜单中列为 **电子邮件路由规则** 。
² **可选。** 启用附件存储。需要 Cloudflare 账户上的信用卡(R2 免费层:10 GB/月)。如果省略或不可用,AgentBox 正常工作但跳过附件。
5. 在 **账户资源** 下,选择 **包括 → 您的账户**。
6. 在 **区域资源** 下,选择 **包括 → 特定区域 → 您的域名** (或 *所有账户区域* ,如果您愿意)。
7. (可选)设置 **TTL** / IP 过滤器,然后 **继续到摘要** → **创建 Token**。
8. **立即复制 Token** — 它只显示一次。这是您的 `CF_API_TOKEN`。
> **每个权限的作用**
> - **Workers 脚本 → 编辑** — 上传/删除电子邮件工作流。
> - **D1 → 编辑** — 创建 `agentbox` 数据库,运行架构并读写所有数据(用户、密钥、设置、收件箱、邮件)。
> - **账户设置 → 读取** — 从 token 中自动发现您的账户 ID。
> - **电子邮件路由规则 → 编辑** — 为每个收件箱创建一个路由规则。
> - **Workers R2 存储 → 编辑** *(可选)* — 自动创建 `agentbox-attachments` R2 存储桶并存储电子邮件附件。 如果省略或不可用,AgentBox 正常工作但跳过附件。
> ⚠️ 设置时出现 **`Authentication error` (代码 `10000`)** 表示 token 缺少权限 — 通常是 **D1 → 编辑**。编辑 token (或创建新 token),添加缺失的行,更新 `CF_API_TOKEN` 并重启。
## 设置
**1. 环境变量** — 在 `.env.local` 中用于本地开发,或在您的 Vercel / CF Pages 项目设置中:
```bash
CF_API_TOKEN=<您的 Cloudflare API token> # 预置基础设施并在运行时访问 D1
AGENTBOX_SECRET=<openssl rand -hex 32> # 签署 session JWT
```
**2. 安装和运行:
```bash
npm install
npm run dev # http://localhost:3000
# 或: npm run build && npm start
```
**3. 首次运行向导:
1. 打开应用程序 → **创建您的管理员账户** (存储在 D1 中,bcrypt 哈希)。
2. **设置 → 添加域名** (从您的 Cloudflare 区域自动获取)。
3. 点击 **立即预置** — 创建 D1 数据库并部署电子邮件工作流。
4. **重要:** 在 Cloudflare 仪表盘中手动启用电子邮件路由:前往您的域名 → **电子邮件** → **电子邮件路由** 并点击 **启用电子邮件路由**。
(这是 Cloudflare API token 无权更改的单个切换开关)。
5. 完成 — 您现在可以在 UI 中生成收件箱,或让代理通过 API 创建它们。
## Docker
多阶段 `Dockerfile` 从 Next.js 的独立输出构建一个微小的、无根镜像。所有状态都存储在 Cloudflare D1 中,因此容器是无状态的 — 不需要卷。
运行预构建的镜像:
```bash
docker run -d -p 3000:3000 --env-file .env --name agentbox ghcr.io/mastomii/agentbox:0.1.0
```
或本地构建和运行:
```bash
# 1. 提供 env(compose 自动读取 .env)
cp .env.example .env # 然后填写 CF_API_TOKEN + AGENTBOX_SECRET
# 2. 使用 compose 构建和运行
docker compose up -d --build
# → http://localhost:3000
```
或使用纯 Docker:
```bash
docker build -t agentbox .
docker run -d -p 3000:3000 --env-file .env --name agentbox agentbox
```
## 代理 API (`/v1`)
身份验证:`Authorization: Bearer <api-key>` — 在 **API 密钥** 页面创建密钥。密钥显示一次,然后存储为 SHA-256 哈希。同时支持 `X-Api-Key` 头。
### 1. 列出收件箱
重用现有收件箱而不是创建新收件箱。
```bash
curl "https://your-host/v1/inboxes?limit=20&address=swift-fox@yourdomain.com" \
-H "Authorization: Bearer ab_..."
**查询参数:** `limit` (默认 50,最大 100),`address` (精确匹配过滤)
```json
{
"inboxes": [
{
"id": "inbox_abc123",
"address": "swift-fox-ab12@yourdomain.com",
"label": "github-signup",
"created_at": 1234567890,
"last_message_at": 1234567890
}
]
}
```
### 2. 创建收件箱
生成新的收件箱(仅需时)。
```bash
curl -X POST https://your-host/v1/inboxes \
-H "Authorization: Bearer ab_..." \
-H "Content-Type: application/json" \
-d '{"label":"github-signup", "local":"swift-fox"}'
```
**正文参数(可选):** `label` (字符串),`local` (自定义用户名前缀;如果省略,则随机)
```json
{ "id": "inbox_abc123", "address": "swift-fox@yourdomain.com" }
```
### 3. 长轮询消息
按收件箱 ID 轮询消息(最多等待 55 秒)。
```bash
curl "https://your-host/v1/inboxes/inbox_abc123/messages?wait=30" \
-H "Authorization: Bearer ab_..."
**查询参数:** `wait` (秒,最大 55;长轮询),`since` (毫秒时间戳),`limit` (默认 100,最大 100)
```json
{
"id": "inbox_abc123",
"address": "swift-fox@yourdomain.com",
"count": 1,
"messages": [
{
"id": "msg_xyz789",
"from": "sender@other.com",
"fromName": "Sender",
"to": "swift-fox@yourdomain.com",
"subject": "Hello",
"text": "Body text",
"receivedAt": 1234567890
}
]
}
```
### 4. 读取完整消息
返回主题文本、html 和附件。
```bash
curl https://your-host/v1/messages/msg_xyz789 \
-H "Authorization: Bearer ab_..."
```
```json
{
"message": {
"id": "msg_xyz789",
"from": "sender@other.com",
"fromName": "Sender",
"to": "swift-fox@yourdomain.com",
"subject": "Hello",
"text": "Body text",
"html": "<p> <p>Body text</p>",
"receivedAt": 1234567890,
"attachments": [
{
"id": "att_abc",
"filename": "invoice.pdf",
"contentType": "application/pdf",
"size": 54321
}
]
}
}
```
### 5. 标记消息为已读
```bash
curl -X POST https://your-host/v1/messages/seen \
-H "Authorization: Bearer ab_..." \
-H "Content-Type: application/json" \
-d '{"ids":["msg_xyz789"]}'
```
```json
{ "ok": true, "count": 1 }
```
### 6. 删除消息
IDempotent。
```bash
curl -X DELETE https://your-host/v1/messages/msg_xyz789 \
-H "Authorization: Bearer ab_..."
```
```json
{ "ok": true, "id": "msg_xyz789" }
```
### 7. 下载附件
需要 R2。流式传输原始字节,非 JSON。
```bash
curl https://your-host/v1/messages/msg_xyz789/attachments/att_abc \
-H "Authorization: Bearer ab_..." -o invoice.pdf
```
### 8. 删除收件箱
删除 Cloudflare 路由规则并删除所有存储的消息。
```bash
curl -X DELETE https://your-host/v1/inboxes/inbox_abc123 \
-H "Authorization: Bearer ab_..."
```
```json
{ "ok": true, "id": "inbox_abc123" }
```
## MCP 服务器
对于 MCP 原生代理,AgentBox 通过单个 Streamable-HTTP 端点公开与 `/v1` API 相同的操作:
```
POST https://your-host/mcp
```
身份验证与 REST API 相同 — 相同的 `Authorization: Bearer <api-key>`(或 `X-Api-Key`)头,您在 **API 密钥** 页面创建。
**工具** (与 REST 端点 1:1 对应):
| 工具 | 等效端点 |
|---|---|
| `list_inboxes` | `GET /v1/inboxes` |
| `create_inbox` | `POST /v1/inboxes` |
| `delete_inbox` | `DELETE /v1/inboxes/{id}` |
| `list_messages` | `GET /v1/inboxes/{id}/messages` (包括 `wait` 长轮询) |
| `get_message` | `GET /v1/messages/{mid}` |
| `delete_message` | `DELETE /v1/messages/{mid}` |
| `mark_seen` | `POST /v1/messages/seen` |
| `get_attachment`¹ | `GET /v1/messages/{mid}/attachments/{aid}` |
¹ 仅在启用 R2 附件存储时公开。返回元数据和下载 URL(使用您的 API 密钥获取),而不是原始字节。
**将其添加到 MCP 客户端:**
```json
{
"mcpServers": {
"agentbox": {
"url": "https://your-host/mcp",
"headers": { "Authorization": "Bearer ab_..." }
}
}
}
```
**或通过 JSON-RPC 直接调用:
```bash
curl -X POST https://your-host/mcp \
-H "Authorization: Bearer ab_..." \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"create_inbox","arguments":{"label":"signup"}}}'
```
## 清理 / 出厂重置
**设置 → 清理所有内容** (输入以确认 `CLEANUP`)拆除了 AgentBox 在 Cloudflare 上创建的所有内容:
1. 删除每个地址的电子邮件路由规则。
2. 删除电子邮件工作流。
3. 删除 R2 存储桶(`agentbox-attachments`)和所有存储的附件。
4. 删除 D1 数据库 — 这 **擦除了所有存储的数据** (用户、密钥、设置、收件箱、邮件)。
您会自动退出并返回到设置向导。`CF_API_TOKEN` 保留在您的环境中,因此您可以立即重新预置。
> ⚠️ 这是不可逆的。没有单独的备份 — D1 是单一的真实来源。
## 备注和限制
- **D1 免费层:** 5 GB 存储,500 万行读取/天,10 万行写入/天 — 远超代理风格收件箱的需求。新邮件在几秒内可见。
- **最大收件箱数量:** Cloudflare 电子邮件路由允许 **约 200 个规则/域名** ,因此每个域名最多可有 ~200 个活动收件箱。代理可以重用现有收件箱或创建新收件箱;删除未使用的收件箱以释放槽位。
- **轮询:** 仪表盘每 30 秒轮询一次(消息)/ 每 60 秒轮询一次(收件箱列表),在标签隐藏时暂停 — 对 D1 配额较为温和。
- **保留:** 无限期 — 消息保留直到您删除它们(或收件箱)。
- **仅接收:** 不包含发送/回复(不包含 MailChannels / Resend / SMTP)。AgentBox 是控制面板 + 读取器。
- **登录速率限制:** 每分钟每个 IP 地址 5 次尝试(进程内滑动窗口)。
## 许可证
MIT — 见 [LICENSE](LICENSE)。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器