Skip to main content
Glama

outlook-ews-mcp

Python MCP Exchange Status License

outlook-ews-mcp 是一个面向本地 Microsoft Exchange 的 MCP 服务器,通过 EWS(exchangelib)实现。它为兼容 MCP 的客户端(Claude Desktop、Claude Code 以及任何其他 MCP 客户端)提供对电子邮件、日历、联系人、文件夹、附件和可用性数据的访问,通过一个可测试的 Python 服务即可完成——无需直接编写邮箱脚本。

outlook-mcp 更名而来。 该名称在 PyPI 上已被一个无关项目占用,因此发行版和 CLI 名称现在为 outlook-ews-mcp。Python 导入路径保持不变。在首次标记的 PyPI 发布之前,请按如下所示从本仓库安装。

目录

Related MCP server: owa-mail-mcp

亮点

  • 电子邮件 — 列出、搜索(子字符串或高级查询语法)、读取、发送、回复、转发、移动、复制、删除、标记、分类、批量操作、原始 MIME 导出、附件添加/删除

  • 系统 — 收件箱规则、外出(自动回复)、只读委托列表

  • 日历 — 列出、创建、更新、删除、响应邀请、查找空闲时段、查看共享/委托邮箱的日历、会议室查找器、批量操作

  • 联系人 — 搜索、读取、创建、更新、删除

  • 文件夹与附件 — 文件夹 CRUD 和附件下载

  • 认证 — 针对本地 Exchange 的 NTLMBasic

  • 传输stdioSSE

  • 架构 — 通过统一的 ExchangeClient 抽象进行集中错误映射(参见项目说明

  • 安全性 — 默认采用更注重隐私的冒烟检查(参见冒烟检查

  • 运维 — 包含 Docker 镜像以及 GitHub 和 GitLab CI/CD 流水线

工具目录

以下每个工具都在 tool_specs.py 中注册,该文件是其名称、描述和模式的唯一来源。只读 标记表示这些工具永远不会修改邮箱——它们获得更高的并发度(参见请求队列),并且可以安全地推测性调用。

系统

工具

描述

只读

ping_exchange

检查与 Exchange 的连接

get_mailbox_info

获取邮箱元数据

list_delegates

列出邮箱委托及其文件夹权限级别——只读,因为 exchangelib 不支持委托写入

list_inbox_rules

列出服务器端收件箱规则

create_inbox_rule

创建服务器端收件箱规则,例如“来自此发件人 → 移动到文件夹”

update_inbox_rule

启用/禁用规则或更改其优先级(此处其他字段不可更新)

delete_inbox_rule

按 ID 删除服务器端收件箱规则

get_out_of_office

获取外出(自动回复)设置

set_out_of_office

关闭、开启自动回复,或安排开始/结束时间窗口

⚠️ create_inbox_rule / update_inbox_rule / delete_inbox_rule 通过 EWS 管理规则,这会移除桌面 Outlook 保留的客户端规则块——这可能会清除用户在 Outlook 中创建的规则。这是 EWS 的文档化行为,并非本项目的缺陷。

电子邮件

工具

描述

只读

list_emails

列出文件夹中的电子邮件

get_email

按 ID 获取完整电子邮件

get_email_mime

导出消息的原始 RFC 822 MIME 内容,base64 编码

get_thread

按顺序获取对话中的每条消息,包括正文

search_emails

按子字符串(主题/正文/发件人)或服务器端高级查询语法搜索

send_email

发送新电子邮件

reply_email

回复电子邮件

forward_email

转发电子邮件

move_email

将电子邮件移动到另一个文件夹

copy_email

将电子邮件复制到另一个文件夹

move_emails

批量移动,带逐项结果——一个坏 ID 不会导致其余失败

copy_emails

批量复制,带逐项结果

delete_emails

批量删除,带逐项结果(除非 hard_delete,否则为软删除)

delete_email

删除电子邮件

mark_email

更新已读状态、重要性或后续标志

categorize_email

设置、添加或删除 Outlook 类别(彩色标签)

mark_emails

mark_email 的批量版本,带逐项结果

categorize_emails

categorize_email 的批量版本,带逐项结果

list_categories

列出使用中的类别及计数,从最近的消息中采样(不是邮箱主类别列表)

list_folders

列出邮箱文件夹

create_folder

创建邮箱文件夹

rename_folder

重命名文件夹——拒绝内置文件夹(收件箱、已发送邮件、日历等)

delete_folder

删除文件夹及其所有内容——拒绝内置文件夹

create_draft

创建电子邮件草稿

update_draft

更新草稿;省略的字段保持不变,attachments(如果提供)替换整个集合

send_draft

发送现有草稿

add_attachment

将本地文件附加到消息,通常是草稿——文件必须位于 EXCHANGE_ATTACHMENT_ROOT

delete_attachment

按 ID 从消息中移除一个附件

get_attachment

将附件保存到磁盘

日历

工具

描述

只读

list_events

列出时间范围内的日历事件;传入 mailbox 可查看同事的默认日历(需要委托/模拟访问权限,不能与 calendar_id 同时使用)

get_event

按 id 获取日历事件;传入 mailbox 可查看同事的日历

create_event

创建日历事件

update_event

更新日历事件

delete_event

删除日历事件

respond_to_invite

接受、拒绝或暂定回复邀请

find_free_slots

查找空闲的会议时间段

delete_events

批量删除事件,并返回逐项结果

respond_to_invites

批量回复邀请,并返回逐项结果

get_my_availability

获取空闲/忙碌时间段;传入 mailbox 可查看同事的日历

list_calendars

列出日历

list_room_lists

列出 Room Finder 会议室列表(会议室分组)

list_rooms

列出 Room Finder 会议室列表中的会议室

联系人

工具

描述

只读

search_contacts

搜索联系人

get_contact

按 id 获取联系人

create_contact

创建个人联系人

update_contact

更新个人联系人

delete_contact

删除个人联系人

典型使用场景

  • 将 Claude Desktop 或其他 MCP 客户端连接到本地 Exchange

  • 搜索收件箱邮件并获取完整邮件内容

  • 从 AI 工作流中发送或起草邮件

  • 查看日历并创建会议

  • 检查空闲/忙碌时间段以安排日程

  • 搜索个人联系人或全局地址列表

  • 通过受控的 MCP 边界公开 Exchange 操作,而不是直接编写邮箱脚本

安全说明

当前代码的做法:

受限连接

仅连接到 EXCHANGE_SERVER 中配置的 Exchange/EWS 端点

无遥测

不包含任何遥测、分析或第三方数据导出逻辑

密钥保存在本地

将密钥保存在环境变量 / .env 中,并被 .gitignore 忽略(.env.env.*,同时保留 .env.example

干净的错误负载

结构化的 MCP 错误响应绝不包含原始 Exchange 异常文本、邮件正文、附件内容或密码;成功的工具只返回被请求的邮箱数据

干净的日志

LOG_LEVEL 仅控制应用自身的 outlook_mcp.* 日志记录器;exchangelib 的 SOAP XML 日志记录器——否则即使在传输错误时也会在 ERROR 级别转储完整的请求/响应 XML——始终被强制静音

干净的 Docker 构建

.dockerignore.env、测试、缓存和 VCS 元数据排除在构建上下文之外

你仍然需要注意的事项:

  • EXCHANGE_VERIFY_SSL=false 会禁用 TLS 证书验证——仅适用于受信任的内部/自签名环境。

  • EXCHANGE_AUTH_TYPE=Basic 会以明文发送凭据,因此服务器拒绝针对 http://EXCHANGE_SERVER 启动;只有在你控制的本地/测试服务器上,才可以用 EXCHANGE_ALLOW_INSECURE_BASIC_AUTH=true 覆盖此设置。

  • get_attachment 会将文件写入磁盘,而 send_email/reply_email/forward_email/ create_draft 会读取本地文件(通过 attachments)并将其内容附加到 外发邮件中。结合不受信任的邮件内容,这可能是通过提示注入窃取进程可读取的任何文件的可行途径。本地文件访问 默认被拒绝,只有在将 EXCHANGE_ATTACHMENT_ROOT 设置为绝对目录后才可用, 该目录随后将 attachments 路径和 get_attachmentsave_path 都限制在该目录树内(未设置的 save_path 仍会回退到系统临时目录)。

  • outlook-ews-mcp-smoke 默认是隐私安全的,只打印脱敏的邮箱信息 和计数;只有在你明确希望将真实的收件箱/事件数据输出到 stdout 时,才设置 OUTLOOK_MCP_SMOKE_INCLUDE_DATA=true

  • 如果使用 LOG_FILE 启用文件日志记录,请使用操作系统权限保护该文件。

  • 如果从 CI 发布 Docker 镜像,请保护 GitLab/GitHub 项目访问权限和 注册表权限。

快速开始

uv venv
source .venv/bin/activate
uv pip install -e .[dev]
cp .env.example .env
outlook-ews-mcp

默认情况下,服务器以 stdio 模式运行。设置 MCP_TRANSPORT=sse 可启动 HTTP 服务器。

配置

开始使用所需的最小 .env——以下所有内容都有可用的默认值:

EXCHANGE_SERVER=https://mail.company.com/EWS/Exchange.asmx
EXCHANGE_USERNAME=DOMAIN\username
EXCHANGE_PASSWORD=secret
EXCHANGE_EMAIL_ADDRESS=user@company.com
EXCHANGE_AUTH_TYPE=NTLM

每个变量的完整注释副本位于 .env.example 中。

变量

默认值

描述

EXCHANGE_SERVER

(必填)

EWS 端点 URL,例如 https://mail.company.com/EWS/Exchange.asmx

EXCHANGE_USERNAME

(必填)

DOMAIN\username 或 UPN。必须恰好一个反斜杠——dotenv 不处理转义序列

EXCHANGE_PASSWORD

(必填)

账户密码

EXCHANGE_EMAIL_ADDRESS

未设置

SMTP 地址;当 EXCHANGE_USERNAME 不是 SMTP 地址时设置

EXCHANGE_AUTH_TYPE

NTLM

NTLMBasic

EXCHANGE_ALLOW_INSECURE_BASIC_AUTH

false

允许通过 http:// 使用 Basic 认证——仅限本地/测试服务器

EXCHANGE_VERIFY_SSL

true

验证服务器的 TLS 证书;仅对受信任的内部/自签名设置使用 false

EXCHANGE_VERSION

未设置(自动检测)

Exchange 服务器版本,例如 EXCHANGE_2016

EXCHANGE_TIMEZONE_FALLBACK

Europe/Moscow

仅当 Exchange 报告无法解析的 GUID 时区 ID 时使用;正常操作使用邮箱自身的默认时区

EXCHANGE_TIMEOUT

30

每个请求的超时时间(秒)(1–300)

EXCHANGE_MAX_RETRY_WAIT_SECONDS

90

当 Exchange 报告自身繁忙时,只读调用的墙钟重试预算,不是重试次数;0 禁用重试。写入操作从不自动重试

EXCHANGE_IMPERSONATE_AS

未设置

要模拟的邮箱(需要 Exchange 模拟权限)

EXCHANGE_ATTACHMENT_MAX_SIZE_MB

10

每个附件的最大大小,在上传和 get_attachment 下载时都强制执行(1–100)

EXCHANGE_ATTACHMENT_MAX_COUNT

10

单次发送/回复/转发/创建草稿调用中的最大附件数(1–100)

EXCHANGE_ATTACHMENT_MAX_TOTAL_SIZE_MB

25

单次调用中附件总大小的上限(1–500)

EXCHANGE_ATTACHMENT_ROOT

未设置(禁用)

限制附件路径的目录。未设置时拒绝所有对 attachments/save_path 的本地文件访问;设置为绝对目录以允许其中的路径

EXCHANGE_EMAIL_BODY_MAX_CHARS

200000

get_emailbody_text/body_html 上限(1,000–5,000,000);较长的正文会被截断并标记 truncated: true

EXCHANGE_EMAIL_MIME_MAX_SIZE_MB

25

原始 MIME 导出在 base64 扩展之前的大小上限(1–100)

EXCHANGE_SIGNATURE_TEXT

未设置

附加到外发文本正文和回复/转发。没有 EWS 签名 API,因此这是配置,而不是邮箱的 Outlook 签名

EXCHANGE_SIGNATURE_HTML

未设置

附加到外发 HTML 正文。与上述相同;两者之间不进行交叉转换。每次调用可通过 include_signature: false 跳过任一签名

MCP_TRANSPORT

stdio

stdiosse

MCP_SSE_HOST

127.0.0.1

MCP_TRANSPORT=sse 时的绑定主机

MCP_SSE_PORT

8080

MCP_TRANSPORT=sse 时的绑定端口

MCP_MAX_CONCURRENCY

4

并发只读工具调用数(1–8);修改调用始终独占运行。参见 请求队列

MCP_MAX_QUEUE_SIZE

20

一次允许的最大调用数,包括运行中和等待中(1–1000);超过后,调用会立即收到 server_busy 错误

LOG_LEVEL

INFO

DEBUGINFOWARNINGERROR

LOG_FILE

未设置(stderr)

日志文件路径;如果设置,请使用操作系统权限保护它

不绑定单个变量的行为说明:

  • list_eventsfind_free_slots 接受有界 limit(默认 200,最大 1000);事件范围上限为 366 天,空闲时段范围上限为 31 天,因此宽泛查询 不会产生无界的 EWS 或 MCP 响应。

  • 列表保持精简:邮件摘要包含发件人但不包含收件人列表 (get_email 中有),list_events 返回的事件不包含正文(get_event 中有), 并且 get_email 仅在 include_headers: true 时返回 RFC-822 头。

  • 当 EWS 未提供已发送副本的持久 ID 时,发送操作返回 id: null (特别是回复、转发和已发送草稿)。

  • 附件元数据包含 downloadable;嵌入的 Exchange 项目附件具有 downloadable: false,无法通过 get_attachment 保存。

请求队列

客户端会并行发出多个工具调用。Exchange 工作是阻塞性的,因此服务器 在工作线程中运行它,并通过一个共享的 FIFO 队列接纳调用。

  • MCP_MAX_CONCURRENCY(默认 4)设置同时运行的只读调用数量,因此 代理请求邮件、文件夹列表和日历时,支付的是最慢的往返时间,而不是总和。 修改调用始终独占运行——一次一个,绝不与读取重叠——因此共享账户状态上的读写竞争不会发生。 超出限制的调用者按到达顺序等待;等待中的修改会阻止后面的读取超越它。

  • MCP_MAX_QUEUE_SIZE(默认 20)限制一次可以接纳的调用数量, 无论是运行中还是等待中。一旦达到该数量,进一步的调用会立即收到 server_busy 错误,而不是加入无界队列。

  • 传输在任务进行中保持响应。 工具被等待而不是在事件循环线程上运行, 因此完成的响应会立即发出,并且在长时间调用仍在运行时,ping 会得到应答。

  • 故意没有每次调用的超时。 阻塞在套接字读取上的线程无法从外部终止; 运行时只能停止等待它,这会放弃线程及其持有的 EWS 会话。exchangelib 的会话池 有硬性上限,并在循环中分配会话而没有放弃路径,因此泄漏的会话最终会使其耗尽, 之后每次调用都会永远阻塞。慢调用会被等待,受 EXCHANGE_TIMEOUT 加上 EXCHANGE_MAX_RETRY_WAIT_SECONDS 的限制:账户的重试策略是快速失败,因此每个 EWS 调用在第一次瞬时错误时就会抛出,而不是 exchangelib 在内部永远重试, 并且 ExchangeClient 只重试只读调用,受该墙钟预算限制。写入从不自动重试。 超出预期预算的溢出会被记录。

Claude Desktop 示例

{
  "mcpServers": {
    "outlook": {
      "command": "outlook-ews-mcp",
      "env": {
        "EXCHANGE_SERVER": "https://mail.company.com/EWS/Exchange.asmx",
        "EXCHANGE_USERNAME": "DOMAIN\\username",
        "EXCHANGE_PASSWORD": "secret",
        "EXCHANGE_EMAIL_ADDRESS": "user@company.com",
        "EXCHANGE_AUTH_TYPE": "NTLM"
      }
    }
  }
}

冒烟检查

填写 .env 后,运行:

outlook-ews-mcp-smoke

默认输出已清理,以便更安全地验证。如果您有意在输出中包含示例邮箱/事件数据:

OUTLOOK_MCP_SMOKE_INCLUDE_DATA=true outlook-ews-mcp-smoke

Docker

docker build -t outlook-ews-mcp .
docker run --rm --env-file .env outlook-ews-mcp

CI/CD

GitHub Actions 和 GitLab CI 都运行 lint、格式化、类型检查、测试、依赖 审计和包构建,使用 pyproject.toml 中固定的 uv 版本。

GitHub

此外,通过 OIDC 可信发布将标记的发布(v*)发布到 PyPI。在首次发布之前,为仓库 viartemev/outlook-ews-mcp、工作流 ci.yml 和环境 pypi 配置 PyPI 待发布者——GitHub 中不存储长期 PyPI 令牌。

GitLab

此外,在默认分支和标签上构建 Docker 镜像并推送到 GitLab 容器注册表,使用内置的 CI_REGISTRY / CI_REGISTRY_USER / CI_REGISTRY_PASSWORD / CI_REGISTRY_IMAGE 变量。

默认镜像标签行为:

触发

推送的标签

默认分支

:$CI_COMMIT_SHORT_SHA:latest

Git 标签

:$CI_COMMIT_TAG

开发

uv run --python 3.12 --with '.[dev]' ruff check .
uv run --python 3.12 --with '.[dev]' pytest -q

项目说明

  • 实现围绕单个 ExchangeClient 抽象,使认证、 传输、重试和错误映射保持集中。

  • 错误以结构化 JSON 形式返回,适合 MCP isError=true 处理。

贡献

欢迎提交 Bug 报告和 PR — 有关如何在没有真实 Exchange 服务器的情况下设置开发环境并运行测试套件,请参阅 CONTRIBUTING.md。如需报告漏洞,请参阅 SECURITY.md

许可证

MIT — 请参阅 LICENSE

Install Server
A
license - permissive license
C
quality
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity
Issues opened vs closed

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    MCP server for any Microsoft Exchange / OWA deployment. Gives LLM agents access to email, calendar, directory search, folders, availability, and meeting analytics via 30 tools.
    30
    7
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    A local MCP server for on-premises Microsoft Exchange, connecting via EWS and NTLM. It provides mail, template, availability, and calendar workflow tools through stdio, with draft-first safety and Windows Credential Manager integration.
    7
    MIT

View all related MCP servers

Related MCP Connectors

  • Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.

  • Fully-managed email as MCP tools - register domains, real mailboxes, send and receive mail.

  • MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/viartemev/outlook-ews-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server