内容
# 🐦 thunderbird-mcp
一款将本地 **Thunderbird** 配置文件(包括邮件、联系人和日历)暴露给LLM的[模型上下文协议](https://modelcontextprotocol.io)服务器。
[](https://github.com/mudler/thunderbird-mcp/actions/workflows/ci.yml)
[](https://github.com/mudler/thunderbird-mcp/actions/workflows/release.yml)
[](./LICENSE)
[](https://github.com/mudler/thunderbird-mcp/pkgs/container/thunderbird-mcp)
它与任何MCP客户端兼容,并设计用于与 [LocalAI](https://localai.io/docs/features/mcp) 配合使用。
---
## 功能
`thunderbird-mcp`直接读取Thunderbird的**磁盘状态**,并使用 **IMAP/SMTP** 进行实时操作。无需安装Thunderbird扩展或插件,无论Thunderbird是否正在运行,它都可以使用。
| 数据源 | 文件路径 | 访问方式 |
| --- | --- | --- |
| 账户、SMTP、日历 | `prefs.js` | 读取 |
| 全文搜索索引 | `global-messages-db.sqlite`(gloda) | 只读 |
| 凭证 | `key4.db` + `logins.json`(NSS) | 只读,使用纯Go解密 |
| 联系人 | `abook.sqlite` | 只读 |
| 日历 | `calendar-data/local.sqlite` | 只读 |
| 实时邮件 | IMAP / SMTP | 获取、修改、发送 |
它是一个单独的静态 **CGO-free** Go二进制文件。
**当Thunderbird持有锁时,预计会有延迟。** SQLite数据库通常实时读取,即使Thunderbird正在运行。当Thunderbird持有独占锁时,第一个受影响的请求会等待约5秒,然后回退到将数据库复制到私有快照,因此大型搜索索引不会立即生效。后续请求将从该快照中提供,并在接下来的60秒内快速响应。启动时可能会为每个数据源支付相同的等待时间。这是预期行为,而不是挂起。
## 工具
三个领域工具,每个工具由一个 `action` 枚举驱动:
### `thunderbird_mail`
`list_accounts`、`list_folders`、`search_messages`、`get_message`、`list_recent`、`set_flags`、`move_message`、`delete_message`、`send_mail`、`reply_message`、`forward_message`、`save_draft`
### `thunderbird_contacts`
`search_contacts`、`get_contact`
### `thunderbird_calendar`
`list_calendars`、`list_events`
`action` 枚举是**动态构建**的:写入操作(如 `set_flags`/`move_message`/`delete_message`)仅在允许写入时出现,而发送操作(如 `send_mail`/`reply_message`/`forward_message`/`save_draft`)仅在 `THUNDERBIRD_ALLOW_SEND=true` 时出现。禁用的操作甚至不会出现在模式中。
有关每个操作的详细参数参考,请参见 [docs/tools.md](docs/tools.md)。
## 安全模型
- **从不写入任何Thunderbird拥有的文件**(mbox/maildir/gloda/abook/calendar/`key4.db`/`logins.json`)。每个SQLite数据库都以只读方式打开。所有修改操作都通过IMAP进行,服务器会同步。
- **本地(POP/本地文件夹)账户、联系人和日历只读。**
- **发送操作受`THUNDERBIRD_ALLOW_SEND=true`控制**(默认为关闭)。`THUNDERBIRD_READ_ONLY=true` 禁用所有修改和发送操作。
- 本地消息路径通过 **路径穿越保护** 解析 - 构造的 `message_ref` 无法逃离配置文件目录。
更多详细信息请参见 [docs/security.md](docs/security.md)。
## 配置
| 变量 | 默认值 | 效果 |
| --- | --- | --- |
| `THUNDERBIRD_PROFILE` | 自动发现 | 配置文件目录路径 |
| `THUNDERBIRD_READ_ONLY` | `false` | 当为 `true` 时,修改和发送操作不可用 |
| `THUNDERBIRD_ALLOW_SEND` | `false` | 当为 `true` 时,启用撰写/发送操作 |
| `THUNDERBIRD_TOOLS` | 所有 | 三个工具名称的逗号分隔允许列表 |
## 快速开始
### 一行命令(Linux/macOS)
```bash
curl -fsSL https://mudler.github.io/thunderbird-mcp/install.sh | sh
```
安装最新版本的二进制文件(amd64/arm64)到 `~/.local/bin`,并在安装前验证其校验和与发布的 `checksums.txt` 匹配。`BINDIR=/usr/local/bin` 更改目标目录,`VERSION=v0.1.0` 固定版本。
### Docker
```bash
docker run -i --rm --network host \
-e THUNDERBIRD_PROFILE=/profile \
-v "$HOME/.thunderbird/xxxx.default-release:/profile:ro" \
ghcr.io/mudler/thunderbird-mcp:latest
```
`--network host` 允许容器访问您的IMAP/SMTP服务器;建议以只读方式挂载配置文件(服务器从不写入它)。
### 从源码编译
```bash
go install github.com/mudler/thunderbird-mcp@latest
THUNDERBIRD_PROFILE=~/.thunderbird/xxxx.default-release thunderbird-mcp
```
### LocalAI
在模型配置中添加:
```yaml
mcp:
stdio: |
{
"mcpServers": {
"thunderbird": {
"command": "docker",
"args": [
"run", "-i", "--rm", "--network", "host",
"-e", "THUNDERBIRD_PROFILE=/profile",
"-e", "THUNDERBIRD_ALLOW_SEND=false",
"-v", "/home/user/.thunderbird/xxxx.default-release:/profile:ro",
"ghcr.io/mudler/thunderbird-mcp:latest"
]
}
}
}
```
## 限制(非目标)
- **OAuth2** 账户不支持实时IMAP/SMTP(大多数Gmail/Outlook设置)。它们仍然出现在索引搜索中;实时获取/发送报告一个明确的“不支持”错误。
- 受 **主密码** 保护的配置文件无法解密其凭证 - 服务器记录一个警告并继续提供只读搜索/联系人/日历工具。
- 无日历或联系人 **写入** 操作。
## 开发
```bash
go test ./... # ginkgo 套件
go vet ./...
CGO_ENABLED=0 go build .
```
凭证解密路径由一个回归测试覆盖,该测试针对一个**真实**的NSS `key4.db`/`logins.json` 固定件(由NSS库本身生成),以及综合的往返测试。
## License
[MIT](./LICENSE)