内容
# macos-mail-mcp
[](https://www.npmjs.com/package/macos-mail-mcp)
[](https://opensource.org/licenses/MIT)
[](https://nodejs.org/)
[](https://www.apple.com/macos/)
一个适用于 Apple Mail(macOS Mail.app)的 MCP 服务器,通过 AppleScript 将 Claude 连接到您的电子邮件。提供 20 种工具用于读取、搜索、管理电子邮件和撰写新邮件。
## 支持的账户
与 **macOS Mail.app 中配置的任何电子邮件账户** 兼容 — iCloud、Gmail、Outlook/Exchange、Yahoo、Fastmail、自定义 IMAP/POP 等。不需要代码更改;只需在 Mail.app 中添加账户,它就可以通过所有 20 种工具使用。
## 要求
- 配置了 Mail.app 的 macOS(至少有一个电子邮件账户)
- Node.js 18+
- Claude Code 或 Claude Desktop 应用
## 安装
### 快速安装(npm)
最简单的方法 — 不需要克隆或构建。
> **Claude Code 和 Claude Desktop 使用单独的 MCP 配置。** 以下 `claude mcp add` 命令配置 **Claude Code 仅** — 它写入 `~/.claude.json`。**Claude Desktop 和 Cowork** 读取不同的文件(`claude_desktop_config.json`)并且必须单独配置。设置您使用的任一或两者。
**Claude Code(CLI):**
```bash
claude mcp add --scope user macos-mail-mcp -- npx -y macos-mail-mcp
```
`--scope user` 使服务器在每个项目中都可用 — 默认的 `local` 范围仅为在运行命令的目录中注册。`-y` 允许 `npx` 在第一次运行时安装软件包而无需交互式提示。
**Claude Desktop(和 Cowork):**
将以下内容添加到 `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"macos-mail-mcp": {
"command": "/opt/homebrew/bin/npx",
"args": ["-y", "macos-mail-mcp"],
"env": { "PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin" }
}
}
}
```
使用 `npx` 的 **绝对路径** — GUI 应用不会继承您的 shell 的 `PATH`,因此单独的 `"npx"` 通常无法启动。使用 `which npx` 查找您的路径:
- Apple Silicon Homebrew:`/opt/homebrew/bin/npx`
- Intel Homebrew:`/usr/local/bin/npx`
- nvm:`~/.nvm/versions/node/<version>/bin/npx`
`env.PATH` 条目允许 `npx` 定位 `node`,原因相同。然后 **完全退出** Claude(Cmd+Q — 关闭窗口不够)并重新打开;配置仅在启动时读取。如果服务器未出现,请在 `~/Library/Logs/Claude/mcp*.log` 中检查启动错误。
### 从源代码安装
如果您更喜欢本地构建或贡献:
```bash
git clone https://github.com/marius-cetanas/macos-mail-mcp.git
cd macos-mail-mcp
npm install
npm run build
```
然后使用 Claude Code 注册:
```bash
claude mcp add --transport stdio --scope user macos-mail-mcp -- node /path/to/macos-mail-mcp/build/index.js
```
或将以下内容添加到 Claude Desktop 配置(`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"macos-mail-mcp": {
"command": "/opt/homebrew/bin/node",
"args": ["/path/to/macos-mail-mcp/build/index.js"]
}
}
}
```
同样使用 `node` 的绝对路径(使用 `which node` 查找)— 相同的原因。然后完全退出并重新打开 Claude。
### macOS 权限
在第一次使用时,macOS 将提示授予控制 Mail.app 的自动化权限。前往 **系统设置 > 隐私和安全 > 自动化** 以管理此权限。
## 工具
### 账户(2)
| 工具 | 描述 |
|---|---|
| `list_accounts` | 列出所有邮件账户(名称、类型、启用状态、电子邮件) |
| `get_account_detail` | 获取完整的账户详细信息(服务器、端口、SSL、邮箱数量) |
### 邮箱(3)
| 工具 | 描述 |
|---|---|
| `list_mailboxes` | 列出某个账户或所有账户的邮箱 |
| `get_mailbox_info` | 获取邮箱详细信息(消息数量、未读数量) |
| `create_mailbox` | 创建一个新的邮箱(顶级或嵌套在父邮箱下) |
### 消息(8)
| 工具 | 描述 |
|---|---|
| `list_messages` | 列出消息,支持分页(限制/偏移)和可选日期过滤(之后/之前) |
| `get_message` | 获取完整的消息内容、头部、收件人、附件。邮箱名称是可选的 — 可以省略以搜索账户中的所有邮箱。 |
| `search_messages` | 按主题、发件人或内容搜索,并可选日期过滤(之后/之前)。结果包括邮箱名称。 |
| `move_message` | 将消息移动到不同的邮箱 |
| `move_messages` | 批量将多个消息移动到不同的邮箱 |
| `delete_message` | 删除消息(移动到垃圾箱) |
| `flag_message` | 设置/清除标记,可选颜色索引(0-6) |
| `mark_read` | 将消息标记为已读或未读 |
### 附件(4)
| 工具 | 描述 |
|---|---|
| `list_attachments` | 列出附件,包含文件名、MIME 类型、大小、下载状态 |
| `save_attachment` | 将特定附件保存到磁盘 |
| `save_all_attachments` | 将消息的所有附件保存到磁盘 |
| `read_attachment` | 内联读取基于文本的附件内容(.txt, .csv, .json, .html, .md, .xml, .log) |
### 撰写(3)
| 工具 | 描述 |
|---|---|
| `send_message` | 发送新的电子邮件,可选 CC、BCC 和附件 |
| `reply_to_message` | 回复或回复所有消息 |
| `forward_message` | 将消息转发给新的收件人 |
## 架构
```
src/
index.ts # MCP 服务器入口点
types.ts # TypeScript 接口
utils.ts # 共享实用工具(sanitize, expandTilde, toolError)
bridge/
applescript-runner.ts # AppleScript 执行引擎
escape-for-json.applescript # 共享 JSON 转义处理程序(自动预添加)
domains/
accounts/
accounts.tools.ts # 工具注册和处理程序
scripts/*.applescript # AppleScript 模板
mailboxes/
mailboxes.tools.ts
scripts/*.applescript
messages/
messages.tools.ts
scripts/*.applescript
compose/
compose.tools.ts
scripts/*.applescript
tests/
utils.test.ts # 共享实用工具测试
bridge/applescript-runner.test.ts # 桥接单元测试
domains/*/ # 域处理程序测试
```
**基于领域的分层架构:**
- **工具层** — 使用 Zod 模式注册 MCP 工具,验证输入,调用桥接层
- **桥接层** — 读取 AppleScript 模板,替换参数(安全转义),通过 `osascript` 执行,解析 JSON 输出
- **脚本层** — 带有 `{{param}}` 占位符的 AppleScript 模板,返回 JSON 字符串。`escapeForJson` 处理程序在 `bridge/escape-for-json.applescript` 中定义,并在运行时自动添加到每个脚本中。
## 已知限制
### AppleScript 基础
此 MCP 通过 AppleScript 与 Mail.app 通信,这是一个稳定但遗留的自动化层。Mail.app 的脚本字典多年来基本未变,但未来的 macOS 更新可能需要脚本调整。这是该方法的固有权衡 — AppleScript 是在不编写本机插件的情况下自动化 Mail.app 的唯一官方支持方法。
### 性能
- **大型邮箱搜索** — `search_messages` 使用 Mail.app 的 `whose` 子句,该子句执行线性扫描并在应用限制之前将所有匹配消息加载到内存中。在非常大的 IMAP 邮箱(50K+ 消息)上按内容搜索可能很慢或超时。当可能时,优先按主题或发件人搜索,并使用 `accountName` 和 `mailboxName` 缩小结果范围。
- **IMAP 附件下载** — IMAP 账户上的附件可能未本地下载。工具检查下载状态,并在需要时在 Mail.app 中打开附件时清楚地报告。
### 消息 ID
Mail.app 的内部消息 ID 是易失性的 — 当应用重新索引或执行移动/删除操作时,它们可能会更改。这意味着多步骤工作流程(例如,列出 → 标记 → 移动)应在突变之间重新获取消息 ID。对于单步骤操作,这不是问题。
### 提供商特定行为
- **Exchange 账户** — 服务器详细信息(主机名、端口、SSL)不会通过 AppleScript 为 Exchange/EWS 账户公开。邮箱和消息操作正常工作。
- **Gmail 标签** — `move_message` 添加目标标签,但可能不会删除原始标签(Gmail 使用标签,而不是文件夹)。
### 其他限制
- **回复/转发中的附件** — AppleScript 不支持在回复/转发消息中添加新附件(Mail.app 限制)。
- **MIME 类型检测** — 当 Mail.app 的原生 MIME 类型属性返回 `missing value` 时,使用基于扩展名的备用方法。
- **邮箱管理** — 支持创建邮箱,但不支持通过 AppleScript 删除和重命名邮箱(Mail.app 限制)。
### 路线图
- **`get_thread`** — 检索对话线程中的所有消息。Mail.app 没有原生线程支持;实现需要解析 RFC 头部(`Message-ID`、`In-Reply-To`、`References`),这对大型邮箱来说很慢。计划在 v2 中实现。
## 开发
```bash
npm run dev # 监视模式(TypeScript 编译器)
npm test # 运行测试
npm run test:watch # 监视模式测试
npm run build # 构建生产环境
```
## 许可证
MIT