mcp_agent_mail
mcp_agent_mail 是为 AI 编程智能体打造的异步协作层,堪称“智能体界的 Gmail"。在现代开发中,多个 AI 智能体常需并行处理后端、前端或基础设施任务,但缺乏统一协调机制容易导致代码冲突、上下文丢失或依赖人工传话。mcp_agent_mail 通过提供可记忆的身份注册、收件箱/发件箱、可搜索的对话线程以及文件预留“租约”机制,让智能体能够像人类发邮件一样高效沟通,主动声明操作意图以避免相互干扰。
该工具特别适合需要同时调度多个 AI 智能体(如 Claude Code、Codex、Gemini CLI 等)的开发者和技术团队,尤其在复杂项目或多代码库协同场景中价值显著。其独特亮点在于结合了 FastMCP 协议、Git 版本控制和 SQLite 数据库:Git 确保所有交互和工件可被人类审计,SQLite 支持高效的索引与查询,而“建议性文件租约”则巧妙解决了并发写入冲突难题。作为一个轻量级且互操作性强的 HTTP 服务,mcp_agent_mail 让智能体集群在无需人工时刻盯守的情况下,也能有序、透明地并行工作,大幅提升自动化开发效率。
使用场景
某初创团队正在并行开发一个电商平台的后端 API、前端界面和基础设施脚本,三名开发者分别指挥不同的 AI 编码助手(如 Claude Code 和 Codex)协同工作。
没有 mcp_agent_mail 时
- 代码冲突频发:多个 AI 助手同时修改同一配置文件,导致彼此覆盖对方的更改,甚至引发构建失败。
- 上下文割裂:负责前端的 AI 不知道后端 AI 刚刚修改了接口定义,导致联调时出现大量无效请求。
- 人工协调成本高:开发者必须时刻充当“联络员”,在不同终端窗口间手动复制粘贴信息,防止 AI 盲目操作。
- 意图不透明:无法预知哪个 AI 正准备修改关键文件,往往在报错后才发现问题根源。
使用 mcp_agent_mail 后
- 智能文件租约:AI 助手在修改文件前会通过 mcp_agent_mail 申请“租约”,其他助手能即时感知并避开该文件,彻底杜绝覆盖冲突。
- 异步消息互通:后端 AI 完成接口变更后,自动发送一封带详细参数的 Markdown 邮件到前端 AI 的收件箱,确保上下文实时同步。
- 自主协同作业:所有助手通过统一的身份注册和搜索线程自主交换信息,开发者无需再手动在不同工具间传递指令。
- 可审计的协作流:所有的沟通记录、文件预留声明和修改意图都存入 SQLite 并提交至 Git,随时可追溯谁在何时打算做什么。
mcp_agent_mail 将原本混乱的多智能体并行开发,转变为有序、透明且可审计的自动化协作流,让人类只需监督而非保姆式干预。
运行环境要求
- Linux
- macOS
未说明
未说明

快速开始
MCP 代理邮件

“这就像你编码代理的 Gmail!”
这是一个面向编码代理的类邮件协调层,以仅支持 HTTP 的 FastMCP 服务器形式暴露。它为代理提供易于记忆的身份、收件箱/发件箱、可搜索的消息历史记录,以及自愿的文件预留“租约”,以避免彼此冲突。
可以把它看作是为你的代理提供的异步电子邮件 + 目录 + 变更意图信号系统,后端由 Git(用于人类可审计的工件)和 SQLite(用于索引和查询)支持。
状态:正在积极开发中。设计细节详尽地记录在 project_idea_and_guide.md 文件中(请从该文件顶部的原始需求开始阅读)。
为什么需要这个项目
现代项目通常会同时运行多个编码代理(后端、前端、脚本、基础设施)。如果没有共享的协调机制,代理们可能会:
- 覆盖彼此的修改或因意外差异而崩溃
- 错过并行工作流中的关键上下文
- 需要人工在不同工具和团队之间传递信息
本项目提供了一个轻量级、可互操作的层,使代理能够:
- 注册一个临时但持久的身份(例如 GreenCastle)
- 发送/接收带有图片的 GitHub 风格 Markdown 消息
- 搜索、总结和串联对话
- 对文件或文件模式声明建议性的文件预留(租约),以表明意图
- 查看当前活跃的代理、程序、模型及其活动目录
它专为 FastMCP 客户端和 CLI 工具(Claude Code、Codex、Gemini CLI、Factory Droid 等)设计,用于在一个或多个代码库之间进行协调。
从创意火花到部署集群
如果一个空白仓库让你感到无从下手,请按照我们在 project_idea_and_guide.md 中记录的成熟流程操作(“附录:从空白仓库到协调集群”):
- 快速构思: 写一段简短的电子邮件风格的文字,描述问题、期望的用户体验以及必须选择的技术栈(大约 15 分钟)。
- 将想法转化为计划: 将这段文字输入 GPT-5 Pro(也可以选择 Grok4 Heavy 或 Opus 4.1),直到生成一份详细的 Markdown 计划,然后在成本较低时不断迭代计划文件。Markdown Web 浏览器示例计划展示了应达到的详细程度。
- 明确规则: 克隆一个优化过的
AGENTS.md文件,添加任何特定技术的最佳实践指南,并让 Codex 根据计划自动生成仓库结构和 Beads 任务列表。 - 启动集群: 启动多个 Codex 实例(或任意组合的代理),让每个代理通过 Agent Mail 注册身份,并在开始编写代码之前确认已阅读
AGENTS.md、计划文档和 Beads 待办事项清单。 - 持续供给: 重复使用推文线程中的固定指令流程,或者更好的是,使用商业 Companion 应用的消息堆栈自动广播这些提示,这样你就再也不需要手动向每个实例发送指令了。
观看完整的 23 分钟演示视频(https://youtu.be/68VVcqMEDrs?si=pCm6AiJAndtZ6u7q),了解整个流程的实际运行情况。
生产力计算与自动化闭环
每投入一小时的 GPT-5 Codex 编码时间——只要它不需要等待人工提示——通常就能产生相当于 10–20 小时的人工工作量,因为代理以机器速度进行推理和打字。Agent Mail 在两个层面放大了这一优势:
- 基础开源服务器: 基于 Git 的邮箱、建议性文件预留、Typer CLI 辅助工具和可搜索的归档,能够在无需人工监督的情况下保持独立代理之间的同步。每条指令、每次租约和每份附件都可以被审计。
- 商业配套组件: iOS 应用程序结合主机自动化功能,可以通过自定义消息堆栈、人工监督广播、Beads 任务意识以及计划编辑工具,直接从手机上配置、配对并引导由 Claude Code、Codex、Gemini CLI、Factory Droid 等组成的异构集群——无需手动使用 tmux 进行编排。自动化系统通过安排提示、遵守有限模式以及强制执行双重确认来防止破坏性操作,从而完成闭环。
结果:你只需投入 1–2 小时的人工监督,就能让数十小时的代理工作并行执行,同时拥有清晰的审计轨迹和内置的冲突避免机制。
总结与快速入门
一行安装命令
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/main/scripts/install.sh?$(date +%s)" | bash -s -- --yes
此命令的作用:
- 如果缺少 uv,则安装并更新当前会话的 PATH 环境变量
- 如果缺少 jq,则安装(用于安全合并配置;会自动检测你的包管理器)
- 创建 Python 3.14 虚拟环境,并使用 uv 安装依赖项
- 自动检测并集成支持的代理工具
- 启动 MCP HTTP 服务器,监听 8765 端口,并打印一个掩码后的 Bearer 令牌
- 在
scripts/目录下创建辅助脚本(包括run_server_with_token.sh) - 在你的
.zshrc或.bashrc中添加amshell 别名,方便快速启动服务器(只需在新终端中输入am即可) - 安装 Beads Rust (
br),即 Beads 任务跟踪器的 Rust 重写版本,并创建指向br的bdshell 别名,以实现向后兼容。这将替换任何现有的bd(Go)安装。若不想安装,可添加--skip-beads参数。有关 CLI 差异的详细信息,请参阅 beads_rust。 - 安装/更新 Beads Viewer
bvTUI,用于交互式任务浏览和 AI 友好的机器人命令(若不想安装,可添加--skip-bv参数)。 - 在退出时打印每个设置步骤的简短摘要,以便你立即了解发生了哪些变化。
如果你希望指定安装位置或选项,可以添加如 --dir <path>、--project-dir <path>、--no-start、--start-only、--port <number> 或 --token <hex> 等标志。
如果你已经安装了 Beads 或 Beads Viewer,可以在安装时添加 --skip-beads 和/或 --skip-bv 来跳过自动安装。
重要提示:Beads Rust (br) 替代 Beads Go (bd)
安装程序会自动将 bd(原生 Go 版本的 Beads CLI)替换为 br(Beads Rust):
br是当前维护的版本。 Beads Rust 是一个全新的实现,仍在持续开发中,而原版 Go 版本已不再积极维护。- 现有
bd用户将获得自动别名支持。 安装程序会创建一个 shell 别名,使bd命令继续通过重定向到br工作。你的现有工作流程和肌肉记忆将得以保留。 - 为代理安装迁移技能。 AI 编码代理将获得一个
bd-br-migration技能,帮助他们适应两种实现之间的任何 CLI 差异。 - 数据格式相同,工作流程兼容。 两种实现都使用相同的
.beads/issues.jsonl格式,因此你现有的 Beads 数据完全兼容。
若想跳过此替换过程,可在安装时添加 --skip-beads 参数。有关 CLI 差异的详细说明,请参阅 beads_rust 仓库。
未来启动服务器
安装完成后,您可以在任何地方通过简单地输入以下命令来启动 MCP Agent Mail 服务器:
am
就这么简单!am 别名(在安装过程中添加到您的 .zshrc 或 .bashrc 文件中)会自动执行以下操作:
- 切换到 MCP Agent Mail 目录
- 运行服务器启动脚本(该脚本使用
uv run来管理虚拟环境) - 从
.env文件加载您保存的 Bearer 令牌,并启动 HTTP 服务器
注意: 如果您刚刚运行了安装程序,请打开一个新的终端窗口,或者运行 source ~/.zshrc(或 source ~/.bashrc)以加载别名。
端口冲突? 您可以使用 --port 参数指定不同的端口(默认为 8765):
使用自定义端口进行安装:
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/main/scripts/install.sh?$(date +%s)" | bash -s -- --port 9000 --yes
或者在安装完成后使用 CLI 命令: uv run python -m mcp_agent_mail.cli config set-port 9000
### 如果您想手动操作
克隆仓库,在 Python 3.14 的虚拟环境中使用 uv 设置并安装(如果尚未安装 uv,请先安装),然后运行 `scripts/automatically_detect_all_installed_coding_agents_and_install_mcp_agent_mail_in_all.sh`。这将自动为您的各种已安装编码助手工具设置好环境,并在端口 8765 上启动 MCP 服务器。如果您希望在未来再次运行 MCP 服务器,只需运行 `scripts/run_server_with_token.sh`:
安装 uv(如果尚未安装):
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
# 克隆仓库
git clone https://github.com/Dicklesworthstone/mcp_agent_mail
cd mcp_agent_mail
# 创建 Python 3.14 虚拟环境并安装依赖
# 注意:如果您使用的是较旧版本的 uv,请先运行 `uv self update`
uv python install 3.14
uv venv -p 3.14
source .venv/bin/activate
uv sync
# 检测已安装的编码助手,集成并启动端口 8765 上的 MCP 服务器
scripts/automatically_detect_all_installed_coding_agents_and_install_mcp_agent_mail_in_all.sh
# 之后,再次使用相同的令牌运行 MCP 服务器
scripts/run_server_with_token.sh
# 现在,您只需在其他终端中启动 Codex-CLI、Claude Code 或其他助手工具;它们应该能够使用邮件工具。请参阅下方,我们将提供一段现成的文字,您可以将其添加到现有的 AGENTS.md 或 CLAUDE.md 文件末尾,以帮助您的助手更好地利用这些新工具。
# 安装后更改端口
uv run python -m mcp_agent_mail.cli config set-port 9000
可直接添加到 AGENTS.md 或 CLAUDE.md 文件中的文案:
## MCP Agent Mail:用于多智能体工作流的协调工具
是什么
- 类似于邮件的层,允许编码助手通过 MCP 工具和资源异步协作。
- 提供身份标识、收件箱/发件箱、可搜索的线程以及咨询性质的文件预留功能,并在 Git 中生成可供人类审计的记录。
为什么有用
- 通过为文件或文件模式明确预留(租约),防止助手之间发生冲突。
- 将通信存储在每个项目的归档中,从而避免占用您的 Token 预算。
- 提供快速读取接口(`resource://inbox/...`, `resource://thread/...`)以及用于封装常见流程的宏。
如何有效使用
1) 同一仓库
- 注册身份:调用 `ensure_project`,然后使用该仓库的绝对路径作为 `project_key` 调用 `register_agent`。
- 在编辑文件前预留:使用 `file_reservation_paths(project_key, agent_name, ["src/**"], ttl_seconds=3600, exclusive=true)` 来表明意图并避免冲突。
- 使用线程进行沟通:使用 `send_message(..., thread_id="FEAT-123")`;通过 `fetch_inbox` 查看收件箱,并使用 `acknowledge_message` 进行确认。
- 快速读取:`resource://inbox/{Agent}?project=<abs-path>&limit=20&agent_token=<registration_token>` 或 `resource://thread/{id}?project=<abs-path>&agent=<Agent>&agent_token=<registration_token>&include_bodies=true`,除非当前的 MCP 会话已经以该代理的身份进行了认证。
- 小贴士:在您的环境变量中设置 `AGENT_NAME`,这样 pre-commit 钩子就可以阻止与他人正在使用的独占文件预留相冲突的提交。
2) 同一项目中的不同仓库(例如 Next.js 前端 + FastAPI 后端)
- 方案 A(单个项目总线):双方都注册到同一个 `project_key` 下(共享密钥/路径)。保留特定的预留模式(例如 `frontend/**` vs `backend/**`)。
- 方案 B(独立项目):每个仓库有自己的 `project_key`;使用 `macro_contact_handshake` 或 `request_contact`/`respond_contact` 来连接助手,然后直接发送消息。在各仓库之间保持共享的 `thread_id`(例如工单编号),以便进行清晰的总结和审计。
宏与细粒度工具
- 当您需要速度或使用较小的模型时,优先选择宏:`macro_start_session`、`macro_prepare_thread`、`macro_file_reservation_cycle`、`macro_contact_handshake`。
- 当您需要精细控制时,使用细粒度工具:`register_agent`、`file_reservation_paths`、`send_message`、`fetch_inbox`、`acknowledge_message`。
常见陷阱
- “from_agent not registered”:务必先在正确的 `project_key` 下注册代理。
- “FILE_RESERVATION_CONFLICT”:调整预留模式,等待过期,或在适当情况下使用非独占预留。
- 认证错误:如果启用了 JWT+JWKS,需包含一个带有与服务器 JWKS 匹配的 `kid` 的 Bearer 令牌;静态 Bearer 令牌仅在禁用 JWT 时使用。
与 Beads(依赖感知任务规划)的集成
Beads 是一个轻量级的任务规划工具,它与 Agent Mail 彼此互补:Beads 负责维护任务的状态和依赖关系,而 Agent Mail 则负责处理消息、文件预留和审计记录。
关于实现方式的说明: MCP Agent Mail 的安装程序会安装 Beads Rust (br),这是一个用 Rust 重写的版本,并创建了一个名为 bd 的别名以保持向后兼容性。原始的 Go 实现位于 steveyegge/beads。两者共享相同的数据格式(.beads/issues.jsonl),但在 CLI 操作上存在一些差异。如果您希望自己管理 Beads,可以在安装时使用 --skip-beads 参数跳过安装。
亮点:
- Beads 负责任务优先级排序;Agent Mail 负责承载对话和相关记录。
- 共享的标识符(例如
bd-123)使 Beads 的问题、Mail 的线程和提交保持一致。 brCLI(别名为bd)提供了与原版类似的功能,并有一些增强。
复制/粘贴用于助手文档的文案(保持原样以供重复使用):
## 与 Beads 集成(依赖感知的任务规划)
Beads 提供了一个轻量级、依赖感知的问题数据库和一个 CLI 工具 (`bd`),用于选择“就绪的工作”、设置优先级和跟踪状态。它补充了 MCP Agent Mail 的消息传递、审计轨迹和文件预留信号。项目:[steveyegge/beads](https://github.com/steveyegge/beads)
推荐约定
- **单一事实来源**:使用 **Beads** 来管理任务状态/优先级/依赖关系;使用 **Agent Mail** 来处理对话、决策和附件(审计)。
- **共享标识符**:将 Beads 问题 ID(例如 `bd-123`)用作 Mail 的 `thread_id`,并在邮件主题前加上 `[bd-123]`。
- **预留**:在开始处理 `bd-###` 任务时,调用 `file_reservation_paths(...)` 来获取受影响的路径;在 `reason` 中包含问题 ID,并在完成后释放。
典型流程(代理)
1) **选择就绪的工作**(Beads)
- `bd ready --json` → 选择一项(优先级最高、无阻塞因素)
2) **预留编辑表面**(Mail)
- `file_reservation_paths(project_key, agent_name, ["src/**"], ttl_seconds=3600, exclusive=true, reason="bd-123")`
3) **宣布开始**(Mail)
- `send_message(..., thread_id="bd-123", subject="[bd-123] 开始:《简短标题》", ack_required=true)`
4) **工作并更新**
- 在线程中回复进展并附上工件/图片;保持每个问题 ID 的讨论在一个线程内进行
5) **完成并释放**
- `bd close bd-123 --reason "Completed"`(Beads 是状态权威)
- `release_file_reservations(project_key, agent_name, paths=["src/**"])`
- 最后一封 Mail 回复:`[bd-123] Completed` 并附上总结和链接
映射速查表
- **Mail `thread_id`** ↔ `bd-###`
- **Mail 主题**:`[bd-###] …`
- **文件预留 `reason`**:`bd-###`
- **提交信息(可选)**:包含 `bd-###` 以实现可追溯性
事件镜像(可选自动化)
- 当 `bd update --status blocked` 时,在 `bd-###` 线程中发送一条高重要性 Mail 消息,描述阻塞原因。
- 当 Mail 对关键决策的“ACK 超时”时,添加一个 Beads 标签(如 `needs-ack`)或提高优先级,以便在 `bd ready` 中显示出来。
需要避免的陷阱
- 不要在 Mail 中创建或管理任务;将 Beads 视为唯一的任务队列。
- 始终在邮件 `thread_id` 中包含 `bd-###`,以避免工具间 ID 偏移。
更倾向于自动化吗?运行 uv run python -m mcp_agent_mail.cli docs insert-blurbs,扫描您的代码目录以查找 AGENTS.md/CLAUDE.md 文件,并附加最新的 Agent Mail + Beads 片段,需经项目确认。安装程序还将在设置完成后立即启动此助手,方便您立即处理入职文档。
Beads 查看器(bv)——面向 AI 的任务分析
Beads 查看器 (bv) 是一个快速的终端 UI,专为 Beads 项目设计,同时提供专为 AI 代理集成设计的 机器人标志。项目:Dicklesworthstone/beads_viewer
为什么代理要使用 bv?
虽然 bd(Beads CLI)负责任务的 CRUD 操作,但 bv 提供 预计算的图分析,帮助代理做出智能的优先级决策:
- PageRank 分数:识别能够解锁最多下游工作的高影响力任务
- 关键路径分析:找到完成任务所需的最长依赖链
- 环路检测:在死锁发生前发现循环依赖
- 并行任务规划:确定哪些任务可以同时执行
与其让代理直接解析 .beads/issues.jsonl 或尝试计算图指标(可能产生幻觉结果),不如调用 bv 的确定性机器人标志,获得可信的 JSON 输出。此仓库中已弃用旧版 .beads/beads.jsonl。
用于 AI 集成的机器人标志
| 标志 | 输出 | 代理用途 |
|---|---|---|
bv --robot-help |
所有面向 AI 的命令 | 发现/能力检查 |
bv --robot-insights |
PageRank、介数中心性、HITS、关键路径、环路 | 快速分类:“什么最具影响力?” |
bv --robot-plan |
并行任务组、每组任务数量、解锁列表 | 执行计划:“哪些任务可以并行?” |
bv --robot-priority |
优先级建议及理由+置信度 | 任务选择:“接下来该做什么?” |
bv --robot-recipes |
可用筛选预设(可操作、被阻塞等) | 工作流设置:“给我看看就绪的工作” |
bv --robot-diff --diff-since <ref> |
自提交/日期以来的变化、新增/关闭的事项、环路变化 | 进度跟踪:“发生了什么变化?” |
示例:代理任务选择工作流
# 1. 获取带有理由的优先级建议
bv --robot-priority
# 返回按优先级排序的任务、影响得分和置信度的 JSON
# 2. 检查完成某项任务会解锁什么
bv --robot-plan
# 返回显示依赖链的并行任务组
# 3. 完成工作后,检查发生了什么变化
bv --robot-diff --diff-since "1 hour ago"
# 返回新增事项、关闭事项、环路变化
何时使用 bv 与 bd
| 工具 | 最佳用途 |
|---|---|
bd |
创建、更新、关闭任务;bd ready 用于简单的“下一步是什么” |
bv |
图分析、影响评估、并行规划、变更跟踪 |
经验法则:使用 bd 处理任务操作,使用 bv 获取任务情报。
与 Agent Mail 集成
将 bv 的洞察与 Agent Mail 的协调相结合:
- 代理 A 运行
bv --robot-priority→ 识别出bd-42具有最大影响力 - 代理 A 预留文件:
file_reservation_paths(..., reason="bd-42") - 代理 A 宣布:
send_message(..., thread_id="bd-42", subject="[bd-42] 开始高影响力重构") - 其他代理 看到预留和 Mail 宣告后,选择不同的任务
- 代理 A 完成工作后,运行
bv --robot-diff报告下游解锁情况
这样就形成了一个反馈循环,通过图分析驱动协作。
核心理念(一览)
- 仅限 HTTP 的 FastMCP 服务器(可流式传输的 HTTP)。无 SSE,无 STDIO。
- 双重持久化模型:
- 每个规范化的消息以及每个收件人的收件箱/发件箱副本都以人类可读的 Markdown 格式存储在项目专属的 Git 仓库中
- 使用带有 FTS5 的 SQLite 实现快速搜索、目录查询以及文件预留/租赁
- 面向代理的“目录/LDAP”式查询;采用令人难忘的形容词+名词命名方式
- 针对编辑表面的咨询式文件预留;可选的提交前保护机制
- 资源层便于便捷读取(例如
resource://inbox/{agent})
典型用例
- 多个代理协同完成跨服务的大规模重构,同时保持同步
- 前端和后端团队的代理逐线程协调工作
- 通过排他性的文件预留和提交前保护机制来保障关键迁移的安全
- 随着线程的发展,搜索和总结长期的技术讨论
- 通过 AI 驱动的建议发现并连接相关项目(例如前端/后端)
工作流常见问题
我是否仍然需要 tmux 广播脚本来“喂”每个 Codex 窗格?
不需要。推文线程中提到的旧版 zsh 循环在单独运行 OSS 堆栈时仍然有用,但 AgentMail Companion 系统现在通过消息堆栈自动处理这一节奏。一旦安装了配套主机服务,您就可以从 iOS 应用或 CLI 中排队预设任务(构建者循环、评审员扫描、测试聚焦等),自动化系统会将这些指令分发到所有已注册的代理——完全无需接触 tmux。
架构
graph LR
A[代理]
S[服务器]
G[Git 仓库]
Q[SQLite FTS5]
A -->|HTTP 工具/资源| S
S -->|写入/读取| G
S -->|索引/查询| Q
subgraph GitTree["Git 树"]
GI1[agents/profile.json]
GI2[agents/mailboxes/...]
GI3[messages/YYYY/\nMM/\nid.md]
GI4[file_reservations/\nsha1.json]
GA[attachments/xx/\nsha1.webp]
end
G --- GI1
G --- GI2
G --- GI3
G --- GI4
G --- GA
Web UI(面向人类的邮件查看器)
服务器自带一个轻量级、由服务器渲染的 Web UI,供人类使用。它允许您浏览项目、代理、收件箱、单条消息、附件、文件预留,并在可用时使用 FTS5 进行全文搜索(如果不可用则自动回退到 LIKE 搜索)。
- 所在位置:内置于 HTTP 服务器的
mcp_agent_mail.http文件中,路径为/mail。 - 使用对象:用于人工审查活动;代理应继续使用 MCP 工具/资源 API。
启动 Web UI
推荐方式(简单):
scripts/run_server_with_token.sh
# 然后打开 http://127.0.0.1:8765/mail
进阶方式(手动命令):
uv run python -m mcp_agent_mail.http --host 127.0.0.1 --port 8765
# 或:
uv run uvicorn mcp_agent_mail.http:build_http_app --factory --host 127.0.0.1 --port 8765
认证说明:
- UI 中的 GET 页面不受 RBAC 中间件保护(该中间件仅对 POST 的 MCP 调用进行分类),但如果您设置了 Bearer 令牌,则独立的 BearerAuth 中间件会默认保护所有路由。
- 在本地开发时,可设置
HTTP_ALLOW_LOCALHOST_UNAUTHENTICATED=true(并可选设置HTTP_BEARER_TOKEN),以便本地主机无需头部即可加载 UI。 - 健康检查端点始终开放,路径为
/health/*。
路由及功能
/mail(统一收件箱 + 项目 + 相关项目发现)- 展示跨所有项目的最新消息的统一倒序收件箱,包含摘要、相对时间戳、发件人/收件人以及项目徽章。
- 收件箱下方列出所有项目(slug、人类名称、创建时间),并提供同级建议。
- 当两个 slug 看起来属于同一产品的一部分时(例如后端 vs. 前端),会建议 可能的同级项目。建议按启发式规则排序,当
LLM_ENABLED=true时,还会通过 LLM 对关键文档(README.md、AGENTS.md等)进行分析。 - 人类可以在仪表板上 确认链接 或 忽略 建议。确认的同级项目会以突出徽章显示,但 不会 自动授权跨项目消息传递;代理仍需通过
request_contact/respond_contact建立AgentLink批准。
/mail/projects(项目索引)- 专门的项目列表视图;点击某个项目即可深入查看。
/mail/{project}(项目概览 + 搜索 + 代理)- 功能丰富的搜索表单,支持以下筛选:
- 检索范围:主题/正文/两者;排序方式:相关性或时间;可选“提升主题权重”。
- 查询词:支持
subject:foo、body:"multi word"、带引号的短语以及普通关键词。 - 可用时采用 FTS5 bm25 排名;否则根据所选范围回退到 SQL LIKE 搜索主题或正文。
- 搜索结果会显示主题、发件人、创建时间、线程 ID,以及使用 FTS 时的高亮片段。
- 代理面板显示该项目已注册的所有代理,并提供每个收件箱的链接。
- 项目标题处设有文件预留和附件的快速链接。
- 功能丰富的搜索表单,支持以下筛选:
/mail/{project}/inbox/{agent}(某代理的收件箱)- 倒序排列的消息列表,包含主题、发件人、创建时间、重要性徽章、线程 ID。
- 支持分页(
?page=N&limit=M)。
/mail/{project}/message/{id}(消息详情)- 显示主题、发件人、创建时间、重要性、收件人(To/Cc/Bcc)以及线程中的其他消息。
- 正文渲染:
- 如果服务器已将 Markdown 预先转换为 HTML,则会使用 Bleach 进行清理(限制标签/属性,并通过 CSSSanitizer 确保安全的 CSS),然后显示。
- 否则,将在客户端使用 Marked 渲染 Markdown,并结合 Prism 实现代码高亮。
- 附件信息记录在消息的 frontmatter 中(WebP 文件或内联数据 URI)。
/mail/{project}/search?q=...(专用搜索页面)- 查询语法与项目概览搜索相同,界面采用“药丸”式标签,方便组合或移除筛选条件。
/mail/{project}/file_reservations(文件预留列表)- 显示当前及历史的文件预留情况(独占/共享、路径模式、时间戳、已释放/已过期状态)。
/mail/{project}/attachments(含附件的消息)- 列出所有包含附件的消息,显示主题和创建时间。
/mail/unified-inbox(跨项目活动)- 展示所有项目中的最新消息,附带线程数量以及发件人/收件人信息。
人类监督员:向代理发送消息
有时,人类操作员需要直接指导或重定向代理,例如处理紧急问题、提供澄清说明或调整优先级。人类监督员功能提供了一个基于 Web 的消息编辑器,允许人类向项目中的任意组合代理发送高优先级消息。
访问方式:在任何项目视图的页眉中点击醒目的 “发送消息” 按钮(带有监督员徽章),路径为 /mail/{project};或者直接导航至 /mail/{project}/overseer/compose。
监督员消息的独特之处
自动前言:每条消息都包含一个格式化的前言,明确标识其来自人类操作员,并指示代理:
- 暂时暂停当前工作
- 将人类的要求置于现有任务之上
- 在完成后恢复原有计划(除非指令另有修改)
高优先级:所有监督员消息都会自动标记为高重要性,确保它们在代理收件箱中醒目突出。
政策绕过:监督员消息会绕过常规联系政策,因此无论代理的联系设置如何,人类始终可以与其取得联系。
特殊发件人身份:消息来自名为 “HumanOverseer” 的特殊代理(按项目自动创建),其属性如下:
- 程序:
WebUI - 模型:
Human - 联系政策:
开放
- 程序:
消息前言
每条监督员消息均以以下前言开头(自动添加):
---
🚨 来自人类监督员的消息 🚨
本消息由负责监督该项目的人类操作员发出。请将下方指示置于您当前任务之上予以优先处理。
您应当:
1. 暂时暂停当前工作
2. 完成下文所述请求
3. 在完成之后恢复原有计划(除非本指示另有修改)
人类的指导将取代所有其他优先级。
---
[此处为您的消息正文]
使用消息编辑器
编辑界面提供以下功能:
- 收件人选择:所有已注册代理的复选框网格,并配有“全选”和“取消全选”的快捷键。
- 主题行:必填项,在代理收件箱中显示。
- 消息正文:支持 GitHub 风格 Markdown 的编辑器,并附带预览功能。
- 线程 ID(可选):用于延续现有对话或开启新对话。
- 前言预览:可实时查看消息在代理端的具体呈现效果。
示例用例
紧急问题:
主题:紧急:停止迁移并回滚更改
PR #453 中的数据库迁移正在导致暂存环境的数据损坏。
请:
1. 立即停止所有与迁移相关的工作
2. 回滚最近两小时内的提交
3. 等待我的审核后再继续
我目前正在调查根本原因。
调整优先级:
主题:新优先级:安全漏洞
我们的认证库刚刚曝出一个严重安全漏洞。
请立即放下手头工作,执行以下操作:
1. 立即更新 `auth-lib` 至版本 2.4.1
2. 检查 src/auth/ 目录下的所有使用情况
3. 运行完整的安全测试套件
4. 在线程 #892 中汇报进展
此项工作优先于重构任务。
澄清说明:
主题:关于 API 设计方案的澄清
我在线程 #234 中看到大家正在讨论 REST 与 GraphQL 的优劣。
目前建议采用 REST,原因如下:
- 前端团队对 REST 更熟悉
- GraphQL 会增加我们现阶段并不需要的复杂性
- 如果后续有需求,我们仍可再引入 GraphQL
请按照 REST 方案继续实施 API。
代理如何看待监督员消息
当代理通过 fetch_inbox 或 resource://inbox/{name} 查看收件箱时,监督员消息与其他消息无异,但具有以下特点:
- 发件人:
HumanOverseer - 重要性:
高(醒目显示) - 正文:以监督员前言开头,随后是人类的消息内容。
- 视觉提示:在 Web 界面中,此类消息可能会有特殊高亮显示(未来增强功能)。
代理可以像回复其他消息一样回复监督员消息,从而延续对话线程。
技术细节
- 存储方式:监督员消息的存储方式与代理之间的消息完全相同(Git + SQLite)。
- Git 历史记录:全程可审计;消息会出现在
messages/YYYY/MM/{id}.md文件中,并保留完整的提交历史。 - 线程连续性:可以加入现有线程,也可以开启新线程。
- 不绕过身份验证:监督员消息编辑表单仍然需要正确的 HTTP 服务器身份验证(若已启用)。
设计理念
人类监督员功能的设计宗旨是:
- 明确性:代理能够清晰区分来自人类的指导与来自其他代理的信息。
- 尊重性:指示内容承认代理已有正在进行的工作,不会要求他们永久性地“丢下一切”。
- 临时性:明确告知代理在完成人类请求后应恢复原有计划。
- 灵活性:人类可以在消息正文中直接覆盖这一默认行为。
通过这种方式,既建立了清晰的层级关系(人类 → 代理),又保持了代理间协作沟通系统的协作性和尊重性。
相关项目发现
Projects 索引(/mail)配备了一个 AI 驱动的发现系统,可智能建议哪些项目应相互关联,例如前端 + 后端或相关的微服务。
发现功能的工作原理
1. 智能分析 系统利用多种信号来识别项目之间的关系:
- 模式匹配:比较项目名称和路径(如“my-app-frontend” ↔ “my-app-backend”)
- AI 理解(当
LLM_ENABLED=true时):读取README.md、AGENTS.md等文档,以理解每个项目的用途并检测自然关系 - 置信度评分:将建议按 0–100% 排序,并提供清晰的理由
2. 精美的建议 相关项目会以精美的卡片形式显示在您的仪表板上,包含:
- 🎯 可视化的置信度指示器,显示匹配强度
- 💬 AI 生成的关系说明
- ✅ 确认链接——接受该建议
- ✖️ 忽略——隐藏不相关的匹配
3. 快速导航 一旦确认,两个项目都会显示交互式徽章,方便您在相关代码库之间即时切换。
为什么是建议而非自动链接?
简而言之:我们始终让您掌握主动权。发现功能帮助您找到潜在关系;而明确的批准则控制谁可以实际通信。
Agent Mail 使用以代理为中心的消息传递机制:每条消息都遵循明确的权限链:
发送消息 → 查找接收者 → 检查 AgentLink 批准 → 投递
这种设计确保了:
- 安全性:不会意外地跨项目传递消息
- 透明性:您始终清楚谁可以与谁交流
- 审计追踪:所有通信路径都经过明确批准
为什么不直接由 AI 自动建立链接呢? 如果让 LLM 自动授权项目间的通信,就会:
- ❌ 绕过人工监督下的联系政策
- ❌ 存在将消息误发给非预期接收者的风险
- ❌ 创建难以审计的隐形路由路径
- ❌ 可能错误地连接名称相似但含义不同的项目
因此,我们为您提供 发现 + 控制 的双重机制:
- ✅ AI 建议可能的相关性(安全的只读分析)
- ✅ 您确认哪些内容合理(只需点击一下)
- ✅ 代理仍使用
request_contact/respond_contact来获取实际的消息权限 - ✅ 明确区分:发现 ≠ 授权
完整的工作流程
1. 系统建议:“这些项目看起来相关”(AI 分析)
↓
2. 您确认:“是的,将它们链接起来”(更新 UI 徽章)
↓
3. 代理请求:request_contact(from_agent, to_agent, to_project)
↓
4. 您批准:respond_contact(accept=true)
↓
5. 消息流动:代理现在可以在项目间通信
不妨将其比作 LinkedIn:系统会建议联系人,但只有您自己决定谁能发送消息。
搜索语法(UI)
UI 使用与 API 的 _parse_fts_query 相同的解析逻辑:
- 字段过滤:
subject:login、body:"api key" - 短语搜索:“build plan”
- 组合条件:
login AND security(全文检索) - 回退到 LIKE 查询:范围决定了是搜索主题、正文,还是两者兼有
查看数据的前提条件
UI 从与 MCP 工具相同的 SQLite 和 Git 产物中读取数据。要填充内容:
- 确保存在一个项目(通过工具调用或 CLI):
- 确保或创建项目:
ensure_project(human_key)
- 确保或创建项目:
- 注册一个或多个代理:
register_agent(project_key, program, model, name?) - 发送消息:
send_message(...)(支持附件和内嵌图片;图片可能会被转换为 WebP 格式)。
消息存在后,访问 /mail,点击您的项目,然后打开某个代理的收件箱或进行搜索。
实现与依赖项
- 模板位于
src/mcp_agent_mail/templates/,由 Jinja2 渲染。 - 在服务器端尽可能使用
markdown2将 Markdown 转换为 HTML;HTML 内容会通过 Bleach 进行清理(必要时还会使用 CSS 过滤器)。 - Tailwind CSS、Lucide 图标、Alpine.js、Marked 和 Prism 通过 CDN 加载到
base.html中,以实现现代化的外观,而无需前端构建步骤。 - 所有渲染均在服务器端完成;没有 SPA 路由器。即使没有 JavaScript,页面也能优雅降级。
安全考虑
- HTML 净化:仅允许有限的一组标签和属性;CSS 会被过滤。链接仅限于 http/https/mailto/data。
- 认证:在暴露到本地主机之外时,请使用 Bearer Token 或 JWT。对于本地开发,可按照上述说明启用本地主机免认证访问。
- 速率限制(可选):可启用令牌桶限流器;UI 的 GET 请求负载较轻,不受 POST 限流的影响。
UI 故障排除
- 本地主机上出现空白页或 401 错误:请取消设置
HTTP_BEARER_TOKEN,或设置HTTP_ALLOW_LOCALHOST_UNAUTHENTICATED=true。 - 未列出任何项目:请使用
ensure_project创建一个项目。 - 收件箱为空:请确认收件人姓名完全匹配,并且确实已向该代理发送了消息。
- 搜索无结果:请尝试更简单的关键词,或切换到 LIKE 查询回退(切换范围/正文)。
静态邮箱导出(共享与分发存档)
share 命令组可将项目的邮箱导出为一个便携式的只读包,任何人都可以通过浏览器查看。它专为审计人员、利益相关者或需要浏览线程、搜索历史或证明交付时间线,而无需启动完整 MCP Agent Mail 系统的团队成员设计。
为什么要导出为静态包?
合规与审计追踪:向审计师或合规官交付项目通信的不可篡改快照。静态包包含加密签名,确保分发过程中的防篡改性。
利益相关者审查:与产品经理、高管或不需要写入权限的外部顾问分享对话历史。他们无需身份验证,即可在浏览器中浏览消息、搜索线程并查看附件。
离线访问:为气隙环境、灾难恢复备份或网络连接不可靠的情况创建便携式存档。
长期归档:以一种几十年后仍可读取的格式保存项目通信记录。静态 HTML 不需要数据库服务器,也没有运行时依赖,相比专有格式更能抵御软件过时带来的影响。
安全分发:对机密项目使用加密技术保护存档。只有持有私钥的接收方才能解密并查看内容。
导出内容包含什么
每个打包文件包含:
- 自包含:所有内容都打包在一个目录中(HTML、CSS/JS、SQLite快照、附件)。你可以将其部署到静态托管服务上,或者在本地直接打开。
- 丰富的阅读界面:类似 Gmail 风格的收件箱,支持项目过滤、搜索和完整线程渲染——每封邮件都会显示其元数据和 Markdown 正文,与在线 Web 界面完全一致。
- 快速搜索与过滤:基于 FTS 的搜索功能和预计算的每条消息摘要,即使在大型存档中也能保持滚动和过滤的流畅响应。
- 可验证的完整性:为每个资产生成 SHA-256 哈希值,并可选择使用 Ed25519 签名,从而轻松验证文件的真实性和是否被篡改。
- 分块友好的存档:大型数据库可以分块以支持 httpvfs 流式传输;配套的
chunks.sha256文件列出了每个分块的哈希值,这样客户端无需重新计算即可信任流式传输的数据块。 - 一键托管:交互式向导可以直接将打包文件发布到 GitHub Pages 或 Cloudflare Pages,或者你也可以使用 CLI 预览命令在本地运行该打包文件。
灾难恢复存档(archive 命令)
当你需要一个可恢复的快照(而不仅仅是只读共享包)时,请使用 archive 子命令。位于 ./archived_mailbox_states/ 下的每个 ZIP 文件都包含:
- 一个 SQLite 快照,经过与
share相同的清理流程处理,但使用archive清理预设,因此已读/未读状态、收件人信息、附件和邮件正文均保持原样。 - 存储 Git 仓库(
STORAGE_ROOT)的逐字节拷贝,保留 Markdown 文档、附件和钩子脚本。
快速参考
# 保存当前状态(默认使用无损预设)
uv run python -m mcp_agent_mail.cli archive save --label nightly
# 列出可用的恢复点(JSON 格式便于脚本使用)
uv run python -m mcp_agent_mail.cli archive list --json
# 灾难后恢复(覆盖前会备份现有数据库和存储)
uv run python -m mcp_agent_mail.cli archive restore archived_mailbox_states/<file>.zip --force
恢复过程中,CLI 将执行以下步骤:
- 将 ZIP 文件解压到临时目录。
- 将现有的
storage.sqlite3、WAL/SHM 文件以及STORAGE_ROOT移动到带有时间戳的.backup-<ts>文件夹中,确保不会丢失任何数据。 - 将快照复制回配置的数据库路径,并从存档内容中重建存储仓库。
每个存档都会写入一个 metadata.json 清单文件,描述所捕获的项目、清理预设,以及一条友好的提示,提醒你稍后应运行的确切 archive restore … 命令。
重置安全网
clear-and-reset-everything 现在会在删除任何内容之前创建此类存档。默认情况下,它会以交互方式提示;你可以通过传递 --archive/--no-archive 来强制选择,并结合 --force --no-archive 实现非交互式的自动化操作。当成功创建存档后,CLI 会同时打印存档路径和恢复命令,以便日后撤销重置操作。
邮箱健康检查:am doctor
doctor 命令组提供全面的诊断和修复功能,用于维护邮箱的健康状态。它特别强调 数据安全——在执行任何破坏性操作之前先创建备份,并采用半自动修复机制来防止意外数据丢失。
为什么需要 am doctor?
随着时间的推移,邮箱状态可能会出现偏差:
- 过期锁文件:进程崩溃后会留下
.archive.lock或.commit.lock文件,阻止后续操作。 - 孤立记录:代理已被删除,但其对应的邮件收件人仍保留在数据库中。
- FTS 索引不同步:全文检索索引与实际邮件内容不再同步。
- 过期的文件预留:预留到期但未被清理。
- WAL 文件:SQLite 的 WAL/SHM 文件会不断累积(正常操作中会出现,但值得监控)。
doctor 命令能够检测这些问题,并提供安全、自动化的修复方案。
诊断检查
对你的邮箱进行全面诊断:
# 检查所有项目
uv run python -m mcp_agent_mail.cli doctor check
# 启用详细输出
uv run python -m mcp_agent_mail.cli doctor check --verbose
# JSON 输出便于自动化
uv run python -m mcp_agent_mail.cli doctor check --json
检查内容:
| 检查项 | 状态 | 描述 |
|---|---|---|
| 锁文件 | OK/WARN | 检测来自崩溃进程的过期归档锁和提交锁 |
| 数据库 | OK/ERROR | 运行 PRAGMA integrity_check 检查 SQLite 是否损坏 |
| 孤立记录 | OK/WARN | 查找没有对应代理的邮件收件人 |
| FTS 索引 | OK/WARN | 比较邮件数量与 FTS 索引条目数 |
| 文件预留 | OK/INFO | 统计待清理的过期预留 |
| WAL 文件 | OK/INFO | 报告是否存在 SQLite 的 WAL/SHM 文件 |
示例输出:
MCP Agent Mail Doctor - 诊断报告
==================================================
检查项 状态 详情
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
锁文件 OK 未发现过期锁文件
数据库 OK 数据库完整性检查通过
孤立记录 OK 未发现孤立记录
FTS 索引 OK FTS 索引同步(1,234 条邮件)
文件预留 INFO 4 个过期预留待清理
WAL 文件 OK 无过期 WAL/SHM 文件
所有检查均通过!
半自动修复
修复命令采用 半自动模式:
- 安全修复(如锁文件、过期预留)会自动应用。
- 涉及数据的修复(如清理孤立记录)则需要确认。
- 在进行任何更改之前,都会先创建一份备份。
# 预览将要修复的内容(干运行)
uv run python -m mcp_agent_mail.cli doctor repair --dry-run
# 运行修复,遇到数据相关更改时会提示确认
uv run python -m mcp_agent_mail.cli doctor repair
# 自动确认所有修复(适用于自动化)
uv run python -m mcp_agent_mail.cli doctor repair --yes
# 指定自定义备份位置
uv run python -m mcp_agent_mail.cli doctor repair --backup-dir /path/to/backups
修复流程:
- 创建备份 — 在任何更改之前,先生成 Git 打包和 SQLite 副本。
- 安全修复(自动执行):
- 修复过期锁文件(移除遗留的
.archive.lock和.commit.lock文件)。 - 释放过期的文件预留(在数据库中标记
released_ts)。
- 修复过期锁文件(移除遗留的
- 数据修复(需确认):
- 删除孤立的邮件收件人。
- 重建 FTS 索引(如有必要)。
备份管理
doctor 命令会在修复前创建带时间戳的备份。你也可以直接管理备份:
# 列出所有可用的备份
uv run python -m mcp_agent_mail.cli doctor backups
# 用于脚本的 JSON 输出
uv run python -m mcp_agent_mail.cli doctor backups --json
备份内容:
每个备份包含:
database.sqlite3— 完整的 SQLite 数据库副本database.sqlite3-wal、database.sqlite3-shm— 如果存在,还包括 WAL 文件archive.bundle或{project}.bundle— 归档仓库的 Git 包manifest.json— 元数据:创建时间、原因、包含内容以及恢复说明
目录结构:
{storage_root}/backups/
2026-01-06T12-30-45_doctor-repair/
manifest.json
database.sqlite3
archive.bundle
从备份恢复
如果出现问题,可以从任意备份中恢复:
# 预览将要恢复的内容
uv run python -m mcp_agent_mail.cli doctor restore /path/to/backup --dry-run
# 执行恢复(会提示确认)
uv run python -m mcp_agent_mail.cli doctor restore /path/to/backup
# 跳过确认提示
uv run python -m mcp_agent_mail.cli doctor restore /path/to/backup --yes
恢复流程:
- 验证备份清单文件是否存在且可读
- 显示备份元数据(创建时间、原因、内容)
- 创建当前状态的预恢复备份(安全网)
- 从备份中恢复 SQLite 数据库
- 从包中恢复 Git 归档
- 报告遇到的任何错误
安全特性:
- 在覆盖之前,将当前数据库保存为
*.sqlite3.pre-restore - 在覆盖之前,将当前归档保存为
*.pre-restore目录 - 恢复过程中出现的错误会被捕获并报告
最佳实践
- 定期运行诊断:
am doctor check运行速度快且无破坏性 - 修复前先检查:使用
--dry-run查看将要进行的更改 - 保留备份:在确认系统正常运行之前,不要删除旧备份
- 自动化检查:将
am doctor check --json添加到 CI/监控中,以便及早预警
快速入门:交互式部署向导
导出和部署最简单的方式是使用交互式向导,它同时支持 GitHub Pages 和 Cloudflare Pages:
# 通过 CLI(推荐)
uv run python -m mcp_agent_mail.cli share wizard
# 或直接运行脚本
./scripts/share_to_github_pages.py
向导的功能
向导提供了一个完全自动化的端到端部署体验:
- 会话恢复:检测中断的会话,并提供从上次停止的地方继续的机会,避免重复导出
- 配置管理:记住您上次的设置,并提供重新使用这些设置的选项,节省重复导出的时间
- 部署目标选择:可以选择 GitHub Pages、Cloudflare Pages 或本地导出
- 自动安装 CLI 工具:检测并安装缺失的工具(GitHub 的
gh、Cloudflare 的wrangler) - 引导式身份验证:逐步指导您完成 GitHub 和 Cloudflare 的浏览器登录流程
- 智能项目选择:
- 以格式化表格显示所有可用项目
- 支持多种选择模式:全部、单个数字(如
1)、列表(如1,3,5)或范围(如1-3、2-5,8) - 记住您之前的选择,方便快速重新导出
- 脱敏配置:可以选择“标准”模式(擦除 API 密钥/令牌等敏感信息,保留代理名称)或“严格”模式(擦除所有消息内容)
- 加密签名:可选的 Ed25519 签名,支持自动生成密钥或重用现有密钥
- 飞行前验证:在开始导出之前,检查 GitHub 仓库名称是否可用
- 部署摘要:显示将要部署的内容(项目数量、包大小、目标、签名状态),并请求确认
- 导出与预览:导出包并启动一个交互式预览服务器,自动检测端口(尝试 9000–9100)
- 交互式预览控制:
- 按 'r' 强制刷新浏览器(手动清除缓存)
- 按 'd' 跳过预览并立即部署
- 按 'q' 退出预览服务器
- 自动刷新查看器资源:始终确保使用源树中的最新 HTML/JS/CSS,即使重复使用包也是如此
- 实时部署:实时显示 Git 和部署输出,方便您跟踪进度
- 自动部署:创建仓库、启用 Pages、推送代码,并为您提供实时 URL
会话恢复(最新版本新增功能)
如果您中断了向导(关闭终端、在预览时按 Ctrl+C 等),它会将您的进度保存到 ~/.mcp-agent-mail/wizard-session/。当您再次运行向导时:
检测到未完成的会话
项目:已选择 3 个
阶段:预览
工作区:~/.mcp-agent-mail/wizard-session/bundle
是否从上次停止的地方继续?(Y/n):
保存的内容:
- 选定的项目和脱敏设置
- 部署配置(目标、仓库名称等)
- 签名密钥偏好和路径
- 导出的包(在会话工作区中)
- 当前阶段(预览、部署)
恢复场景:
- 预览时关闭终端:恢复 → 跳过重新导出 → 立即启动预览
- 导出后改变主意:恢复 → “是否重用包?” → 预览或重新导出
- 想稍后部署:恢复 → 在预览中按 ‘d’ → 不需重新导出即可部署
- 修改了查看器代码:恢复 → 自动从源树刷新资源
成功部署后,会话状态会自动清除。如果会话变得无效(工作区被删除、项目被移除等),也会自动清除。
配置持久化
每次成功部署后,向导会将您的配置保存到 ~/.mcp-agent-mail/wizard-config.json。下次运行时,它会显示:
找到上一次配置
项目:已选择 3 个
脱敏:标准
目标:github-new
是否再次使用这些设置?(Y/n):
这使得您可以使用相同的设置快速重新部署。保存的配置包括:
- 选定的项目索引(会根据当前项目列表进行验证)
- 脱敏设置
- 部署目标和参数(仓库名称、隐私设置、项目名称)
- 签名偏好(是否签名、是否生成新密钥)
- 上次使用的签名密钥路径(在不生成新密钥时作为默认选项)
配置与项目无关:如果您添加或删除项目,向导会验证保存的索引,并在需要时提示您重新选择。
会话与配置的区别:
- 会话状态(
wizard-session/):临时存储,用于恢复中断的运行,包含导出的包 - 配置文件(
wizard-config.json):持久化存储,用于在全新运行中“使用上次设置”,不包含包
多项目选择
项目选择器支持灵活的选择语法:
可用项目:
# Slug 路径
1 backend-abc123 /abs/path/backend
2 frontend-xyz789 /abs/path/frontend
3 infra-def456 /abs/path/infra
4 scripts-ghi789 /abs/path/scripts
选择要导出的项目(例如 'all'、'1,3,5' 或 '1-3'):
选择模式:
all:导出所有项目(默认)1:仅导出第1个项目1,3,5:导出第1、3、5个项目1-3:导出第1、2、3个项目(包含范围)2-4,7:导出第2、3、4、7个项目(组合范围和列表)
无效的选择(超出范围或格式错误)将被拒绝,并显示有用的错误信息,向导会再次提示。
动态端口分配
预览服务器会自动检测9000–9100范围内可用的端口,而不是在9000端口已被占用时失败。实际使用的端口会显示如下:
正在启动预览服务器...
使用端口 9001(按 Ctrl+C 停止服务器)
等待服务器启动...
✓ 服务器已就绪,将在 http://127.0.0.1:9001 打开浏览器
这可以防止多个预览同时运行或9000端口被其他服务占用时出现端口冲突。
部署摘要面板
在开始导出之前,向导会显示一个全面的摘要:
═══ 部署摘要 ═══
项目:已选择3个
包大小:约32 MB
脱敏处理:标准
目标:GitHub Pages
仓库:mailbox-viewer-2024
可见性:私有
签名:已启用(Ed25519)
是否继续导出并部署?(Y/n):
这为您提供了最后一次检查所有设置的机会,以便在需要时取消操作。包大小是根据每个项目约10 MB加上静态资源约2 MB估算得出的。
实时部署流式输出
Git 操作和 Cloudflare 部署会以实时流式方式输出,让您清楚地看到正在发生的一切:
初始化 Git 仓库并推送...
初始化仓库...
在 /tmp/mailbox-preview-abc123/.git/ 初始化了一个空的 Git 仓库
✓ 初始化仓库完成
添加文件...
✓ 添加文件完成
创建提交...
[main (root-commit) 1a2b3c4] 初始邮箱导出
425 个文件更改,新增 123456 行
✓ 创建提交完成
推送到 GitHub...
正在枚举 430 个对象,已完成。
计数对象:100% (430/430),已完成。
使用最多 8 个线程进行增量压缩
对象压缩:100% (425/425),已完成。
写入对象:100% (430/430),12.34 MiB | 5.67 MiB/s,已完成。
✓ 推送到 GitHub 完成
✓ 成功推送到 owner/mailbox-viewer-2024
这提供了透明度,并在部署失败时有助于诊断问题。
平台特定细节
对于 GitHub Pages:
- 向导会检测您的包管理器(brew/apt/dnf),并提供自动安装
ghCLI 的选项 - 对于 apt/dnf,会显示完整的手动安装说明(包括仓库设置),因为自动化需要 sudo 权限
- 交互式运行
gh auth login以通过浏览器进行身份验证 - 使用您指定的名称和可见性(公开/私有)创建新仓库
- 初始化 git、提交并推送,同时显示流式输出
- 通过 GitHub API 自动启用 GitHub Pages
- 提供 GitHub Pages URL(可能需要 1–2 分钟才能上线)
对于 Cloudflare Pages:
- 检测 npm 并提供自动安装
wranglerCLI 的选项 - 交互式运行
wrangler login以通过浏览器进行身份验证 - 直接部署到 Cloudflare 的全球 CDN(无需 Git 仓库)
- 实时流式输出 wrangler 的操作结果
- 立即提供
.pages.devURL(站点即时上线) - 优势:即时部署、275+ 全球节点、自动 HTTPS、免费层级无请求限制
对于本地导出:
- 将包保存到指定目录
- 无需安装 CLI 或进行身份验证
- 适合手动部署到自定义主机或进行检查
错误处理与恢复
向导包含全面的错误处理机制:
- 飞行前验证:在开始导出之前检查 GitHub 仓库是否可用,以避免冲突
- 端口冲突解决:自动为预览服务器找到可用端口
- 无效选择处理:验证项目选择并提示更正
- CLI 安装失败:如果自动安装失败,会显示手动安装说明
- Git 操作失败:每一步 Git 操作都会被验证;一旦出现首次失败,就会停止并显示清晰的错误信息
- 部署失败:区分仓库创建、推送和 Pages 启用失败的情况
如果在导出后部署失败,包仍会保留在临时目录中,您可以使用下方手动部署部分中显示的 Git 命令手动部署。
向导会自动处理所有操作。如需手动控制或高级选项,请参阅下方的详细流程。
基本导出流程(手动)
1. 导出一个包
# 导出所有项目到指定目录
uv run python -m mcp_agent_mail.cli share export --output ./my-bundle
# 仅导出特定项目
uv run python -m mcp_agent_mail.cli share export \
--output ./my-bundle \
--project backend-abc123 \
--project frontend-xyz789
# 使用 Ed25519 签名进行防篡改分发
uv run python -m mcp_agent_mail.cli share export \
--output ./my-bundle \
--signing-key ./keys/signing.key \
--signing-public-out ./keys/signing.pub
# 导出并使用 age 加密以实现安全分发
uv run python -m mcp_agent_mail.cli share export \
--output ./my-bundle \
--age-recipient age1abc...xyz \
--age-recipient age1def...uvw
导出过程:
- 创建 SQLite 数据库的快照(只读,不含 WAL/SHM 文件)
- 将邮件正文、附件和元数据复制到包结构中
- 根据脱敏预设应用脱敏规则(默认为
standard) - 生成包含所有资产 SHA-256 哈希值的
manifest.json - 可选地使用 Ed25519 签名
manifest.json(生成manifest.sig.json) - 将所有内容打包成 ZIP 存档(可选,默认开启)
- 如果启用了分块功能,则写入分段数据库以及
chunks.sha256清单,以便能够低成本验证流式页面 - 可选地使用 age 对 ZIP 进行加密(生成
bundle.zip.age)
更新现有包
一旦您发布了包,就可以在不重新运行完整向导的情况下直接更新它。每次导出都会将所使用的设置(项目、脱敏预设、附件阈值、分块配置)记录在 manifest.json 中。新的 share update 命令会读取这些默认设置,在临时目录中重新生成 SQLite 快照和查看器资源,然后以原子方式替换原始包——在此过程中会移除过时的分块文件或附件。
# 使用最初记录的设置更新包
uv run python -m mcp_agent_mail.cli share update ./my-bundle
# 更新时覆盖一个或多个导出选项
uv run python -m mcp_agent_mail.cli share update ./my-bundle \
--project backend-abc123 \
--inline-threshold 16384 \
--chunk-threshold 104857600
# 重新签名并打包更新后的捆绑包
uv run python -m mcp_agent_mail.cli share update ./my-bundle \
--zip \
--signing-key ./keys/signing.key
如果之前启用了分块功能,但更新后的快照不再需要它,share update 会自动清理 chunks/ 目录、chunks.sha256 和 mailbox.sqlite3.config.json 文件,确保捆绑包目录结构与新的清单文件一致。您仍然可以在更新时调整任何设置;覆盖配置会被写回 manifest.json 的 export_config 部分,以便在下次刷新时生效。
2. 在本地预览
# 在 localhost:9000 上提供捆绑包服务
uv run python -m mcp_agent_mail.cli share preview ./my-bundle
# 自定义端口并自动打开浏览器
uv run python -m mcp_agent_mail.cli share preview ./my-bundle \
--port 8080 \
--open-browser
这将启动一个轻量级的 HTTP 服务器来提供静态文件。在浏览器中打开 http://127.0.0.1:9000/viewer/ 即可浏览归档内容。
交互式预览控制:
- 'r':强制刷新浏览器(增加手动缓存破坏令牌,触发查看器刷新)
- 'd':请求部署(退出代码为 42;向导检测到后将继续部署)
- 'q':退出预览服务器
- Ctrl+C:停止预览服务器
预览服务器会自动从源目录刷新查看器资源(如果有),确保您在开发过程中始终看到最新的 HTML/JS/CSS。
3. 验证完整性
# 验证 SRI 哈希值和签名
uv run python -m mcp_agent_mail.cli share verify ./my-bundle
# 使用显式公钥验证(覆盖 manifest.sig.json)
uv run python -m mcp_agent_mail.cli share verify ./my-bundle \
--public-key AAAA...base64...
验证内容包括:
- 所有第三方库(Marked.js、DOMPurify、SQL.js)的 SHA-256 哈希值
- SQLite 数据库和附件的 SHA-256 哈希值
- 对规范清单文件的 Ed25519 签名(如果存在)
4. 解密(如果已加密)
# 使用 age 身份文件(私钥)解密
uv run python -m mcp_agent_mail.cli share decrypt bundle.zip.age \
--identity ~/.age/key.txt
# 使用密码进行解密(交互式提示)
uv run python -m mcp_agent_mail.cli share decrypt bundle.zip.age \
--passphrase
# 指定自定义输出路径
uv run python -m mcp_agent_mail.cli share decrypt bundle.zip.age \
--output ./decrypted-bundle.zip \
--identity ~/.age/key.txt
解密完成后,解压归档文件,并使用 share preview 查看内容。
导出选项参考
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
--output, -o |
路径 | (必填) | 静态捆绑包将被写入的目录 |
--project, -p |
列表 | 所有项目 | 限制导出为特定项目 slug 或人机密钥(可重复) |
--inline-threshold |
字节 | 65536(64KB) | 将小于该阈值的附件以内联 base64 data URI 形式嵌入 |
--detach-threshold |
字节 | 26214400(25MB) | 将大于该阈值的附件标记为外部文件(不打包) |
--scrub-preset |
字符串 | standard |
清理预设:standard 或 strict(参见清理预设部分) |
--chunk-threshold |
字节 | 20971520(20MB) | 如果 SQLite 数据库超过此大小,则将其拆分为多个分块 |
--chunk-size |
字节 | 4194304(4MB) | 大型数据库拆分时的分块大小 |
--dry-run |
标志 | false | 仅生成安全摘要和预览,不写入文件 |
--zip / --no-zip |
标志 | true | 将捆绑包打包成 ZIP 归档 |
--signing-key |
路径 | 无 | Ed25519 签名密钥的路径(32 字节原始种子) |
--signing-public-out |
路径 | 无 | 签名后将 Ed25519 公钥写入此文件 |
--age-recipient |
字符串 | 无 | 用于加密的 age 公钥(可多次指定以支持多接收方) |
--interactive, -i |
标志 | false | 启动交互式向导(打印指导信息;完整向导待开发) |
安全特性
XSS 防护(DOMPurify + CSP)
消息正文通过纵深防御流程渲染:
- Marked.js 将 GitHub 风格的 Markdown 解析为 HTML
- DOMPurify 对 HTML 进行净化,移除危险标签和属性
- 内容安全策略 (CSP) 限制脚本来源、阻止内联事件处理器,并限制网络访问
这可以防止消息正文中的恶意内容执行 JavaScript 或窃取数据。
CSP 配置说明:
script-src:允许自身、CDN(Tailwind、Alpine.js)以及'unsafe-eval'(SQL.js WebAssembly 所需)connect-src:允许*(所有来源),以支持预览模式轮询和灵活的部署场景style-src:允许自身、内联样式(用于 Tailwind)以及字体 CDN- 为兼容性考虑,已移除 Trusted Types(Firefox 和 Safari 尚不支持)
加密签名(Ed25519)
当您提供签名密钥时,导出过程会执行以下步骤:
- 生成
manifest.json的规范 JSON 表示 - 使用 Ed25519 对其进行签名(速度快,签名长度 64 字节,安全性 128 位)
- 将签名和公钥写入
manifest.sig.json
接收者可以使用 share verify 验证签名,以确保:
- 捆绑包自签名以来未被篡改
- 捆绑包是由持有私钥的人创建的
- 所有资产与其声明的 SHA-256 哈希值一致
要求及回退机制:
- 需要 PyNaCl >= 1.6.0(随本包自动安装)
- 如果 PyNaCl 不可用或签名失败,导出将优雅地回退到未签名模式
- 向导默认重用现有签名密钥(除非用户明确要求重新生成)
- 私钥会自动通过
.gitignore排除在 Git 版本控制之外(匹配 signing-*.key 模式)
加密(age)
age 加密工具(https://age-encryption.org/)提供了现代且安全的文件加密功能。当您提供接收方的公钥时,导出过程会对最终的 ZIP 归档进行加密。只有持有相应私钥的人才能解密。
生成密钥的方法如下:
# 安装 age(以 macOS 为例)
brew install age
# 生成新的密钥对
age-keygen -o key.txt
# 公钥会打印到标准输出;请与导出人员共享
# 私钥会保存到 key.txt;务必保密
清理预设
导出流程支持可配置的数据清理,以移除敏感信息:
standard:清除已读状态、移除文件预留和代理链接,从消息正文和附件元数据中擦除秘密信息(GitHub Token、Slack Token、OpenAI Key、Bearer Token、JWT)。保留代理名称(这些已经是无意义的假名,如“BlueMountain”)、完整的消息正文和附件。strict:包含所有standard清理内容,并将整个消息正文替换为“[消息正文已清理]”占位符,同时从捆绑包中移除所有附件。
所有预设都会在捆绑包写入之前,对消息主题、正文和附件元数据进行清理。
静态查看器功能
捆绑的 HTML 查看器提供以下功能:
仪表板布局:
- Gmail 风格的三栏式界面:项目侧边栏、消息列表(中间)和详细信息面板(右侧)
- 包元数据头部:显示包创建时间、导出设置和脱敏预设
- 摘要面板:并排显示包含的项目、附件统计和编辑摘要
- 消息列表:虚拟滚动的消息列表,带有发件人、主题、摘要片段和重要性标签
- 原始清单查看器:可折叠的 JSON 格式完整清单,用于验证
高级布尔搜索(新功能):基于 SQLite FTS5 并回退至 LIKE,支持复杂查询:
- 布尔运算符:
(auth OR login) AND NOT admin - 带引号的短语:
"build plan"(完全匹配) - 括号:控制优先级,如
(A OR B) AND (C OR D) - 运算符优先级:NOT > AND > OR(例如,
A OR B AND C=A OR (B AND C)) - 自动防抖:140 毫秒延迟,避免每次按键都频繁访问数据库
- 性能:FTS5 搜索在大型数据集上比 LIKE 快 10 到 100 倍
消息懒加载(性能优化):
- 初始加载仅获取所有消息的 280 字节摘要(速度提升 3 至 6 倍)
- 点击消息时按需加载完整正文
- 极大地减少内存占用和初始加载时间
虚拟滚动(新功能):基于 Clusterize.js 的虚拟列表渲染:
- 能够流畅处理 10 万条以上消息而不卡顿
- 任何时候仅存在约 30 个 DOM 节点(可见行 + 缓冲区)
- 通过键盘导航保持原生滚动条体验
Markdown 渲染:消息正文采用 GitHub 风格的 Markdown 渲染,支持代码块、表格、任务列表和内联图片。
机会性 OPFS 缓存:SQLite 数据库会在后台缓存在 Origin Private File System (OPFS) 中:
- 首次加载:从网络下载,并在空闲时缓存到 OPFS
- 后续加载:直接从 OPFS 加载(甚至比 IndexedDB 还快)
- 自动缓存键验证防止数据过时
暗黑模式:通过 localStorage 持久化在浅色和深色主题之间切换。暗黑模式状态由主查看器控制器统一管理,以确保一致性。
附件预览:消息正文中直接渲染内联图片。外部附件显示文件大小和下载链接。
消息详情视图:点击消息列表中的任意一条消息即可加载其完整内容(懒加载),查看元数据(发件人、收件人、时间戳、重要性),并浏览附件。
无需服务器:在初始 HTTP 服务之后(可以是 S3、GitHub Pages 或 Netlify 等静态文件托管服务),所有功能均在客户端运行。无需后端、无需 API 调用、无需身份验证。
浏览器兼容性:适用于所有现代浏览器(Chrome、Firefox、Safari、Edge),并对缺失的功能(OPFS、FTS5)提供优雅降级。
部署选项
选项 1:GitHub Pages(通过向导自动化部署)
# 使用向导进行全自动部署
uv run python -m mcp_agent_mail.cli share wizard
# 选择:GitHub Pages → 提供仓库名称 → 向导会完成所有操作
或手动操作:
# 导出并解压
uv run python -m mcp_agent_mail.cli share export --output ./bundle --no-zip
cd bundle
# 初始化 git 并推送到 GitHub
git init
git add .
git commit -m "Initial export"
git remote add origin git@github.com:yourorg/project-archive.git
git push -u origin main
# 在仓库设置中启用 GitHub Pages(源:main 分支,根目录)
选项 2:Cloudflare Pages(通过向导自动化部署)
# 使用向导实现全球 CDN 即时部署
uv run python -m mcp_agent_mail.cli share wizard
# 选择:Cloudflare Pages → 提供项目名称 → 向导会直接部署
或使用 wrangler CLI 手动部署:
# 导出并部署
uv run python -m mcp_agent_mail.cli share export --output ./bundle --no-zip
npx wrangler pages deploy ./bundle --project-name=project-archive
# 您的站点已上线:https://project-archive.pages.dev
Cloudflare Pages 的优势:
- 即时部署(无需 Git 仓库)
- 全球 CDN,覆盖 275+ 个节点
- 自动 HTTPS 和 DDoS 防护
- 零宕机更新
- 宽敞的免费套餐(每月 500 次构建,无限请求)
选项 3:S3 + CloudFront
# 导出并解压
uv run python -m mcp_agent_mail.cli share export --output ./bundle --no-zip
# 上传到 S3
aws s3 sync ./bundle s3://your-bucket/archives/project-2024/ --acl public-read
# 通过 CloudFront 访问
# https://d123abc.cloudfront.net/archives/project-2024/
选项 4:Nginx 静态网站
server {
listen 443 ssl;
server_name archives.example.com;
ssl_certificate /etc/letsencrypt/live/archives.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/archives.example.com/privkey.pem;
root /var/www/archives/project-2024;
index index.html;
# 启用 gzip 以提高传输效率
gzip on;
gzip_types text/html text/css application/javascript application/json application/wasm;
# 缓存静态资源
location ~* \.(js|css|wasm|png|jpg|webp)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# CSP 头已在 index.html 的 meta 标签中设置
# 添加仅 HTTPS 和框架保护
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
}
选项 5:通过文件共享加密分发
适用于机密档案:
# 使用 age 加密导出
uv run python -m mcp_agent_mail.cli share export \
--output ./bundle \
--signing-key ./signing.key \
--age-recipient age1auditor... \
--age-recipient age1manager...
# 生成 bundle.zip.age
# 上传到 Dropbox、Google Drive 或通过安全文件传输发送
# 接收者本地解密
uv run python -m mcp_agent_mail.cli share decrypt bundle.zip.age \
--identity ~/.age/key.txt
# 验证完整性
unzip bundle.zip
uv run python -m mcp_agent_mail.cli share verify ./bundle
# 本地预览
uv run python -m mcp_agent_mail.cli share preview ./bundle
示例工作流
季度审计包
# 导出 2024 年第四季度通信记录用于审计
uv run python -m mcp_agent_mail.cli share export \
--output ./audit-q4-2024 \
--scrub-preset strict \
--signing-key ./audit-signing.key \
--signing-public-out ./audit-signing.pub \
--age-recipient age1auditor@firm.example
# 生成:audit-q4-2024.zip.age
# 连同 audit-signing.pub 一起发送给审计员
# 审计员验证:
age -d -i auditor-key.txt audit-q4-2024.zip.age > audit-q4-2024.zip
unzip audit-q4-2024.zip
python -m mcp_agent_mail.cli share verify ./audit-q4-2024 \
--public-key $(cat audit-signing.pub)
面向利益相关者的执行摘要
# 仅导出高优先级线程
# (导出后在 UI 中进行筛选,或使用 SQL 创建筛选后的快照)
uv run python -m mcp_agent_mail.cli share export \
--output ./exec-summary \
--project backend-prod \
--scrub-preset standard
# 托管在内部 Web 服务器上
cp -r ./exec-summary /var/www/exec-archives/2024-12/
# 共享链接:https://internal.example.com/exec-archives/2024-12/
灾难恢复备份
# 每月加密备份
uv run python -m mcp_agent_mail.cli share export \
--output ./backup-$(date +%Y-%m) \
--scrub-preset none \
--signing-key ./dr-signing.key \
--age-recipient age1dr@company.example
# 存储在异地备份系统中
aws s3 cp backup-2024-12.zip.age s3://dr-backups/mcp-mail/ \
--storage-class GLACIER_IR
# 恢复流程记录在运行手册中
导出问题排查
导出失败并提示“数据库已锁定”
导出过程会使用 SQLite 的在线备份 API 来创建快照。如果服务器正在写入数据,请等待几秒钟后再重试。对于大型数据库,建议在导出期间暂时停止服务器。
打包文件过大
使用 --detach-threshold 将大附件标记为外部引用。这些附件不会包含在包中,但会在查看器中显示文件元数据。
# 将小于 1MB 的文件打包,大于此大小的文件标记为外部
uv run python -m mcp_agent_mail.cli share export \
--output ./bundle \
--detach-threshold 1048576
或者,也可以通过 --project 参数筛选特定项目。
加密包无法解密
请确认您使用的是正确的身份文件:
# 从身份文件中获取您的公钥
age-keygen -y identity.txt
# 确保此公钥已在导出时作为 --age-recipient 值包含在内
# 如果有多个身份文件,请逐一尝试
age -d -i identity.txt bundle.zip.age > bundle.zip
签名验证失败
签名验证需要满足以下条件:
- 原始的
manifest.json文件(未修改)。 manifest.sig.json文件(包含签名和公钥)。- 清单中引用的所有资产,且其 SHA-256 哈希值必须匹配。
如果验证失败,可能是包在传输过程中被篡改或损坏。请重新导出并重新传输。
查看器显示空白页面或报错
请检查浏览器控制台以查找错误信息。常见问题包括:
- 不支持 OPFS:较旧的浏览器可能不支持 Origin Private File System。此时查看器将回退到内存模式(速度较慢)。
- 数据库过大:浏览器对内存数据库的大小限制通常为 1–2GB 左右。对于非常大的归档,可以使用分块功能(
--chunk-threshold)。 - CSP 违规:如果托管该包,请确保 Web 服务器没有添加冲突的 CSP 头。查看器的 CSP 定义在
index.html中,不应被覆盖。
磁盘布局(按项目)
<store>/projects/<slug>/
agents/<AgentName>/profile.json
agents/<AgentName>/inbox/YYYY/MM/<msg-id>.md
agents/<AgentName>/outbox/YYYY/MM/<msg-id>.md
messages/YYYY/MM/<msg-id>.md
messages/threads/<thread-id>.md # 可选的人类摘要,由服务器维护
file_reservations/<sha1-of-path>.json
attachments/<xx>/<sha1>.webp
消息文件格式
消息采用 GitHub 风格的 Markdown 格式,并带有 JSON 前言(用 ---json 包围)。附件可以是通过相对路径引用的 WebP 文件,也可以是内嵌的 base64 编码 WebP 数据 URI。
---json
{
"id": 1234,
"thread_id": "TKT-123",
"project": "/abs/path/backend",
"project_slug": "backend-abc123",
"from": "GreenCastle",
"to": ["BlueLake"],
"cc": [],
"created": "2025-10-23T15:22:14Z",
"importance": "high",
"ack_required": true,
"attachments": [
{"type": "file", "media_type": "image/webp", "path": "projects/backend-abc123/attachments/2a/2a6f.../diagram.webp"}
]
}
---
# /api/users 路由的构建计划
... 正文 Markdown ...
数据模型(SQLite)
projects(id, human_key, slug, created_at)agents(id, project_id, name, program, model, task_description, inception_ts, last_active_ts, attachments_policy, contact_policy)messages(id, project_id, sender_id, thread_id, subject, body_md, created_ts, importance, ack_required, attachments)message_recipients(message_id, agent_id, kind, read_ts, ack_ts)file_reservations(id, project_id, agent_id, path_pattern, exclusive, reason, created_ts, expires_ts, released_ts)agent_links(id, a_project_id, a_agent_id, b_project_id, b_agent_id, status, reason, created_ts, updated_ts, expires_ts)project_sibling_suggestions(id, project_a_id, project_b_id, score, status, rationale, created_ts, evaluated_ts, confirmed_ts, dismissed_ts)fts_messages(message_id UNINDEXED, subject, body)+ 用于增量更新的触发器
并发与生命周期
- 每个请求/任务对应一个独立的操作。
- 归档写操作受每个项目的
projects/<slug>/目录下的.archive.lock文件保护。 - Git 索引/提交操作通过仓库级别的
.commit.lock文件在共享归档仓库中串行化执行。 - 数据库操作持续时间短,并限定于每次工具调用的范围内;FTS 触发器会保持搜索索引的最新状态。
- 资源先写入磁盘,再以具有描述性信息的消息作为一个整体提交。
- 附件采用内容寻址(SHA-1),以避免重复。
工作原理(关键流程)
- 创建身份
register_agent(project_key, program, model, name?, task_description?)→ 创建/更新一个命名身份,将个人资料持久化到 Git 并提交。
- 发送消息
send_message(project_key, sender_name, to[], subject, body_md, cc?, bcc?, attachment_paths?, convert_images?, importance?, ack_required?, thread_id?, auto_contact_if_blocked?)- 在
messages/YYYY/MM/目录下写入规范的消息文件,为发送者生成一个发件箱副本,并为每个收件人生成一个收件箱副本;然后提交所有相关文件。 - 可选地,将图片(本地路径或 data URI)转换为 WebP 格式,并将小尺寸的图片内嵌到邮件中。
sequenceDiagram
participant Agent
participant Server
participant DB
participant Git
Agent->>Server: 调用 send_message
Server->>DB: 插入消息及收件人信息
DB-->>Server: 操作成功
Server->>Git: 写入规范的 Markdown 文件
Server->>Git: 写出发件箱副本
Server->>Git: 写入收件箱副本
Server->>Git: 提交更改
Server-->>Agent: 返回结果
- 检查收件箱
fetch_inbox(project_key, agent_name, since_ts?, urgent_only?, include_bodies?, limit?)返回最近的消息,并在可用时保留线程 ID。acknowledge_message(project_key, agent_name, message_id)用于标记已读回执。
- 避免文件锁定冲突(租约)
file_reservation_paths(project_key, agent_name, paths[], ttl_seconds, exclusive, reason)在数据库中记录建议性租约,并在 Git 中写入 JSON 格式的预留文件;如果存在重叠的排他性租约,则会报告冲突(尽管如此,租约仍会被授予,冲突信息也会一并返回)。release_file_reservations(project_key, agent_name, paths? | file_reservation_ids?)释放当前有效的租约(若未指定路径,则释放所有租约)。JSON 文件将保留在 Git 中以供审计历史参考。- 可选:在代码仓库中安装 pre-commit 钩子,阻止与其他代理的排他性文件租约发生冲突的提交。
sequenceDiagram
participant Agent
participant Server
participant DB
participant Git
Agent->>Server: 调用 file_reservation_paths
Server->>DB: 过期旧租约并检查重叠情况
DB-->>Server: 返回冲突或授权信息
Server->>DB: 插入文件预留记录
Server->>Git: 写入文件预留 JSON 文件
Server->>Git: 提交更改
Server-->>Agent: 返回授权路径及任何冲突信息
- 搜索与摘要
search_messages(project_key, query, limit?)使用 FTS5 对主题和正文进行全文检索。summarize_thread(project_key, thread_id, include_examples?)从线程中提取关键点、行动项和参与者。reply_message(project_key, message_id, sender_name, body_md, ..., sender_token?)创建带有主题前缀的回复,并保持或创建线程。
语义与不变量
- 身份
- 名称由易于记忆的形容词加名词组成,且在每个项目中唯一;
name_hint经过清理(仅包含字母数字字符),并在可用时使用。 whois返回存储的个人资料;list_agents可按最近活动筛选。last_active_ts在相关交互(如发送消息、检查收件箱等)时会更新。
- 名称由易于记忆的形容词加名词组成,且在每个项目中唯一;
- 线程
- 回复会继承原始消息的
thread_id;如果原始消息没有thread_id,则回复会将其设置为原始消息的 ID。 - 主题行会加上前缀(如
Re:),以便在邮箱中更易阅读。
- 回复会继承原始消息的
- 附件
- 图片引用(文件路径或 data URI)会被转换为 WebP 格式;在政策允许的情况下,小尺寸图片会内嵌到邮件中。
- 非绝对路径的
attachment_paths(以及 Markdown 中的图片路径)会相对于项目归档根目录STORAGE_ROOT/projects/<slug>/解析,而不是代码仓库的根目录。 - 默认情况下,绝对路径附件是被禁用的。如果在网络部署中启用
ALLOW_ABSOLUTE_ATTACHMENT_PATHS=true,那么发送消息就会变成一种文件系统读取原语,可以访问服务器进程所能访问的任意路径。 - 附件会存储在
attachments/<xx>/<sha1>.webp中,并通过相对路径在邮件头中引用。
- 文件预留
- 基于 TTL 的租约;排他性意味着“请不要在到期或释放之前修改重叠的部分”,以免影响他人。
- 冲突检测是基于精确的路径模式;共享预留可以共存,但排他性预留会产生冲突。
- 即使租约被释放,Git 中仍会保留 JSON 文件以供审计(数据库会记录释放时间)。
- 搜索
- 外部内容 FTS 虚拟表和触发器会在插入/更新/删除时对主题/正文建立索引。
- 查询被限制在特定项目 ID 内,并按
created_ts DESC排序。
联系模型与“轻度同意”消息传递
目标:在不向无关代理发送垃圾信息的情况下,让协作“自动生效”。服务器默认强制实施项目隔离,并在项目内部添加可选的同意层,以便代理只与相关的同行联系。
按项目隔离
- 所有工具都需要一个
project_key。代理只能看到该特定项目中发给自己的消息。 - 在项目 A 中工作的代理对项目 B 中的代理是不可见的,除非建立了明确的跨项目联系(见下文)。这样可以避免无关仓库之间的干扰。
政策(按代理)
open: 接受项目中的任何定向消息。auto(默认):当存在明显的共同上下文时允许接收消息(例如,相同的线程参与者;最近重叠的活跃文件预留;近期在 TTL 内有过直接联系);否则需要发起联系请求。contacts_only: 必须先获得批准的联系链接。block_all: 拒绝所有新联系(返回 CONTACT_BLOCKED 错误)。
使用 set_contact_policy(project_key, agent_name, policy) 来更新政策。
请求/批准联系
request_contact(project_key, from_agent, to_agent, reason?, ttl_seconds?, registration_token?)创建或刷新待处理的联系链接,并向接收方发送一条带有回执请求的小型“介绍”消息。respond_contact(project_key, to_agent, from_agent, accept, ttl_seconds?, registration_token?)批准或拒绝联系请求;批准后可在到期前进行通信。list_contacts(project_key, agent_name)显示出站联系及其目标项目,并标注到期和可通信状态的审计标志。
认证说明:这些工具需要代理已在当前 MCP 会话中认证,或者提供相应的 registration_token。send_message(..., auto_contact_if_blocked=true) 现在会默认创建待处理的联系请求;只有当双方代理都已在同一 MCP 会话中认证时,才会自动批准。macro_contact_handshake(..., auto_accept=true) 也遵循同样的规则:只有当目标代理已在当前 MCP 会话中认证,或明确提供了 target_registration_token 时,才会自动批准。如果联系已获批准,则宏命令会复用该批准;否则请求将继续处于待处理状态,并返回 response_error。
自动允许启发式规则(无需明确请求)
- 同一线程:允许回复或向线程参与者发送消息。
- 最近的重叠文件预留:如果发送者和接收者在项目中持有有效的文件预留,则允许通信。
- 最近的先前联系:通过滑动的 TTL 机制,允许同一对用户之间的后续沟通。
这些启发式规则在防止冷垃圾信息的同时,最大限度地减少了摩擦。
跨项目协调(前端与后端仓库)
当两个仓库代表同一个基础项目时(例如 frontend 和 backend),您有两种选择:
在两个工作空间中使用相同的
project_key。这样,两个仓库中的代理将共享一个项目命名空间,并自动享受完整的收件箱/发件箱协调功能。保持独立的
project_key并建立显式联系:- 在
backend中,代理GreenCastle调用:request_contact(project_key="/abs/path/backend", from_agent="GreenCastle", to_agent="BlueLake", reason="API 合同变更", registration_token="<GreenCastle token>")
- 在
frontend中,BlueLake调用:respond_contact(project_key="/abs/path/backend", to_agent="BlueLake", from_agent="GreenCastle", accept=true, registration_token="<BlueLake token>")
- 批准后,双方可以交换消息;在默认的
auto策略下,服务器会允许后续对话和基于预留的协调,而无需再次请求。
- 在
重要提示:您也可以为受信任的配对创建互惠链接或设置 open 策略。同意层默认开启(CONTACT_ENFORCEMENT_ENABLED=true),但在明显的协作场景中设计为非阻塞模式。
资源层(只读 URI)
将常见的读取操作暴露为客户端可获取的资源。完整列表和参数请参见 API 快速参考 → 资源。
示例(概念性)资源读取:
{
"method": "resources/read",
"params": {"uri": "resource://inbox/BlueLake?project=/abs/path/backend&limit=20&agent_token=<registration_token>"}
}
sequenceDiagram
participant 客户端
participant 服务器
participant 数据库
客户端->>服务器: 读取收件箱资源
服务器->>数据库: 选择该代理的消息
数据库-->>服务器: 返回消息记录
服务器-->>客户端: 发送收件箱数据
文件预留与可选的预提交保护程序
- 保护程序状态与预推送
- 查看保护程序状态:
mcp-agent-mail guard status /path/to/repo
- 安装两种保护程序(预提交 + 预推送):
mcp-agent-mail guard install <project_key> <repo_path> --prepush
- 预提交保护程序遵循
WORKTREES_ENABLED和AGENT_MAIL_GUARD_MODE设置(警告级别)。 - 预推送保护程序会枚举待推送的提交记录(
rev-list),并使用diff-tree命令,同时禁用外部差异工具。 - 安全的组合安装方式(链式运行器):
- Python 链式运行器会被写入
.git/hooks/pre-commit和.git/hooks/pre-push文件中。 - 它会按字典顺序执行
hooks.d/<hook>/*脚本,如果存在则再执行<hook>.orig(保留现有钩子,不覆盖)。 - Agent Mail 将其保护程序分别安装为
hooks.d/pre-commit/50-agent-mail.py和hooks.d/pre-push/50-agent-mail.py。 - Windows 平台还提供了 shim 文件(
pre-commit.cmd/.ps1、pre-push.cmd/.ps1),用于调用 Python 链式运行器。
- Python 链式运行器会被写入
- 匹配与安全细节:
- 对于重命名或移动操作,会同时检查旧名称和新名称(使用
git diff --cached --name-status -M -z)。 - 全链路 NUL 安全:路径以 NUL 分隔符收集和传递,以避免歧义。
- 原生 Git 匹配:根据 Git 的通配符路径语义,针对仓库根目录的相对路径检查预留情况;同时尊重
core.ignorecase设置。 - 紧急绕过(谨慎使用):设置
AGENT_MAIL_BYPASS=1,或直接使用原生 Git 的--no-verify选项。在警告模式下,保护程序绝不会阻止操作。
- 对于重命名或移动操作,会同时检查旧名称和新名称(使用
- 查看保护程序状态:
基于 Git 的项目身份标识(可选)
开关:启用基于 Git 的身份标识功能需要设置
WORKTREES_ENABLED=1或GIT_IDENTITY_ENABLED=1。默认关闭。身份模式(默认为
dir):包括dir、git-remote、git-toplevel、git-common-dir。检查特定路径的身份标识:
- 资源(MCP):
resource://identity/%2Fabs%2Fpath(资源段内的绝对路径必须进行 URL 编码) - CLI(诊断):
mcp-agent-mail mail status /abs/path
- 资源(MCP):
优先级(当开关打开时):
- 提交的标记文件
.agent-mail-project-id(推荐) - 发现 YAML 文件
.agent-mail.yaml中的project_uid - Git 共享目录下的私有标记文件
.git/agent-mail/project-id - 远程指纹:规范化后的
originURL 加上默认分支 git-common-dir的哈希值;若不存在则使用目录哈希值。
- 提交的标记文件
迁移辅助工具:
- 写入提交标记:
mcp-agent-mail projects mark-identity . --commit - 构建发现文件:
mcp-agent-mail projects discovery-init . --product <product_uid>
- 写入提交标记:
示例身份负载(资源):
{
"project_uid": "c5b2c86b-7c36-4de6-9a0a-2c4e1c3a1c4a",
"slug": "repo-a1b2c3d4e5",
"identity_mode_used": "git-remote",
"canonical_path": "github.com/owner/repo",
"human_key": "/abs/worktree/path",
"repo_root": "/abs/repo",
"git_common_dir": "/abs/repo/.git",
"branch": "feature/x",
"worktree_name": "repo-wt-x",
"core_ignorecase": true,
"normalized_remote": "github.com/owner/repo"
}
采用/合并遗留项目(可选)
将每个工作树下的遗留项目整合到一个规范化的项目中(安全、明确且可审计)。
- 制定合并计划(不进行实际更改):
mcp-agent-mail projects adopt <from> <to> --dry-run
- 执行合并(迁移工件并重新键数据库行):
mcp-agent-mail projects adopt <from> <to> --apply
- 安全保障与行为:
- 要求两个项目位于同一仓库中(通过
git-common-dir验证)。 - 将归档的 Git 工件从
projects/<old-slug>/…移至projects/<new-slug>/…,同时保留历史记录。 - 将数据库中的行(代理、消息、文件预留)从源项目重新键到目标项目。
- 在目标项目下记录
aliases.json文件,包含"former_slugs": [...]以便发现。 - 如果代理名称冲突会导致目标项目中出现重复,则会中止合并(需先修正名称后再尝试)。
- 尽可能实现幂等性;干运行始终会在实际应用前打印清晰的计划。
- 要求两个项目位于同一仓库中(通过
构建槽位与辅助工具(可选)
amctl env打印有用的环境变量键:SLUG、PROJECT_UID、BRANCH、AGENT、CACHE_KEY、ARTIFACT_DIR- 示例:
mcp-agent-mail amctl env --path . --agent AliceDev
am-run将命令包裹起来,并设置这些键值:- 示例:
mcp-agent-mail am-run frontend-build -- npm run dev - 认证:在与 HTTP 服务器通信时,
am-run现在会尽可能自动从数据库中加载本地代理的registration_token。你也可以通过--registration-token参数传递或设置AGENT_MAIL_REGISTRATION_TOKEN。
- 示例:
构建槽位(建议性、按项目粗粒度锁定):
- 标志:
--ttl-seconds:租约时长(默认 3600 秒)--shared/--exclusive:非排他性或排他性租约(默认排他性)--block-on-conflicts:如果在开始前检测到排他性冲突,则退出并返回非零状态
- 获取:
- 工具:
acquire_build_slot(project_key, agent_name, slot, ttl_seconds=3600, exclusive=true)
- 工具:
- 续订:
- 工具:
renew_build_slot(project_key, agent_name, slot, extend_seconds=1800)
- 工具:
- 释放(非破坏性;标记为已释放):
- 工具:
release_build_slot(project_key, agent_name, slot)
- 工具:
- 注意事项:
- 槽位记录在项目归档目录下
build_slots/<slot>/<agent>__<branch>.json - 当
exclusive=true时,如果有其他活跃的排他性持有者,则会报告冲突 - 适用于长时间运行的任务(开发服务器、监视器等);可与
am-run和amctl env配合使用
- 槽位记录在项目归档目录下
- 标志:
产品总线
将多个仓库(例如前端、后端、基础设施)归入一个产品之下,以实现跨产品的收件箱/搜索功能以及共享线程。
- 确保创建一个产品:
mcp-agent-mail products ensure MyProduct --name "My Product"
- 将一个项目(slug 或路径)链接到该产品:
mcp-agent-mail products link MyProduct .
- 检查产品及关联项目:
mcp-agent-mail products status MyProduct
- 产品范围的消息搜索(FTS):
mcp-agent-mail products search MyProduct "urgent AND deploy" --agent Alice --registration-token "$AGENT_MAIL_REGISTRATION_TOKEN" --limit 50
- 产品范围的收件箱:
mcp-agent-mail products inbox MyProduct Alice --registration-token "$AGENT_MAIL_REGISTRATION_TOKEN" --limit 50 --urgent-only --include-bodies --since-ts "2025-11-01T00:00:00Z"
- 产品范围的线程摘要:
mcp-agent-mail products summarize-thread MyProduct "bd-123" --agent Alice --registration-token "$AGENT_MAIL_REGISTRATION_TOKEN" --per-thread-limit 100 --no-llm
- 认证说明:
- 产品范围的搜索、收件箱和线程摘要现在需要经过身份验证的代理。这些命令接受
--registration-token/AGENT_MAIL_REGISTRATION_TOKEN参数,并会在可能的情况下自动使用本地存储的唯一明确令牌。
- 产品范围的搜索、收件箱和线程摘要现在需要经过身份验证的代理。这些命令接受
容器
- 在本地构建并运行:
docker build -t mcp-agent-mail . docker run --rm -p 8765:8765 \ -e HTTP_HOST=0.0.0.0 \ -e STORAGE_ROOT=/data/mailbox \ -v agent_mail_data:/data \ mcp-agent-mail - 或使用 Compose:
docker compose up --build - 注意事项:
- 以非特权用户身份运行(
appuser,uid 10001)。 - 包含针对
/health/liveness的健康检查。 - 服务器通过 python-decouple 从
.env文件读取配置。你可以将其以只读方式挂载到容器内的/app/.env路径。 - 默认绑定主机为容器内的
0.0.0.0;暴露了8765端口。 - 持久化归档位于
/data/mailbox目录下(默认映射到agent_mail_data卷)。 - 绑定挂载 uid 不匹配问题: 如果你将宿主机目录(而非命名卷)绑定挂载到
/data/mailbox,宿主机上的文件通常由 uid 1000 拥有,而不是容器中的appuser(uid 10001)。Git 通常会拒绝操作此类“可疑所有权”的目录,这会导致出现不明显的错误Unknown parameter: --cached,表现为 diff/status 错误。镜像现在通过git config --global --add safe.directory将/data/mailbox(以及作为容器内兜底方案的*)加入白名单。如果你从一个省略了这一步骤的分支重建镜像,可以重新添加safe.directory配置行,或者对宿主机路径执行chown -R 10001:10001操作(参见 issue #143)。
- 以非特权用户身份运行(
备注
- 每个产品都会存储一个唯一的
product_uid;你可以通过 uid 或名称来引用产品。 - 服务器还提供了用于编排的工具:
ensure_product、products_link、search_messages_product以及resource://product/{key}。
排他性文件预留是建议性的,但可见且可审计:
- 预留 JSON 文件会被写入
file_reservations/<sha1(path)>.json,其中记录了持有者、模式、排他性、创建时间及到期时间。 - pre-commit 防护程序会扫描当前有效的排他性预留,并阻止任何触及被其他代理持有的冲突路径的提交。
- 代理必须设置
AGENT_NAME,以便防护程序知道谁“拥有”这次提交。 - 服务器会持续评估预留是否过期(代理不活动 + 邮件/文件系统/Git 无响应),并自动释放已废弃的锁;
force_release_file_reservation工具使用相同的启发式方法,并在另一个代理解除过期租约时通知之前的持有者。
将防护程序安装到代码仓库中(概念性工具调用):
{
"method": "tools/call",
"params": {
"name": "install_precommit_guard",
"arguments": {
"project_key": "/abs/path/backend",
"code_repo_path": "/abs/path/backend"
}
}
}
配置
配置通过 python-decouple 从现有的 .env 文件加载。请勿使用 os.getenv 或自动 dotenv 加载器。
更改 HTTP 端口
如果 8765 端口已被占用(例如被 Cursor 的 Python 插件使用),你可以更改它:
选项 1:安装时 自定义端口的一行命令:
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/main/scripts/install.sh?$(date +%s)" | bash -s -- --port 9000 --yes
或者使用本地脚本: ./scripts/install.sh --port 9000 --yes
**选项 2:安装后(CLI)**
```bash
# 使用 CLI 命令更改端口
uv run python -m mcp_agent_mail.cli config set-port 9000
# 查看当前端口配置
uv run python -m mcp_agent_mail.cli config show-port
# 重启服务器使更改生效
scripts/run_server_with_token.sh
选项 3:手动编辑 .env 文件
# 使用文本编辑器手动编辑 .env 文件(推荐)
nano .env # 或 vim、code 等。
# 或追加(⚠️ 警告:如果 HTTP_PORT 已存在,将会创建重复项)
echo "HTTP_PORT=9000" >> .env
选项 4:CLI 服务器覆盖
# 使用 CLI 命令直接覆盖服务器配置
uv run python -m mcp_agent_mail.cli config set-port 9000
# 查看当前端口配置
uv run python -m mcp_agent_mail.cli config show-port
# 重启服务器使更改生效
scripts/run_server_with_token.sh
在服务器启动时覆盖端口(不会修改 .env 文件)
uv run python -m mcp_agent_mail.cli serve-http --port 9000
```python
from decouple import Config as DecoupleConfig, RepositoryEnv
decouple_config = DecoupleConfig(RepositoryEnv(".env"))
STORAGE_ROOT = decouple_config("STORAGE_ROOT", default="~/.mcp_agent_mail_git_mailbox_repo")
HTTP_HOST = decouple_config("HTTP_HOST", default="127.0.0.1")
HTTP_PORT = int(decouple_config("HTTP_PORT", default=8765))
HTTP_PATH = decouple_config("HTTP_PATH", default="/mcp/")
您可能需要设置的常见变量:
配置参考
| 名称 | 默认值 | 描述 |
|---|---|---|
STORAGE_ROOT |
~/.mcp_agent_mail_git_mailbox_repo |
每个项目的仓库和 SQLite 数据库的根目录 |
HTTP_HOST |
127.0.0.1 |
HTTP 传输绑定的主机 |
HTTP_PORT |
8765 |
HTTP 传输绑定的端口 |
HTTP_PATH |
/mcp/ |
推荐的 MCP 端点挂载路径(同时也会挂载 /api 和 /mcp 的别名) |
HTTP_JWT_ENABLED |
false |
启用 JWT 验证中间件 |
HTTP_JWT_SECRET |
用于 HS* 算法的 HMAC 密钥(开发环境) | |
HTTP_JWT_JWKS_URL |
用于公钥验证的 JWKS URL | |
HTTP_JWT_ALGORITHMS |
HS256 |
允许的算法列表,以逗号分隔 |
HTTP_JWT_AUDIENCE |
预期的 aud 声明(可选) |
|
HTTP_JWT_ISSUER |
预期的 iss 声明(可选) |
|
HTTP_JWT_ROLE_CLAIM |
role |
包含角色信息的 JWT 声明名称 |
HTTP_RBAC_ENABLED |
true |
强制执行只读与工具类的 RBAC 权限控制 |
HTTP_RBAC_READER_ROLES |
reader,read,ro |
读者角色列表,以逗号分隔 |
HTTP_RBAC_WRITER_ROLES |
writer,write,tools,rw |
写者角色列表,以逗号分隔 |
HTTP_RBAC_DEFAULT_ROLE |
reader |
当未指定角色时使用的默认角色 |
HTTP_RBAC_READONLY_TOOLS |
health_check,fetch_inbox,whois,search_messages,summarize_thread |
只读工具名称列表,以逗号分隔 |
HTTP_RATE_LIMIT_ENABLED |
false |
启用令牌桶限流器 |
HTTP_RATE_LIMIT_BACKEND |
memory |
可选值为 memory 或 redis |
HTTP_RATE_LIMIT_PER_MINUTE |
60 |
旧版每 IP 地址的限流值(回退值) |
HTTP_RATE_LIMIT_TOOLS_PER_MINUTE |
60 |
工具调用的每分钟限流值 |
HTTP_RATE_LIMIT_TOOLS_BURST |
0 |
工具调用的突发流量限制(0=自动=rpm) |
HTTP_RATE_LIMIT_RESOURCES_PER_MINUTE |
120 |
资源读取的每分钟限流值 |
HTTP_RATE_LIMIT_RESOURCES_BURST |
0 |
资源读取的突发流量限制(0=自动=rpm) |
HTTP_RATE_LIMIT_REDIS_URL |
用于多工作进程限流的 Redis URL | |
HTTP_REQUEST_LOG_ENABLED |
false |
打印请求日志(Rich + JSON 格式) |
LOG_JSON_ENABLED |
false |
输出 structlog JSON 日志 |
MCP_AGENT_MAIL_OUTPUT_FORMAT |
工具和资源的默认输出格式(json 或 toon) |
|
TOON_DEFAULT_FORMAT |
全局默认输出格式的回退值(json 或 toon) |
|
TOON_STATS |
false |
发送 TOON 令牌统计信息(使用 tru --stats) |
TOON_TRU_BIN |
显式指定 tru 编码器的路径或命令(覆盖 TOON_BIN) |
|
TOON_BIN |
tru |
toon_rust 编码器的路径或命令(拒绝使用 Node 的 toon) |
INLINE_IMAGE_MAX_BYTES |
65536 |
在发送消息时内联 WebP 图片的字节数阈值 |
CONVERT_IMAGES |
true |
将图片转换为 WebP 格式,并可选择将小图片内联 |
KEEP_ORIGINAL_IMAGES |
false |
同时存储原始图片数据和 WebP 格式图片(存放在 attachments/originals/ 目录下) |
ALLOW_ABSOLUTE_ATTACHMENT_PATHS |
false |
允许在附件和 Markdown 图片引用中使用绝对文件系统路径。在网络部署中请保持此选项关闭,除非您明确需要服务器端读取文件。 |
LOG_LEVEL |
INFO |
服务器日志级别 |
HTTP_CORS_ENABLED |
false |
当为真时启用 CORS 中间件 |
HTTP_CORS_ORIGINS |
允许的来源列表,以逗号分隔(例如:https://app.example.com,https://ops.example.com) |
|
HTTP_CORS_ALLOW_CREDENTIALS |
false |
是否允许在 CORS 请求中携带凭据 |
HTTP_CORS_ALLOW_METHODS |
* |
全部方法或允许的方法列表,以逗号分隔 |
HTTP_CORS_ALLOW_HEADERS |
* |
全部头部或允许的头部列表,以逗号分隔 |
HTTP_BEARER_TOKEN |
静态 Bearer 令牌(仅在 JWT 禁用时使用) | |
HTTP_ALLOW_LOCALHOST_UNAUTHENTICATED |
true |
允许本地主机请求无需认证(开发便利功能) |
HTTP_OTEL_ENABLED |
false |
启用 OpenTelemetry 应用程序监控 |
OTEL_SERVICE_NAME |
mcp-agent-mail |
用于遥测的服务名称 |
OTEL_EXPORTER_OTLP_ENDPOINT |
OTLP 导出器的端点 URL | |
APP_ENVIRONMENT |
development |
环境名称(开发/生产) |
DATABASE_URL |
sqlite+aiosqlite:///./storage.sqlite3 |
SQLAlchemy 异步数据库 URL |
DATABASE_ECHO |
false |
是否回显 SQL 语句以用于调试 |
DATABASE_POOL_SIZE |
50(sqlite)/25(其他) |
SQLAlchemy 连接池的基础大小(可选覆盖) |
DATABASE_MAX_OVERFLOW |
4(sqlite)/25(其他) |
允许超出连接池大小的额外连接数 |
DATABASE_POOL_TIMEOUT |
45(sqlite)/30(其他) |
等待连接池连接的最大时间(秒),超过后将失败 |
GIT_AUTHOR_NAME |
mcp-agent |
Git 提交的作者姓名 |
GIT_AUTHOR_EMAIL |
mcp-agent@example.com |
Git 提交的作者邮箱 |
LLM_ENABLED |
true |
启用 LiteLLM 用于线程摘要和发现 |
LLM_DEFAULT_MODEL |
gpt-5-mini |
默认的 LiteLLM 模型标识符 |
LLM_TEMPERATURE |
0.2 |
LLM 文本生成的温度参数 |
LLM_MAX_TOKENS |
512 |
LLM 补全的最大 token 数量 |
LLM_CACHE_ENABLED |
true |
启用 LLM 响应缓存 |
LLM_CACHE_BACKEND |
memory |
LLM 缓存后端(memory 或 redis) |
LLM_CACHE_REDIS_URL |
如果缓存后端为 Redis,则需提供 Redis URL | |
LLM_COST_LOGGING_ENABLED |
true |
记录 LLM API 费用及 token 使用情况 |
FILE_RESERVATIONS_CLEANUP_ENABLED |
false |
启用后台清理过期的文件预留任务 |
FILE_RESERVATIONS_CLEANUP_INTERVAL_SECONDS |
60 |
文件预留清理任务的执行间隔 |
FILE_RESERVATION_INACTIVITY_SECONDS |
1800 |
在文件预留被视为过期之前的不活动时间阈值(秒) |
FILE_RESERVATION_ACTIVITY_GRACE_SECONDS |
900 |
最近邮件/文件系统/Git 活动的宽限期,以保持文件预留有效 |
FILE_RESERVATIONS_ENFORCEMENT_ENABLED |
true |
阻止针对邮件归档路径(agents/, messages/, attachments/)的冲突文件预留的消息写入操作 |
ACK_TTL_ENABLED |
false |
启用过期 ACK 扫描(日志/面板;参见 views/resources) |
ACK_TTL_SECONDS |
1800 |
过期 ACK 的年龄阈值(秒) |
ACK_TTL_SCAN_INTERVAL_SECONDS |
60 |
过期 ACK 扫描的执行间隔 |
ACK_ESCALATION_ENABLED |
false |
启用过期 ACK 的升级处理 |
ACK_ESCALATION_MODE |
log |
升级模式为 log 或 file_reservation |
ACK_ESCALATION_CLAIM_TTL_SECONDS |
3600 |
升级文件预留的有效期 |
ACK_ESCALATION_CLAIM_EXCLUSIVE |
false |
使升级文件预留具有独占性 |
ACK_ESCALATION_CLAIM_HOLDER_NAME |
负责拥有升级文件预留的操作员代理姓名 | |
CONTACT_ENFORCEMENT_ENABLED |
true |
在发送消息前强制执行联系人政策 |
CONTACT_AUTO_TTL_SECONDS |
86400 |
自动批准的联系人有效期(1天) |
CONTACT_AUTO_RETRY_ENABLED |
true |
在违反政策时自动重试联系人请求 |
MESSAGING_AUTO_REGISTER_RECIPIENTS |
true |
在 send_message 期间自动创建缺失的本地收件人,并重试路由 |
MESSAGING_AUTO_HANDSHAKE_ON_BLOCK |
true |
当联系人政策阻止送达时,尝试进行联系握手(自动接受)并重试 |
TOOLS_LOG_ENABLED |
true |
记录工具调用以用于调试 |
LOG_RICH_ENABLED |
true |
启用 Rich 控制台日志记录 |
LOG_INCLUDE_TRACE |
false |
是否包含跟踪级别的日志 |
TOOL_METRICS_EMIT_ENABLED |
false |
是否定期发出工具使用指标 |
TOOL_METRICS_EMIT_INTERVAL_SECONDS |
60 |
指标发布的间隔时间 |
RETENTION_REPORT_ENABLED |
false |
启用保留/配额报告 |
RETENTION_REPORT_INTERVAL_SECONDS |
3600 |
保留报告的发布间隔(1小时) |
RETENTION_MAX_AGE_DAYS |
180 |
保留政策报告的最大年龄 |
QUOTA_ENABLED |
false |
是否启用配额管理 |
QUOTA_ATTACHMENTS_LIMIT_BYTES |
0 |
每个项目附件存储的上限(0=无限制) |
QUOTA_INBOX_LIMIT_COUNT |
0 |
每个代理收件箱消息数量的上限(0=无限制) |
RETENTION_IGNORE_PROJECT_PATTERNS |
demo,test*,testproj*,testproject,backendproj*,frontendproj* |
保留/配额报告中要忽略的项目模式列表,以逗号分隔 |
AGENT_NAME_ENFORCEMENT_MODE |
coerce |
代理命名政策:strict(拒绝无效的形容词+名词命名)、coerce(无效时自动生成)、always_auto(始终自动生成)。 |
开发快速入门
先决条件:完成上述设置(Python 3.14 + uv venv + uv sync)。
开发辅助工具:
# 快速端点冒烟测试(需本地运行服务器)
bash scripts/test_endpoints.sh
# pre-commit 钩子冒烟测试(不使用 pytest)
bash scripts/test_guard.sh
数据库模式(自动):
# 表格会在首次运行时根据 SQLModel 定义创建。
# 如果模型发生变更,请删除 SQLite 数据库(以及 WAL/SHM 文件),然后再次运行迁移。
uv run python -m mcp_agent_mail.cli migrate
运行服务器(仅 HTTP)。可使用 Typer CLI 或模块入口:
uv run python -m mcp_agent_mail.cli serve-http
uv run python -m mcp_agent_mail.http --host 127.0.0.1 --port 8765
使用配置的主机/端口,通过 HTTP(可流式传输的 HTTP)传输协议连接您的 MCP 客户端。该端点支持 /api、/api/、/mcp 和 /mcp/ 路径。
搜索语法提示(SQLite FTS5)
- 基本术语:
plan users - 短语搜索:
"build plan" - 前缀搜索:
mig* - 布尔运算符:
plan AND users NOT legacy - 默认情况下未启用字段加权;主题和正文已被索引。请保持查询简洁。当 FTS 不可用时,UI/API 会自动回退到对主题/正文的 SQL LIKE 查询。
设计选择及理由
- 仅 HTTP 的 FastMCP:可流式传输的 HTTP 是现代远程传输方式;出于设计考虑,此处未暴露 STDIO。
- Git + Markdown:便于人工审核、可 diff 的工件,符合开发者的工作流程(收件箱/发件箱思维模型)。
- SQLite + FTS5:高效的索引/搜索功能,同时具有最小的运维开销。
- 建议性文件预留机制:明确并可审查操作意图;可选的 guard 会在提交时强制执行预留。
- WebP 附件:默认使用紧凑的图片格式;内嵌小图表可保持上下文连贯。
- 可选:在
attachments/目录下保留原始二进制文件和去重清单,以供审计和重复使用。
- 可选:在
示例(概念性工具调用)
为使 README 更加聚焦,本节已被移除。规范的方法签名请参阅下方的 API 快速参考。
运维注意事项
- 每个请求/任务使用一个异步会话;不要在并发协程之间共享。
- 在异步代码中使用显式加载;避免隐式懒加载。
- 需要时使用支持异步的文件操作;Git 操作通过文件锁进行序列化。
- 清理关闭时应释放所有引入的异步引擎/资源(如果后续引入的话)。
安全与运维
- 传输
- 仅 HTTP(可流式传输的 HTTP)。生产环境中请将其置于反向代理(如 NGINX)后,并启用 TLS 终止。
- 认证
- 可选的 JWT(HS*/JWKS)通过 HTTP 中间件实现;可通过设置
HTTP_JWT_ENABLED=true启用。 - 静态 Bearer 令牌(
HTTP_BEARER_TOKEN)独立于 JWT;一旦设置,BearerAuth 将保护所有路由(包括 UI)。您可以单独使用它,也可以与 JWT 一起使用。 - 当配置了 JWKS(
HTTP_JWT_JWKS_URL)时,传入的 JWT 必须包含匹配的kid头部;缺少kid或kid未知的令牌将被拒绝。 - 提供基于角色的访问控制(RBAC)入门功能,通过角色配置实现;请参阅
HTTP_RBAC_*设置。 - 仅 Bearer 的 RBAC 注意事项:当 JWT 被禁用时,请求将使用
HTTP_RBAC_DEFAULT_ROLE(默认为reader)。这意味着非本地主机的工具调用将仅具有读取权限,除非您将HTTP_RBAC_DEFAULT_ROLE设置为writer,禁用 RBAC(HTTP_RBAC_ENABLED=false),或切换到 JWT 角色。设置HTTP_ALLOW_LOCALHOST_UNAUTHENTICATED=true后,本地主机请求将自动提升为写入权限。
- 可选的 JWT(HS*/JWKS)通过 HTTP 中间件实现;可通过设置
- 反向代理 + TLS(最小示例)
- NGINX location 块:
upstream mcp_mail { server 127.0.0.1:8765; } server { listen 443 ssl; server_name mcp.example.com; ssl_certificate /etc/letsencrypt/live/mcp.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mcp.example.com/privkey.pem; location /mcp/ { proxy_pass http://mcp_mail; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto https; } }
- NGINX location 块:
- 备份与保留
- Git 仓库和 SQLite 数据库位于
STORAGE_ROOT下;为保证一致性,请一并备份。
- Git 仓库和 SQLite 数据库位于
- 可观测性
- 在由
mcp.http_app()返回的 ASGI 层添加日志记录和指标采集(Prometheus、OpenTelemetry)。
- 在由
- 并发控制
- 归档写入:每个项目使用
.archive.lock文件,防止跨项目头部阻塞。 - 提交:仓库级别的
.commit.lock文件用于序列化 Git 索引/提交操作,以避免跨项目竞争。
- 归档写入:每个项目使用
Python 客户端示例(HTTP JSON-RPC)
为使 README 更加聚焦,本节已被移除。客户端代码示例应放在 examples/ 目录中。
故障排除
- “sender_name 未注册”
- 首先使用
register_agent或create_agent_identity创建代理,或者检查您使用的project_key是否与发送方的项目匹配。
- 首先使用
- pre-commit 钩子阻止提交
- 设置
AGENT_NAME为您的代理身份;释放或等待冲突的独占文件预留结束;检查.git/hooks/pre-commit文件。
- 设置
- 内嵌图片未成功嵌入
- 确保
convert_images=true;如果压缩后的 WebP 大小低于服务器设定的INLINE_IMAGE_MAX_BYTES阈值(默认 64KB),图片将自动内嵌。超过此大小的图片则会作为附件存储。
- 确保
- 未找到消息
- 使用
resource://message/{id}时,请确认project参数以消除歧义;每个项目的 ID 是唯一的。
- 使用
- 收件箱为空但消息存在
- 检查
since_ts、urgent_only和limit参数;确保收件人姓名完全匹配(区分大小写)。
- 检查
常见问题解答
为什么同时使用 Git 和 SQLite?
- Git 提供可供人工审计的工件和历史记录;SQLite 提供快速查询和 FTS 搜索功能。两者各有所长,互补不足。
文件预留是否强制执行?
- 是的,但可选。当
FILE_RESERVATIONS_ENFORCEMENT_ENABLED=true(默认值)时,如果邮件归档路径(agents/、messages/、attachments/)存在冲突的活动独占预留,服务器会阻止消息写入。文件预留本身是建议性的,始终会返回granted和conflicts信息。此外,可选的 pre-commit 钩子会在代码仓库提交时,针对项目文件路径进行本地强制执行。
- 是的,但可选。当
为什么只使用 HTTP?
- 可流式传输的 HTTP 是现代 MCP 的远程传输协议;避免使用额外的传输方式可以降低复杂性,并鼓励采用统一的集成路径。
为什么选择 JSON-RPC 而不是 REST 或 gRPC?
- MCP 定义了一种工具/资源方法调用模型,该模型自然映射到单个端点上的 JSON-RPC。它使客户端保持简单(一个 URL、方法名 + 参数),与代理兼容良好,且避免 SDK 锁定,同时保持语言无关性。
为什么将“资源”(读操作)与“工具”(变更操作)分开?
- 清晰的语义支持对资源进行激进的缓存和安全预取,而工具则明确表示为可审计的变更操作。这种划分还无需猜测即可实现 RBAC(只读与写入权限)。
为什么消息的规范存储在 Git 中,而不只是数据库中?
- Git 提供持久、可差异比较、可供人工审查的工件,这些工件可以克隆、分支和审计。SQLite 则提供快速索引和 FTS 功能。两者的结合在不依赖重量级消息总线的情况下,既保留了治理能力,又保证了可运维性。
为什么使用建议性文件预留而非全局锁?
- 代理之间是异步协调的;硬锁会导致队头阻塞和脆弱的故障。建议性预留能够显式地表达意图和冲突,而可选的 pre-commit 保护机制则可以在关键位置进行本地强制执行。
为什么代理名称采用形容词+名词的形式?
- 这种易于记忆的身份标识可以减少收件箱、提交日志和用户界面中的混淆。该命名方案具有较低的冲突风险,同时保持人性化(相比 GUID)并便于目录列表的预测。
为什么
project_key是绝对路径?- 使用工作区的绝对路径可以在不同 Shell 和代理之间创建稳定且不易发生冲突的项目身份。Slug 也是由此确定性地派生出来的,从而避免无意中分叉同一个项目。
为什么使用 WebP 格式的附件并支持可选内联?
- WebP 格式能够提供紧凑且高质量的图像。小尺寸的图片可以内联以提高可读性;较大的图片则作为附件存储。如果需要保留原始图片,也可以通过设置
KEEP_ORIGINAL_IMAGES=true来实现。
- WebP 格式能够提供紧凑且高质量的图像。小尺寸的图片可以内联以提高可读性;较大的图片则作为附件存储。如果需要保留原始图片,也可以通过设置
为什么同时支持静态 Bearer 令牌和 JWT/JWKS?
- 本地开发应尽量无摩擦(只需一个 Bearer 令牌)。而在生产环境中,则受益于带有角色声明的可验证 JWT、通过 JWKS 实现密钥轮换,以及分层的 RBAC。
为什么使用 SQLite FTS5 而不是外部搜索服务?
- FTS5 以最少的运维开销提供快速且相关性强的搜索功能。它是嵌入式的、可移植的,并且可以随 Git 归档一起轻松备份。如果 FTS 不可用,系统会自动降级为 SQL LIKE 查询。
为什么 LLM 的使用是可选的?
- 摘要和发现功能应起到增强作用,而不是成为核心功能的门槛。将 LLM 的使用设为可选,既能控制成本和延迟,又能在启用时提供更丰富的用户体验。
API 快速参考
工具
小贴士:若想按工作流程分组查看工具,并获取推荐的操作手册,请请求
resource://tooling/directory?format=json。 输出格式(所有工具/资源):
- 工具接受可选的
format参数,取值为json或toon;资源则接受?format=toon。 - TOON 格式返回
{format:"toon", data:"<TOON>", meta:{...}}(回退格式为{format:"json", ... , meta:{toon_error:"..."}})。 - 默认为 JSON,除非设置了
MCP_AGENT_MAIL_OUTPUT_FORMAT或TOON_DEFAULT_FORMAT。
| 名称 | 签名 | 返回值 | 备注 |
|---|---|---|---|
health_check |
health_check() |
{status, environment, http_host, http_port, database_url} |
轻量级就绪性探针 |
ensure_project |
ensure_project(human_key: str) |
{id, slug, human_key, created_at} |
幂等创建/确保项目 |
register_agent |
register_agent(project_key: str, program: str, model: str, name?: str, task_description?: str, attachments_policy?: str) |
代理档案字典 | 创建/更新代理;将档案写入 Git |
whois |
whois(project_key: str, agent_name: str, include_recent_commits?: bool, commit_limit?: int) |
代理档案字典 | 丰富的一个代理档案(可选包含最近的提交) |
create_agent_identity |
create_agent_identity(project_key: str, program: str, model: str, name_hint?: str, task_description?: str, attachments_policy?: str) |
代理档案字典 | 始终创建一个新的唯一代理 |
send_message |
send_message(project_key: str, sender_name: str, to: list[str], subject: str, body_md: str, cc?: list[str], bcc?: list[str], attachment_paths?: list[str], convert_images?: bool, importance?: str, ack_required?: bool, thread_id?: str, auto_contact_if_blocked?: bool, sender_token?: str) |
{deliveries: list, count: int, attachments?} |
写入规范邮件及收件箱/发件箱,转换图片。非绝对路径的 attachment_paths 将相对于项目归档根目录解析。 |
reply_message |
reply_message(project_key: str, message_id: int, sender_name: str, body_md: str, to?: list[str], cc?: list[str], bcc?: list[str], subject_prefix?: str, sender_token?: str) |
{thread_id, reply_to, deliveries: list, count: int, attachments?} |
保留/创建线程,继承标志位 |
request_contact |
request_contact(project_key: str, from_agent: str, to_agent: str, to_project?: str, reason?: str, ttl_seconds?: int, registration_token?: str) |
联系链接字典 | 请求与另一代理通信的权限 |
respond_contact |
respond_contact(project_key: str, to_agent: str, from_agent: str, accept: bool, from_project?: str, ttl_seconds?: int, registration_token?: str) |
联系链接字典 | 批准或拒绝联系请求 |
list_contacts |
list_contacts(project_key: str, agent_name: str, registration_token?: str) |
list[dict] |
列出带有目标项目和过期审计元数据的对外联系链接 |
set_contact_policy |
set_contact_policy(project_key: str, agent_name: str, policy: str, registration_token?: str) |
代理字典 | 设置策略:open、auto、contacts_only、block_all |
fetch_inbox |
fetch_inbox(project_key: str, agent_name: str, limit?: int, urgent_only?: bool, include_bodies?: bool, since_ts?: str, registration_token?: str) |
list[dict] |
非破坏性读取收件箱 |
mark_message_read |
mark_message_read(project_key: str, agent_name: str, message_id: int, registration_token?: str) |
{message_id, read, read_at} |
每个收件人的已读回执 |
acknowledge_message |
acknowledge_message(project_key: str, agent_name: str, message_id: int, registration_token?: str) |
{message_id, acknowledged, acknowledged_at, read_at} |
设置已确认和已读状态 |
macro_start_session |
macro_start_session(human_key: str, program: str, model: str, task_description?: str, agent_name?: str, registration_token?: str, file_reservation_paths?: list[str], file_reservation_reason?: str, file_reservation_ttl_seconds?: int, inbox_limit?: int) |
{project, agent, file_reservations, inbox} |
协调确保→注册→可选文件预留→收件箱获取流程 |
macro_prepare_thread |
macro_prepare_thread(project_key: str, thread_id: str, program: str, model: str, agent_name?: str, registration_token?: str, task_description?: str, register_if_missing?: bool, include_examples?: bool, inbox_limit?: int, include_inbox_bodies?: bool, llm_mode?: bool, llm_model?: str) |
{project, agent, thread, inbox} |
封装注册、线程摘要和收件箱上下文 |
macro_file_reservation_cycle |
macro_file_reservation_cycle(project_key: str, agent_name: str, paths: list[str], ttl_seconds?: int, exclusive?: bool, reason?: str, auto_release?: bool, registration_token?: str) |
{file_reservations, released} |
文件预留 + 可选释放围绕重点编辑块的表面区域 |
macro_contact_handshake |
`macro_contact_handshake(project_key: str, requester | agent_name: str, target | to_agent: str, to_project?: str, reason?: str, ttl_seconds?: int, auto_accept?: bool, welcome_subject?: str, welcome_body?: str, requester_registration_token?: str, target_registration_token?: str)` |
search_messages |
search_messages(project_key: str, query: str, limit?: int, agent_name?: str, registration_token?: str) |
list[dict] |
FTS5 搜索(bm25),范围限定在认证代理可见的消息内 |
summarize_thread |
summarize_thread(project_key: str, thread_id: str, include_examples?: bool, llm_mode?: bool, llm_model?: str, per_thread_limit?: int, agent_name?: str, registration_token?: str) |
单线程:{thread_id, summary, examples} 多线程(逗号分隔):{threads[], aggregate} |
提取参与者、关键点和行动。使用逗号分隔的线程 ID 获取多线程摘要。 |
install_precommit_guard |
install_precommit_guard(project_key: str, code_repo_path: str) |
{hook} |
在目标仓库中安装 Git 预提交保护钩子 |
uninstall_precommit_guard |
uninstall_precommit_guard(code_repo_path: str) |
{removed} |
从仓库中移除保护钩子 |
file_reservation_paths |
file_reservation_paths(project_key: str, agent_name: str, paths: list[str], ttl_seconds?: int, exclusive?: bool, reason?: str, registration_token?: str) |
{granted: list, conflicts: list} |
咨询性租约;每条路径对应一个 Git 工件 |
release_file_reservations |
release_file_reservations(project_key: str, agent_name: str, paths?: list[str], file_reservation_ids?: list[int], registration_token?: str) |
{released, released_at} |
释放代理当前持有的文件预留 |
force_release_file_reservation |
force_release_file_reservation(project_key: str, agent_name: str, file_reservation_id: int, notify_previous?: bool, note?: str, registration_token?: str) |
{released, released_at, reservation} |
使用不活跃/邮件/文件系统/Git 的启发式方法清除过时的预留,并通知前一位持有者 |
renew_file_reservations |
renew_file_reservations(project_key: str, agent_name: str, extend_seconds?: int, paths?: list[str], file_reservation_ids?: list[int], registration_token?: str) |
{renewed, file reservations[]} |
延长现有文件预留的 TTL |
资源
输出格式(资源):
- 在任何资源 URI 后附加
?format=toon即可接收{format:"toon", data:"<TOON>", meta:{...}}。 - 所有资源都将
format声明为可选查询参数(FastMCP 模板接受该参数)。 - 对于没有可变路径参数的资源(如
resource://tooling/projects),请包含?format=json或?format=toon。 - 默认为 JSON,除非设置了
MCP_AGENT_MAIL_OUTPUT_FORMAT或TOON_DEFAULT_FORMAT。
| URI | 参数 | 返回值 | 备注 |
|---|---|---|---|
resource://config/environment{?format} |
— | {environment, database_url, http} |
检查服务器设置 |
resource://tooling/directory{?format} |
— | {generated_at, metrics_uri, clusters[], playbooks[]} |
分组工具目录 + 工作流 playbook |
resource://tooling/schemas{?format} |
— | {tools: {<name>: {required[], optional[], aliases{}}}} |
工具参数提示 |
resource://tooling/metrics{?format} |
— | {generated_at, tools[]} |
每个工具的聚合调用/错误计数 |
resource://tooling/locks{?format} |
— | {locks[], summary} |
当前锁定及其所有者(仅用于调试)。类别:archive(每个项目 .archive.lock)和 custom(例如仓库 .commit.lock)。 |
resource://tooling/capabilities/{agent}{?project} |
列出 | {generated_at, agent, project, capabilities[]} |
分配给代理的能力(参见 deploy/capabilities/agent_capabilities.json) |
resource://tooling/recent/{window_seconds}{?agent,project} |
列出 | {generated_at, window_seconds, count, entries[]} |
按代理/项目筛选的近期工具使用情况 |
resource://tooling/projects{?format} |
— | list[project] |
所有项目 |
resource://project/{slug} |
slug |
{project..., agents[]} |
项目详情 + 代理 |
resource://file_reservations/{slug}{?active_only} |
slug, active_only? |
list[file reservation] |
文件预订及过时元数据(启发式、上次活动时间戳) |
resource://message/{id}{?project,agent,agent_token} |
id, project, agent?, agent_token? |
message |
包含正文的单条消息;除非当前 MCP 会话已为该项目认证,否则需提供代理身份验证 |
resource://thread/{thread_id}{?project,agent,agent_token,include_bodies} |
thread_id, project, agent?, agent_token?, include_bodies? |
{project, thread_id, messages[]} |
针对已认证查看者的线程列表 |
resource://inbox/{agent}{?project,since_ts,urgent_only,include_bodies,limit,agent_token} |
列出 | {project, agent, count, messages[]} |
收件箱列表 |
resource://mailbox/{agent}{?project,limit,agent_token} |
project, limit, agent_token? |
{project, agent, count, messages[]} |
邮箱列表 |
resource://mailbox-with-commits/{agent}{?project,limit,agent_token} |
project, limit, agent_token? |
{project, agent, count, messages[]} |
丰富了提交元数据的邮箱列表 |
resource://outbox/{agent}{?project,limit,include_bodies,since_ts,agent_token} |
列出 | {project, agent, count, messages[]} |
代理发送的消息 |
resource://views/acks-stale/{agent}{?project,ttl_seconds,limit,agent_token} |
列出 | {project, agent, ttl_seconds, count, messages[]} |
超过 TTL 仍未确认的待确认消息 |
resource://views/urgent-unread/{agent}{?project,limit,agent_token} |
列出 | {project, agent, count, messages[]} |
尚未阅读的高优先级/紧急消息 |
resource://views/ack-required/{agent}{?project,limit,agent_token} |
列出 | {project, agent, count, messages[]} |
代理待处理的确认事项 |
resource://views/ack-overdue/{agent}{?project,ttl_minutes,limit,agent_token} |
列出 | {project, agent, ttl_minutes, count, messages[]} |
超过 TTL 仍未确认的待确认消息 |
客户端集成指南
- 首先获取引导元数据。 在向代理展示工具之前,先发出
resources/read请求以获取resource://tooling/directory?format=json(并可选地获取resource://tooling/metrics?format=json)。使用返回的集群和 playbook 来呈现当前工作流所需的精简工具集,而不是将所有操作直接暴露在 UI 中。 - 按工作流划分工具范围。 当代理进入新阶段(例如“消息生命周期”)时,在您的 MCP 客户端中仅加载该集群的工具。这与已提供的工作流宏保持一致,避免“工具过载”。
- 监控实际使用情况。 定期拉取或订阅由服务器发出的包含
tool_metrics_snapshot事件的日志流(或查询resource://tooling/metrics?format=json),以便检测高错误率的工具,并决定是否需要提供宏或额外指导。 - 对于小型模型,回退到宏。 如果您正在将任务路由到轻量级模型,请优先使用宏助手(
macro_start_session、macro_prepare_thread、macro_file_reservation_cycle、macro_contact_handshake),并在代理明确要求之前隐藏细粒度的操作。 - 显示最近的操作。 读取
resource://tooling/recent/60?agent=<name>&project=<slug>(可根据需要调整窗口大小),以显示与代理/项目相关的最近几次成功工具调用。
有关应用上述指南的可运行参考实现,请参阅 examples/client_bootstrap.py。
{
"steps": [
"resources/read -> resource://tooling/directory?format=json",
"选择活跃集群(例如消息传递)",
"挂载集群.tools中列出的工具以及宏(如果模型规模≤S)",
"可选:resources/read -> resource://tooling/metrics?format=json 用于仪表盘显示",
"可选:resources/read -> resource://tooling/recent/60?agent=<name>&project=<slug> 用于 UI 提示"
]
}
监控与告警
- 启用指标输出。 设置
TOOL_METRICS_EMIT_ENABLED=true,并选择一个间隔(例如TOOL_METRICS_EMIT_INTERVAL_SECONDS=120是一个不错的起点)。服务器会定期发出一条结构化日志条目,如下所示:
{
"event": "tool_metrics_snapshot",
"tools": [
{"name": "send_message", "cluster": "messaging", "calls": 42, "errors": 1},
{"name": "file_reservation_paths", "cluster": "file reservations", "calls": 11, "errors": 0}
]
}
- 传输日志。 将结构化的日志流(stderr/stdout 或 JSON 日志文件)转发到你的可观测性堆栈中(例如 Loki、Datadog、Elastic),并解析
tools[]数组。 - 对异常情况发出告警。 创建一条规则,当任何工具的
errors / calls比率超过某个阈值时触发告警(例如在 5 分钟窗口内超过 5%),以便你可以决定是否公开宏命令或改进文档。 - 仪表板展示集群数据。 按照
cluster进行分组,查看代理程序主要在哪些任务上花费时间,以及哪些工作流可能需要额外的宏命令或约束机制。
有关详细步骤,请参阅 docs/observability.md 中的分步指南(包含 Loki/Prometheus 示例管道),以及 docs/GUIDE_TO_OPTIMAL_MCP_SERVER_DESIGN.md 中涵盖工具管理、功能控制、安全性和可观测性最佳实践的全面设计指南。
运维团队可以参考 docs/operations_alignment_checklist.md,其中链接到了 deploy/capabilities/ 中的功能模板,以及 deploy/observability/ 中的 Prometheus 告警规则示例。
部署快速提示
- 直接使用 uvicorn:
uvicorn mcp_agent_mail.http:build_http_app --factory --host 0.0.0.0 --port 8765 - Python 模块:
python -m mcp_agent_mail.http --host 0.0.0.0 --port 8765 - Gunicorn:
gunicorn -c deploy/gunicorn.conf.py mcp_agent_mail.http:build_http_app --factory - Docker:
docker compose up --build
CI/CD
- 代码风格检查与类型检查 CI:GitHub Actions 工作流会在 main/develop 分支的推送和 PR 上运行 Ruff 和 Ty。
- 发布:推送类似
v0.1.0的标签会构建并推送多架构 Docker 镜像至 GHCR,路径为ghcr.io/<owner>/<repo>,同时打上latest和版本标签。 - 夜间构建:定时工作流每天运行数据库迁移,并列出项目以实现轻量级的维护可见性。
日志轮转(可选)
如果不使用 journald,可在 deploy/logrotate/mcp-agent-mail 中找到示例 logrotate 配置文件,用于每周轮转 /var/log/mcp-agent-mail/*.log 文件,保留 7 个历史版本。
日志记录(journald vs 文件)
- 默认的 systemd 单元文件(
deploy/systemd/mcp-agent-mail.service)配置为将日志发送至 journald(StandardOutput/StandardError=journal)。 - 如果需要文件日志,请配置进程管理器将日志写入
/var/log/mcp-agent-mail/*.log,并安装提供的 logrotate 配置。 - systemd 的环境变量文件路径为
/etc/mcp-agent-mail.env(参见deploy/systemd/mcp-agent-mail.service)。
容器镜像构建与多架构推送
使用 Docker Buildx 构建多架构镜像。示例流程如下:
# 创建并选择构建器(只需执行一次)
docker buildx create --use --name mcp-builder || docker buildx use mcp-builder
# 在本地构建并测试(linux/amd64)
docker buildx build --load -t your-registry/mcp-agent-mail:dev .
# 多架构构建并推送(amd64、arm64)
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t your-registry/mcp-agent-mail:latest \
-t your-registry/mcp-agent-mail:v0.1.0 \
--push .
推荐标签:使用动态的 latest 标签,以及每次发布时固定的版本标签。请确保已配置好镜像仓库登录信息(docker login)。
systemd 手动部署步骤
- 将项目文件复制到
/opt/mcp-agent-mail,并确保权限正确(所有者为appuser)。 - 根据
deploy/env/production.env将环境变量文件放置于/etc/mcp-agent-mail.env。 - 将服务文件
deploy/systemd/mcp-agent-mail.service安装至/etc/systemd/system/。 - 重新加载 systemd 并启动:
sudo systemctl daemon-reload
sudo systemctl enable mcp-agent-mail
sudo systemctl start mcp-agent-mail
sudo systemctl status mcp-agent-mail
可选(非 journald 日志轮转):将 deploy/logrotate/mcp-agent-mail 安装至 /etc/logrotate.d/,并通过进程管理器或应用配置将日志写入 /var/log/mcp-agent-mail/*.log。
有关 Gunicorn 的初始配置,请参阅 deploy/gunicorn.conf.py。如需了解项目方向及规划内容,请阅读 project_idea_and_guide.md。
CLI 命令
该项目为常见操作提供了一个开发者 CLI:
serve-http:运行 HTTP 传输(仅支持流式 HTTP)migrate:确保模式和 FTS 结构存在lint/typecheck:开发者辅助工具list-projects [--include-agents]:枚举项目guard install <project_key> <code_repo_path>:将预提交守护程序安装到代码仓库中guard uninstall <code_repo_path>:从代码仓库中移除守护程序share wizard:启动交互式部署向导(自动安装 CLI、认证、导出并部署至 GitHub Pages 或 Cloudflare Pages)share export --output <path> [options]:将邮箱导出为静态 HTML 包(完整选项请参阅“静态邮箱导出”部分)share update <bundle_path> [options]:使用记录的(或覆盖的)导出设置刷新现有包share preview <bundle_path> [--port N] [--open-browser]:在本地服务一个静态包以便检查share verify <bundle_path> [--public-key <key>]:验证包的完整性(SRI 哈希值和 Ed25519 签名)share decrypt <encrypted_path> [--identity <file> | --passphrase]:解密 Age 加密的包config set-port <port>:更改 HTTP 服务器端口(更新 .env 文件)config show-port:显示当前配置的 HTTP 端口clear-and-reset-everything [--force] [--archive/--no-archive]:删除 SQLite 数据库(包括 WAL/SHM),并在可选保存恢复点后清空STORAGE_ROOT下的所有内容。若不加标志,则会先提示创建归档;--force --no-archive则跳过所有提示以供自动化使用。list-acks --project <key> --agent <name> [--limit N]:列出某个代理缺失确认的消息acks pending <project> <agent> [--limit N]:显示某个代理的待处理确认acks remind <project> <agent> [--min-age-minutes N] [--limit N]:突出显示超过阈值时间的待处理 ACKacks overdue <project> <agent> [--ttl-minutes N] [--limit N]:列出超出 TTL 的逾期 ACKfile_reservations list <project> [--active-only/--no-active-only]:列出文件预留file_reservations active <project> [--limit N]:列出活跃的文件预留file_reservations soon <project> [--minutes N]:显示即将到期的文件预留doctor check [PROJECT] [--verbose] [--json]:对邮箱健康进行全面诊断doctor repair [PROJECT] [--dry-run] [--yes] [--backup-dir PATH]:半自动修复,更改前会先备份doctor backups [--json]:列出可用的诊断备份doctor restore <backup_path> [--dry-run] [--yes]:从诊断备份中恢复
示例:
# 交互式向导:导出并部署至 GitHub Pages(最简单)
./scripts/share_to_github_pages.py
# 使用签名和加密导出静态包
uv run python -m mcp_agent_mail.cli share export \
--output ./bundle \
--signing-key ./keys/signing.key \
--age-recipient age1abc...xyz
# 在本地预览包
uv run python -m mcp_agent_mail.cli share preview ./bundle --port 9000 --open-browser
# 验证包的完整性
uv run python -m mcp_agent_mail.cli share verify ./bundle
# 使用记录的设置原地刷新现有包
uv run python -m mcp_agent_mail.cli share update ./bundle
# 更改服务器端口
uv run python -m mcp_agent_mail.cli config set-port 9000
# 将守护程序安装到代码仓库中
uv run python -m mcp_agent_mail.cli guard install /abs/path/backend /abs/path/backend
# 列出某个代理的待处理确认
uv run python -m mcp_agent_mail.cli acks pending /abs/path/backend BlueLake --limit 10
# 运行邮箱健康诊断
uv run python -m mcp_agent_mail.cli doctor check
# 预览修复而不实际更改
uv run python -m mcp_agent_mail.cli doctor repair --dry-run
# 执行修复(先创建备份,并提示是否进行数据更改)
uv run python -m mcp_agent_mail.cli doctor repair
# 列出可用的备份
uv run python -m mcp_agent_mail.cli doctor backups
# 从备份中恢复
uv run python -m mcp_agent_mail.cli doctor restore /path/to/backup --dry-run
# 警告:破坏性重置(全新开始)
uv run python -m mcp_agent_mail.cli clear-and-reset-everything --force
客户端集成
使用自动化安装程序可自动连接支持的工具(例如 Claude Code、Cline、Windsurf、OpenCode)。运行 scripts/automatically_detect_all_installed_coding_agents_and_install_mcp_agent_mail_in_all.sh 或上述快速入门中的单行命令。
工具专用集成脚本
对于手动集成或自定义,提供了专用脚本:
| 工具 | 脚本 | 配置内容 |
|---|---|---|
| Claude Code | scripts/integrate_claude_code.sh |
.claude/settings.json、钩子、MCP 服务器 |
| Codex CLI | scripts/integrate_codex_cli.sh |
~/.codex/config.toml、MCP 服务器、通知处理器 |
| Gemini CLI | scripts/integrate_gemini_cli.sh |
~/.gemini/settings.json、MCP 服务器、钩子 |
| Factory Droid | scripts/integrate_factory_droid.sh |
~/.factory/settings.json、MCP 服务器、钩子 |
每个脚本:
- 从您的设置中检测 MCP 服务器端点
- 生成或重复使用用于身份验证的 Bearer 令牌
- 配置与 MCP 服务器的连接
- 安装用于收件箱提醒的钩子/通知处理器
- 在服务器上引导您的项目和代理身份
自动收件箱提醒
代理们常常专注于工作而忘记查看邮件。集成脚本会安装轻量级钩子,定期提醒代理有未读消息。
工作原理:
- 一个限速的钩子脚本(
scripts/hooks/check_inbox.sh)会在某些工具调用后运行 - 它通过快速的 curl 请求检查收件箱(避免 Python 导入开销)
- 如果有未读消息,它会输出简短的提醒
- 限速为每 2 分钟最多一次,以避免过多干扰
Claude Code / Gemini CLI:
该钩子被配置为 PostToolUse 钩子,在 Bash 或 shell 工具调用后触发:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "...check_inbox.sh" }]
}
]
}
}
Codex CLI:
使用 config.toml 中的顶级 notify 配置(必须出现在任何 [section] 标题之前),在 agent-turn-complete 事件时触发:
notify = ["/path/to/.codex/hooks/notify_wrapper.sh"]
额外钩子(仅适用于 Claude Code):
| 事件 | 作用 |
|---|---|
SessionStart |
显示活跃的文件预留和待处理确认 |
PreToolUse(编辑) |
提醒文件预留将在 10 分钟内到期 |
PostToolUse(send_message) |
列出最近的确认请求 |
PostToolUse(file_reservation_paths) |
显示当前的文件预留 |
钩子使用的环境变量
收件箱检查钩子接受以下环境变量(由集成脚本自动设置):
| 变量 | 描述 | 默认值 |
|---|---|---|
AGENT_MAIL_PROJECT |
项目键(绝对路径) | 必填 |
AGENT_MAIL_AGENT |
代理名称 | 必填 |
AGENT_MAIL_URL |
服务器 URL | http://127.0.0.1:8765/mcp/ |
AGENT_MAIL_TOKEN |
Bearer 令牌 | 无 |
AGENT_MAIL_INTERVAL |
检查间隔秒数 | 120 |
关于贡献:请不要误会,我目前不接受任何外部对我项目的贡献。我实在没有足够的精力去评审这些内容,而且这些项目都以我的名义发布,因此如果出现问题,责任也在我。从我的角度来看,这种风险与收益极不对称。此外,我还得考虑其他“利益相关方”的意见,而我开发的这些工具大多是为我自己免费制作的,这样做并不明智。当然,你仍然可以提交问题,甚至提出修复建议的拉取请求,但我不会直接合并它们。相反,我会让 Claude 或 Codex 通过
gh工具来审查这些提交,并独立决定是否以及如何处理这些问题。尤其是漏洞报告,我们非常欢迎。如果这让你感到不适,我深表歉意,但我的初衷只是避免大家浪费时间,同时也避免产生不必要的误会。我明白这与当前倡导社区贡献的开源精神并不一致,但这是我能够保持现有开发速度并维持心理健康的方式。
版本历史
v0.3.22026/04/16v0.3.02026/01/07v0.2.12026/01/06v0.2.02026/01/06v0.1.52026/01/04v0.1.42026/01/04v0.1.32025/12/31v0.1.22025/12/31v0.1.12025/12/31常见问题
相似工具推荐
openclaw
OpenClaw 是一款专为个人打造的本地化 AI 助手,旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚,能够直接接入你日常使用的各类通讯渠道,包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息,OpenClaw 都能即时响应,甚至支持在 macOS、iOS 和 Android 设备上进行语音交互,并提供实时的画布渲染功能供你操控。 这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地,用户无需依赖云端服务即可享受快速、私密的智能辅助,真正实现了“你的数据,你做主”。其独特的技术亮点在于强大的网关架构,将控制平面与核心助手分离,确保跨平台通信的流畅性与扩展性。 OpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者,以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力(支持 macOS、Linux 及 Windows WSL2),即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你
n8n
n8n 是一款面向技术团队的公平代码(fair-code)工作流自动化平台,旨在让用户在享受低代码快速构建便利的同时,保留编写自定义代码的灵活性。它主要解决了传统自动化工具要么过于封闭难以扩展、要么完全依赖手写代码效率低下的痛点,帮助用户轻松连接 400 多种应用与服务,实现复杂业务流程的自动化。 n8n 特别适合开发者、工程师以及具备一定技术背景的业务人员使用。其核心亮点在于“按需编码”:既可以通过直观的可视化界面拖拽节点搭建流程,也能随时插入 JavaScript 或 Python 代码、调用 npm 包来处理复杂逻辑。此外,n8n 原生集成了基于 LangChain 的 AI 能力,支持用户利用自有数据和模型构建智能体工作流。在部署方面,n8n 提供极高的自由度,支持完全自托管以保障数据隐私和控制权,也提供云端服务选项。凭借活跃的社区生态和数百个现成模板,n8n 让构建强大且可控的自动化系统变得简单高效。
AutoGPT
AutoGPT 是一个旨在让每个人都能轻松使用和构建 AI 的强大平台,核心功能是帮助用户创建、部署和管理能够自动执行复杂任务的连续型 AI 智能体。它解决了传统 AI 应用中需要频繁人工干预、难以自动化长流程工作的痛点,让用户只需设定目标,AI 即可自主规划步骤、调用工具并持续运行直至完成任务。 无论是开发者、研究人员,还是希望提升工作效率的普通用户,都能从 AutoGPT 中受益。开发者可利用其低代码界面快速定制专属智能体;研究人员能基于开源架构探索多智能体协作机制;而非技术背景用户也可直接选用预置的智能体模板,立即投入实际工作场景。 AutoGPT 的技术亮点在于其模块化“积木式”工作流设计——用户通过连接功能块即可构建复杂逻辑,每个块负责单一动作,灵活且易于调试。同时,平台支持本地自托管与云端部署两种模式,兼顾数据隐私与使用便捷性。配合完善的文档和一键安装脚本,即使是初次接触的用户也能在几分钟内启动自己的第一个 AI 智能体。AutoGPT 正致力于降低 AI 应用门槛,让人人都能成为 AI 的创造者与受益者。
stable-diffusion-webui
stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。
everything-claude-code
everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上
opencode
OpenCode 是一款开源的 AI 编程助手(Coding Agent),旨在像一位智能搭档一样融入您的开发流程。它不仅仅是一个代码补全插件,而是一个能够理解项目上下文、自主规划任务并执行复杂编码操作的智能体。无论是生成全新功能、重构现有代码,还是排查难以定位的 Bug,OpenCode 都能通过自然语言交互高效完成,显著减少开发者在重复性劳动和上下文切换上的时间消耗。 这款工具专为软件开发者、工程师及技术研究人员设计,特别适合希望利用大模型能力来提升编码效率、加速原型开发或处理遗留代码维护的专业人群。其核心亮点在于完全开源的架构,这意味着用户可以审查代码逻辑、自定义行为策略,甚至私有化部署以保障数据安全,彻底打破了传统闭源 AI 助手的“黑盒”限制。 在技术体验上,OpenCode 提供了灵活的终端界面(Terminal UI)和正在测试中的桌面应用程序,支持 macOS、Windows 及 Linux 全平台。它兼容多种包管理工具,安装便捷,并能无缝集成到现有的开发环境中。无论您是追求极致控制权的资深极客,还是渴望提升产出的独立开发者,OpenCode 都提供了一个透明、可信