outlook-mcp
outlook-ews-mcp
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 的
NTLM和Basic传输 —
stdio和SSE架构 — 通过统一的
ExchangeClient抽象进行集中错误映射(参见项目说明)安全性 — 默认采用更注重隐私的冒烟检查(参见冒烟检查)
运维 — 包含 Docker 镜像以及 GitHub 和 GitLab CI/CD 流水线
工具目录
以下每个工具都在 tool_specs.py 中注册,该文件是其名称、描述和模式的唯一来源。只读 标记表示这些工具永远不会修改邮箱——它们获得更高的并发度(参见请求队列),并且可以安全地推测性调用。
系统
工具 | 描述 | 只读 |
| 检查与 Exchange 的连接 | ✅ |
| 获取邮箱元数据 | ✅ |
| 列出邮箱委托及其文件夹权限级别——只读,因为 | ✅ |
| 列出服务器端收件箱规则 | ✅ |
| 创建服务器端收件箱规则,例如“来自此发件人 → 移动到文件夹” | |
| 启用/禁用规则或更改其优先级(此处其他字段不可更新) | |
| 按 ID 删除服务器端收件箱规则 | |
| 获取外出(自动回复)设置 | ✅ |
| 关闭、开启自动回复,或安排开始/结束时间窗口 |
⚠️
create_inbox_rule/update_inbox_rule/delete_inbox_rule通过 EWS 管理规则,这会移除桌面 Outlook 保留的客户端规则块——这可能会清除用户在 Outlook 中创建的规则。这是 EWS 的文档化行为,并非本项目的缺陷。
电子邮件
工具 | 描述 | 只读 |
| 列出文件夹中的电子邮件 | ✅ |
| 按 ID 获取完整电子邮件 | ✅ |
| 导出消息的原始 RFC 822 MIME 内容,base64 编码 | ✅ |
| 按顺序获取对话中的每条消息,包括正文 | ✅ |
| 按子字符串(主题/正文/发件人)或服务器端高级查询语法搜索 | ✅ |
| 发送新电子邮件 | |
| 回复电子邮件 | |
| 转发电子邮件 | |
| 将电子邮件移动到另一个文件夹 | |
| 将电子邮件复制到另一个文件夹 | |
| 批量移动,带逐项结果——一个坏 ID 不会导致其余失败 | |
| 批量复制,带逐项结果 | |
| 批量删除,带逐项结果(除非 | |
| 删除电子邮件 | |
| 更新已读状态、重要性或后续标志 | |
| 设置、添加或删除 Outlook 类别(彩色标签) | |
|
| |
|
| |
| 列出使用中的类别及计数,从最近的消息中采样(不是邮箱主类别列表) | ✅ |
| 列出邮箱文件夹 | ✅ |
| 创建邮箱文件夹 | |
| 重命名文件夹——拒绝内置文件夹(收件箱、已发送邮件、日历等) | |
| 删除文件夹及其所有内容——拒绝内置文件夹 | |
| 创建电子邮件草稿 | |
| 更新草稿;省略的字段保持不变, | |
| 发送现有草稿 | |
| 将本地文件附加到消息,通常是草稿——文件必须位于 | |
| 按 ID 从消息中移除一个附件 | |
| 将附件保存到磁盘 | ✅ |
日历
工具 | 描述 | 只读 |
| 列出时间范围内的日历事件;传入 | ✅ |
| 按 id 获取日历事件;传入 | ✅ |
| 创建日历事件 | |
| 更新日历事件 | |
| 删除日历事件 | |
| 接受、拒绝或暂定回复邀请 | |
| 查找空闲的会议时间段 | ✅ |
| 批量删除事件,并返回逐项结果 | |
| 批量回复邀请,并返回逐项结果 | |
| 获取空闲/忙碌时间段;传入 | ✅ |
| 列出日历 | ✅ |
| 列出 Room Finder 会议室列表(会议室分组) | ✅ |
| 列出 Room Finder 会议室列表中的会议室 | ✅ |
联系人
工具 | 描述 | 只读 |
| 搜索联系人 | ✅ |
| 按 id 获取联系人 | ✅ |
| 创建个人联系人 | |
| 更新个人联系人 | |
| 删除个人联系人 |
典型使用场景
将 Claude Desktop 或其他 MCP 客户端连接到本地 Exchange
搜索收件箱邮件并获取完整邮件内容
从 AI 工作流中发送或起草邮件
查看日历并创建会议
检查空闲/忙碌时间段以安排日程
搜索个人联系人或全局地址列表
通过受控的 MCP 边界公开 Exchange 操作,而不是直接编写邮箱脚本
安全说明
当前代码的做法:
受限连接 | 仅连接到 |
无遥测 | 不包含任何遥测、分析或第三方数据导出逻辑 |
密钥保存在本地 | 将密钥保存在环境变量 / |
干净的错误负载 | 结构化的 MCP 错误响应绝不包含原始 Exchange 异常文本、邮件正文、附件内容或密码;成功的工具只返回被请求的邮箱数据 |
干净的日志 |
|
干净的 Docker 构建 |
|
你仍然需要注意的事项:
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_attachment的save_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 中。
变量 | 默认值 | 描述 |
| (必填) | EWS 端点 URL,例如 |
| (必填) |
|
| (必填) | 账户密码 |
| 未设置 | SMTP 地址;当 |
|
|
|
|
| 允许通过 |
|
| 验证服务器的 TLS 证书;仅对受信任的内部/自签名设置使用 |
| 未设置(自动检测) | Exchange 服务器版本,例如 |
|
| 仅当 Exchange 报告无法解析的 GUID 时区 ID 时使用;正常操作使用邮箱自身的默认时区 |
|
| 每个请求的超时时间(秒)(1–300) |
|
| 当 Exchange 报告自身繁忙时,只读调用的墙钟重试预算,不是重试次数; |
| 未设置 | 要模拟的邮箱(需要 Exchange 模拟权限) |
|
| 每个附件的最大大小,在上传和 |
|
| 单次发送/回复/转发/创建草稿调用中的最大附件数(1–100) |
|
| 单次调用中附件总大小的上限(1–500) |
| 未设置(禁用) | 限制附件路径的目录。未设置时拒绝所有对 |
|
|
|
|
| 原始 MIME 导出在 base64 扩展之前的大小上限(1–100) |
| 未设置 | 附加到外发文本正文和回复/转发。没有 EWS 签名 API,因此这是配置,而不是邮箱的 Outlook 签名 |
| 未设置 | 附加到外发 HTML 正文。与上述相同;两者之间不进行交叉转换。每次调用可通过 |
|
|
|
|
| 当 |
|
| 当 |
|
| 并发只读工具调用数(1–8);修改调用始终独占运行。参见 请求队列 |
|
| 一次允许的最大调用数,包括运行中和等待中(1–1000);超过后,调用会立即收到 |
|
|
|
| 未设置(stderr) | 日志文件路径;如果设置,请使用操作系统权限保护它 |
不绑定单个变量的行为说明:
list_events和find_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-smokeDocker
docker build -t outlook-ews-mcp .
docker run --rm --env-file .env outlook-ews-mcpCI/CD
GitHub Actions 和 GitLab CI 都运行 lint、格式化、类型检查、测试、依赖
审计和包构建,使用 pyproject.toml 中固定的 uv 版本。
GitHub | 此外,通过 OIDC 可信发布将标记的发布( |
GitLab | 此外,在默认分支和标签上构建 Docker 镜像并推送到 GitLab 容器注册表,使用内置的 |
默认镜像标签行为:
触发 | 推送的标签 |
默认分支 |
|
Git 标签 |
|
开发
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。
Maintenance
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
- AlicenseAqualityDmaintenanceMCP server for any Microsoft Exchange / OWA deployment. Gives LLM agents access to email, calendar, directory search, folders, availability, and meeting analytics via 30 tools.307MIT
- FlicenseAqualityBmaintenanceMCP server for corporate Exchange that provides access to email, calendar, and people directory via OWA JSON API.20
- FlicenseAqualityBmaintenanceMCP server for Claude to access on-premises Outlook/Exchange mailboxes via EWS with NTLM authentication, providing tools for email, calendar, and contact management without relying on Microsoft 365 or Graph API.18
- AlicenseNot gradedqualityAmaintenanceA 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.7MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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