内容
# Outlook COM MCP 服务器
本地的模型上下文协议(MCP)服务器,用于读取经典 Outlook 邮件和日历数据,并通过 COM 创建回复草稿,无需 Microsoft Graph API。
> [!WARNING]
> 该项目读取当前登录的经典 Outlook 配置文件中的数据。当 MCP 客户端调用工具时,选定的邮件或日历数据将返回给该客户端。在使用前,请确认您的组织的数据处理政策。
## 为什么存在
某些环境无法使用 Microsoft Graph,因为应用注册、租户同意或 Graph 权限不可用。此服务器使用 Outlook 桌面 COM 对象模型作为本地替代方案。
它故意设计得很窄:
- 读取邮件元数据和选定的邮件正文。
- 读取日历事件。
- 枚举收件箱、已发送或草稿文件夹树,并搜索嵌套文件夹。
- 将回复或全部回复消息保存到 Outlook 草稿。
- 显式标记选定的邮件为已读或未读。
- 绝不发送、删除、移动或存档邮件。
## 状态
早期开发中。服务器仅针对 Windows 和经典 Outlook。新版 Outlook for Windows 不支持 COM 自动化。
## 架构
```text
MCP 客户端 / 安全 MCP 隧道
|
| 标准输入输出(JSON-RPC)
v
OutlookComMcp.exe
|
| 专用的单线程公寓(STA)线程 + COM 延迟绑定
v
经典 Outlook
```
实现使用延迟绑定的 COM,而不是重新分发 Outlook 互操作程序集。Outlook 调用在专用的单线程公寓(STA)线程上运行。
## MCP 工具
| 工具 | 效果 | 备注 |
| --- | --- | --- |
| `search_emails` | 只读 | 搜索收件箱、已发送、草稿或指定的文件夹。支持递归和仅限未读搜索。 正文预览是可选的。 |
| `list_mail_folders` | 只读 | 列出邮件文件夹树,并返回文件夹/存储 ID 以进行有针对性的搜索。 |
| `get_email` | 只读 | 使用搜索返回的 `EmailId` 和 `StoreId` 读取一条消息。 |
| `set_email_read_state` | 状态更改 | 显式标记选定的邮件为已读或未读。搜索和读取工具绝不会更改此状态。 |
| `list_calendar_events` | 只读 | 列出与 ISO 8601 范围重叠的事件,最多 31 天。 |
| `create_reply_draft` | 添加式写入 | 保存回复草稿。它不会发送邮件。全部回复必须显式请求。 |
工具结果使用结构化内容和有界结果大小。电子邮件正文是不可信任的输入,不应作为指令解释。
## 要求
- Windows 10 或更高版本
- 经典 Outlook for Windows,已安装并配置
- 与访问 Outlook 配置文件的同一用户的交互式 Windows 会话
- .NET 8 SDK 用于构建,或 .NET 8 桌面运行时用于框架依赖的发布
服务器不打算作为 `LocalSystem`、Windows 服务或无头服务器进程运行。
## 构建
```powershell
dotnet restore OutlookComMcp.sln
dotnet build OutlookComMcp.sln --configuration Release
dotnet test OutlookComMcp.sln --configuration Release
```
发布依赖于框架的 Windows 可执行文件:
```powershell
dotnet publish src/OutlookComMcp/OutlookComMcp.csproj `
--configuration Release `
--runtime win-x64 `
--self-contained false `
--output artifacts/win-x64
```
## 通过标准输入输出运行
服务器将 MCP 协议消息写入标准输出。诊断信息将输出到标准错误流。
```powershell
dotnet run --project src/OutlookComMcp/OutlookComMcp.csproj
```
本地标准输入输出功能的 MCP 客户端示例配置:
```json
{
"mcpServers": {
"outlook-com": {
"command": "C:\\Apps\\OutlookComMcp\\OutlookComMcp.exe",
"args": []
}
}
}
```
## 从 ChatGPT 开发人员模式连接
ChatGPT 开发人员模式不会直接启动任意本地标准输入输出进程。OpenAI 安全 MCP 隧道可以从安装了经典 Outlook 的 Windows 机器启动或转发到此标准输入输出服务器。
概念性隧道配置文件:
```powershell
$env:CONTROL_PLANE_API_KEY = "<运行时 API 密钥>"
tunnel-client init `
--profile outlook-com `
--tunnel-id tunnel_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx `
--mcp-command "C:\Apps\OutlookComMcp\OutlookComMcp.exe"
tunnel-client doctor --profile outlook-com --explain
tunnel-client run --profile outlook-com
```
然后在 ChatGPT 中创建一个开发者模式应用,选择 **隧道** 作为连接类型,并选择关联的隧道。
有关当前设置、权限和网络要求的详细信息,请参阅 [安全 MCP 隧道文档](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels)。
## 安全边界
- 不存在发送工具。
- 不存在删除、移动、存档或发送工具。
- `create_reply_draft` 被注释为非只读、非幂等工具,客户端可以要求确认。
- `set_email_read_state` 是非只读但幂等的。它需要确切的电子邮件/存储 ID,并且绝不会隐式运行。
- 回复全部默认值为 `false`。
- 搜索结果、 正文大小、扫描计数、日历范围和回复 正文大小都有边界限制。
- 标准输出保留用于 MCP 传输;应用程序错误使用标准错误流。
- 每次操作后释放 COM 引用。
保存草稿仍然是写入操作。请在手动发送之前在 Outlook 中查看收件人和内容。
## 已知限制
- 仅限经典 Outlook;新 Outlook 不公开 COM 对象模型。
- 文件夹列表和递归搜索从默认收件箱、已发送、草稿或提供的文件夹 ID 开始。整个存储和共享存储发现尚未实现。
- 递归邮件搜索限制为 100 个文件夹、10 个层级和 5,000 个扫描项目。
- 日历访问目前使用默认日历。
- 正文输出为纯文本。富 HTML 编排和签名插入尚未实现。
- 运行时集成测试需要具有配置的 Outlook 配置文件的 Windows 机器;CI 运行不带 Outlook 的单元测试。
## 开发
该解决方案使用:
- .NET 8
- 官方 [MCP C# SDK](https://github.com/modelcontextprotocol/csharp-sdk)
- xUnit.net v3
- 用于构建和单元测试的 Windows GitHub Actions
该项目不存储任何 Microsoft Graph 依赖项或 Outlook 凭证。
## 许可证
尚未选择许可证。在添加许可证之前,适用正常的版权限制。