mcpField
R
RadMail — the email operating system for agents

RadMail — the email operating system for agents

远程服务
radmail.ai通信协作02 天前更新

关于 RadMail — the email operating system for agents

RadMail 是供 Agent 使用的 MCP 邮件服务,支持收件箱分流、承诺跟踪和回复起草。代码级硬性拦截会对资金、银行信息变更、首次联系、决策及提示词注入情形拒绝生成草稿;托管端点不提供发送工具。

主要功能

  1. 01按紧急度和重要性整理邮件
  2. 02跟踪未完成承诺及期限
  3. 03搜索并读取邮件和会话
  4. 04为符合条件的邮件起草回复
  5. 05对硬性拦截情形不生成草稿
  6. 06检查域名 SPF、DKIM 和 DMARC

适用场景

  1. 01识别需要关注的紧急邮件
  2. 02跟踪承诺及其截止时间
  3. 03按发件人或主题查找邮件
  4. 04准备供人工审核的回复

MCP 相关

向 MCP Agent 提供邮件分流、搜索、读取、承诺跟踪和草稿工具。托管服务不提供发送工具;代码会阻止为指定高风险邮件类别生成草稿。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://radmail.ai/api/mcp/sandbox
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

安装包
npmradmail-mcp0.5.0

工具

6

此工具无需参数。

详细介绍

RadMail MCP

面向 Agent 的电子邮件操作系统——拒绝机制值得信赖。

2026 年,每个收件箱都接入了 AI。没有哪个可以放心让它点下 发送。RadMail 可以——因为重大操作会以与模型无关的方式,在代码中拒绝执行:资金、银行信息变更、首次联系的发件人、决策和提示词注入都永远只能由人工处理。任何提示词都无法说服 RadMail 自动发送这类邮件。

这是一个模型上下文协议(MCP)服务,因此任何 AI Agent 都能使用这个收件箱。

如果一组 MCP Agent 在你坐镇决策席时负责执行,那么收件箱就是最需要先设置硬性停止机制的地方。 社会工程欺诈可能诱使你进行电汇或更改银行信息,这些操作一旦执行便无法撤销——而能点击发送的自主流程也可能被诱导造成损失。RadMail 让 Agent 处理收件箱的日常工作(分类、即时处理队列、承诺跟踪、起草邮件),同时让资金、银行信息变更、首次联系、决策和提示词注入从设计上就只能由人工处理,而不是依赖 Agent 可能被说服放弃的策略。这正是公司收件箱能够委托处理的前提。

为什么连草稿也不提供,而不只是禁止发送

询问这一类产品如何确保人在环路中,公开的答案通常是草稿:Agent 撰写邮件,由人工审批,不会自动发送。对于普通邮件,这种设计是正确的,RadMail 也正是这样做的——draft_reply 会返回一段供人审核并发送的文本,而托管版根本不提供发送工具。

对于五类情况,RadMail 会采取更严格的措施,这也是整个产品的核心:资金、银行信息变更、首次联系、决策和提示词注入都不会生成草稿。 对于更改电汇信息的邮件线程,草稿并非安全保障——它是攻击的最后一步。商业电子邮件入侵并不会在发送按钮处失败;它会在审批按钮处得逞:把一封看似可信、措辞得体的回复摆在忙碌的人面前,让对方只需点头同意。递上一封预先写好的回复,会让审批变得比阅读更容易。因此,RadMail 会扣下草稿,只把邮件内容和相关信号交给你,由人来撰写回复。

这两个方面都可以通过实际运行验证,无需账户——运行以下两条命令并比较:

# Ordinary mail: a draft comes back.
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"draft_reply","arguments":{"from":"[email protected]","subject":"Re: the deck","body":"Can you send me the updated deck by Thursday?","knownSender":true}}}' | npx -y radmail-mcp

# A banking change: no draft comes back.
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"draft_reply","arguments":{"from":"[email protected]","subject":"Updated wire instructions","body":"Our bank details changed. Remit the $48,200 to the new account by Friday.","knownSender":true}}}' | npx -y radmail-mcp

这两条命令均于 2026-10-14 按原样对已发布的软件包运行。第一条会返回草稿,以及 "mcpEnforcement": "No hard-stop. Still a DRAFT — the MCP surface never sends mail."。第二条会返回 "draft": null、"hardStop": "changed-banking" 和 "mcpEnforcement": "HARD-STOP (changed-banking). No draft offered — human-only forever (BEC defense)."。注意第二条仍会提供什么:提取出的承诺和原因,均带有污染标记——被扣下的是拟议回复,而不是信息。

这五类情况以 draftRefusalClasses 的形式发布在契约中,拒绝机制只会逐步收紧,绝不会放宽。

坦率说明代价。 对于你最希望有人代劳的邮件,这种体验恰恰会更差。如果凌晨 2 点收到更改电汇信息的通知,而你希望有一封回复等着审批,RadMail 不会提供任何待你审批的内容——这是有意为之。这种取舍就是产品本身。如果你需要每个邮件线程都有一封可以直接审批的回复,包括涉及资金变动的邮件,那么采用“起草并审批”模式的服务才是合适的工具,而 RadMail 并不适合。

一次调用即可开始

调用 triage_inbox,并省略令牌——RadMail 会自动为你创建一个免费沙盒租户,并在一次往返中返回可用的分类结果。重复使用返回的令牌。(在零身份验证的托管沙盒中,triage_inbox 无需参数——它会对内置演示收件箱进行分类,因此首次调用就能返回完整的核心功能。)

此服务运行的是沙盒引擎(启发式、内存运行、免费、无需凭证)。它确实可以运行——但并非生产环境中“99%”的引擎。

工具

工具功能
triage_inbox对一批邮件进行一次往返处理:即时处理队列 + 所有未完成承诺 + 所有硬性拦截项。一次调用即可处理整个范围。
list_right_now仅列出不可错过的队列——按最新 × 最重要排序,每项均说明出现原因。为沙盒传入 messages(包含硬性拦截标记),或设置 RADMAIL_API_KEY 后省略该参数,以查看你的真实即时处理队列(只读)。
why_surfaced用通俗语言说明邮件为何出现——以及决定其重要性 × 紧迫性的信号。透明可见,而非黑箱。
draft_reply起草用于履行承诺的回复——绝不用于硬性拦截的邮件(金钱 / 银行业务 / 首次联系仅限人工处理)。
list_commitments列出未完成的承诺及其截止时间范围。为沙盒传入 messages 以提取承诺,或设置 RADMAIL_API_KEY 后省略该参数,以查看你真实追踪的承诺(只读)。
search按发件人 / 主题 / 内容查找你要找的邮件——按相关性最高、最新优先排序(不使用文件系统 grep)。为沙盒传入 messages,或设置 RADMAIL_API_KEY 后省略该参数,以搜索你的真实收件箱(只读)。
read_email**仅限连接模式:**通过 RadMail 的 id,从你的真实收件箱获取一封完整邮件(邮件头 + textBody + 附件名称);返回 rfcMessageId,即回复时用于建立邮件线程的 RFC 5322 Message-ID。只读;正文内容会带有污染标记。
read_thread**仅限连接模式:**按 threadId 获取一个对话线程——包含该线程及其中收到的邮件,按时间从早到晚排列,每封邮件均带有 id、rfcMessageId 和 inReplyTo。仅元数据;coverage 会说明省略了哪些内容。只读。
list_emails**仅限连接模式:**列出你的真实收件箱,按最新优先排序,仅包含元数据,并提供用于轮询的 since 和 nextCursor。如果 RadMail 部署版本过旧,无法遵守 since / cursor,则会安全失败。只读。
list_prepared_drafts**仅限连接模式:**列出 RadMail 自带 AI 准备的回复草稿(可选指定一个 emailId)。只读——RadMail 绝不会自行发送准备好的草稿。
list_watched_threads**仅限连接模式:**列出你关注的线程,显示最后发言者(me_last / them_last / unknown)以及 stalled 标记。只读。
get_attachment**仅限连接模式:**将真实邮件中的一个附件保存到 RADMAIL_ATTACHMENT_DIR,并返回其路径。只读;服务器会决定是否允许提供该文件(密钥范围、邮箱、发件人允许列表、大小上限)。
check_send_domain无需身份验证,适用于任何域名:只读检查 SPF / DKIM / DMARC 健康状况(判定结果 + 原始记录 + 通俗建议)。会探测常见的 DKIM 选择器(default、google、resend、sendgrid、mail、k1、s1、s2)。只读 DNS——无需密钥,也不具备发送能力。
check_before_send仅限连接模式:询问 RadMail,你的 Agent 是否可以通过自己的服务提供商发送某封邮件——返回 pass / review / human_only 及原因——但不会发送邮件。不会发送或存储任何内容。human_only 表示由用户通过自己的邮箱发送,或直接丢弃;review 表示先展示给负责人;pass 表示未匹配到已知风险模式,而非审核通过。任何未返回判定结果的答复(检查已关闭、密钥被拒绝、超时)都会返回 checked: false、verdict: null——表示未检查,绝不表示通过。需要一个未限制为单个邮箱的密钥。请参阅检查 Agent 自行发送的邮件。
triage为单封邮件评分(triage_inbox 的单邮件形式)。
provision_sandbox明确创建一个免费沙盒租户。
report_need / request_capability告诉 RadMail 哪些操作不顺手 / 你希望具备哪些功能——服务界面会随之调整。
radmail_learning_insightsRadMail 对你工作方式的了解。
两个可选功能只会在本地服务上添加工具,绝不会在托管服务上添加:send_email(参见 可选功能:发送邮件),以及五个收件箱操作——archive_email、snooze_email、mark_read、label_email、act_on_emails(参见 可选功能:收件箱操作)。每个已连接的读取工具都标注为 readOnlyHint: true——但 get_attachment 除外,它会在本地机器上写入文件,因此不带只读声明。这些标注位于冻结清单中,因此修改任何一项都会像修改描述一样导致启动检查失败。
“有多少个工具?”——以及更重要的第二个数字

电子邮件 MCP 服务的公开汇总通常会引用工具数量来衡量功能深度。工具数量衡量的是覆盖范围,而非判断能力——对于一个被授予收件箱访问权限的服务,真正有用的是第二个数字:这些工具中,有多少个可以发送邮件?

RadMail 会同时公布这两个数字,并将其作为可复现的定期观测结果;你可以针对任何 MCP 服务(包括本服务)复现这些结果:

层级工具数可发送邮件的工具
无需身份验证的托管沙盒(https://radmail.ai/api/mcp/sandbox)60
此软件包的 0.6.0 默认配置(也是此软件包的托管 /api/mcp,无论是否携带 bearer)190
…启用 RADMAIL_SEND_TOOL=1(仅限本地 stdio)201——send_email,它会将邮件交给 RadMail 的出站关卡,且无法解除拦截
…启用可选收件箱操作(仅限本地 stdio)240——新增的五个工具会更改收件箱状态(归档、延后、已读状态、标签);没有任何一个会发送、移至垃圾箱或删除邮件

第 1 行是 2026-10-09 的观测结果;第 2 至 4 行摘自此代码库在 0.6.0 版本中的冻结清单(2026-10-26),该版本尚未发布到 npm——已发布的 0.5.0 早于 send_email、收件箱操作、check_before_send 和 0.6.0 的读取工具。按照 连接前验证 中的 tools/list 命令复现第 1 行。第 2 行可从冻结清单中复现——服务拒绝偏离的正是这套工具范围(src/send-tool-manifest.ts 和 src/triage-tool-manifest.ts 存放可选功能对应的条目):

node -e 'const s=require("fs").readFileSync("src/tool-manifest.ts","utf8");
const n=[...s.matchAll(/"name": "([a-z_]+)"/g)].map(m=>m[1]);
console.log(n.length, n.join(" "))'

⚠️ **需要坦诚说明一个注意事项,因为简单的检查方式会得出错误结论:**在该列表中搜索 send 会匹配到 check_send_domain,它是通过 DNS 对 SPF/DKIM/DMARC 进行只读查询的工具——它会读取域名已发布的记录,不会发送任何内容;还会匹配到 check_before_send,它会询问 RadMail 是否应该发送某条消息,同样不会发送任何内容。请阅读每个工具的描述,而不只是看名称。无论你评估的是哪个服务,这一点都适用,并非仅针对本服务。

重点在于这个比例,但它并非对其他服务的评判。 对于本来就应该发送邮件的 Agent 来说,覆盖广且能发送邮件的工具范围是合理的设计,而此类别中的大多数产品正是为这类任务构建的。但对于某一类电子邮件来说,这种设计并不合适:在这种场景下,被说服去发送邮件本身就是整个攻击过程。RadMail 表示,所有托管端点都不提供可发送邮件的工具——为何这是 capability-absent(能力不存在),而不是某人可以切换的设置,请参见 安全契约。

这属于哪一种形态?(第四种——而且这种差异正是产品本身)

已发布的这一类别盘点通常会将电子邮件 MCP 服务归为大致三种形态:

  1. 面向应用的事务性/生命周期邮件发送——送达率、模板、日志、域名管理。
  2. 由 Agent 拥有的收件箱——Agent 拥有自己的地址,并端到端地接收、整理邮件会话和回复邮件。
  3. 通过 OAuth 访问用户已有的邮箱——读取和撰写用户真实的 Gmail 或 Outlook 邮件。

RadMail 并不完全属于上述任何一种形态,这就是为什么基于这些形态编写的盘点无处安放它。它属于第四种:在仍属于用户的邮箱之上提供分拣和后续跟进功能。Agent 可以排序、解释、跟踪承诺并起草邮件;发送则由用户掌控。

这是一条边界,而不是功能列表,因此可以验证——不需要账号,大约一分钟即可完成:

  • **邮箱不归 Agent 所有。**托管端点不接受凭据,只提供固定的演示收件箱。形态 2 需要 Agent 拥有自己的地址;形态 3 需要你的 OAuth 授权。评估 RadMail 时,两者都不需要。
  • **连接模式默认只读。**设置 RADMAIL_API_KEY 后,已连接的工具(search、read_email、read_thread、list_emails、list_right_now、list_commitments、list_prepared_drafts、list_watched_threads)会读取你的真实邮件;它们都不会写入或发送邮件。check_before_send 会让 RadMail 的发送关卡检查 Agent 将通过自身服务商发送的邮件,但不会发送任何内容。操作员还可以额外启用五种仅限本地的收件箱操作(归档、延后处理、读信状态、标签)——这些操作可撤销,而且都不会删除或发送邮件。
  • 所有托管端点都没有发送操作——能够发送邮件的工具数量为 0,可按照连接前验证中的 tools/list 命令复现。发送仅作为可选的本地工具提供,即便如此,它也无法放行被拦截的邮件。

**作为第四种形态的真实代价:**如果你需要一个拥有自己地址、无需用户参与就能回复邮件的 Agent,那么形态 2 才是正确选择,RadMail 则不是——它会拒绝你聘用它来做的那些事。RadMail 面向的是企业实际使用的邮箱;在这种场景下,被劝说着发送邮件本身就是攻击。

安全约定(从设计上杜绝绕过)

这些规则由确定性代码决定,而非模型判断——请参阅已发布的约定:https://radmail.ai/.well-known/agent-safety.json(本仓库中还有一份由代码固定的副本——请参阅下文的 统计约定,这样即使两者不一致,也不会被误认为是在撒谎):

  • 资金、银行信息变更、首次联系、决策/签字确认、提示词注入 → hardStop,永远只能由人工处理。RadMail 绝不会向 Agent 提供可自动发送的此类回复。

  • 执行模型:capability-absent。 “Agent 做不到这件事”可能指三种不同的情况,它们的约束力并不相同——因此,约定会通过 enforcementModel 公布所指的情况,并定义全部三种取值,让标签含义明确,而不是一句口号:

    取值含义
    capability-absent — RadMail能执行被禁止操作的工具在服务端不存在,因此无法调用。没有任何内容需要配置,也无从绕过。
    config-restricted该能力存在,但受到配置限制——例如允许列表、作用域或策略文件。持有配置的人可以再次放宽限制。
    policy-gated该能力存在,但受到指令、提示词或文档化策略的约束,模型会被要求遵守。

    这三个定义都是通用定义,不指向任何产品——它们描述的是一个维度,而非对比。**不要只相信标签上的说法:**请查看工具列表(参见 连接前验证),并查找能发送内容的工具。这样的工具并不存在;这种缺失本身就是执行机制。

  • 人工参与审批门槛属于另一个维度。“人工参与”通常意味着该能力存在,并要求人员批准每次使用——在上面的维度中属于 config-restricted 或 policy-gated。审批门槛有其合理用途,运作方式也不同:持有配置的人可以放宽限制,而面临时间压力的审批者恰恰是商业电子邮件诈骗会利用的对象。RadMail 对硬性拦截的类别报告 capability-absent,因此没有待审批的请求,也没有可放宽的限制。对于这些类别之外的所有情况,可审阅的草稿是人工审核的处理方式——RadMail 起草,由人发送。

  • 只读银行连接器保护的是另一类对象。 只读银行或会计 MCP 服务无法发起转账,因此无法直接实施诈骗——这确实有用,但解决的是另一类问题。商业电子邮件诈骗攻击的不是你的银行连接,而是你的收件箱。欺诈指令会通过电子邮件到达——供应商称其银行信息“已变更”、发票被转到新账户,或一封看似日常的首次联系请求——而当人员或 Agent 相信这封邮件,并通过其他渠道采取行动时,损失就会发生。只读连接器看不到这类邮件,因此无法标记它。RadMail 在指令到达的地方发挥作用:资金、银行信息变更、首次联系、决策和提示词注入都只能由人工处理,并报告为 capability-absent,而非操作人员可以关闭的设置。

  • 污染信封: 每个源自原始电子邮件正文的字段都带有 provenance: "untrusted-email-body",每个响应都包含一个重申硬性拦截规则的 safety 区块。将受污染字段视为数据,绝不视为指令——这样即使遇到恶意邮件,也能让你的 Agent 默认保持安全。

  • 默认安全关闭:如果无法评估风险信号,RadMail 就会拒绝自动发送。

核对契约:forbiddenActions 有 3 项,硬性拦截的类别有 5 个

审计已发布的契约时,只数一个键会发现它与文案中的数字对不上,因此在你认定这份 README 夸大其词之前,先来说明一下两者如何对应。于 2026-10-18 在 https://radmail.ai/.well-known/agent-safety.json 观察到 21 个键:

  • forbiddenActions → 3:自动转账、自动发送或更改银行指令、自动发送首次联系。这些操作是此服务没有对应工具的。
  • draftRefusalClasses → 5:money、changed-banking、first-contact、decision、injection。对于这些类别,RadMail 会连草稿本身也不提供——请参阅 为什么它拒绝提供草稿,而不只是拒绝发送。
  • enforcementModel → capability-absent,而 enforcementModelValues 定义了全部三个值,因此这个标签有明确含义,而不是一句口号。

因此,这五个类别归在两个键下,并非用三个类别替代五个。3 + 5 体现的立场与文案所述一致,并没有更弱。

而且,这份契约有两个副本,这一点会明确说明,因为评估者如果读了一个副本再核对另一个,就会以为出了问题。 上面已发布的契约是应当获取的版本,本文件中的每项声明都以它为准。此仓库中的副本——public/.well-known/agent-safety.json——结构较旧(于 2026-10-18 观察到:20 个键,全部五个类别都归在 forbiddenActions 下,且完全没有 enforcementModel,所以不要去那里找这个字段)。它的作用有所不同:这是一个测试会拿来与运行中的防火墙核对的副本。test/agent-safety-contract-matches-the-code.test.ts 会询问实际的发送处置引擎,确认每种永久仅限人工处理的操作类型是否确实会被拒绝;如果文档列出了此服务未提供的工具,测试就会失败。没有任何机制会自动比较两个副本——它们属于不同仓库,CI 中也没有网络——因此,这是一个明确列出的问题,而非隐而不报。两者在五个类别和默认拒绝方面一致;如果你发现存在重要分歧,那就是一个 Bug,联系地址在文末。

按资金安全检查清单审计(其中三项不适用)

已发布的资金转移 MCP 服务审计会评估三个方面:可配置的支出预算、有文档记录的人工审批步骤,以及频率限制。对于能够转移资金的服务,这三个问题问得恰当。对于 RadMail,诚实的答案是,两项不适用,而另一项的标准比该领域的预期更严格:

审计项RadMail 的回答
可配置的支出预算不适用——没有支出需要设限。 预算限制的是一项能力;而这里根本不存在这项能力。回答“是,每天 $X”会让人误以为存在资金转移途径,只是设了上限。
频率限制(每天付款数、每小时自动发送数)不适用。 对服务无法执行的操作进行限流,只是做样子。普通邮件也没有需要限流的自动发送——draft_reply 返回的是由人发送的文本。
有文档记录的人工审批步骤适用——而答案比该领域的预期更严格。 对于这五类操作,没有任何内容需要审批:既不会提供草稿,也不存在发送动词。审批关卡是合理的设计,但也存在已知的失效方式:在时间压力下的审批者,恰恰是商业邮件入侵诈骗意图利用的对象。

请亲自验证这两项不适用,而不要只相信结论。 在冻结的清单上——也就是此服务拒绝偏离的功能范围——运行 grep -ic budget src/tool-manifest.ts,并对 velocity 和 spend 执行同样的查询,结果均为 0(观测时间:2026-10-18)。托管的 tools/list 返回 6 个工具,其中 0 个具备发送能力(观测时间:2026-10-18:triage_inbox、list_right_now、why_surfaced、list_commitments、draft_reply、search)。单独来看,缺少某个字段只是较弱的证据;真正重要的是缺少相应的动词,而且无需账号即可查看。

直言其代价: RadMail 无法支付发票,也不会获得这项能力。如果你的 Agent 的工作是转移资金,就需要一个支付服务——而支出预算、频率限制和审批步骤正是应该在这类服务上询问的问题,所以请在那里询问。RadMail 的职责是处理诈骗指令送达的收件箱。

对照安全类别发布的 BEC 控制清单进行审查(五项中有三项不归我们管)

向邮件安全类别询问如何防止商业电子邮件诈骗(BEC),已发布的指南会归纳出五项控制措施。问 RadMail,坦诚的答案是:一项比业内预期更严格,一项部分适用,三项明确不适用——因为 RadMail 和邮件安全网关解决的是同一问题的不同方面,把两者混为一谈,最终会让买家毫无防护。

已发布的 BEC 控制措施RadMail 的回答
对电汇、薪资变更和供应商银行账户变更进行第二位授权审核人审核——不能因紧急情况或职位高低而免除审批适用,而且比业内预期更严格。 对 Agent 来说,不存在可以免除的审批请求,因为没有工具:money 和 changed-banking 均为 capability-absent,RadMail 甚至会扣下草稿,因此没有预先写好的内容可供批准。审核人是唯一的撰写者。
通过此前已知可靠的号码进行带外回拨验证尚未实现,RadMail 也不会添加此功能。 RadMail 不拨打电话,也不保存供应商的备案联系方式,因此无法通过第二个渠道确认账户变更。硬性拦截的作用是提供一个暂停时机,让人拨打电话——它不会替人拨打电话;若误以为它会这样做,就会造成危险的误解。
验证发件基础设施(SPF / DKIM / DMARC)部分适用,而且范围比名称所暗示的更窄。 check_send_domain 是一项无需认证、只读的 DNS 查询,用于检查由你指定的域名的 SPF / DKIM / DMARC,并探测常见选择器。它不会对收到邮件的邮件头进行逐封认证,不会评估特定邮件是否对齐,也不能根据查询结果采取行动。
对收到的邮件进行冒充 / 行为异常检测不适用。这不是邮件安全产品。 RadMail 会评估重要性 × 紧急程度,并对已经进入收件箱的邮件标记五类硬性拦截情形。它不会对发件人关系建模来判断邮件是否伪造,也不应被用来替代具有这项功能的产品。
自动修复——隔离、撤回、事件聚类不适用,原因与其他功能相同。 托管端仅提供 6 个工具,只能读取、分类和起草;不会移动、删除或隔离邮件。

不要只相信这三项不适用,亲自验证。 在冻结的清单上——也就是此服务拒绝偏离的功能范围——运行 grep -ic quarantine src/tool-manifest.ts,以及对 delete 和 archive 执行相同命令,结果都为 0;grep -ic send 的结果为 2(重新测量于 2026-10-26,当时新增了 check_before_send;此前为 1):其中一个词出现在只读 DNS 查询 check_send_domain 中,另一个出现在 check_before_send 中;后者会询问 RadMail 的关卡如何处理一封邮件,但不会发送任何内容。托管端的 tools/list 返回 6 个工具,0 个可发送工具(观察于 2026-10-23:triage_inbox、list_right_now、why_surfaced、list_commitments、draft_reply、search)。

明确说明两者各自负责什么,避免买错产品。 BEC 网关防御针对邮箱的攻击者邮件——执行过滤、身份验证、冒充建模和隔离。RadMail 则限制 Agent 在邮件进入邮箱后能对其做什么。这两者并不冲突:即使网关几乎能拦住所有邮件,它仍会放过此前未见过的邮件;而在 2026 年,这类邮件另一端越来越常见的是一个拥有发送权限、却不会本能地警觉银行账户变更的自主进程。如果你没有入站邮件安全产品,RadMail 不能替代它,你应该购买一款。 如果你已经有这类产品,同时又把收件箱交给 Agent 使用,那么网关不会管 Agent 接下来会做什么——这正是 RadMail 所负责的部分。

连接前先验证

安全契约可由机器验证——用一条命令获取并检查,无需账号或密钥:

curl -s https://radmail.ai/.well-known/agent-safety.json

然后,不要只听它一面之词——重新读取工具列表,查找能发送内容的工具。 这正是上文 capability-absent 行所指的检查,同样不需要密钥:

curl -s -X POST https://radmail.ai/api/mcp/sandbox \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

重新读取工具名称。列表里没有 send、send_email、pay 或 update_banking——这种缺失本身就是执行限制。(只有一种例外,且仅限操作人员主动选择的情况:使用 RADMAIL_SEND_TOOL=1 启动的本地 stdio 服务也会列出 send_email——见下文的 Opt-in: sending。同样,启用 RADMAIL_TRIAGE_TOOLS=1 并提供分拣密钥的本地服务会列出五项收件箱操作,但它们都不会发送或删除内容。托管端点绝不会列出这两类工具。)在托管沙盒中观测于 2026-10-09:6 个工具——triage_inbox、list_right_now、why_surfaced、list_commitments、draft_reply、search。这是对托管沙盒层级在特定日期的观测,不是上限:上表中的本地 stdio 包提供了更完整的工具集。请重新运行命令,不要相信这一行。

还有一项无法从外部检查的声明——请在源代码中检查。 本 README 中最有力的句子是 “没有工具能释放已暂扣的发送”(见下文 Opt-in: sending)。一段文字不是证据;托管端的 tools/list 无法验证这项声明,因为托管层级根本没有发送工具。此声明由本仓库中的测试断言——请运行测试,而不是相信这段文字:

git clone https://github.com/radmail-ai/radmail-mcp && cd radmail-mcp && npm install
RADMAIL_TELEMETRY=off node --test --import tsx \
  --test-name-pattern="release a held send" test/send-email.test.ts

测试断言了三件事:无论结果如何,工具获取的每个 URL 都是发送路径,绝不会是 /confirm 路由;客户端和工具的源代码中都不会在任何位置提及确认/释放路由;以及输入架构中没有可用于指定要操作的先前请求的字段。观测于 2026-10-05:3 项通过,0 项失败——与本文件中的其他计数一样,这是特定日期的观测。请重新运行。

🔑 现在让它失败,因为你没见过生效的防护,就不能算真正的防护。 在 src/lib/send.ts 中添加一行——

echo 'export const RELEASE_PATH = "/api/v1/sends/confirm";' >> src/lib/send.ts

——然后重新运行上面的命令:第二项断言会失败,测试套件也会以非零状态退出。接着运行 git checkout src/lib/send.ts 将其还原。RadMail 公布了证伪步骤,而不是让你假定检查确实有效。

复现解释本身——以及这份 README 从未公布的参数名

why_surfaced 表明,排名是可解释的,而不是一个附带故事的分数。上文三次提到了它,但它唯一的参数从未写明,因此直到现在,最快的验证方式只能靠猜。两条命令,无需账号,也无需密钥:

# 1. get an id out of the demo inbox
curl -s -X POST https://radmail.ai/api/mcp/sandbox \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_right_now","arguments":{}}}'

# 2. ask why that one surfaced — the argument is message_id (snake_case)
curl -s -X POST https://radmail.ai/api/mcp/sandbox \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"why_surfaced","arguments":{"message_id":"m_001"}}}'

观察于 2026-10-19——六个具名信号及其调整的基础分数,而不是一句话:

Why "Re: PO-4471 — confirm revised delivery window" [m_001] scored importance 94 x urgency 94:

  • sender is a known counterparty (base importance 78)
  • you owe an open commitment on this thread
  • arrived in the last few hours
  • explicit same-day deadline language
  • an explicit confirmation is requested
  • a commitment on this thread is due soon

值得测量而非断言的部分:相同输入返回了相同的字节。 在 2026-10-19 连续调用三次,返回的都是字节完全相同、长 433 字节的负载——sha256 e0eebdcf46ae7aada7abc0ac41e5a48608773026252fd49a511f07f5d8cb549c。这里所说的 “不是黑箱”,指的是这些信号就是读取得到的评分输入,因此可以对解释做差异比较、固定在测试中,也可以展示给不同意该排名的人。由模型讲述自己猜测而写出的解释,是一种合理的设计,而且读起来往往更顺畅——但对它进行两次相同的调用,结果未必一致;无法重复的内容就无法做差异比较。请重新运行这些命令,而不是轻信这段文字;并按这里限定的范围理解这一主张:这是启发式沙盒层级,也就是无需账号即可验证的部分。

两个层级接受的参数不同,这是有意为之,并非偏差。 托管沙盒提供固定的演示收件箱,因此其中的 why_surfaced 接受 message_id——ID 为 m_001–m_006,list_right_now 会将它们列在方括号中。本地 stdio 包没有自己的收件箱(你需要传入自己的消息),因此其中的 why_surfaced 接受消息对象——包含 from 和 body,可选包含 knownSender / hasReply / receivedAt / subject——结构与 triage 相同。2026-10-19 在托管层级测得:猜测 camelCase 的 {"messageId":"m_001"} 不会静默失败,而是会答复 No demo message with id "". Pass a message_id from triage_inbox (available ids: m_001, m_002, m_003, m_004, m_005, m_006).——这正是你需要的列表。现将约定公布于此,以便读者直接看到,而不必自行摸索。

这个服务的独立评级——不是我们申请的,也不受我们控制

这一行以上的内容都是 RadMail 在检查 RadMail。读者有理由对其打折看待。因此,下面是由其他人衡量的同一项声明,发布在 RadMail 不拥有、不能编辑、也从未提交过的页面上:

AxioRank MCP Security Index 对 radmail-mcp 的评级

AxioRank 的 MCP Security Index 会抓取服务声明的工具范围,并对其爆炸半径进行评级——“其中每个工具能做的最强大之事”。该服务的评分卡(数据读取日期为 2026-10-22):

AxioRank 的测量项结果
等级A — “暴露面极小”
爆炸半径0 / 100
发现的工具6
标记的能力0
执行 · 删除 · 写入 · 读取0 · 0 · 0 · 6

用其原话来说:“radmail-mcp 声明的高影响能力中,没有 AxioRank 标记的项目。”

但免责声明比评级本身更重要,所以这里照录原文,而非转述: “该评级反映的是 radmail-mcp 声明自身具备的能力的爆炸半径,只读;它并不表示该服务安全或可信,也不代表对供应商的评价。” 还有:“评级显示爆炸半径很小,并不意味着认可。” 这才是正确的解读。爆炸半径为零表示危险动词未出现在声明的能力范围中——这正是 capability-absent 行所表达的内容,也正是你可以通过上面的 tools/list 命令自行重新推导的结论,只需调用一次。它并不表示代码写得很好,也不代表这是一项安全审计。

RadMail 与 AxioRank 没有任何关系,没有申请此项收录,也无法更改其内容。上方的徽章由 AxioRank 实时提供,因此如果他们的评级发生变化,徽章也会随之变化——包括评级下降。这正是引用它的意义。

该页面上的 high 提示,以及触发它的那个关键词

同一张评分卡还显示了一条提示:high — “凭据 / 密钥访问能力。” 如果只引用评级、跳过旁边这个红色词语,那就是不诚实。因此要说明的是:AxioRank 将该区块标注为*“工具描述和架构中的关键词匹配……为透明起见而展示,不计入评级”*——而它匹配到的关键词是 api_key,这个 README 可以明确指出,因为这是测量结果,而非猜测。

curl -s -X POST https://radmail.ai/api/mcp/sandbox \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | grep -o RADMAIL_API_KEY

对 2026-10-22 的整段载荷进行统计:api_key 1 次;token、credential、secret、password 各 0 次。唯一一次命中出现在 search 的描述中,其中解释了如何升级为连接模式:设置 RADMAIL_API_KEY 后运行本地软件包,同一工具就会读取你的真实收件箱,而非演示收件箱。读取工具说明的关键词扫描器无法区分一句关于密钥的话,和一个处理密钥的工具——而这里属于前者。这里没有任何工具会读取、写入、存储或转发凭据;同一张评分卡上方一行的能力计数也证实了这一点(读取 6,其余全为 0)。

诚实地说:这条提示对我们的文本而言属实,却会让人对我们的能力范围产生错误印象。 我们不会为了迎合关键词扫描器,而删掉告诉运营者如何连接真实收件箱的句子——我们宁愿公开这些统计数字,并让你亲自运行 grep。

连接

最快方式 — 无需身份验证的托管沙盒(无需安装、无需密钥、无需注册)。将任意 MCP 客户端指向可流式传输的 HTTP 端点:

{
  "mcpServers": {
    "radmail": {
      "url": "https://radmail.ai/api/mcp/sandbox",
      "transport": "streamable-http"
    }
  }
}

本地 stdio(此软件包 — 功能更完整,可对传入的消息进行分类):

{
  "mcpServers": {
    "radmail": {
      "command": "npx",
      "args": ["-y", "radmail-mcp"]
    }
  }
}

radmail-mcp 已在 npm 上发布 — 上方的 npx 命令可直接使用。想完全不安装?请使用上方的无身份验证托管沙盒。

⚠️ 关于已发布版本的说明(截至 2026-09-30 的实际情况)。 npm view radmail-mcp dist-tags 显示 latest: 0.5.0,但该 tarball 中的构建版本通过 MCP 自报为 0.4.0 — dist/ 在版本号升级前就已打包。此仓库的 main 分支版本为 0.5.1,且已修复根本原因(现在 prepublishOnly 会在打包前重新构建 dist/);修正后的软件包尚未发布,因为发布需要交互式运行 npm login,只有维护者才能执行。你可以自行复现:npm pack radmail-mcp && tar -xzOf radmail-mcp-*.tgz package/dist/src/server-info.js | grep version。安全约定的任何部分都不依赖版本号 — 但 RadMail 会主动公布此项检查,而不是让你自行假定。

也可以从源码运行:git clone https://github.com/radmail-ai/radmail-mcp && npm i && npm run build && npm start(stdio)。托管部署:Vercel Node 无服务器函数(api/mcp.ts;/ 重写到 MCP 处理程序)。

已发布的软件包目前尚不具备的功能(截至 2026-10-25 检查:npm view radmail-mcp dist-tags → latest: 0.5.0,于 2026-08-11 发布)。 send_email、五个收件箱操作、get_attachment、check_before_send、0.6.0 版的读取工具(read_thread、list_emails、list_prepared_drafts、list_watched_threads)以及托管版 bearer 预览功能,都比该 tarball 更新。它们将在下一个版本 0.6.0 中发布,目前尚未发布。在此之前,请从源码运行 — git clone https://github.com/radmail-ai/radmail-mcp && cd radmail-mcp && npm ci && npm run build — 并让客户端连接 node /absolute/path/to/radmail-mcp/dist/src/index.js,而不是 npx -y radmail-mcp。下方命令采用 npx 形式,因为 0.6.0 发布后即可使用;使用 0.5.0 时,它们启动的服务不包含这些工具。

已连接模式 — 你的真实收件箱

向服务提供 RadMail API 密钥,已连接工具就不再只是演示。省略 messages,然后:

  • search 可在你真实的 RadMail 收件箱中查找曾收到的任何邮件(使用 offset 翻页;每次响应都会包含 nextOffset);
  • read_email 获取完整邮件(邮件头 + textBody + 附件名称);
  • read_thread 显示邮件所属的对话 — 按时间从早到晚列出邮件,每封邮件都包含 rfcMessageId 和 inReplyTo;
  • list_emails 按**since + nextCursor** 从最新邮件开始遍历收件箱 — 这种轮询方式可确保遍历过程中有新邮件到达时,页面内容不会发生偏移;
  • list_right_now 返回你绝不能错过的真实队列 — 实时引擎为每个项目提供的级别、重要性、紧急程度和原因;
  • list_commitments 列出你尚未履行的真实承诺 — 方向(owed_by_us / owed_to_us)、相关方、行动、截止日期/表述、状态、置信度,以及每项承诺所来自的 emailId / threadId;
  • list_prepared_drafts 显示 RadMail 自行准备的回复草稿(绝不会自动发送);
  • list_watched_threads 列出你关注的对话串以及最后发言者;
  • check_before_send 询问 RadMail:你的 Agent 通过自身的服务提供商发送的消息是否应该发出 — 详见下文。 如实命名 ID(在 0.6.0 中变更)。 在每个已连接的结果中,id 是 RadMail 自己的 ID——将其传给 read_email / get_attachment;rfcMessageId 是 RFC 5322 Message-ID,回复时会通过它建立线程(send_email 的 inReplyTo)。在 0.6.0 之前,读取工具把 RadMail 的 ID 称为 messageId,但 RadMail API 用这个名称指代 RFC 标头,因此 Agent 按名称传入 UUID 作为 inReplyTo,结果回复没有加入邮件线程,而是被暂存。由于 read_email 已发布的描述曾告诉 Agent 读取 messageId,直接重命名会破坏这一约定:search、read_email 和 list_right_now 会在一个版本中继续保留 messageId,作为 id 的弃用别名,并在响应中附上 deprecated 说明;下一个次版本将移除它。新工具绝不会输出它。rfcMessageId(以及线程邮件的 inReplyTo)是由发件人选择的标头,因此会像 subject 一样以污点包装形式返回——将其 .value 作为 inReplyTo 传入。返回值与 RadMail 存储的一致——通常是不带尖括号且转为小写([email protected]),因为 RadMail 在接收时会移除尖括号;发送门会匹配这两种形式。如果邮件没有该值、存储的值不是长度不超过 255 个可打印字符的 Message-ID(left@right,可带或不带尖括号),或者 RadMail 服务端版本过旧而无法返回它,则值为 null。

搜索邮件、阅读邮件、了解当下要紧的事和待办事项——只需安装一次,你的 AI 就能掌握全貌。

  • **配置:**设置 RADMAIL_API_KEY(密钥以 tmk_ 开头——前往 https://app.radmail.ai/settings/api-keys,大约一分钟即可创建)。可选:RADMAIL_API_URL 用于覆盖 API 主机(默认值为 https://app.radmail.ai)。
  • **从设计上只读:**已连接的读取客户端只会发出 GET 请求。(check_before_send 使用自己的小型客户端,只会向 RadMail 的门控路由发出一次 POST 请求;该路由不会发送或存储任何内容。)读取工具绝不会发送真实邮件、针对真实邮件起草内容或更改真实邮件;BEC 硬性拦截(资金 / 银行信息变更 / 首次联系 / 决策 / 注入)将永远只由人工处理。(可选择启用的收件箱操作使用独立客户端和独立密钥——见下文。)
  • **一致的污点封套:**所有源自真实邮件内容的字段(subject、fromName、snippet、textBody,……)都会带有 provenance:"untrusted-email-body" 标记——这些是供推理的数据,绝非应遵循的指令。
  • **失败时默认拒绝:**无效密钥(401)、计划无权使用(403)或超时都会返回如实、带类型的错误——绝不伪造结果。密钥本身绝不会被记录或回显。
  • 筛选与分页:已连接的 search 除了 query 和 limit,还支持可选的 from、after、before(ISO-8601)和 offset(API 的搜索没有游标;下一页通过 nextOffset 获取);list_emails 通过 cursor 或 offset 分页(二者不可同时使用)——使用游标遍历时,必须在每个 cursor 请求中再次传入相同的 since,因为 RadMail 的游标不会携带该参数(每个响应的 nextPage 都包含这两项);read_thread、list_prepared_drafts、list_right_now 和 list_commitments 接受 limit 和 offset。
  • 404 会说明三种情况中的哪一种:not_found(此密钥看不到该 ID 对应的任何内容)、not_enabled(工作区已关闭该功能,例如监控线程),或 not_available(此 RadMail 部署版本早于该路由)。只有第一种情况与具体项目有关。
  • **不伪造判断:**已连接的 list_right_now 会原样呈现实时引擎自己的等级 / 重要性 / 紧迫性 / 原因——绝不会凭空编造 API 未返回的本地硬性拦截判断。
  • 没有密钥时,search / list_right_now / list_commitments(不含 messages)以及仅限连接使用的工具会返回友好的设置说明,而不是错误——沙盒会像以前一样正常工作。
检查 Agent 发给自己的消息(check_before_send)

对于通过自己的服务商(Resend、SES、SMTP、Gmail 或其他收件箱 API)发送邮件的 Agent:传入邮件将要发送时的确切内容——to / cc / bcc、subject、body、可选的 inReplyTo、from,以及附件元数据(filename、sizeBytes、contentType;不会发送或扫描附件内容)——RadMail 的 POST /api/v1/gate 会在任何内容发出之前,执行其自身发送流程中的检查:工作区的内容清理器、抑制列表、确定性检查清单和级别门控。不会发送任何内容、不会存储任何内容,也不会联系任何邮件服务商。

答案告知 Agent 的内容
verdict: "human_only"由人员从自己的邮箱发送,或直接丢弃。绝不要自行发送,也不要改写或再次询问以得到不同答案。涉及金钱、银行信息变更、决策、注入的指令、首次联系的收件人、明确拒绝(内容清理器、抑制列表),或必须由人员处理的情况。
verdict: "review"先向所有者展示这封原样消息及其原因;只有对方确认应该发送时才发送——阅读不代表同意。收件人是监管机构/政府部门/法院/银行、出现确定性检查结果(占位符、未在线程中的 Re:、拼写错误的域名,……),或存在任何附件。
verdict: "pass"未匹配到已知的风险模式。这不代表已获批准,也不表示 RadMail 会在没有人员介入的情况下发送该消息。
checked: false、verdict: null**未检查——绝不能放行。**工作区已关闭检查(gate_not_enabled,RadMail 返回 404 gate_api_disabled——目前默认关闭),密钥仅限于单个邮箱(mailbox_confined_key——请使用不受限于单个邮箱的密钥),请求遭到拒绝(401)、被拒绝处理(400,附 RadMail 自身的原因)、触发速率限制、RadMail 无法完成检查(5xx)、请求超时,或返回的答案不是可识别的判定结果。

字段按名称复制——verdict、tier、reasons[{ code, message, evidence? }]、firstContact、checks.identity(早于此功能的 RadMail 服务不含此字段 → null),以及 RadMail 的备注,作为 radmailNote 返回;sent 始终为 false。服务端返回的其他任何内容都不会传给 Agent。仅当某条原因的 evidence 摘录是 Agent 自己在相应字段中提交的文本片段时才会保留;返回的内容是该文本中 Agent 自己的片段(带污染标记),而不是 RadMail 对该文本的副本。某条原因的 message 是 RadMail 自己撰写的句子,可能会提及工作区中的地址(例如线程的发件人);仅当 firstContact 地址是 Agent 自己的某个收件人时才会返回——其他地址都会隐藏并计数(evidenceWithheld、firstContactWithheld)。映射结果只能提高限制级别:hard_stop 级别或首次联系的收件人至少会得到 human_only;sensitive 级别或任何原因至少会得到 review(发生这种情况时会设置 verdictRaised)。附带 readOnlyHint: true、destructiveHint: false、idempotentHint: true。如果没有密钥,则返回设置说明,且不会发出请求。

托管端点:每个请求使用一个密钥(预览版,默认关闭——Doug 会将其开启)

默认关闭。 托管部署只有在其环境中设置了 RADMAIL_HOSTED_BEARER=1(必须恰好为 1)时才会接受 bearer。此仓库中没有任何内容会设置它,由 Doug 将其开启。关闭时,托管端点的行为与此预览版推出前相同:bearer 会被忽略,不会返回 401 拒绝请求,且所有请求都仅限沙盒使用——因此,在设置此标志前,部署此代码不会增加任何新功能。GET /api/mcp 会报告 connectedPreview.enabled。

开启后,此软件包自己的托管部署(api/mcp.ts)会在每个请求中接受 RadMail 密钥——这样,远程 MCP 客户端无需运行本地进程即可访问真实收件箱:

POST /api/mcp
Authorization: Bearer tmk_live_…        (or tmk_test_…)
  • 该请求的已连接读取工具会使用该密钥,其他任何操作都不会使用它。部署不会持有密钥:没有 bearer 的请求与之前一样仅限沙盒使用,即使部署环境中碰巧设置了 RADMAIL_API_KEY 也是如此。
  • 仅限读取工具。 无论有没有密钥,也不论其环境如何,托管端点都不会注册 send_email 或任何收件箱操作。get_attachment 会在此处拒绝执行(它会在运行服务的机器上保存文件)。此处的 check_before_send 在提供 bearer 时可以使用,与读取工具一样:它会向 RadMail 的审核关卡查询消息,但不会发送任何内容。
  • 密钥绝不会被记录、回显或放入响应中——前缀也不例外,而且不会发送到遥测系统。
  • 预览版开启时,如果 bearer 以 RadMail 密钥的格式开头但格式有误,则会返回 HTTP 401 拒绝请求(会说明预期格式,但绝不会泄露密钥值),因此即使输错也不会悄悄向用户展示演示收件箱。不属于 RadMail 密钥的 bearer 则和以前一样会被忽略。
  • 预览版: 目前还没有 OAuth——客户端必须能够发送自定义标头——并且端点仍保留每个 IP 每分钟 60 次请求的速率限制。GET /api/mcp 会在清单检查旁报告 connectedPreview。
实时引擎由用户主动调教

已连接模式会读取由收件箱所有者主动调教的实时引擎——返回的等级、重要性和原因反映了以下控制项(均位于 RadMail 应用中:https://app.radmail.ai):

  • VIP 发件人——由所有者命名的“始终重要”允许名单(例如银行家、重要合作伙伴)。VIP 是最高优先级的信誉覆盖规则——它优先于回复历史和所有启发式规则。
  • 静音发件人——与之对应的明确“绝不重要”设置。静音只会抑制发件人信誉;监管通知和逾期信号仍会显示(静音绝不会隐藏真实的合规通知)。
  • 代理人——可享有重要性模型中所有者级别互动权重的其他地址(例如助手、运营经理)。此设置仅影响重要性:代理人绝不会获得发送或审批权限。
  • 一键调教——每日摘要中的每条内容都附有签名的 👍/👎 反馈链接(另有 ⭐“此发件人的邮件始终重要”操作),可用于调整后续排序。
  • 降低自有产品优先级——所有者自有的 SaaS / 通知邮件无法借助回复历史进入重要邮件区。
  • 每日摘要——可选择启用的汇总式“需要您处理”邮件,每天早上 7 点按组织所在时区发送一次;启用后会静默单封邮件提醒,而“立即处理”区仍会持续触发提醒。

目前真实邮件的接入方式:RadMail 的 Apple Mail 连接器(macOS)会为已连接的收件箱提供邮件;托管版 Gmail / Microsoft 365 OAuth 连接器尚未正式发布。

Claude Code:

claude mcp add radmail -e RADMAIL_API_KEY=tmk_... -- npx -y radmail-mcp

Claude Desktop(claude_desktop_config.json):

{
  "mcpServers": {
    "radmail": {
      "command": "npx",
      "args": ["-y", "radmail-mcp"],
      "env": { "RADMAIL_API_KEY": "tmk_..." }
    }
  }
}

Cursor(.cursor/mcp.json):

{
  "mcpServers": {
    "radmail": {
      "command": "npx",
      "args": ["-y", "radmail-mcp"],
      "env": { "RADMAIL_API_KEY": "tmk_..." }
    }
  }
}

radmail-mcp 已在 npm 上发布,因此上面的 npx 命令可直接使用。想使用源码?将 command 指向 node dist/src/index.js 即可——连接模式的工作方式相同。

选择加入:发送(仅限本地 stdio)

尚未加入已发布的 npm 包。 send_email 是在 [email protected](npm latest,于 2026-08-11 发布)之后添加的,因此使用下方变量运行 npx -y radmail-mcp 启动的服务不会列出 send_email。它将在下一个版本(0.6.0,尚未发布)中提供。在此之前,请从源代码运行:git clone https://github.com/radmail-ai/radmail-mcp && cd radmail-mcp && npm ci && npm run build,并将下方的 npx -y radmail-mcp 替换为 node /absolute/path/to/radmail-mcp/dist/src/index.js。

默认关闭,不会出现在托管端点中;只有在本地服务的操作员同时设置以下两项时才会启用:

git clone https://github.com/radmail-ai/radmail-mcp && cd radmail-mcp && npm ci && npm run build

# RADMAIL_API_KEY       the read key (search / read_email / right-now) — never used to send
# RADMAIL_SEND_TOOL=1   lists send_email on THIS server
# RADMAIL_SEND_API_KEY  a separate key with the send scope, ideally confined to one mailbox
claude mcp add radmail \
  -e RADMAIL_API_KEY=tmk_... \
  -e RADMAIL_SEND_TOOL=1 \
  -e RADMAIL_SEND_API_KEY=tmk_... \
  -- node /absolute/path/to/radmail-mcp/dist/src/index.js     # `npx -y radmail-mcp` once 0.6.0 is published

send_email 会将邮件交给 RadMail 的出站网关(POST /api/v1/send),并报告以下三种结果之一:

结果发生了什么
sentRadMail 的网关已通过所有者连接的邮箱将邮件发出。
held邮件未发送。handoff: false 时,所有者会在 RadMail 应用中的 reviewUrl 处放行或丢弃邮件。handoff: true 时(涉及资金、银行信息变更、决策、注入的指令、给新对象发送第一封邮件——由 handoffClasses 指明),没有人会在 RadMail 中放行邮件:有人打开 reviewUrl,复制草稿,然后从自己的邮箱发送。
refused邮件既未发送,也未暂存——输入无效、发送已关闭、没有发送密钥,或收件人已被屏蔽。

由 RadMail 决定,而非 Agent。 只有在所有收件人都属于所有者自己的团队(即工作区标记为内部的域名)或是已建立双向联系的对象时,邮件才会立即发送;其他情况一律暂存。发给监管机构、政府部门、法院或银行的邮件始终会暂存。涉及资金、银行信息变更、首次联系、决策和指令注入的内容会交由人工处理,由其从自己的邮箱发送;RadMail 绝不会发送此类邮件。没有任何工具可以放行暂存的邮件——响应中附带的是应用页面链接,而不是令牌,客户端只会调用发送路径。不要只听信这一说法:上文的 接入前验证 中提供了用于断言这一点的命令,以及一行即可让断言失败的编辑。

⚖️ 请准确理解此项变更的影响。 在已启用发送的服务上,上文的 不具备此能力 标签不再适用于发送:该能力确实存在,只是受配置限制(config-restricted),而暂存的邮件意味着由人工批准请求。五类硬性拦截的内容仍必须经人工处理才能发出。每个响应中的安全说明都会指出服务的类型:启用发送的服务会用 sendSurface 声明替换“绝不发送邮件”这句话,而不是保留错误的说法。

工具描述会要求 Agent 在向所有者团队之外的任何对象发送邮件前,针对邮件的确切文本自行进行通信审查——RadMail 的网关可以识别机器生成文本的特征和未在原邮件线程中的回复,但不能替代对文风的审查。

选择启用:收件箱操作(仅限本地 stdio)

默认关闭,不会出现在任何托管端点上,只有操作者同时设置这两项时才会在本地服务上注册(单独设置任意一项都不会注册任何内容):

这些工具比已发布的 npm 包(0.5.0)更新,因此在 0.6.0 发布之前,请从源码运行此服务:

git clone https://github.com/radmail-ai/radmail-mcp && cd radmail-mcp && npm ci && npm run build

# RADMAIL_TRIAGE_TOOLS=1   lists the five inbox-action tools on THIS server
# RADMAIL_TRIAGE_API_KEY   a separate key with the `triage` scope, ideally confined to one mailbox
#                          (RADMAIL_API_KEY, the read key, is never used to change mail)
claude mcp add radmail \
  -e RADMAIL_API_KEY=tmk_... \
  -e RADMAIL_TRIAGE_TOOLS=1 \
  -e RADMAIL_TRIAGE_API_KEY=tmk_... \
  -- node /absolute/path/to/radmail-mcp/dist/src/index.js

0.6.0 发布到 npm 后,用 -- npx -y radmail-mcp 替换 node 行即可达到相同效果;使用 0.5.0 时会启动一个不含这些工具的服务。

工具功能
archive_email归档一封邮件(archived: false 会将其移回)。
snooze_email将一封邮件延后至一个带时区的 ISO 8601 日期时间(snoozed: false 会唤醒它)。延后状态保存在 RadMail 中;不会更改邮件服务商的邮箱。
mark_read将一封邮件标记为已读(read: false 会将其标记为未读)。
label_email添加(on: true)或移除(on: false)邮箱中已有的标签——Gmail 标签或 Outlook 类别。绝不会创建标签。
act_on_emails一次调用最多处理上述操作中的 50 项。各项按顺序执行;某项遭到拒绝不会导致其余操作失败——请读取每项的 ok / status 和 summary。

这些工具会调用 RadMail 的 v1 操作 API(POST /api/v1/emails/{id}/actions、POST /api/v1/emails/actions),执行与用户在 RadMail 中相同的更改;当工作区启用了回写功能时,会将更改写回 Gmail / Outlook 邮箱;会检查密钥的 triage 权限范围、其邮箱限制以及签发该密钥的成员是否有权访问邮箱;并在该成员和密钥名下审计每项更改。

  • 不移至垃圾箱,不删除,不发送。 可执行的操作类型严格限定为 archive | unarchive | snooze | unsnooze | mark_read | mark_unread | label,批量操作架构会拒绝其他内容,RadMail 也会在服务端拒绝这些操作。
  • 可撤销且具幂等性。 每项更改都可通过这些工具中的相反操作撤销;如果请求的状态与邮件当前状态相同,则会返回 changed: false,不会写入任何内容,也不会联系邮箱服务——因此超时后重试是安全的。标注为 readOnlyHint: false、destructiveHint: true、idempotentHint: true。destructiveHint 为 true,因为 MCP 规范规定,只有执行纯增量更新的工具才能将其设为 false;归档、标记为已读或移除标签都会更改已有状态,因此跳过非破坏性工具确认的客户端不会在此跳过确认。这不代表会删除任何内容。
  • “未启用”不表示邮件有错误。 RadMail 工作区关闭该功能时,每个工具都会返回 outcome: "not_enabled"——"此 RadMail 工作区尚未启用收件箱操作"——且不会有任何更改。若 not_found(此密钥无法查看该 ID),则会单独报告。
  • 服务会说明自身状态。 在启用了这些工具的服务上,safety 区块会增加一条 triageSurface 说明,指令会增加一段补充内容,启动行会显示 INBOX ACTIONS ON。默认服务的这三处内容会逐字节保持不变。

请通过测试验证“不删除”的声明,而不是只阅读这段说明:RADMAIL_TELEMETRY=off node --test --import tsx --test-name-pattern="no trash or delete" test/inbox-actions.test.ts。

遥测(需求信号 — 可选择退出)

此服务会向 https://app.radmail.ai/api/mcp-demand 发送匿名需求信号遥测数据,以便 RadMail 了解 Agent 实际使用了哪些工具,以及它们提出了哪些能力需求:发送的内容包括工具名称、事件类型(call / need / capability)、你通过 report_need / request_capability 明确提交的需求或能力文本,以及你传入的可选 Agent ID。**绝不会发送的内容:**电子邮件内容、邮件批次、搜索查询、结果——也绝不会发送你的 API 密钥(仅在连接模式下会传输安全的显示前缀 tmk_live_ + 前 4 个字符,以便区分连接模式的使用情况)。遥测采用即发即弃方式,超时为 3 秒,所有故障都会被静默忽略——遥测绝不会拖慢或中断工具调用。使用 RADMAIL_TELEMETRY=off 完全退出。

目录如何列出此服务

第三方目录和答案引擎不会读取此 README——它们会镜像官方 MCP 注册表中的 server.json 记录。由发布者控制的两个字段决定人类或模型在这些页面上实际看到的内容:

  • title — 可选的人类可读显示名称,最多 100 个字符,包含在 2025-12-11 服务器架构中,不包含在 2025-09-29 架构中。目录若有标题就会显示;没有标题的记录则会退回显示纯软件包标识。
  • description — 显示在其下方的一行摘要。

并排查看此仓库声明的内容和在线注册表提供的内容——无需密钥,无需克隆:

# what main declares
curl -s https://raw.githubusercontent.com/radmail-ai/radmail-mcp/main/server.json \
  | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d.get("title")); print(d["description"])'

# what the live registry serves today
curl -s 'https://registry.modelcontextprotocol.io/v0/servers?search=radmail' \
  | python3 -c 'import json,sys; [print(s["server"]["version"], "|", s["server"].get("title"), "|", s["server"]["description"]) for s in json.load(sys.stdin)["servers"]]'

⚠️ 两者目前尚不一致,我们在此如实说明,而非含糊带过。 截至 2026-10-10 的观察结果:注册表中 ai.radmail/radmail-mcp 当前的(isLatest)记录版本为 0.5.0,采用 2025-09-29 架构——该架构没有 title 字段——并带有较旧的 93 字符描述,而 main 上的版本为 0.5.1。因此,请将本节视为 RadMail 声明的内容,而非目录今天显示的内容;上方第二条命令会给出最终结果。

更新记录需要凭据,并须由人工执行——运行 mcp-publisher login github(或 login dns --domain radmail.ai),然后运行 mcp-publisher publish。mcp-publisher validate 无需凭据,因此任何人都可以在信任记录之前检查其格式是否正确;截至 2026-10-10,对此仓库运行该命令会返回 ✅ server.json is valid。

链接

合规立场

这是一种工具,而非保证——采用 BAA + 共同责任框架。绝不声称“通过 HIPAA 认证”或“获得 FedRAMP 授权”。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。