mcpField
M
mail-mcp

mail-mcp

本地服务
github.com/tecnologicachile通信协作1125 天前更新

关于 mail-mcp

mail-mcp 是用 Rust 编写的邮件 MCP 服务,面向需要让 AI Agent 读取、搜索和处理邮件的用户。它支持 IMAP、SMTP、EWS 和 Microsoft Graph,并提供 OAuth2 与多账户配置。

主要功能

  1. 01读取、搜索、发送和转发邮件
  2. 02支持 IMAP、SMTP、EWS 和 Graph
  3. 03支持 OAuth2 与多账户
  4. 04创建、修改和发送草稿
  5. 05提供跨邮箱与邮件线程搜索

适用场景

  1. 01搜索邮件并获取完整对话
  2. 02草拟邮件供人工审核后发送
  3. 03通过不同邮件后端管理多个账户

MCP 相关

该 MCP 服务向 AI Agent 提供邮件读取、搜索、发送及草稿管理工具。默认使用 stdio,也可选择无状态的 Streamable HTTP 传输。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

mail-mcp

面向 AI Agent 的生产就绪型邮件 MCP 服务
IMAP + SMTP + EWS + Microsoft Graph API — 使用 Rust 构建

发行版 许可证 星标


大多数邮件 MCP 服务只能通过 IMAP 读取邮件。这个服务则能处理所有操作:读取、搜索、发送、回复、转发、批量操作、Microsoft Graph API 和 Exchange Web Services,并支持真正的 OAuth2、多账户和多服务提供商。使用 Rust 编写,快速且安全。

v0.6.1 版新增内容

  • RUST_LOG=info 时,邮件内容不会写入日志。 在该 日志级别下,rmcp 库会完整记录每个 JSON-RPC 响应;使用 HTTP 传输时, 邮件主题和正文会写入服务端日志(对于 systemd 服务,即写入 journal)。当 RUST_LOG 设置为全局级别 info 或更详细时,rmcp 现在会被限制在 warn,除非 RUST_LOG 明确指定了它(例如,调试时设置 RUST_LOG=info,rmcp=info)。stdio 传输不会记录响应;如果未设置 RUST_LOG,则行为不变。如果你通过 HTTP 运行 v0.6.0 或更早版本,请设置 RUST_LOG=info,rmcp=warn。
  • 修正 EWS 设置的作用域。 Microsoft 现在会因 AADSTS70011 (invalid_scope)错误拒绝 https://outlook.office365.com/EWS.AccessAsUser.All。快速入门现改用 https://outlook.office.com/EWS.AccessAsUser.All。现有 EWS 令牌仍可 使用;只有获取新令牌时才会受到影响。

v0.6.0 版新增内容

除非选择启用,否则现有安装不会发生变化。

  • 为 Shell 和 PowerShell 安装方式提供自更新功能。 安装程序现在还会 安装 mail-mcp-update;运行它即可原地更新到最新发行版。Homebrew 安装仍通过 brew upgrade 更新。
  • 使用轮换后的 OAuth2 刷新令牌,并可将其持久化。 Microsoft 每次刷新时都会返回新的刷新令牌;此前服务会丢弃该令牌,并一直使用配置的 令牌进行刷新,直到配置的令牌过期。现在服务会使用最新的令牌进行刷新。将 MAIL_OAUTH2_TOKEN_STORE 设置为文件路径,即可在重启后保留该令牌 (文件权限设为 0600;即使无法写入也不会导致操作失败)。配置中更改的 刷新令牌始终优先于已存储的令牌。
  • 工具和字段描述中加入发送规则。 预览并确认规则以及“body_text 和 body_html 是独立字段”规则,现在也会显示在发送工具和正文 字段的描述中,供不会转发服务指令的 MCP 网关使用。有关 mail-mcp 位于网关 后方时还会发生哪些变化,请参阅 在 MCP 网关后方运行。

v0.5.0 版本新增内容

  • 新增:草稿工具(draft_create、draft_update、draft_send、 draft_delete、draft_list),解决了 #3 和 #17。Agent 可以 将邮件保存到账号自己的“草稿”文件夹中,修改后再发送,让用户可以先在邮件客户端中 审阅。所有后端均支持这五种工具:IMAP + SMTP、Exchange Web Services 和 Microsoft Graph;每个账号会按顺序选择后端(EWS 配置、否则 Graph 配置、否则 IMAP)。list_all_accounts 会通过 drafts_with 报告后端。
  • 独立开关:MAIL_DRAFTS_ENABLED(默认值为 false)。它与 MAIL_IMAP_WRITE_ENABLED 相互独立:对已有 draft_id 执行任何操作前,都会先 检查目标确实是草稿(IMAP“草稿”文件夹、EWS IsDraft、Graph isDraft),因此 启用草稿功能不会授予对其他邮件的移动或删除权限。draft_send 还需要 MAIL_SMTP_WRITE_ENABLED。
  • Graph 账号需要 Mail.ReadWrite 范围才能操作草稿;请参阅 账号设置。EWS 附件流程(先使用 SaveOnly 执行 CreateItem,再执行 CreateAttachment)采用了 @verdelyi 在 #14 中提出的方法。
  • 修复:SMTP 邮件现在会携带发件人域名下的 Message-ID (#7)。此前,lettre 不会自行生成 Message-ID,因此发送工具返回的 ID 为空,已发送邮件副本也没有 Message-ID。
  • 已在 IMAP(Zoho)和 Microsoft Graph 上进行实时验证;EWS 草稿流程由单元测试覆盖。

v0.4.17 版本新增内容

  • 新增:imap_search_all_mailboxes,由 @tdabasinskas 在 #35 中贡献。它会在账号中 所有可选邮箱内执行一次搜索,并返回最新的匹配项,每项都标注其邮箱。此工具适用于 没有“All Mail”文件夹的服务提供商(如 iCloud);这类服务中,同一会话会分散在 INBOX、Sent Messages 和项目文件夹中。搜索任务会分配给 MAIL_IMAP_SEARCH_CONCURRENCY 个连接(默认值为 4,限制在 1..=8);某个邮箱 搜索失败时会报告错误,但不会中止搜索。可通过 include_mailboxes / exclude_mailboxes 限定范围。
  • 按 Message-ID 搜索会话,由 @tdabasinskas 在 #34 中贡献。 imap_search_messages 新增了 thread_message_id 条件,可匹配指定邮件,以及 In-Reply-To 或 References 中包含该 ID 的所有邮件,让 Agent 能通过一次搜索 获取整个会话。

v0.4.16 版本新增内容

  • imap_list_mailboxes 的上限现在可配置且会在结果中显示,由 @tdabasinskas 在 #33 中贡献。此前,该工具会 静默省略超过 200 个的邮箱;对于文件夹较多的账号(例如 iCloud 上有 217 个文件夹), Sent Messages 等文件夹就不会显示。现在可通过 MAIL_IMAP_MAX_MAILBOXES 设置 上限(默认值为 200,限制在 1..=10000),响应还会增加 total 和 truncated 两个字段,让客户端始终能判断列表是否被截断。除非设置该变量,否则行为 不变。

v0.4.15 新功能

  • 新增:可选的流式 HTTP 传输,由 @tdabasinskas 在 #32 中贡献。设置 MAIL_MCP_TRANSPORT=http,即可使用 MCP 流式 HTTP(无状态)而非 stdio 提供服务;适合在另一台机器上通过 MCP 网关运行服务。默认绑定到 127.0.0.1:8000 的 /mcp 路径,可通过 MAIL_MCP_HTTP_HOST / MAIL_MCP_HTTP_PORT / MAIL_MCP_HTTP_PATH 配置,并在收到 SIGINT/SIGTERM 时优雅关闭。此端点没有内置身份验证——请将其限制在回环地址上,或置于经过身份验证的网关后;请参阅 docs/advanced-configuration.md#remote-http-transport。stdio 仍为默认方式:除非设置此变量,否则不会有任何变化。

v0.4.14 新功能

社区版本——这两项改动均来自外部贡献者。感谢大家!

  • 新增:MAIL_ATTACHMENT_UPLOAD_DIR——限制外发附件的 file_path 范围,由 @mjones-PL 在 #31 中贡献,解决了 #11 的问题。如果不加限制,发送工具会读取服务进程可访问的任意文件——受到提示词注入的模型可能会将 SSH 密钥或 .env 文件作为附件外传。将此变量设为某个目录后,每个 file_path 都会被规范化(解析 .. 和符号链接),且必须指向该目录范围内;对于不存在的文件和超出范围的文件,都会返回相同错误,因此无法通过此检查探测文件是否存在。此功能为可选:未设置时,行为不变。请参阅 docs/security.md#outbound-attachment-scope。
  • 修复:FROM_EMAIL 验证不再拒绝不含点的内部主机名,由 @arwack 在 #30 中贡献。解决了升级到 v0.4.13 时的注意事项:企业内部中继上的 noreply@localhost / alerts@intranet 等地址现在重新获准使用,同时仍会检查真正的拼写错误(包含多个 @、空白字符、本地部分为空)。如果你因此暂缓升级到 v0.4.13,现在可以放心升级到 v0.4.14。

v0.4.13 新功能

  • effective_from() 辅助函数 + FROM_EMAIL 启动验证,由 @arwack 在 #29 中贡献——这是对其 #19 的后续改进。from_email → user 回退逻辑现在集中在一处(SmtpAccountConfig::effective_from()),并会在服务启动时验证 MAIL_SMTP_<ID>_FROM_EMAIL,而不是等到首次发送时才失败。
  • 行为变更——升级前请阅读:格式错误的 FROM_EMAIL(包含多个 @、空白字符、本地部分为空或域名不含点)现在会阻止服务启动,适用于所有账户。请注意,目前不含点的域名(例如 user@localhost 或 alerts@intranet)也会被拒绝;如果你使用此类内部中继地址,请暂缓升级——目前正在 #29 中讨论后续放宽点号规则的改动。
  • 由 @tordable 在 #28 中加强了 APPEND 线格式测试:现在每项 append 测试都会断言邮箱引用格式、声明的字面量长度以及逐字节一致的负载。

v0.4.12 版本更新

社区发布版本 — 两项更改均由社区贡献者提交。感谢大家!

  • 支持 iCloud 邮箱别名,读取邮件不再将其标记为已读,由 @felipefdl 在 #16 中提交。现在,短邮箱名会在搜索、复制和移动操作中解析为各服务提供商的真实文件夹(iCloud 上的 Sent → Sent Messages,Gmail 上的 Sent → [Gmail]/Sent Mail,Trash → Deleted Messages,以及其他文件夹,支持多语言)。现在,原始邮件提取使用 BODY.PEEK[],因此通过 MCP 读取邮件不会再产生设置 \Seen 标记的副作用 — 若服务端拒绝 PEEK,则回退到 BODY[](已弃用并在 #23 中移除的 RFC822 项目不会使用)。作者已在真实 iCloud 邮箱上验证,并新增了别名解析测试和 iCloud 设置文档。
  • 优化多阶段 Dockerfile + docker-compose,由 @monssefbaakka 在 #5 中提交。采用 cargo-chef 层缓存、支持 TARGETARCH 的 musl 交叉构建(amd64/arm64),以及 scratch 运行时镜像 — 体积为 16.9 MB,低于原来的 25.5 MB — 已验证可通过 stdio 响应 MCP initialize/tools-list。工具链版本固定值已更新为 Rust 1.90(代码库中的 let-chains 要求版本 >= 1.88)。

v0.4.11 版本更新

社区错误修复版本 — 两项修复均由社区贡献者提交。感谢大家!

  • 已修复:在严格的 IMAP 服务端(iCloud 等)上,保存到 Sent 会静默失败,由 @dominikknafelj 在 #26 中修复,问题由 #25 报告。v0.4.10 中引入的 \Seen 标记未采用 RFC 3501 要求的带括号标记列表语法(发送的是 APPEND "Sent" \Seen …,而不是 APPEND "Sent" (\Seen) …),因为 async-imap 会原样插入标记参数。严格的服务端会拒绝 APPEND,导致已发送邮件副本丢失 — 但工具仍会返回 status: ok。现在会在发送前规范化标记;smtp_send_message / smtp_reply_message / smtp_forward_message 的响应中新增 saved_to_sent 字段(值为 true/false,若禁用保存则为 null),以便调用方检测归档失败。 @tordable 同时诊断并修复了相同根本原因,见 #24。
  • 已修复:在 iCloud 上读取邮件会返回空内容,由 @tdabasinskas 在 #23 中修复。原始邮件提取使用了已弃用的 RFC822 项目,iCloud 虽然接受该项目,却不会填充内容。现在提取使用 IMAP4rev1 的 BODY[] 项目 — \Seen 语义不变,且适用于所有服务端 — 并新增模拟服务端回归测试,以固定线路格式。

v0.4.10 新功能

社区发布版——这三项更改均由外部贡献者提供。感谢大家!

  • 兼容网易 IMAP(126.com / 163.com / yeah.net),由 @pep-27 在 #21 中贡献。网易服务 器会拒绝未表明身份的客户端访问邮箱。现在,mail-mcp 会在身份验证后, 只要服务端声明支持 ID 功能,就发送 RFC 2971 ID 命令。包含模拟服务 器回归测试,以及 docs/account-setup.md 中的网易设置文档。
  • MAIL_SMTP_<ID>_FROM_EMAIL——覆盖发件人地址,由 @arwack 在 #19 中贡献。适用于共享或群组 邮箱:SMTP 使用个人账户进行身份验证,但 From 地址应为群组地址。此设置适用于发送、 回复(包括“全部回复”时的自身地址检测)和转发;未设置时回退到 _USER。
  • 发件箱副本现在会标记为 \Seen,由 @ray-of-darkness 在 #9 中贡献。SMTP 发送后 MCP 应用追加到“已发送”文件夹的副本不再显示为未读。

v0.4.9 新功能

  • 新增工具 imap_get_attachment——将单个附件下载到磁盘。 此前,获取附件字节数据只有两种方式:imap_get_message (返回附件元数据,以及可选提取的 PDF 文本,但不返回二进制数据)和 imap_get_message_raw(上限为 1 MB,并以 Base64 编码后放入响应中)。带有 X 光图像的 7 MB 邮件无法获取——它超过了上限,而且将其全部写入响应也会耗尽大模型的 上下文。
  • 工作原理:调用 imap_get_attachment,并提供 message_id 以及一个选择器—— 可以是 part_id(imap_get_message 为每个附件返回的值),也可以是 filename。服务端会获取完整邮件(服务端不设大小上限),只提取并解码指定部分,然后写入磁盘,返回 { file_path, filename, content_type, part_id, size_bytes }。 二进制数据不会进入响应,因此上下文占用很小。保存的路径可直接传给本地读取器(例如图像描述工具或 PDF 阅读器)。
  • **文件保存位置:**若提供 output_dir 参数,则使用该目录;否则使用 MAIL_ATTACHMENT_DOWNLOAD_DIR 环境变量指定的目录;再否则使用系统临时目录。 文件名会经过净化处理(仅保留基本文件名,并移除控制字符),以防止路径遍历; 文件名前还会添加邮件 UID 和部分 ID,以避免冲突。
  • **可选的内联 Base64:**设置 include_base64: true 也可在响应中获取字节数据,但附件大小必须不超过 max_inline_bytes (默认 256 KiB)。默认关闭。

v0.4.8 更新内容

  • SAVE_SENT 现在按账户设置,并采用感知提供商的默认值。 以前,通过 IMAP APPEND 将外发邮件副本保存到“已发送”文件夹,由一个全局标志 MAIL_SMTP_SAVE_SENT 控制。问题在于:已经在服务器端保存已发送邮件的提供商(Gmail、 Zoho)会在“已发送”文件夹中留下两份相同副本;而通用 SMTP 服务器或 Office 365(不会在 SMTP 提交时自动保存邮件)则会在标志为 false 时完全丢失副本。
  • 感知提供商的默认值(未配置任何值时):
    • Gmail(smtp.gmail.com):在服务器端保存,并按 Message-ID 去重 → MCP 不会追加(false)。
    • Zoho(smtp.zoho.com):在服务器端保存,但不 去重 → MCP 不会追加(false),以避免重复。
    • Office 365 / 通用 SMTP:不会在 SMTP 提交时自动保存 → MCP 会追加(true),否则已发送邮件副本会丢失。
  • 按账户覆盖:MAIL_SMTP_<ID>_SAVE_SENT=true|false 的 优先级最高。全局设置 MAIL_SMTP_SAVE_SENT 仍然有效,可作为 粗粒度覆盖值(优先级高于提供商默认值,低于按账户设置)。
  • 优先级:按账户 → 全局 → 感知提供商的默认值。
提供商在服务器端自动保存MCP 默认值
Gmail是(会去重)false
Zoho是(不去重)false
Office 365(SMTP)否true
通用 SMTP / 中继否true

v0.4.7 更新内容

  • 严重问题修复 — graph_send_message 在带线程的回复中会静默丢弃附件。 使用 in_reply_to + attachments 调用时,createReply → PATCH → send 流程会在针对 /me/messages/{id} 的 PATCH 请求中包含附件。Microsoft Graph 将 Message.attachments 视为导航属性,并会在 PATCH 请求中静默丢弃该字段(返回 2xx 响应且不报错),因此发出的邮件会变成没有附件的单部分 text/html。MCP 返回 status: ok,调用方误以为操作成功。数据就这样无声丢失。
  • **修复方法:**在 send_via_reply() 中,现在会在 PATCH 和发送之间,逐个将附件上传到 POST /me/messages/{draft_id}/attachments。小于 3 MB 的文件会以内嵌方式发送(使用 base64 编码的 contentBytes 的 JSON);大于或等于 3 MB 的文件则使用 createUploadSession,通过分块 PUT 上传,每块 4 MB。从 PatchDraftRequest 结构体中移除了 attachments 字段,避免通过类型检查无误的编辑再次引入该回归问题。
  • 已正常工作的流程不变。 send_via_sendmail(不带 in_reply_to 的新邮件)使用 POST /me/sendMail,在 JSON 中内嵌 attachments — Graph 确实接受此端点上的该字段,也从未丢弃它。该路径未作改动。
  • **新增回归测试:**如果有人将该字段重新添加到结构体中,patch_draft_request_never_serializes_attachments 就会失败。
  • **参考:**仓库根目录下的 BUG_GRAPH_ATTACHMENTS.md 记录了完整的复现步骤、根本原因,以及支撑此修复的实证依据。

v0.4.6 版本更新

  • 在服务端强制执行硬性规则 #1。 连续三个版本仅通过提示词进行强化(v0.4.3 → v0.4.4 → v0.4.5),仍无法完全避免大模型偶尔将字面量 </body_text><parameter name="body_html"> 标记泄漏到收件人的收件箱中。v0.4.6 新增了真正的验证器:如果 body_text 或 body_html 包含工具调用包装语法,它会在尝试 SMTP / Graph / EWS 之前拒绝该工具调用。此检查已接入全部 5 个发送路径(smtp_send_message、smtp_reply_message、smtp_forward_message、graph_send_message、ews_send_message)。
  • 禁止标记不区分大小写,且范围严格限定为在人类通信中没有正当用途的伪标签:<body_text>、</body_text>、<body_html>、</body_html>、<function_calls>、</function_calls>、<invoke name=、</invoke> 和 <parameter name="body_*">。如果一般技术内容恰好在 XML 架构中提及 <parameter>,或在代码示例中提及 <invoke>,仍会通过检查。
  • 更新了硬性规则 #1 的措辞,明确说明服务端会拒绝违规内容,让大模型知道这是必须遵守的硬性约束,而非可以忽略的建议。
  • 不会破坏遵循规范的调用方:格式正确的消息发送方式与之前完全相同。

v0.4.5 版本更新

  • serverInfo 现在会报告 name="mail-mcp" 和 crate 的 version(此前框架返回的是自身的 rmcp 0.16.0,这个值不会随版本发布而变化)。这有助于通过 /mcp 验证当前使用的版本,也能让任何按(服务端、版本)建立索引的客户端缓存随每次版本升级而失效。
  • 重新整理了 MCP 指令:3 条关键的防串接规则(在 v0.4.3 和 v0.4.4 中位于区块末尾,可能因截断或注意力减弱而丢失)现在作为硬性规则 #1、#2、#3 放在最前面,紧接标题之后。内容整合为 3 个简短段落(之前是 3 个较长部分,合计约 1500 个字符)。
  • 服务端功能没有变化。 SMTP/IMAP/EWS/Graph、工具集和行为均保持不变。只有向客户端公开的文本发生了变化。
这些规则生效的重要说明

使用 claude --continue(或 /resume)恢复会话的客户端不会刷新 MCP system_prompt,而是继续使用该会话首次握手时获取的内容。如果你的会话早于 v0.4.5,即使磁盘上的二进制文件已更新,这些规则也不会进入当前上下文。如需获取这些规则,请在项目中启动一个新会话(不要使用 --continue)。

v0.4.4 版本更新

  • MCP instructions 中新增了预览规范规则:大模型向用户展示待发送的邮件预览时,应呈现一份整洁的正文版本(使用类似 Markdown 的项目符号、粗体,并将链接显示为文本 + URL),同时说明邮件将以 multipart 格式发送;但不得在预览中倾倒原始 HTML 源码(<p>、<strong>、<a href>……)。原因有两个:

    1. 人类审核者想读的是邮件内容,而不是检查标记;展示 HTML 只会造成干扰。
    2. 在预览中并排展示纯文本字符串和 HTML 字符串,正是过去导致大模型在最终工具调用中将两者串接起来的上下文(v0.4.3 记录了这个 bug)。在预览中隐藏 HTML 源码,就能避免这种诱因。

    这是对 v0.4.3 中引入的预览不等于工具调用规则的补充。

v0.4.3 新增内容

  • 服务端指导,防止格式错误的工具调用。 MCP instructions 块现在明确告知调用方大模型: body_text 和 body_html 是两个独立的 JSON 字段,绝不能拼接。 先前的措辞(“同时发送 body_text 和 body_html”)含义不明确,一些大模型将其理解为“在单个 body_text 字符串中用 <body_text>...</body_html> 伪标签拼接 两者”。发生这种情况时,收件人看到的内容会混乱且重复;而且之后任何通过此 MCP 打开已保存副本的 Claude 会话都会触发使用政策拦截(泄露的 <invoke>...</invoke> 在安全过滤器看来像是提示注入尝试)。新指令提供了正确与错误示例,并禁止在邮件字段中使用伪标签/工具调用包装语法。

v0.4.2 新增内容

  • 修复发布流水线:已禁用 CI 发布工作流中的 publish-npm 作业。该作业继承自上游分支,并尝试发布到 @bradsjm/mail-imap-mcp-rs,这是本组织不拥有的作用域,因此每次发布都会在该步骤返回 404。完整说明以及如何在需要时重新启用 npm 发布,请参阅下方的“发布”。
  • 推送标签时自动触发发布:.github/workflows/release.yml 现在会在 push: tags: ['v*'] 时运行,因此只需为 vX.Y.Z 创建标签并推送,即可发布新版本。仍保留 workflow_dispatch,作为手动备用方式。
  • 清理:移除了无效的 init-npm-placeholder.yml 工作流(该工作流也引用了分支的 npm 作用域)。
  • 文档:README 新增“发布”部分,说明新的发布流程和 npm 发布决策。

v0.4.1 新增内容

  • 修复:save_to_sent_folder 现在会归档实际发送的 RFC822 字节(通过 lettre.formatted() 获取),而不是手工拼出的纯文本占位内容。已发送文件夹中的副本会保留 HTML 正文、多部分/替代结构以及 RFC 2047 编码的主题——不再把原本的重音字符显示为 ???,也不会再悄悄丢弃 HTML。
  • 改进:本地化的已发送文件夹检测——Enviado[s]、Elementos enviados、Enviadas、Itens enviados、Envoyés、Éléments envoyés、 Gesendet、Posta inviata、Verzonden、Wysłane,以及嵌套变体。 之前只识别英文名称,因此 Zoho/本地化 IMAP 账户会回退到不存在的 "Sent" 文件夹。
  • 改进:smtp_forward_message 现在接受 body_html(此前被硬编码为仅支持纯文本)。
  • 改进:EWS 发送功能新增 bcc、in_reply_to、references(通过 <t:InternetMessageHeaders>),并加入完整的收件人及主题长度验证——现在与 SMTP 和 Graph 发送路径一致。
  • 改进:Graph API 线程关联回退现在会记录日志。消息查询 HTTP 调用失败(速率限制、5xx、权限问题)时记录 WARN,让运维人员知道线程关联因实际错误而降级;原始消息确实不存在时记录 DEBUG。
  • 重构:EWS XML 解析已从子串匹配迁移到 quick-xml。这修复了潜在的命名空间冲突错误(<soap:Body> 与 <t:Body>),能正确解码 XML 实体和 CDATA,并能处理包含 = 的属性值(EWS 项目 ID 等类 base64 字符串中常见)。
  • 清理:cargo build --release 不再产生警告。
  • 测试:64 项(之前为 47 项)。

为什么选择此项目

mail-mcp典型邮件 MCP
IMAP 读取/写入18 个工具3-5 个工具
SMTP 发送/回复/转发支持不支持或无法正常工作
Microsoft Graph API支持不支持
EWS(Exchange Web Services)支持不支持
OAuth2(XOAUTH2)原生支持不支持
多账户支持单账户
Microsoft 365 + Hotmail两者均可用通常都不可用
语言Rust(快速、安全)TypeScript/Python
测试64 项单元测试 + 集成测试仅模拟测试
发布构建中的警告0不定

功能矩阵

提供方IMAPSMTPGraph APIEWSOAuth2多账户
Microsoft 365(企业版)是取决于管理员设置是是是是
Hotmail / Outlook.com是被 MS 屏蔽是是是是
Gmail是是——是是
Apple iCloud是是———是
Zoho是是———是
Fastmail是是———是
任意 IMAP/SMTP 服务是是———是

EWS 是添加 Microsoft 账户最简单的方式——读取和发送共用一个 OAuth2 令牌。即使租户屏蔽了 Graph API 和 IMAP,也能正常使用。

快速入门 — 让 Claude Code 帮你完成

将此提示词复制并粘贴到 Claude Code 中,它会为你安装、编译并配置所有内容:

Install and configure the mail-mcp MCP server from https://github.com/tecnologicachile/mail-mcp

1. Clone the repo, build with cargo build --release
2. Add the MCP server to .claude.json with the binary path
3. For Microsoft accounts: use EWS (simplest) — run device code flow with
   client_id d3590ed6-52b3-4102-aeff-aad2292ab01c and scope
   https://outlook.office.com/EWS.AccessAsUser.All offline_access
   Then configure MAIL_EWS_<ID>_USER and MAIL_EWS_<ID>_REFRESH_TOKEN
4. For Gmail: configure MAIL_IMAP + MAIL_SMTP with App Password from
   https://myaccount.google.com/apppasswords
5. For Zoho: configure MAIL_IMAP + MAIL_SMTP with standard password
6. Enable write/send: MAIL_IMAP_WRITE_ENABLED=true, MAIL_SMTP_WRITE_ENABLED=true

My email accounts to configure:
- <[email protected]>

将最后一行替换为你的电子邮件地址。Claude Code 会引导你完成每个步骤,包括 Microsoft 账户的 OAuth2 设备代码流程。

手动设置(2 分钟)

安装预编译二进制文件:

# macOS and Linux (Homebrew)
brew install tecnologicachile/tap/mail-mcp

# macOS and Linux (shell installer)
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/tecnologicachile/mail-mcp/releases/latest/download/mail-mcp-installer.sh | sh

Shell 和 PowerShell 安装程序还会安装 mail-mcp-update,用于将现有安装更新到最新版本。使用 Homebrew 时,请运行 brew upgrade mail-mcp。

# Windows
powershell -ExecutionPolicy Bypass -c "irm https://github.com/tecnologicachile/mail-mcp/releases/latest/download/mail-mcp-installer.ps1 | iex"

或者从源代码构建:

git clone https://github.com/tecnologicachile/mail-mcp.git
cd mail-mcp
cargo build --release

将以下内容添加到 MCP 客户端配置中(Claude Code、Cursor 等)。使用预编译二进制文件时,请设置 "command": "mail-mcp":

{
  "mcpServers": {
    "mail": {
      "command": "./target/release/mail-mcp",
      "env": {
        "MAIL_IMAP_DEFAULT_HOST": "imap.gmail.com",
        "MAIL_IMAP_DEFAULT_USER": "[email protected]",
        "MAIL_IMAP_DEFAULT_PASS": "your-app-password",
        "MAIL_SMTP_DEFAULT_HOST": "smtp.gmail.com",
        "MAIL_SMTP_DEFAULT_PORT": "587",
        "MAIL_SMTP_DEFAULT_USER": "[email protected]",
        "MAIL_SMTP_DEFAULT_PASS": "your-app-password",
        "MAIL_SMTP_DEFAULT_SECURE": "starttls",
        "MAIL_IMAP_WRITE_ENABLED": "true",
        "MAIL_SMTP_WRITE_ENABLED": "true"
      }
    }
  }
}

完成。你的 AI Agent 现在可以读取、搜索、发送和回复电子邮件,还能管理邮件。

Microsoft 账户?使用 Graph API

Microsoft 会屏蔽个人账户的 SMTP。请改用 Graph API:

{
  "env": {
    "MAIL_IMAP_DEFAULT_HOST": "outlook.office365.com",
    "MAIL_IMAP_DEFAULT_USER": "[email protected]",
    "MAIL_IMAP_DEFAULT_PASS": "your-app-password",
    "MAIL_OAUTH2_DEFAULT_PROVIDER": "microsoft",
    "MAIL_OAUTH2_DEFAULT_CLIENT_ID": "9e5f94bc-e8a4-4e73-b8be-63364c29d753",
    "MAIL_OAUTH2_DEFAULT_CLIENT_SECRET": "none",
    "MAIL_OAUTH2_DEFAULT_REFRESH_TOKEN": "<your-token>"
  }
}

通过设备代码流程,1 分钟即可获取令牌。请参阅账户设置指南。

37 个 MCP 工具

读取(10 个工具)
工具功能
list_all_accounts列出所有账户及其功能(IMAP、SMTP、Graph、EWS)
imap_list_accounts列出 IMAP 账户
imap_verify_account测试连接和身份验证
imap_list_mailboxes列出文件夹
imap_mailbox_status邮件数量
imap_search_messages使用游标分页搜索;thread_message_id 可查找某条邮件及其回复
imap_search_all_mailboxes在每个邮箱中一次性按相同条件搜索(例如,查找分布在 INBOX、Sent 和项目文件夹中的完整对话),按时间从新到旧排序,并标注邮箱
imap_get_message已解析的邮件(文本、HTML、附件)
imap_get_message_rawRFC822 源内容
imap_get_attachment将单个附件下载到磁盘(不受原始大小上限限制)
写入(11 个工具)
工具功能
imap_update_message_flags添加或移除标记
imap_copy_message复制(支持跨账户)
imap_move_message移动到文件夹
imap_delete_message确认后删除
imap_create_mailbox创建文件夹
imap_delete_mailbox删除文件夹
imap_rename_mailbox重命名文件夹
imap_append_message追加原始邮件
imap_bulk_move一次移动最多 500 封邮件
imap_bulk_delete一次删除最多 500 封邮件
imap_bulk_update_flags一次为最多 500 封邮件更新标记
发送(5 个工具)
工具功能
smtp_send_message发送电子邮件(文本/HTML、抄送/密送)
smtp_reply_message使用线程标头回复
smtp_forward_message转发邮件,并内联附上原始内容
smtp_verify_account测试 SMTP 连接
graph_send_message通过 Microsoft Graph API 发送邮件(支持回复线程)
EWS — Exchange Web Services(3 个工具)
工具功能
ews_search_messages通过 EWS 搜索电子邮件(收件箱、已发送、草稿等)
ews_get_message通过 EWS 获取完整邮件内容
ews_send_message通过 EWS 发送电子邮件
草稿(5 个工具)

Agent 准备邮件,由用户在邮件客户端中审核(或要求 Agent 发送)。所有账户使用同一组工具:草稿会保存到 IMAP 草稿文件夹;如果账户已配置为使用 EWS 或 Microsoft Graph,则会通过它们保存(list_all_accounts 会显示 drafts_with)。

工具功能
draft_create保存新草稿(抄送/密送、HTML、附件、邮件串)
draft_update替换草稿内容;返回新的 draft_id
draft_send发送草稿并将其从草稿文件夹中移除
draft_delete删除草稿(仅限草稿;需要 confirm: true)
draft_list列出草稿,最新的排在最前

使用 MAIL_DRAFTS_ENABLED=true 启用。此设置独立于 MAIL_IMAP_WRITE_ENABLED:仅启用草稿时,Agent 可以撰写草稿,但无法移动、标记或删除其他邮件,而且每个草稿工具都会拒绝非草稿 ID。draft_send 还需要 MAIL_SMTP_WRITE_ENABLED=true。Graph 账户需要 Mail.ReadWrite 作用域。

附件

使用任意发送工具发送文件。支持两种模式:

// Large files — MCP reads from disk (recommended)
"attachments": [{"file_path": "/path/to/report.pdf"}]

// Small files — inline base64
"attachments": [{"filename": "note.txt", "content_type": "text/plain", "content_base64": "SGVsbG8="}]

系统会根据文件路径自动检测文件名和 MIME 类型。回复时设置 include_original_attachments: true,即可转发原始附件。

下载收到的邮件中的附件:使用 imap_get_attachment,并提供 message_id 和 part_id(来自 imap_get_message),或提供 filename。 该工具会将解码后的文件写入磁盘并返回路径——没有大小上限,且二进制内容不会出现在响应中。使用 MAIL_ATTACHMENT_DOWNLOAD_DIR 设置默认下载目录(默认使用系统临时目录),也可以在每次调用时传入 output_dir。

若要限制发送工具通过 file_path 可附加的本地文件,请设置 MAIL_ATTACHMENT_UPLOAD_DIR;该目录之外的路径(包括通过 .. 或符号链接访问的路径)都会被拒绝。请参阅 docs/security.md。

批量操作(2 个工具)
工具功能
imap_search_and_move搜索并移动匹配项
imap_search_and_delete搜索并删除匹配项
设置助手(1 个工具)
工具功能
get_setup_guide按服务提供商提供设置说明(Microsoft OAuth2、Gmail/iCloud App Passwords、Zoho 等)

多账户

可根据需要配置任意数量的账户:

# Gmail
MAIL_IMAP_GMAIL_HOST=imap.gmail.com
[email protected]
MAIL_IMAP_GMAIL_PASS=app-password

# Apple iCloud (App-Specific Password from appleid.apple.com)
MAIL_IMAP_ICLOUD_HOST=imap.mail.me.com
[email protected]
MAIL_IMAP_ICLOUD_PASS=app-specific-password
MAIL_SMTP_ICLOUD_HOST=smtp.mail.me.com
[email protected]
MAIL_SMTP_ICLOUD_PASS=app-specific-password
MAIL_SMTP_ICLOUD_SECURE=starttls

# Microsoft 365
MAIL_IMAP_WORK_HOST=outlook.office365.com
[email protected]
MAIL_OAUTH2_WORK_PROVIDER=microsoft
MAIL_OAUTH2_WORK_CLIENT_ID=your-client-id
MAIL_OAUTH2_WORK_CLIENT_SECRET=none
MAIL_OAUTH2_WORK_REFRESH_TOKEN=your-token

# Zoho
MAIL_IMAP_DEFAULT_HOST=imap.zoho.com
[email protected]
MAIL_IMAP_DEFAULT_PASS=password
MAIL_SMTP_DEFAULT_HOST=smtp.zoho.com
[email protected]
MAIL_SMTP_DEFAULT_PASS=password
MAIL_SMTP_DEFAULT_SECURE=starttls

在工具调用中使用 account_id:"account_id": "gmail"、"account_id": "icloud"、"account_id": "work"、"account_id": "default"。

安全

  • 强制使用 TLS:适用于所有连接(localhost 代理除外)
  • 密码存储在 SecretString 中——绝不记录日志或在响应中返回
  • 写操作受控——需要显式设置 MAIL_IMAP_WRITE_ENABLED=true
  • 发送操作受控——需要显式设置 MAIL_SMTP_WRITE_ENABLED=true
  • 草稿单独受控——MAIL_DRAFTS_ENABLED=true 允许撰写草稿,而无需开放任何其他写入权限
  • 删除确认——需要 confirm: true
  • 使用 ammonia 清理 HTML(防止 XSS)
  • 输出有上限——正文文本、HTML、附件会截断至可配置的限制
  • 缓存 OAuth2 令牌,并预留 10 分钟的刷新缓冲时间
  • 响应中不包含机密信息——凭据不会通过 MCP 工具泄露
  • HTTP 传输为可选且未经身份验证——默认使用 stdio;MAIL_MCP_TRANSPORT=http 会绑定到回环地址,除非另有指定,并且应置于经过身份验证的网关之后

配置参考

完整的环境变量参考
IMAP(每个账户)
变量必填默认值说明
MAIL_IMAP_<ID>_HOST是—IMAP 服务
MAIL_IMAP_<ID>_PORT否993IMAP 端口
MAIL_IMAP_<ID>_USER是—用户名
MAIL_IMAP_<ID>_PASS是*—密码(*使用 OAuth2 时可选)
MAIL_IMAP_<ID>_SECURE否true使用 TLS
SMTP(每个账户)
变量必需默认值描述
MAIL_SMTP_<ID>_HOST是—SMTP 服务器
MAIL_SMTP_<ID>_PORT否587SMTP 端口
MAIL_SMTP_<ID>_USER是—用户名
MAIL_SMTP_<ID>_PASS否—密码(使用 OAuth2 时可选)
MAIL_SMTP_<ID>_SECURE否starttlsstarttls、tls 或 plain
MAIL_SMTP_<ID>_FROM_EMAIL否= _USER发件人地址与 SMTP 身份验证用户名不同时使用(例如共享/群组邮箱)
OAuth2(每个账户)
变量必需默认值描述
MAIL_OAUTH2_<ID>_PROVIDER是—google 或 microsoft
MAIL_OAUTH2_<ID>_CLIENT_ID是—OAuth2 客户端 ID
MAIL_OAUTH2_<ID>_CLIENT_SECRET是—客户端密钥(公共客户端使用 none)
MAIL_OAUTH2_<ID>_REFRESH_TOKEN是—刷新令牌
Graph API OAuth2(每个账户)
变量必需默认值描述
MAIL_GRAPH_<ID>_PROVIDER是—microsoft
MAIL_GRAPH_<ID>_CLIENT_ID是—OAuth2 客户端 ID
MAIL_GRAPH_<ID>_CLIENT_SECRET是—客户端密钥(公共客户端使用 none)
MAIL_GRAPH_<ID>_REFRESH_TOKEN是—刷新令牌(Mail.Send 范围)
EWS — Exchange Web Services(每个账户;Microsoft 的最简单选项)
变量必需默认值描述
MAIL_EWS_<ID>_USER是—电子邮件地址
MAIL_EWS_<ID>_REFRESH_TOKEN是—OAuth2 刷新令牌(EWS 范围)
MAIL_EWS_<ID>_CLIENT_ID否d3590ed6...(Microsoft Office)OAuth2 客户端 ID
MAIL_EWS_<ID>_CLIENT_SECRET否none客户端密钥

提示: EWS 只需要 2 个变量(USER + REFRESH_TOKEN)。客户端 ID 默认为 Microsoft Office,其所有权限都已预先批准。

全局设置
变量默认值描述
MAIL_IMAP_WRITE_ENABLEDfalse启用 IMAP 写入操作
MAIL_SMTP_WRITE_ENABLEDfalse启用 SMTP/Graph 发送操作
MAIL_DRAFTS_ENABLEDfalse启用草稿工具(draft_send 还需要启用 MAIL_SMTP_WRITE_ENABLED)
MAIL_SMTP_SAVE_SENTfalse将已发送邮件保存到 IMAP Sent 文件夹(如果你的提供商发送邮件时不会自动保存,请启用此项——例如 Gmail 会自动保存,Zoho 则不一定)
MAIL_SMTP_CONNECT_TIMEOUT_MS30000SMTP TCP/TLS/身份验证超时时间(连接阶段)
MAIL_SMTP_SEND_TIMEOUT_MS300000SMTP DATA 传输超时时间(5 分钟,可容纳大型附件)
MAIL_SMTP_TIMEOUT_MS(已弃用)旧版单一超时时间。作为 MAIL_SMTP_SEND_TIMEOUT_MS 的备用值。建议改用上面的拆分变量。
MAIL_IMAP_CONNECT_TIMEOUT_MS30000TCP 连接超时时间
MAIL_IMAP_GREETING_TIMEOUT_MS15000TLS/问候超时时间
MAIL_IMAP_SOCKET_TIMEOUT_MS300000套接字 I/O 超时时间
MAIL_IMAP_MAX_MAILBOXES200imap_list_mailboxes 返回的最大邮箱数(1–10000);响应会报告 total 和 truncated
MAIL_IMAP_SEARCH_CONCURRENCY4imap_search_all_mailboxes 使用的并行 IMAP 连接数(1–8)
MAIL_OAUTH2_TOKEN_STORE(未设置)保存轮换后 OAuth2 刷新令牌的文件,以便在重启后保留令牌(参见 OAuth2 令牌存储)
MAIL_MCP_TRANSPORTstdiostdio;或使用 http 提供 MCP 流式 HTTP 服务(参见 远程 HTTP 传输)
MAIL_MCP_HTTP_HOST127.0.0.1HTTP 绑定地址(IP 字面值)
MAIL_MCP_HTTP_PORT8000HTTP 绑定端口
MAIL_MCP_HTTP_PATH/mcpHTTP 端点路径
## 路线图
  • IMAP 读取操作(搜索、获取、解析)
  • IMAP 写入操作(复制、移动、删除、标记)
  • IMAP 批量操作(每次最多 500 项)
  • 基于游标的分页,带 TTL
  • SMTP 发送、回复、转发
  • Microsoft Graph API(sendMail)
  • OAuth2 XOAUTH2(Google + Microsoft)
  • 面向企业的独立 Graph API 令牌
  • 通过环境变量支持多个账户
  • 从附件中提取 PDF 文本
  • HTML 清理(ammonia)
  • 提供商设置文档,附直接链接
  • 发送附件(SMTP/Graph)
  • 回复时附上原始附件
  • CDATA 清理(修复 Zoho 问题)
  • 邮件确认协议(发送前预览)
  • 令牌优化说明(减少 75%)
  • 按需设置指南工具
  • EWS(Exchange Web Services) — 在 Microsoft 上使用单个令牌进行读取和发送
  • 支持使用 Microsoft Office Client ID 的 EWS(适用于受限租户)
  • Graph API 会话串接 — 使用 createReply 流程正确串接对话
  • HTML 格式指南 — 对于发送给真人的邮件,大模型更倾向于使用 multipart(文本 + HTML)
  • 已发送邮件文件夹归档保留完整 MIME — 与收件人收到的邮件逐字节一致(v0.4.1)
  • 本地化的已发送邮件文件夹检测 — 西班牙语 / 葡萄牙语 / 法语 / 德语 / 意大利语 / 荷兰语 / 波兰语(v0.4.1)
  • EWS 功能与 SMTP/Graph 对齐 — BCC、会话串接标头、收件人验证(v0.4.1)
  • 通过 quick-xml 实现 EWS XML 解析器 — 正确处理实体、CDATA 和命名空间(v0.4.1)
下一步 — 支持即时搜索的本地缓存
  • SQLite + FTS5 本地邮件缓存 — 即时搜索(<10ms,而非 3-10s)
  • 增量同步 — UIDVALIDITY + 最后一个 UID 增量同步
  • 连接池 — 为每个账户维护持久的 IMAP 会话
  • 跨账户搜索 — 一次搜索所有账户
  • 邮件统计信息 — 数量、主要发件人、按日期统计的活动情况
未来
  • Docker 镜像
  • npm/npx 分发
  • 草稿管理
  • 联系人搜索
  • IMAP IDLE(实时通知)
  • 托管文档网站

文档

指南说明
账户设置各提供商的分步指南、OAuth2、应用专用密码、Azure Client ID
工具契约完整的工具定义和架构
消息 ID 格式稳定的消息标识符格式
游标分页分页行为和过期时间
安全性安全功能和最佳实践
高级配置超时和性能调优

开发

cargo test              # 64 unit + integration tests
cargo fmt -- --check    # formatting
cargo clippy --all-targets -- -D warnings  # linting

贡献者指南请参阅 AGENTS.md。

发布

发布通过 cargo-dist 自动完成。要发布新版本:

  1. 在 Cargo.toml 中更新 version = "X.Y.Z"(发布工作流会确保该版本与推送的标签一致)。
  2. 将此更新和任何发布说明提交到 main。
  3. 创建标签并推送:
    git tag vX.Y.Z
    git push origin main --tags
    
  4. .github/workflows/release.yml 中的 push: tags: ['v*'] 触发器会为 Linux / macOS(Intel + Apple Silicon)/ Windows 编译二进制文件,生成安装脚本(.sh、.ps1),创建 GitHub Release,并附上所有带 SHA256 校验和的构件。
  5. 如果发生故障,可以在 Actions 标签页中手动重新运行工作流(保留了 workflow_dispatch 触发器作为应急方案)。

有意禁用了 npm 发布。 上游分支被配置为以 @bradsjm/mail-imap-mcp-rs 发布,而本组织并不拥有此作用域,因此每次发布时 npm publish 都会返回 404。npm tarball 仍会生成并附加到每个 GitHub Release,供用户手动通过 npm install ./mail-mcp-npm-package.tar.gz 安装。若要为此分支启用 npm 注册表发布:创建一个 npm 组织(例如 @tecnologicachile),在 npmjs.com 上配置指向此仓库的 Trusted Publishing,在 dist-workspace.toml 中设置 publish-jobs = ["npm"],然后运行 dist generate --allow-dirty,以恢复 release.yml 中的 publish-npm 作业。

贡献

欢迎贡献!请查看 issues,寻找适合新手的议题。

如果 mail-mcp 对你有用,请给仓库点个 ⭐,帮助其他人发现它。

许可证

MIT 许可证——详情请参阅 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

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

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