协作Outlook MCP服务器
本地人 主控程序 服务器,允许Claude通过Microsoft Graph API完全访问Microsoft 365电子邮件和日历。构建为作为独立包分发——不需要任何秘密,也不需要任何环境变量。每个用户都通过基于浏览器的OAuth流使用自己的Microsoft帐户进行身份验证。
适用于任何Microsoft 365帐户:工作、学校或个人(outlook.com、hotmail.com、live.com)。
设计无损
此服务器是故意构建的,即使克劳德被误导,也不会造成不可逆转的伤害:
- 不删除。 邮件只能存档(移动到存档)或在文件夹之间移动。没有删除操作。
- 没有发送。 电子邮件只能创建为草稿。没有发送操作
Mail.SendOAuth作用域从不被请求——令牌在物理上无法发送邮件,即使提示注入攻击试图调用它。 - 不删除日历。 事件可以创建、更新和回复,但不能删除。
安全
快速注射保护
当Claude阅读电子邮件时,内容在到达模型之前会经过多层HTML清理程序。这可以防止攻击者在电子邮件中嵌入可能操纵克劳德行为的隐藏指令。
消毒剂可防止:
| 攻击向量 | 防御 |
|---|---|
通过CSS隐藏文本(display:none, visibility:hidden, opacity:0) | 检测并剥离,包括元素含量 |
零大小文本(font-size:0, height:0, width:0) | 检测并剥离 |
屏幕外定位(position:absolute; left:-9999px) | 检测并剥离 |
相同颜色的文本/背景(color:white 上 background:white) | 颜色比较检测和条纹 |
text-indent:-9999px 和 overflow:hidden 零维度 | 检测并剥离 |
aria-hidden="true" 元素 | 带内容的条带 |
危险标签(`, , , , `,等等) | 完全删除,包括内容 |
| 不可见的Unicode字符(零宽度空格、连接符、BOM、方向标记) | 已剥离 |
| Unicode标签字符(U+E0001-U+E007F,用于同形符号攻击) | 已剥离 |
| 跟踪像素(1x1图像) | 检测并删除 |
| HTML注释(可以隐藏指令) | 已删除 |
data: 属性中的URI和base64 | 已删除 |
山宁泰电子邮件内容被包裹在边界标记中(--- BEGIN EMAIL CONTENT --- / --- END EMAIL CONTENT ---)这样克劳德就可以清楚地区分电子邮件内容和自己的指示。
身份验证安全
- OAuth 2.0与PKCE --没有存储或传输客户端机密。身份验证使用带有代码交换证明密钥的授权码流,这是一种为公共客户端设计的标准。
- 本地主机环回 --登录期间,服务器在随机端口上启动一个临时HTTP侦听器。浏览器重定向回
http://localhost:{port}/callback在认证之后。监听器在收到回调后立即关闭。 - CSRF保护 --随机
state每次登录都会生成参数,并在回调时进行验证。 - 本地令牌存储 --访问和刷新令牌仅存储在用户的计算机上。它们从不传输给任何第三方。
- 自动令牌刷新 --令牌在到期前60秒刷新。并发保护可确保,如果多个工具同时使用过期的令牌启动,则只会发出一个刷新请求。
- 最小范围 --只请求了四个OAuth作用域:
offline_access,User.Read,Mail.ReadWrite,Calendars.ReadWrite值得注意的是,Mail.Send被排除在外。
范围合理性
| 范围 | 为什么 |
|---|---|
offline_access | 允许令牌刷新而无需重新身份验证 |
User.Read | 验证经过身份验证的身份(o365_whoami) |
Mail.ReadWrite | 阅读邮件、创建草稿、移动/存档邮件、管理文件夹 |
Calendars.ReadWrite | 读取/创建/更新事件,回复 |
工具(18)
认证
| 工具 | 说明 |
|---|---|
o365_login | 打开Microsoft登录的浏览器窗口。令牌保存在本地。 |
o365_logout | 从此计算机中删除存储的令牌。 |
o365_whoami | 显示当前经过身份验证的用户。 |
电子邮件
| 工具 | 说明 |
|---|---|
list_messages | 列出收件箱或特定文件夹中的邮件。支持分页 top/skip. |
get_message | 阅读一封经过HTML净化为安全纯文本的完整电子邮件。 |
search_messages | 按关键字搜索电子邮件。支持 KQL语法 (subject:, from:等等)。 |
list_mail_folders | 列出所有未读/总计数的邮件文件夹。 |
create_mail_folder | 创建新的顶级文件夹或子文件夹。 |
move_message | 将一封或多封邮件移动到任何文件夹。 |
archive_message | 将一封或多封邮件移动到“存档”文件夹。 |
mark_message_read | 将邮件标记为已读或未读。 |
create_draft | 创建电子邮件草稿。是否 不 发送。 |
日历
| 工具 | 说明 |
|---|---|
list_calendars | 列出用户有权访问的所有日历 |
list_events | 列出日期范围内的事件。重复事件会自动扩展为单个事件。支持大范围自动分页。 |
get_event | 获取完整的活动详细信息,包括与会者、重复模式和在线会议链接。 |
create_event | 创建一个支持与会者、地点、重复模式(每日、每周、每月、每年)、全天活动和特定日历的活动。 |
update_event | 更新现有事件。仅发送已更改的字段。 |
rsvp_event | 接受、暂时接受或拒绝日历事件。 |
设置
1.安装
git clone
cd cowork-outlook-plugin
npm install
npm run build不需要环境变量。Azure AD应用程序客户端ID嵌入在包中。
2.连接到克劳德桌面
添加到您的 claude_desktop_config.json:
{
"mcpServers": {
"outlook": {
"command": "node",
"args": ["/path/to/cowork-outlook-plugin/build/index.js"]
}
}
}3.身份验证
告诉克劳德:
登录我的Microsoft 365帐户
克劳德会打电话的 o365_login,这将打开您的浏览器,进入Microsoft登录页面。登录并同意权限后,浏览器将重定向到localhost回调,令牌将被保存,您就可以开始了。
如果您的组织需要管理员同意,则租户管理员需要首先批准该应用程序。该应用程序的家庭租户中的用户已预先获得同意。
令牌存储
代币存储在您的机器上:
| 平台 | 路径 |
|---|---|
| 窗户 | %APPDATA%\cowork-outlook-mcp\tokens.json |
| macOS | ~/Library/Application Support/cowork-outlook-mcp/tokens.json |
| Linux | ~/.config/cowork-outlook-mcp/tokens.json |
- 访问令牌持续约1小时,并自动刷新(具有60秒缓冲区)。
- 刷新令牌持续约90天(滚动)。如果您在90天内未使用服务器,则需要重新登录。
- 跑
o365_logout以删除存储的令牌。
发展
npm test # Run all 166 tests
npm run test:watch # Watch mode
npm run dev # Dev mode with tsx hot reload
npm run build # Compile TypeScript to build/测试
该项目是通过测试驱动开发构建的。每个工具、身份验证层、HTML清理程序和Graph客户端都包含在以下测试中 维测试 和 市政废物 (Mock Service Worker)用于HTTP级别的模拟。
test/
├── auth/
│ ├── graph-client.test.ts # 12 tests (GET/POST/PATCH, auto-refresh, concurrency, pagination)
│ ├── oauth.test.ts # 15 tests (PKCE, localhost callback, token exchange, full flow)
│ └── token-store.test.ts # 9 tests (save/load/delete, expiry detection)
├── tools/
│ ├── mail/ # 50 tests across 9 files
│ └── calendar/ # 41 tests across 6 files
└── utils/
└── html-sanitizer.test.ts # 39 tests (every attack vector listed above)建筑
src/
├── index.ts # MCP server entry point (stdio transport)
├── config.ts # Hardcoded client ID, scopes, token paths
├── auth/
│ ├── oauth.ts # OAuth 2.0 Authorization Code + PKCE flow
│ ├── token-store.ts # Local token persistence
│ └── graph-client.ts # Authenticated Graph API client (auto-refresh, pagination, concurrency guard)
├── tools/
│ ├── types.ts # GraphClient and ToolDefinition interfaces
│ ├── index.ts # Tool registry (assembles all tools)
│ ├── auth/ # Login (PKCE + localhost), logout, whoami
│ ├── mail/ # 9 email tools
│ └── calendar/ # 6 calendar tools
├── utils/
│ └── html-sanitizer.ts # Prompt injection defence for email content
└── types/
├── config.ts # OAuth and token types
└── graph.ts # Microsoft Graph API response types运作原理
┌──────────┐ stdio ┌────────────────────┐ HTTPS ┌──────────────────┐
│ Claude │◄───────────►│ MCP Server (local) │◄──────────►│ Microsoft Graph │
└──────────┘ └────────────────────┘ └──────────────────┘
│
▼
~/.../tokens.json
(local token cache)- Claude通过stdio发送工具调用(例如。,
list_messages) - MCP服务器检查有效令牌,必要时进行刷新
- 服务器使用用户的访问令牌进行Graph API调用
- 回复已格式化(电子邮件已净化)并返回给Claude
没有数据通过任何中介。MCP服务器在本地运行,并直接与Microsoft的Graph API对话。
Azure AD应用程序注册(适用于贡献者)
该应用程序已注册,其客户端ID已嵌入源代码中。如果您需要注册自己的:
- 首选 Azure门户>应用程序注册
- 点击 新注册
- 配置:
- 姓名: 随你喜欢 - 支持的帐户类型: “任何组织目录中的帐户和个人Microsoft帐户” - 重定向URI: 留空
- 注册后:
- 首选 认证 >启用 允许公共客户端流 - 在...之下 移动和桌面应用程序,添加重定向URI: http://localhost - 首选 API权限 >添加Microsoft Graph委派权限: offline_access, User.Read, Mail.ReadWrite, Calendars.ReadWrite - 如果您是租户管理员,请授予管理员同意
- 替换
CLIENT_ID常数insrc/config.ts使用应用程序的客户端ID
许可证
麻省理工学院
