mcpField
I
iris

iris

本地服务
github.com/SuperAngryMonkey通信协作05 周前更新

关于 iris

iris 是面向 AI Agent 的本地 Microsoft 365 邮件 MCP 服务,默认支持读取邮件和编辑草稿。发送默认关闭;只有显式配置后才能启用,且发送需要确认并通过允许列表检查。

主要功能

  1. 01读取并搜索邮箱邮件
  2. 02创建、修改和删除草稿
  3. 03默认禁用邮件发送
  4. 04发送时要求确认并检查允许列表
  5. 05记录工具调用

适用场景

  1. 01搜索邮件并阅读对话线程
  2. 02在 Outlook 中准备草稿供人工审核
  3. 03启用发送时限制收件人
  4. 04查看工具活动审计日志

MCP 相关

iris 以本地 stdio MCP 服务运行,并提供邮件和草稿工具。它也可通过 Cloudflare Worker 部署为 HTTP MCP 服务;只有显式启用后才会提供发送工具。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"superangrymonkey-iris": {
"command": "uvx",
"args": [
"iris-mcp"
],
"env": {
"IRIS_CLIENT_ID": "<IRIS_CLIENT_ID>",
"IRIS_TENANT_ID": "<IRIS_TENANT_ID>",
"IRIS_DRAFT_FOLDER": "<IRIS_DRAFT_FOLDER>",
"IRIS_ALLOWLIST": "<IRIS_ALLOWLIST>",
"IRIS_DISABLE_READ": "<IRIS_DISABLE_READ>",
"IRIS_ENABLE_SEND": "<IRIS_ENABLE_SEND>"
}
}
}
}
启动命令uvx iris-mcp
需要配置的环境变量
IRIS_CLIENT_IDApplication (client) ID of YOUR OWN Entra app registration. There is no shared app; you register one.
IRIS_TENANT_IDDirectory (tenant) ID. Defaults to 'organizations'.
IRIS_DRAFT_FOLDERMail folder drafts are written to, created on first use. Defaults to 'AI Drafts'. Empty string uses Drafts.
IRIS_ALLOWLISTPath to a recipient allowlist file. If absent or empty, all recipients are permitted.
IRIS_DISABLE_READSet to '1' to unregister the read tools (list/search/get messages and threads) for a drafts-only surface.
IRIS_ENABLE_SENDSet to '1' to enable sending. ALSO requires Mail.Send granted on the Entra app and a fresh sign-in. Off by default; when unset, iris cannot send and the send tool is not registered.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiiris-mcp0.3.0

工具

12

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

iris

面向 AI Agent 的 Microsoft 365 邮件服务,可读取邮箱并撰写草稿,但不会发送邮件,除非你决定启用发送功能。

默认情况下,iris 请求委托 Graph 权限范围 Mail.ReadWrite,绝不请求 Mail.Send。它持有的访问令牌没有发送邮件的能力, 因此,任何提示词、越狱手段或此代码中的漏洞都无法让邮件发出。它会将 草稿写入邮箱中的一个文件夹;你打开 Outlook 并点击“发送”。

发送功能需要明确选择启用(IRIS_ENABLE_SEND=1),并且必须授予 Mail.Send 权限范围并重新同意——即便如此,每次发送仍需人工确认, 并经过允许列表检查。保持关闭(默认设置),就如上所述,无法发送邮件 这一特性是结构性的。请参阅启用发送。

这就是整个设计。其他一切都是细节。


为什么这样设计

通常,人们担心把邮箱交给 Agent 后,它会发送你未批准的内容——发给 错误的人、使用不恰当的语气,或者因为有人说服它这么做。常见的解决 办法是确认提示,这只是一道防护措施:代码会请求许可,而代码也可以被 绕过。

iris 直接移除了发送能力。Microsoft Graph 会拒绝使用此令牌发起的发送 尝试,因为你批准的同意页面从未包含该权限。安全边界由 Microsoft 把守, 而非由此程序把守;即使此程序出错,这一边界依然有效。

这种取舍确实存在:按照设计,每封邮件都需要人工参与。如果你想要自主 发送邮件,iris 就不是合适的工具。

安装

uvx iris-mcp        # run without installing
pip install iris-mcp

Python 3.10 或更高版本。 macOS 自带 Python 3.9,版本太旧——mcp 需要 3.10+。请使用 uv(它自带 uvx, 并管理自己的 Python),或通过 Homebrew 安装较新的 Python (brew install [email protected])。macOS 上的系统 python3 无法使用。

设置

你必须注册自己的 Entra 应用程序。 没有共享的应用程序注册,也没有 托管服务——iris 会直接从你的计算机连接到你的租户。这是有意为之:使用 共享应用程序就意味着要信任他人的客户端 ID 能访问你的邮件。

  1. Entra 管理中心 → 应用注册 → 新注册。单租户即可。无需重定向 URI。
  2. 身份验证 → 设置 → 启用 允许公共客户端流。设备代码登录 需要此设置。任何地方都不会使用客户端机密。
  3. API 权限 → Microsoft Graph → 委托 → 添加 Mail.ReadWrite。仅用于草稿(默认设置)时,不要添加其他权限,并且 保持 Mail.Send 关闭——正是这一权限的缺失,使无法发送邮件这一特性 成为结构性的。只有在打算启用发送功能时才添加 Mail.Send(请参阅 启用发送)。
  4. 复制应用程序(客户端)ID和目录(租户)ID。两者都不是机密。

然后将 iris 添加到你的 MCP 客户端:

{
  "mcpServers": {
    "iris": {
      "command": "uvx",
      "args": ["iris-mcp"],
      "env": {
        "IRIS_CLIENT_ID": "<application (client) id>",
        "IRIS_TENANT_ID": "<directory (tenant) id>"
      }
    }
  }
}

登录一次:调用 iris_login,打开该 URL,输入代码,然后调用 iris_login_finish。令牌缓存会写入服务所在目录,权限模式为 600。

要部署到整个团队? 请参阅管理员部署 指南,了解如何在整个 Microsoft 365 租户中授权 iris:管理员同意、逐用户分配,以及为何继续采用委托模式而非应用程序权限。

客户端

iris 是本地 stdio MCP 服务:你的 MCP 客户端会在同一台计算机上将其作为 子进程启动。它适用于所有支持本地 stdio 服务的客户端,包括 Claude Desktop、 Cursor 和 Grok CLI (grok mcp add iris -- uvx iris-mcp)。

它不适用于只接受通过 HTTP 连接远程 MCP 服务的客户端。Grok 应用 / Grok Bot 属于这一类——它接受托管的 HTTP 服务,而非本地 stdio 服务——因此 iris 无法直接连接到它。可以将 iris 转接为 HTTP 传输,但这不在本项目的范围内。

工具

工具功能
iris_login启动设备代码登录,返回一个 URL 和代码
iris_login_finish完成登录;输入代码期间可以安全地重复调用
iris_auth_status查看登录用户、权限范围,以及 Graph 是否可访问
iris_list_folders列出顶级邮件文件夹,供你选择一个用于存放草稿
iris_list_messages列出文件夹中的近期邮件,最新的排在前面(默认使用收件箱;支持 unread_only、since)
iris_search_messages使用 Outlook/KQL 语法搜索邮箱(from:、subject:、received>=……)
iris_get_message完整读取一封邮件:邮件头、纯文本正文和附件名称
iris_get_thread读取整个会话,最早的邮件排在前面
iris_create_draft撰写草稿(to/cc/bcc、主题、正文或 HTML、可选的 reply-to、可选的 folder)
iris_list_drafts列出草稿文件夹中待处理的邮件(可选的 folder)
iris_update_draft就地修改草稿
iris_delete_draft删除草稿;需要 confirm=true
iris_send_draft仅在 IRIS_ENABLE_SEND=1 时提供。 发送现有草稿;需要 confirm=true,并会重新检查允许列表
读取邮件

这四个读取工具均为只读:它们不会将邮件标记为已读,不会创建文件夹,并且每次调用都会写入审计日志。邮件正文是第三方文本——Agent 应将其视为数据,而不是指令。如果你只想使用草稿工具,可设置 IRIS_DISABLE_READ=1 将这些工具取消注册(无论是否设置,该工具获得的权限范围都相同;请参阅 SECURITY.md)。

多个邮箱

在 MCP 客户端配置中以另一个名称运行第二个实例,为其设置独立的 IRIS_CLIENT_ID / IRIS_TENANT_ID(用于另一个租户中的邮箱),并使用独立的 IRIS_TOKEN_CACHE、IRIS_FLOW_FILE 和 IRIS_AUDIT_LOG 路径,以确保两者不会共用登录信息:

"iris-work": {
  "command": "iris-mcp",
  "env": {
    "IRIS_CLIENT_ID": "<app id in the other tenant>",
    "IRIS_TENANT_ID": "<other tenant id>",
    "IRIS_TOKEN_CACHE": "~/.config/iris-work/token_cache.json",
    "IRIS_FLOW_FILE": "~/.config/iris-work/pending_flow.json",
    "IRIS_AUDIT_LOG": "~/.config/iris-work/audit.log"
  }
}

如果你的客户端不会展开 ~,请使用绝对路径。

草稿存放位置

草稿会存放在专用的顶级邮件文件夹中,默认名称为 AI Drafts(IRIS_DRAFT_FOLDER),并在首次使用时创建。将该变量设为空字符串,即可改用常规 Drafts 文件夹。

你也可以为每封草稿选择文件夹:将 folder 传给 iris_create_draft(和 iris_list_drafts),即可指定任意文件夹;如果该文件夹不存在,会在首次使用时创建。传入 "" 或 "Drafts" 可使用常规 Outlook Drafts 文件夹,也可以先调用 iris_list_folders,从现有文件夹中选择。省略 folder 时会使用 IRIS_DRAFT_FOLDER 的默认值,因此现有配置不会发生变化。

这些都是真正的草稿,Outlook 会照常发送——但由于它们存放在自己的文件夹中,因此不会出现在 Drafts 视图里。这样设计正是为了让 Agent 撰写的邮件单独存放在一个需要你主动查看的位置,而不会和你尚未完成的邮件混在一起。

有一点需要注意:Graph 的 createReply 总是会先将回复放入 Drafts,因此 iris 会在之后将其移走;移动操作会分配新的邮件 ID。

启用发送

默认情况下,发送功能处于关闭状态,而且按设计需要经过三个有意的步骤——缺少任何一步,iris 仍然无法发送:

  1. 在你的 Entra 应用注册中,除了 Mail.ReadWrite,还要添加 Mail.Send(Delegated)。
  2. 在服务器的环境中设置 IRIS_ENABLE_SEND=1。只有这样才会请求 Mail.Send,并注册 iris_send_draft 工具。
  3. 再次运行 iris_login 以重新同意授权——缓存的令牌早于新增的作用域,只有重新同意后才会包含该作用域。

随后,iris_send_draft(draft_id, confirm=true) 会发送现有草稿。如果没有 confirm,它会拒绝执行;发送前会再次确认邮件仍是未发送的草稿,并重新检查收件人允许列表。流程仍然是撰写 → 审阅 → 发送;iris 绝不会一次性撰写并发送。

请理解其中的权衡。关闭发送功能时,Microsoft 会根据你的授权强制执行“无法发送”,即使代码有误也依然如此。启用发送功能后,最后一道防线是每次调用时的确认——这是代码中的一道防护栏,而这类检查恰恰可能被漏洞或措辞巧妙的提示词绕过。只有在可以接受这种较弱保障的场景中才启用它。

其他控制措施

  • 收件人允许列表 — recipients.allow,每行填写一个地址或域名。文件不存在或为空时,表示允许所有收件人。如果需要,可以将 IRIS_ALLOWLIST 指向其他位置。
  • 紧急停止开关 — 在服务器旁创建一个 DISABLED 文件,或设置 IRIS_DISABLED=1,所有工具都会拒绝执行。
  • 审计日志 — 每次调用都会追加到 audit.log(IRIS_AUDIT_LOG)。

限制

不支持附件。不支持共享邮箱或委派邮箱——仅支持 /me。不支持通过 parentFolderId 嵌套文件夹。登录采用面向公共客户端的委派设备代码方式,因此影响范围恰好只有一个邮箱:你的邮箱。

安全

关于禁止发送的保障、如何自行验证,以及同样重要的内容——iris 通过 Mail.ReadWrite 可以访问什么,请参阅 SECURITY.md。

作为 HTTP 服务运行(Cloudflare Worker)

除了 pip install iris-mcp(stdio)之外,iris 还提供了一个 Cloudflare Python Worker,位于 worker/,可通过 HTTP 提供 MCP 服务——适用于只能访问远程 URL 的 Agent(例如托管式聊天机器人)。一键部署和完整设置说明请见 worker/README.md。

许可证

MIT — 请参阅 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

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

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