内容
<!-- mcp-name: io.github.salahawad/outlook-personal-mcp -->
# outlook-personal-mcp
一款给予 Claude Code 和 Codex 对个人 Outlook.com 邮箱和日历完全控制权的 MCP 服务器,通过 Microsoft Graph API 实现。采用 Python 编写,使用 MCP stdio 传输,并使用每个用户设备代码 OAuth,因此您的凭证永远不会离开您的机器。遵循 MIT 许可协议。
---
## 功能
- **邮件** — 列出、搜索、读取、发送、回复、转发、移动、复制、标记、标记为已读/未读、删除(软删除或硬删除)
- **草稿** — 创建、更新、附加本地文件、发送
- **文件夹** — 列出、创建、重命名、删除
- **日历** — 列出日历、列出/搜索/获取/创建/更新/删除事件、响应邀请(接受/拒绝/暂定)、检查可用时间
- **每个用户的 OAuth** — 您注册自己的免费 Azure 应用;服务器使用您的 Microsoft 帐户进行身份验证,并在本地缓存令牌
- **本地_stdio** — 作为 MCP 主机的子进程运行;您的邮箱数据从未通过第三方中转
---
## 先决条件
- Python 3.10 或更高版本
- [`uv`](https://docs.astral.sh/uv/)(快速的 Python 包和工具运行器)— **运行时必需**:服务器通过 `uvx` 启动,不会由您的 MCP 主机(包括 Claude Desktop)捆绑。可以使用 `curl -LsSf https://astral.sh/uv/install.sh | sh`(macOS/Linux)或 `powershell -c "irm https://astral.sh/uv/install.ps1 | iex"`(Windows)进行安装。
- 个人 Microsoft 帐户(Outlook.com、Hotmail、Live 等)
- 免费的 Azure 应用注册(参见下方,约需 3 分钟)
---
## Azure 应用注册
1. 前往 [https://portal.azure.com](https://portal.azure.com) → **Microsoft Entra ID** → **应用注册** → **新建注册**。
2. 任意命名(例如 `outlook-personal-mcp`)。在 **支持的帐户类型** 中选择 **仅限个人 Microsoft 帐户**。无需重定向 URI,点击 **注册**。
3. 打开应用 → **身份验证** → **高级设置** → **允许公共客户端流** → 设置为 **是** → **保存**。(此项为设备代码登录流所必需。)
4. 前往 **API 权限** → **添加权限** → **Microsoft Graph** → **委托权限**,然后添加:
- `Mail.ReadWrite`
- `Mail.Send`
- `Calendars.ReadWrite`
(`User.Read` 默认包含;`offline_access` 在运行时自动请求,无需添加。)
5. 从 **概述** 页面复制 **应用程序(客户端)ID**。这就是您的 `OUTLOOK_MCP_CLIENT_ID`。
### 替代方法:使用 Azure CLI 创建应用
如果您有 [`az` CLI](https://learn.microsoft.com/cli/azure/install-azure-cli),整个注册过程只需一条命令:
```bash
az login --use-device-code --allow-no-subscriptions # 使用个人帐户登录
az ad app create \
--display-name "outlook-personal-mcp" \
--sign-in-audience PersonalMicrosoftAccount \
--is-fallback-public-client true \
--required-resource-accesses '[{"resourceAppId":"00000003-0000-0000-c000-000000000000","resourceAccess":[{"id":"024d486e-b451-40bb-833d-3e66d98c5c73","type":"Scope"},{"id":"e383f46e-2787-4529-855e-0e479a3ffac0","type":"Scope"},{"id":"1ec239c2-d7c9-4623-a91a-a9775856bb36","type":"Scope"}]}]' \
--query appId -o tsv
```
打印出的 `appId` 即为您的 `OUTLOOK_MCP_CLIENT_ID`。(GUID 为 Microsoft Graph 委托范围 `Mail.ReadWrite`、`Mail.Send` 和 `Calendars.ReadWrite`。)**注意:** 新的应用注册需要几分钟才能传播到 Microsoft 的消费者登录端点 — 如果您的首次登录失败,出现 `AADSTS700016`(“应用程序 … 未找到”),请等待几分钟后重试。
---
## 安装与首次登录
运行一次性交互式登录。它会打印一个短 URL 和一个代码;打开 URL,在任意浏览器中输入代码,批准权限,即可完成。令牌缓存在 `~/.config/outlook-personal-mcp/token_cache.bin`(模式 600)中,并在后续运行中自动刷新 — 除非刷新令牌过期或被撤销,否则您不会再次被提示。
```bash
OUTLOOK_MCP_CLIENT_ID=<您的应用客户端 ID> uvx mcp-outlook-personal login
```
> 要从源代码运行最新的未发布代码而不是 PyPI 版本,请将 `mcp-outlook-personal` 替换为 `--from git+https://github.com/salahawad/outlook-personal-mcp mcp-outlook-personal`。
---
## 配置 Claude Code
将服务器添加到项目的 `.mcp.json`(或所有项目的 `~/.claude/.mcp.json`)中:
```json
{
"mcpServers": {
"outlook": {
"command": "uvx",
"args": ["mcp-outlook-personal"],
"env": { "OUTLOOK_MCP_CLIENT_ID": "<您的应用客户端 ID>" }
}
}
}
```
或者,使用 CLI:`claude mcp add`。
---
## 配置 Codex
将服务器添加到 `~/.codex/config.toml` 中:
```toml
[mcp_servers.outlook]
command = "uvx"
args = ["mcp-outlook-personal"]
env = { OUTLOOK_MCP_CLIENT_ID = "<您的应用客户端 ID>" }
```
---
## 安装为 Claude Desktop 扩展(.mcpb)
该服务器也打包为 [Claude Desktop 扩展](https://www.anthropic.com/engineering/desktop-extensions)(`.mcpb`)。从检出中构建软件包:
```bash
npx @anthropic-ai/mcpb pack . dist/mcp-outlook-personal.mcpb
```
然后,在 Claude Desktop 中打开 **设置 → 扩展**,安装 `dist/mcp-outlook-personal.mcpb` 文件,并在提示时输入您的 **Azure 应用客户端 ID**(以及任何可选设置)。
> **要求:** 扩展程序使用 `uvx mcp-outlook-personal` 启动服务器,因此 [`uv`](https://docs.astral.sh/uv/) 必须安装并在您的 `PATH` 中 — Claude Desktop 不会捆绑它(参见 [先决条件](#先决条件))。Codex 和其他_stdio 主机使用上述配置,而不是 `.mcpb`。
---
## 配置(环境变量)
| 变量 | 必需 | 默认值 | 描述 |
|---|---|---|---|
| `OUTLOOK_MCP_CLIENT_ID` | **是** | — | Azure 应用的应用程序(客户端)ID |
| `OUTLOOK_MCP_AUTHORITY` | 否 | `https://login.microsoftonline.com/consumers` | MSAL 授权 URL(仅在更改为工作/学校租户时更改) |
| `OUTLOOK_MCP_TOKEN_CACHE` | 否 | `~/.config/outlook-personal-mcp/token_cache.bin` | MSAL 令牌缓存文件路径 |
| `OUTLOOK_MCP_FILE_ROOT` | 否 | `~/.local/share/outlook-personal-mcp/files` | 仅限 `add_attachment` 读取或 `download_attachment`写入的文件目录 |
| `OUTLOOK_MCP_MAX_FILE_BYTES` | 否 | `3145728` | 本地附件读取和附件下载的最大字节数 |
| `OUTLOOK_MCP_ALLOW_PERMANENT_DELETE` | 否 | `false` | 设置为 `true` 以启用 `permanent_delete` 工具(不可逆 — 参见下方) |
| `OUTLOOK_MCP_DEBUG` | 否 | `false` | 设置为 `true` 以将每个 Graph 请求的方法、URL 和 HTTP 状态代码记录到 stderr。永不记录令牌或消息内容。 |
---
## 工具
### 帐户
| 工具 | 描述 |
|---|---|
| `whoami` | 返回已登录的 Microsoft 帐户配置文件 |
### 邮件
| 工具 | 描述 |
|---|---|
| `list_messages` | 列出消息(最新的在前);可选按文件夹或仅限未读筛选 |
| `search_messages` | 跨整个邮箱进行全文搜索(Graph `$search`) |
| `get_message` | 获取单个消息;可选包含完整正文 |
| `list_attachments` | 列出消息的附件(id、名称、大小、内容类型) |
| `download_attachment` | 将附件下载到 `OUTLOOK_MCP_FILE_ROOT` 下的路径(拒绝覆盖现有文件) |
| `send_mail` | 发送电子邮件 |
| `reply` | 回复消息(`reply_all` 回复所有人) |
| `forward` | 将消息转发给收件人,并附带可选评论 |
| `move_message` | 将消息移动到另一个文件夹 |
| `copy_message` | 将消息复制到另一个文件夹 |
| `mark_read` | 将消息标记为已读或未读 |
| `flag_message` | 标记或取消标记消息 |
| `delete_message` | 删除消息(将其移动到已删除项;可逆) |
| `permanent_delete` | **永久** 删除消息(不可逆)。仅在 `OUTLOOK_MCP_ALLOW_PERMANENT_DELETE=true` 时可用 |
### 文件夹
| 工具 | 描述 |
|---|---|
| `list_folders` | 列出邮件文件夹,包含未读和总消息数 |
| `create_folder` | 创建邮件文件夹,可选嵌套在父文件夹下 |
| `rename_folder` | 重命名邮件文件夹 |
| `delete_folder` | 删除邮件文件夹(将其移动到已删除项) |
### 草稿
| 工具 | 描述 |
|---|---|
| `create_draft` | 创建草稿消息(未发送) |
| `update_draft` | 更新草稿的主题和/或正文 |
| `add_attachment` | 将本地文件(`OUTLOOK_MCP_FILE_ROOT` 下的常规非符号链接文件)附加到草稿 |
| `send_draft` | 发送现有草稿 |
### 日历
| 工具 | 描述 |
|---|---|
| `list_calendars` | 列出用户日历 |
| `list_events` | 列出事件;如果提供 `start`/`end`(ISO 8601),则返回该时间窗口内的事件 |
| `search_events` | 按自由文本搜索事件 |
| `get_event` | 获取一个事件,包括正文、与会者和在线会议链接 |
| `create_event` | 创建日历事件,附带可选与会者和在线会议 |
| `update_event` | 更新现有事件的字段(仅提供字段更改) |
| `delete_event` | 删除/取消日历事件 |
| `respond_event` | 响应会议邀请:`accept`、`decline` 或 `tentative` |
| `find_availability` | 获取指定时间窗口内的一组人员的空闲/忙碌可用性 |
---
## 永久删除
`permanent_delete` 工具绕过已删除项文件夹并不可逆地删除消息。**默认禁用** — 当 `OUTLOOK_MCP_ALLOW_PERMANENT_DELETE` 未设置(或为 `false`)时,该工具不会注册到 MCP 服务器,因此不会出现在工具列表中。
要启用它,请在 `.mcp.json` / `config.toml` 中服务器的环境块中设置 `OUTLOOK_MCP_ALLOW_PERMANENT_DELETE=true`。仅当您理解后果时才这样做:没有撤销,也没有个人帐户的可恢复项路径。
---
## 安全
- **令牌缓存是一种凭证。** `~/.config/outlook-personal-mcp/token_cache.bin` 文件包含长期有效的刷新令牌。以 `600` 模式写入,但像密码一样对待 — 永远不要提交,永远不要分享,并存储在加密卷中。
- **数据保留本地。** 服务器作为 Claude Code / Codex 的子进程通过_stdio 运行。您的邮箱内容直接在 MCP 主机和 Microsoft Graph API 之间传递;不涉及第三方中转。
- **撤销。** 要撤销访问权限,请删除令牌缓存文件和/或前往 [https://account.microsoft.com/permissions](https://account.microsoft.com/permissions) 以删除 Azure 应用的同意。您还可以从门户中完全删除 Azure 应用注册。
- **文件路径。** `download_attachment` 仅在 `OUTLOOK_MCP_FILE_ROOT` 下写入,并且拒绝覆盖现有文件。`add_attachment` 仅读取 `OUTLOOK_MCP_FILE_ROOT` 下的常规非符号链接文件。相对路径在该根目录下解析;绝对路径超出该范围(以及任何路径遍历符号链接)将被拒绝。两个工具强制执行 `OUTLOOK_MCP_MAX_FILE_BYTES`。在确认任何涉及文件系统的工具调用之前,请查看这些路径。
---
## 开发
```bash
git clone https://github.com/salahawad/outlook-personal-mcp
cd outlook-personal-mcp
uv venv && uv pip install -e ".[dev]"
uv run pytest
uv run ruff check .
```
---
## 隐私政策
该服务器完全在您的机器上运行,仅在您的机器和 Microsoft 的 Graph API 之间发送数据 — 没有第三方中转,没有遥测,维护者不会收到任何数据。OAuth 令牌缓存在 `~/.config/outlook-personal-mcp/token_cache.bin`(模式 600)中。有关完整的隐私政策,请参见 [PRIVACY.md](PRIVACY.md)。
---
## 许可证
MIT — 参见 [LICENSE](LICENSE)。