A Python CLI (and MCP server) for reading and writing Proton Calendar events via Proton's undocumented internal API. There's no official Proton Calendar API or CalDAV support because of the end-to-end encryption, so this reverse-engineers the web client's endpoints and reproduces the client-side PGP key hierarchy.
Unofficial. Not affiliated with or endorsed by Proton AG. Use at your own risk - the API is undocumented and may change.
- Auth: SRP login, 2FA, CAPTCHA handling, persistent session
- Calendars: list calendars on the account
- Events: list, create, update, delete events (with full PGP encrypt/decrypt round-trip)
- Multi-calendar / multi-address: signs with the correct address key per calendar member
- MCP server: stdio FastMCP server exposing the same operations as tools (for use with Claude Code or other MCP clients)
Requires Python 3.11+ and proton-core for SRP authentication. proton-core isn't on PyPI - on Arch Linux it's available as python-proton-core. For other distros, install from source or create the venv with --system-site-packages if your distro ships it.
git clone https://github.com/Nojuza/proton-calendar-cli.git
cd proton-calendar-cli
python -m venv .venv --system-site-packages # so proton-core is visible
.venv/bin/pip install -e .This installs the proton-cal command and the proton_calendar package.
# Authenticate (prompts for password + 2FA, stores session in ~/.config/proton-calendar-cli/)
proton-cal login
# List calendars
proton-cal calendars
# List events for the next 7 days
proton-cal events --days 7
# Create an event
proton-cal create "Team standup" \
--start "2026-05-26 09:00" \
--end "2026-05-26 09:30" \
--description "Weekly sync" \
--location "Zoom"
# Update an event (only the fields you pass are changed)
proton-cal update <event-id> --summary "Renamed standup" --location "In person"
# Delete
proton-cal delete <event-id>All time-based commands accept --tz (default Australia/Melbourne) and --calendar <id> to target a specific calendar.
If a password is stored in gnome-keyring under service proton-calendar-cli / account proton, the CLI uses it automatically instead of prompting:
secret-tool store --label="Proton Calendar CLI" service proton-calendar-cli account protonThe package also installs an MCP stdio server (python -m proton_calendar.mcp_server) exposing:
list_calendarslist_eventscreate_eventupdate_eventdelete_event
Example MCP config:
{
"mcpServers": {
"proton-calendar": {
"command": "/path/to/proton-calendar-cli/.venv/bin/python",
"args": ["-m", "proton_calendar.mcp_server"]
}
}
}The server reads the password from gnome-keyring (no interactive prompt available over stdio). Sessions are restored from ~/.config/proton-calendar-cli/. Run proton-cal login once before using the MCP server.
src/proton_calendar/
auth.py - Session management, SRP auth, unlock, API requests
calendar.py - Calendar listing
captcha_server.py - CAPTCHA human verification flow
cli.py - Click CLI
crypto.py - PGP sign/encrypt/decrypt, session-key extraction
events.py - Event CRUD (encrypt/decrypt, iCal building)
keys.py - Key unlocking chain (user -> address -> calendar)
mcp_server.py - FastMCP stdio server
For deeper technical notes on the auth flow, key hierarchy, encryption model, and exact API payloads, see RESEARCH.md.
- Recurring events: not implemented.
RRULEhandling is on the roadmap. - API date filtering: Proton ignores
Start/Endquery params onGET /calendar/v1/{calID}/eventsand paginates all events at 100 per page - the CLI paginates and filters client-side. The Gogo-proton-apilibrary has the same limitation. - Reverse engineered: Proton may change their internal API at any time.
These were essential while building this:
ProtonMail/go-proton-api- the best reference for key unlocking and endpoint signaturesProtonMail/WebClients- calendar crypto inpackages/shared/lib/calendar/ProtonMail/proton-python-client- SRP auth wrapper used here
No license file yet - all rights reserved by default. If you'd like to use or extend this, open an issue.