内容
# Proton 邮件桥接 MCP 服务器
一款通过 Proton Bridge 的 IMAP/SMTP 接口连接到 Proton Mail 的模型上下文协议(MCP)服务器,为 Claude 和 LMStudio 等 AI 助手提供电子邮件操作功能。
**状态**: 第一阶段 / 概念验证
## 功能
### 可用 MCP 工具
1. **列出邮件** - 列出指定文件夹中的邮件
2. **读取邮件** - 按 ID 读取完整的邮件内容
3. **发送邮件** - 发送新的邮件(纯文本,无附件)
4. **搜索邮件** - 按条件搜索邮件
5. **列出文件夹** - 列出所有可用的邮件文件夹
## 前提条件
### 系统要求
- **Python 3.10+**
- 已安装并运行 **Proton Bridge**
- 具有有效凭证的 **Proton Mail 账户**
### Proton Bridge 设置
1. 下载并安装 [Proton Bridge](https://proton.me/mail/bridge)
2. 启动 Proton Bridge 并使用 Proton 账户登录
3. 生成 Bridge 凭证:
- 在 Proton Bridge 中,进入设置
- 复制 Bridge 用户名和密码(不是 Proton 账户密码)
4. 验证 Bridge 是否在默认端口运行:
- IMAP: `127.0.0.1:1143`
- SMTP: `127.0.0.1:1025`
## 安装
### 1. 克隆/下载项目
```bash
cd /path/to/proton-mcp-server
```
### 2. 创建虚拟环境(推荐)
```bash
python3 -m venv venv
source venv/bin/activate # 在 Windows 上:venv\Scripts\activate
```
### 3. 安装依赖项
```bash
pip install -r requirements.txt
```
### 4. 配置服务器
选择以下三种配置方法之一:
#### 选项 A:环境变量(.env 文件)- 推荐
```bash
cp .env.example .env
# 编辑 .env 文件,填写实际凭证
```
编辑 `.env`:
```ini
PROTON_USERNAME=your_bridge_username@proton.me
PROTON_PASSWORD=your_bridge_password
IMAP_HOST=127.0.0.1
IMAP_PORT=1143
SMTP_HOST=127.0.0.1
SMTP_PORT=1025
ATTACHMENT_DOWNLOAD_PATH=/tmp/proton-attachments
MAX_EMAIL_RESULTS=50
```
#### 选项 B:配置文件(config.json)
创建 `config.json`:
```json
{
"proton_username": "your_bridge_username@proton.me",
"proton_password": "your_bridge_password",
"imap_host": "127.0.0.1",
"imap_port": 1143,
"smtp_host": "127.0.0.1",
"smtp_port": 1025,
"attachment_download_path": "/tmp/proton-attachments",
"max_email_results": 50
}
```
#### 选项 C:命令行参数
通过命令行传递配置:
```bash
python server.py \
--proton-username your_bridge_username@proton.me \
--proton-password your_bridge_password \
--imap-host 127.0.0.1 \
--imap-port 1143
```
**优先级顺序**:命令行参数 > 环境变量 > 配置文件
## 运行服务器
### 独立模式(用于测试)
```bash
python server.py
```
服务器将启动并监听 stdin/stdout 中的 MCP 协议消息。
### 与 LMStudio 结合使用
1. 打开 LMStudio 设置
2. 导航到 MCP 服务器配置
3. 添加新服务器:
```json
{
"name": "proton-mail-bridge",
"command": "python",
"args": ["/path/to/proton-mcp-server/server.py"],
"env": {
"PROTON_USERNAME": "your_bridge_username@proton.me",
"PROTON_PASSWORD": "your_bridge_password"
}
}
```
4. 重启 LMStudio
### 与 Claude Desktop 结合使用
编辑 `~/Library/Application Support/Claude/claude_desktop_config.json`(macOS):
```json
{
"mcpServers": {
"proton-mail-bridge": {
"command": "python",
"args": ["/path/to/proton-mcp-server/server.py"],
"env": {
"PROTON_USERNAME": "your_bridge_username@proton.me",
"PROTON_PASSWORD": "your_bridge_password"
}
}
}
}
```
重启 Claude Desktop。
## 使用示例
连接到 AI 助手后:
### 列出最近的邮件
```
"列出我在收件箱中的最近邮件"
```
### 读取特定邮件
```
"读取邮件 ID 42 并包含附件"
```
### 发送邮件
```
"发送一封邮件给 john@example.com,主题为 'Meeting Tomorrow',内容为 'Let's meet at 3pm'"
```
### 搜索邮件
```
"搜索邮件中包含 'invoice' 的邮件"
```
### 列出文件夹
```
"显示我所有的邮件文件夹"
```
## API 参考
### list_emails
列出文件夹中的邮件。
**参数:**
- `folder`(可选,默认: "INBOX")- 文件夹名称
- `limit`(可选,默认: 50,最大: 50)- 最大结果数
- `unread_only`(可选,默认: false)- 仅限未读邮件
**返回:**
```json
{
"emails": [
{
"id": "123",
"from": "sender@example.com",
"to": ["you@proton.me"],
"subject": "Hello",
"date": "2026-02-09T10:30:00Z",
"unread": true,
"has_attachments": true,
"preview": "First 200 chars...",
"folder": "INBOX"
}
]
}
```
### read_email
读取完整的邮件内容。
**参数:**
- `email_id`(必填)- list_emails 中的邮件 ID
- `include_attachments`(可选,默认: false)- 包含 base64 内容
**返回:**
```json
{
"id": "123",
"from": "sender@example.com",
"to": ["you@proton.me"],
"cc": [],
"subject": "Hello",
"date": "2026-02-09T10:30:00Z",
"body_text": "Plain text body",
"body_html": "<html>...</html>",
"attachments": [
{
"filename": "document.pdf",
"size": 102400,
"content_type": "application/pdf",
"content_base64": "JVBERi0xLjQK..."
}
]
}
```
### send_email
发送一封新邮件。
**参数:**
- `to`(必填)- 收件人邮件地址数组
- `subject`(必填)- 邮件主题
- `body`(必填)- 纯文本内容
- `cc`(可选)- CC 收件人数组
- `bcc`(可选)- BCC 收件人数组
**返回:**
```json
{
"success": true,
"message_id": "<generated_id@proton.me>"
}
```
### search_emails
按条件搜索邮件。
**参数:**
- `query`(必填)- 搜索字符串
- `folder`(可选,默认: "INBOX")- 搜索的文件夹
- `search_in`(可选,默认: ["subject", "from", "body"])- 搜索字段
- `limit`(可选,默认: 50,最大: 50)- 最大结果数
**返回:** 与 `list_emails` 相同
### list_folders
列出所有邮件文件夹。
**参数:** 无
**返回:**
```json
{
"folders": [
{"name": "INBOX", "message_count": 42},
{"name": "Sent", "message_count": 128},
{"name": "Drafts", "message_count": 3}
]
}
```
## 错误处理
所有操作都以一致的格式返回错误:
```json
{
"error": "连接到 Proton Bridge 失败",
"error_type": "ConnectionError",
"details": "无法连接到 127.0.0.1:1143"
}
```
常见错误类型:
- `ConnectionError` - Bridge 未运行或端口错误
- `AuthenticationError` - 凭证无效
- `FolderNotFoundError` - 文件夹不存在
- `EmailNotFoundError` - 邮件 ID 未找到
- `ValidationError` - 缺少必填参数
## 故障排除
### "连接被拒绝" 错误
**问题**: 无法连接到 Proton Bridge
**解决方案**:
1. 验证 Proton Bridge 是否正在运行
2. 检查 Bridge 设置中的端口(应为 1143/1025)
3. 确保没有防火墙阻止本地连接
### "身份验证失败" 错误
**问题**: 凭证无效
**解决方案**:
1. 使用 Bridge 密码,而不是 Proton 账户密码
2. 在 Bridge 设置中重新生成 Bridge 密码
3. 检查用户名是否包含完整的邮件地址(@proton.me)
### "邮件未找到" 错误
**问题**: 无效的邮件 ID
**解决方案**:
1. 使用 `list_emails` 获取有效的 ID
2. 邮件 ID 是文件夹特定的(IMAP UID)
3. 不要在删除邮件后重用 ID
### 附件无法保存
**问题**: 权限被拒绝或路径不存在
**解决方案**:
1. 确保 `ATTACHMENT_DOWNLOAD_PATH` 可写
2. 服务器自动创建目录
3. 检查磁盘空间
## 架构概述
### 项目结构
```
proton-mcp-server/
├── server.py # MCP 服务器入口点
├── imap_client.py # IMAP 操作模块
├── smtp_client.py # SMTP 操作模块
├── config.py # 配置管理
├── models.py # 邮件数据结构
├── requirements.txt # Python 依赖项
├── .env.example # 示例配置
└── README.md # 本文件
```
### 模块化设计
代码库设计为可扩展:
- **config.py**: 基于优先级的配置加载器
- **models.py**: 邮件、附件、响应的数据类
- **imap_client.py**: 所有 IMAP 操作(读取、搜索、列出)
- **smtp_client.py**: 所有 SMTP 操作(发送)
- **server.py**: MCP 协议处理程序和工具定义
### 添加新功能(第二阶段)
要扩展功能:
1. **添加新的 IMAP 操作**: 编辑 `imap_client.py`
2. **添加新的 SMTP 操作**: 编辑 `smtp_client.py`
3. **添加新的 MCP 工具**:
- 在 `server.py::handle_list_tools()` 中定义工具
- 在 `server.py::handle_call_tool()` 中添加处理程序
4. **添加新的数据模型**: 在 `models.py` 中定义
示例:添加 "标记为已读" 功能:
```python
# imap_client.py
def mark_as_read(self, email_id: str) -> Dict[str, Any]:
# 实现代码
pass
# server.py - 添加到 handle_call_tool()
elif name == "mark_as_read":
email_id = arguments.get("email_id")
result = imap_client.mark_as_read(email_id=email_id)
```
## 第二阶段路线图
未来版本计划的功能:
- [ ] 回复/转发邮件
- [ ] 标记已读/未读
- [ ] 将邮件移动到文件夹
- [ ] 删除邮件
- [ ] 发送带有附件的邮件
- [ ] 具有指数退避的重试逻辑
- [ ] 大结果集的分页
- [ ] 结果缓存
- [ ] 异步操作(如有需要)
## 技术说明
### IMAP/SMTP 行尾
Proton Bridge 需要 CR/LF (`\r\n`) 行尾进行身份验证。Python 的 `imaplib` 和 `smtplib` 自动处理这一点。
### 邮件 ID 格式
邮件 ID 是 IMAP UID(每个文件夹的唯一标识符)。它们是:
- 文件夹特定(ID "5" 在收件箱 ≠ ID "5" 在已发送)
- 在文件夹内持久
- 顺序但不一定连续
### 日期格式
所有日期使用 ISO 8601 格式: `2026-02-09T10:30:00Z`(UTC 时区)
### 附件处理
- 始终返回元数据(文件名、大小、类型)
- 仅在 `include_attachments=true` 时包含内容
- 内容为 base64 编码
- 文件保存在 `ATTACHMENT_DOWNLOAD_PATH`
## 安全考虑
### 凭证
- **永远不要提交 `.env` 文件** 到版本控制
- 使用 Bridge 生成的密码(每个设备唯一)
- 定期轮换 Bridge 密码
### 网络
- Bridge 仅监听 localhost(127.0.0.1)
- 默认情况下没有外部网络暴露
- IMAP/SMTP 连接使用 STARTTLS
### 附件
- 保存在本地文件系统(配置安全路径)
- 考虑磁盘空间限制
- 定期清理旧附件
## 贡献
这是第一阶段的概念验证。欢迎贡献:
- 错误修复
- 第二阶段功能
- 文档改进
- 测试覆盖
## 许可证
[在此指定您的许可证]
## 支持
对于问题和疑问:
1. 检查上面的故障排除部分
2. 验证 Proton Bridge 是否正确配置
3. 使用 Proton Bridge 的内置 IMAP/SMTP 测试
## 致谢
使用以下技术构建:
- [模型上下文协议(MCP)](https://modelcontextprotocol.io/)
- [Proton 邮件桥接](https://proton.me/mail/bridge)
- Python 标准库(imaplib、smtplib、email)