关于 protonlite
protonlite 是轻量级 Python 客户端,可访问 Proton Mail、Calendar、Contacts 和 Drive,并在本机解密数据。它面向希望不使用 Bridge 访问 Proton 服务的用户,也提供供 Agent 使用的可选 MCP 服务。
主要功能
- 01访问邮件、日历、联系人和 Drive
- 02本机解锁密钥并解密
- 03以邮件为主的命令行界面
- 04收件人和发送确认策略
适用场景
- 01读取和搜索 Proton 邮件
- 02管理日历事件与联系人
- 03上传或获取 Drive 文件
- 04限制 Agent 发送邮件
MCP 相关
可选 MCP 服务提供邮件、日历、联系人和 Drive 工具,以及邮件策略控制。MCP 客户端使用 CLI 保存的会话;服务不接收密码。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
18收录的工具列表 · 更新于 5 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| limit | integer | 否 | |
| folder | string | 否 | |
| unread_only | boolean | 否 |
详细介绍
protonlite
一个轻量、依赖精简的 Python 客户端和 Proton Mail(ProtonMail)API,支持 Proton Mail、Calendar、Contacts 和 Drive,无需 Proton Mail Bridge 或付费套餐。还提供可选的 MCP 服务,让 Agent(Claude Code、Cursor)能够使用你的邮箱。
Proton 不提供 IMAP 或 SMTP。官方接入方式是 Proton Mail Bridge,但它需要付费套餐。protonlite 直接与 Proton 的 Web API 通信,因此免费账户也能使用;端到端加密则移植自 Proton 自有的 MIT 许可 Go 库
(go-srp、
go-proton-api)。它采用 MIT 许可,依赖精简:仅使用 OpenPGP(PGPy13,PGPy 的一个维护中分支)、bcrypt 和 requests。没有 CAPTCHA 求解器,也没有计算机视觉技术栈——用户只需像使用 Proton 自家应用一样,在 Proton 的验证页面上完成验证。
非官方项目。 本项目与 Proton AG 无关联,也未获其认可或支持。 “Proton”、“Proton Mail”、“Proton Calendar”和“Proton Drive”是 Proton AG 的商标。 本项目使用未公开文档的私有 API,该 API 可能随时变更;使用本项目也可能受 Proton 服务条款约束。使用风险自负,且仅限你拥有的账户。
功能
- Mail ——读取收件箱和任意文件夹,解密邮件(将 HTML 转换为纯文本),搜索、发送邮件(纯文本或 HTML、附件、在线回复、定时发送)、保存草稿、标记已读/未读、移至废纸篓/删除、管理标签和文件夹、清空废纸篓、查看存储用量。
- Calendar ——查看日程、创建/编辑/取消活动、发送邀请、回复邀请。
- Contacts ——读取、创建、编辑和删除联系人(签名/加密的 vCard)。
- Drive ——列出、下载、上传(加密)、移动、重命名、移至废纸篓,以及创建公开分享链接。
所有操作都采用端到端加密:密钥会在本地使用账户密码解锁,邮件、活动、联系人和文件也会在你的设备上解密。
安装
pip install protonlite
需要 Python 3.10+。
快速开始
import os
import datetime as dt
from protonlite import ProtonMail
# --- Signing in -------------------------------------------------------------
# The recommended way is the CLI `protonlite login`, which reads the password
# with getpass so it never lives in a script. For automation, read it from the
# environment rather than hard-coding it. Proton usually asks a human to
# complete a verification page; login raises HumanVerificationRequired with
# that URL -- open it, then call again passing verification_token (see
# "Signing in" below). Sign in each account once; every login saves its own
# session file.
ProtonMail.login(
"[email protected]",
password=os.environ["PROTON_PASSWORD"].encode(),
session_path="[email protected]",
)
# --- More than one account --------------------------------------------------
# Reopen each saved session independently -- no password needed. The two
# clients are fully independent mailboxes.
client = ProtonMail.from_session(session_path="[email protected]") # personal
client1 = ProtonMail.from_session(session_path="[email protected]") # work
# (after a CLI `protonlite login`, ProtonMail.for_account("work") finds it by name)
print(client.addresses()[0]["Email"], "/", client1.addresses()[0]["Email"])
# --- Mail -------------------------------------------------------------------
for msg in client.list_messages(unread_only=True):
print(msg.time, msg.sender.address, msg.subject)
full = client.read_message(msg.id)
print(full.text) # HTML flattened to prose
client.send(to=["[email protected]"], subject="Hi", body="Hello")
client1.send(to=["[email protected]"], subject="Hi from work", body="Hello")
# --- Calendar ---------------------------------------------------------------
cal_id = client.list_calendars()[0]["ID"]
begins = dt.datetime.now(dt.timezone.utc) + dt.timedelta(days=1)
event = client.create_event(cal_id, summary="Demo",
start=begins, end=begins + dt.timedelta(hours=1))
for ev in client.list_events(cal_id, start=int(begins.timestamp()) - 3600,
end=int(begins.timestamp()) + 86400):
print(dt.datetime.fromtimestamp(ev.start, dt.timezone.utc), ev.title)
client.delete_event(cal_id, event["id"])
# --- Contacts ---------------------------------------------------------------
cid = client.create_contact(name="Ada Lovelace", emails=["[email protected]"])
for row in client.list_contact_emails():
print(row["name"], row["email"])
client.delete_contacts([cid])
# --- Drive ------------------------------------------------------------------
drive = client.drive()
with open("report.pdf", "rb") as fh:
drive.upload("", "report.pdf", fh.read(), "application/pdf")
for entry in drive.list_folder(""):
print(entry["name"], entry["type"])
link = drive.share_link("report.pdf")
print(link["url"]) # https://drive.proton.me/urls/...#password
命令行
简洁的 CLI 涵盖邮件的基本操作:
protonlite login --user [email protected]
protonlite unread
protonlite read <message-id>
protonlite send --to [email protected] --subject "Hi" --body "Hello"
登录
从服务器登录 Proton 几乎总会触发人工验证页面(hCaptcha)。登录流程会显示验证 URL,供用户在浏览器中完成验证;protonlite 不会求解验证码,也不会通过你自己的代码之外的任何渠道索要密码。账户密码仅用于在本地派生密钥——不会被保存;已保存的会话只包含 OAuth 风格的令牌和派生出的密钥口令,仅此而已。支持双重验证(TOTP)。
MCP 服务
protonlite 提供可选的 MCP 服务,让任何 MCP 客户端(Cursor、Claude Code、Claude Desktop)都能通过它使用 Proton。使用 CLI 登录一次,然后指定该会话运行服务:
pip install "protonlite[mcp]"
protonlite login --user [email protected] # one-time; saves a session file
PROTONLITE_SESSION=~/[email protected] protonlite-mcp
protonlite mcp 会启动同一个服务,因此无需本地安装即可通过 uvx --from "protonlite[mcp]" protonlite mcp 运行(MCP 注册表条目使用的就是此命令)。
将其接入 MCP 客户端(例如 Claude Desktop/Cursor 的 mcpServers 配置):
{
"mcpServers": {
"proton": {
"command": "protonlite-mcp",
"env": { "PROTONLITE_SESSION": "/home/you/[email protected]" }
}
}
}
服务不会接收密码,而是复用已保存的会话。它提供 18 个工具:list_messages、read_message、search_messages、send_message、calendar、contacts,一套完整的 Proton Drive 工具——drive_list、drive_download、drive_upload、drive_mkdir、drive_move、drive_rename、drive_trash、drive_share_link、drive_unshare_link——以及三个发送策略工具:email_policy_status、email_allow 和 set_send_confirmation。它会将其他人的内容作为不可信数据返回。drive_share_link 会创建公开链接,其 URL 本身就是全部秘密,因此仅适用于你打算分享的文件。send_message 也可以附加本地文件,例如刚通过 drive_download 获取的文件。
发送策略(允许列表和确认)
send_message 受收件人允许列表和可选的“发送前确认”规则约束,Agent 可以读取和更改这两项设置:
email_policy_status显示当前允许列表以及是否启用了确认。email_allow设置允许列表——指定地址或通配模式(*@company.com)用于限制发送,["*"]表示允许发送给任何人,[]表示禁止所有发送。set_send_confirmation用于开启或关闭确认规则。开启后,首次调用send_message不会发送任何内容,而是返回确认请求;只有再次调用并设置confirm=true时才会发送。
这三个工具都可由 Agent 更改,因此它们本身只是便利设置,起到建议作用。强制控制由人员通过带外方式设置,Agent 无法放宽——可以使用环境变量或 protonlite policy CLI:
- 收件人上限。
PROTON_ALLOWED_RECIPIENTS(逗号分隔的地址或通配模式),或protonlite policy ceiling <addrs>,设置了email_allow工具无法超越的上限:无论 Agent 如何操作,向范围外的任何人发送内容都会被拒绝。 - 强制确认。
PROTON_REQUIRE_SEND_CONFIRMATION=1,或protonlite policy require-confirm on,会完全禁止 Agent 使用send_message——发送始终会被拒绝,confirm参数也无法解除限制,因此人员需要在终端中使用protonlite send发送。(Agent 自己的set_send_confirmation只控制较宽松的两步规则,设置confirm=true即可通过;意志坚定或受到操纵的 Agent 可以自行传入该值,因此这是检查点,而非屏障。)
在终端中管理强制策略:
protonlite policy show # print the effective policy
protonlite policy ceiling *@your-company.com # a ceiling the agent cannot exceed
protonlite policy require-confirm on # agent can no longer send; you send via the CLI
protonlite policy require-confirm off # lift it
此外,只能在会要求你批准每次工具调用的 MCP 客户端中运行此服务,因为 send_message 和 drive_upload 会读取本地文件并将其发送出去。如需设置 Agent 永远无法绕过的发送关卡——每次发送都必须通过默认拒绝的人为审批钩子——请使用下文的 hermes-proton。
状态与限制
写入功能(上传到 Drive、创建日历事件、分享链接)是通过逆向工程 Proton 的 Go 和 Web 客户端实现的,并已使用真实账号进行验证,但该 API 未公开文档,可能会发生变化。日历密钥生成会调用 gpg(Proton 要求使用 PGPy 无法生成的 Ed25519 密钥)。欢迎提交 Bug 报告和 PR。
相关项目
protonlite 也是 hermes-proton 的底层引擎。它是适用于 Hermes Agent 的 Proton 插件,增加了收件人允许列表和每次发送都需通过人工审批的关卡。
许可证
MIT。请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。