Disclaimer: This is an unofficial, community-built tool and is not endorsed by or affiliated with Proton AG. Use at your own risk.
An unofficial command-line tool for Proton — Mail, Drive, Calendar, Pass, and Contacts from your terminal.
Implements the same authentication and encryption as the Proton web client: SRP login, PGP key hierarchy, and full end-to-end encryption using go-srp and gopenpgp.
Grab the latest binary for your platform from GitHub Releases.
| Platform | Binary |
|---|---|
| Linux (x86_64) | proton-cli_VERSION_linux_amd64 |
| Linux (ARM64) | proton-cli_VERSION_linux_arm64 |
| macOS (Apple Silicon) | proton-cli_VERSION_darwin_arm64 |
| macOS (Intel) | proton-cli_VERSION_darwin_amd64 |
| Windows (x86_64) | proton-cli_VERSION_windows_amd64.exe |
| Windows (ARM64) | proton-cli_VERSION_windows_arm64.exe |
Linux / macOS:
# Download (replace URL with the latest release)
curl -LO https://github.com/roman-16/proton-cli/releases/latest/download/proton-cli_VERSION_linux_amd64
# Make executable and move to PATH
chmod +x proton-cli_*
sudo mv proton-cli_* /usr/local/bin/proton-cliWindows: download the .exe from the releases page and add it to your PATH.
If you have Go installed:
go install github.com/roman-16/proton-cli@latestgit clone https://github.com/roman-16/proton-cli.git
cd proton-cli
go build .export PROTON_USER=alice@proton.me
export PROTON_PASSWORD='your-password'
# export PROTON_TOTP=123456 # if 2FA is enabledThe session is saved to ~/.config/proton-cli/session.json and reused automatically. The raw api command works without a password; encrypted commands (mail read, drive, calendar, contacts) require it.
# List your inbox
proton-cli mail list
# Read a message
proton-cli mail read MESSAGE_ID
# List your drive files
proton-cli drive ls
# See all commands
proton-cli --help# List messages
proton-cli mail list
proton-cli mail list --folder sent
proton-cli mail list --folder drafts --page 1 --page-size 10
proton-cli mail list --unread
# Search messages
proton-cli mail search --keyword "invoice"
proton-cli mail search --from "amazon" --after 2026-01-01
proton-cli mail search --subject "order" --folder inbox --limit 50
# Read a message (decrypted)
proton-cli mail read MESSAGE_ID
# Send a message
proton-cli mail send --to "recipient@example.com" --subject "Hello" --body "Message text"
# Move, trash, delete
proton-cli mail move --folder archive MESSAGE_ID
proton-cli mail trash MESSAGE_ID
proton-cli mail delete MESSAGE_ID # permanent
# Mark messages
proton-cli mail mark --read MESSAGE_ID
proton-cli mail mark --unread MESSAGE_ID
proton-cli mail mark --starred MESSAGE_ID
proton-cli mail mark --unstar MESSAGE_ID
# Attachments
proton-cli mail attachments list MESSAGE_ID
proton-cli mail attachments download MESSAGE_ID ATTACHMENT_ID ./output.pdf
# Labels and folders
proton-cli mail labels list
proton-cli mail labels create --name "Important" --color "#8080FF"
proton-cli mail labels create --name "Projects" --folder --color "#1DA583"
proton-cli mail labels delete LABEL_ID
# Addresses
proton-cli mail addresses list
# Filters
proton-cli mail filters list
proton-cli mail filters create --name "Archive invoices" \
--sieve 'require ["fileinto"]; if header :contains "Subject" "invoice" { fileinto "Archive"; }'
proton-cli mail filters enable FILTER_ID
proton-cli mail filters disable FILTER_ID
proton-cli mail filters delete FILTER_ID# List files
proton-cli drive ls
proton-cli drive ls /Documents
proton-cli drive ls /Documents/Projects
# Create folders
proton-cli drive mkdir /Documents/NewFolder
# Upload files
proton-cli drive upload ./photo.jpg # to root
proton-cli drive upload ./report.pdf /Documents # to subfolder
# Download files
proton-cli drive download /Documents/report.pdf ./report.pdf
proton-cli drive download /Photos/pic.jpg # to stdout
# Rename
proton-cli drive rename /Documents/old-name.txt new-name.txt
# Move
proton-cli drive mv /Documents/report.pdf /Archive
# Delete (move to trash)
proton-cli drive rm /Documents/old-report.pdf
proton-cli drive rm --permanent /Documents/secret.txt # permanent delete
# Trash management
proton-cli drive trash list
proton-cli drive trash restore LINK_ID
proton-cli drive trash empty# List calendars
proton-cli calendar list
# List events
proton-cli calendar list-events
proton-cli calendar list-events --start 2026-04-15 --end 2026-04-20
proton-cli calendar list-events --calendar "Work"
# Get event details (by IDs or title search)
proton-cli calendar get-event CALENDAR_ID EVENT_ID
proton-cli calendar get-event "Meeting"
# Create event
proton-cli calendar create-event \
--title "Meeting" \
--location "Vienna" \
--start "2026-04-16T14:00" \
--duration 1h
# Update event
proton-cli calendar update-event CALENDAR_ID EVENT_ID \
--title "Updated Meeting" \
--location "Graz"
# Delete event (by IDs or title search)
proton-cli calendar delete-event CALENDAR_ID EVENT_ID
proton-cli calendar delete-event "Meeting"
# Create / delete calendars
proton-cli calendar create --name "Work" --color "#8080FF"
proton-cli calendar delete CALENDAR_ID# List contacts
proton-cli contacts list
# Get contact (by ID or name/email search)
proton-cli contacts get CONTACT_ID
proton-cli contacts get "John Doe"
proton-cli contacts get "john@example"
# Create contact
proton-cli contacts create --name "John Doe" --email "john@example.com" --phone "+1234567890"
# Update contact
proton-cli contacts update "John Doe" --email "new@example.com" --phone "+0987654321"
# Delete contact
proton-cli contacts delete "John Doe"
proton-cli contacts delete CONTACT_ID# List vaults
proton-cli pass vaults list
# List all items
proton-cli pass list
proton-cli pass list --vault "Work"
# Get item (by IDs or name/URL search)
proton-cli pass get SHARE_ID ITEM_ID
proton-cli pass get "github.com"
proton-cli pass get "My Login"
# Create items
proton-cli pass create --type login --name "GitHub" --username "me" --password "secret" --url "github.com"
proton-cli pass create --type note --name "My Note" --note "Some text"
proton-cli pass create --type card --name "Visa" --holder "Roman" --number "4111..." --expiry "2028-12"
# Edit item
proton-cli pass edit SHARE_ID ITEM_ID --password "new-secret"
proton-cli pass edit "GitHub" --username "new-me"
# Trash / restore / delete
proton-cli pass trash SHARE_ID ITEM_ID
proton-cli pass restore SHARE_ID ITEM_ID
proton-cli pass delete SHARE_ID ITEM_ID
proton-cli pass delete "GitHub"
# Manage vaults
proton-cli pass vaults create --name "Work"
proton-cli pass vaults delete SHARE_IDproton-cli settings get # account settings
proton-cli settings mail # mail settingsFor any endpoint not covered by the high-level commands:
proton-cli api GET /calendar/v1
proton-cli api GET /drive/volumes
proton-cli api POST /calendar/v1 --body '{"Name":"Work","Color":"#7272a7","Display":1,"AddressID":"..."}'
proton-cli api DELETE /calendar/v1/CALENDAR_ID
proton-cli api GET /mail/v4/messages --query Page=0 --query PageSize=10Pipe through jq for formatting:
proton-cli api GET /calendar/v1 | jq '.Calendars[].ID'All commands default to human-readable table output. Pass --json for machine-readable JSON:
proton-cli mail list --json
proton-cli contacts list --json
proton-cli calendar list-events --json
proton-cli drive ls --json| Variable | Description |
|---|---|
PROTON_USER |
Proton account email |
PROTON_PASSWORD |
Account password (needed for encrypted operations) |
PROTON_TOTP |
TOTP code (if 2FA is enabled) |
PROTON_API_URL |
API base URL (default: https://mail.proton.me/api) |
PROTON_APP_VERSION |
App version header (default: Other) |
- Session creation — creates an unauthenticated session via
POST /auth/v4/sessions - SRP authentication — Secure Remote Password login with go-srp, with 2FA/TOTP support
- Session persistence — saves tokens + salted key password to
~/.config/proton-cli/session.json - Key hierarchy — unlocks User key → Address keys → per-service keys (Calendar, Drive, Contacts)
- End-to-end encryption — encrypts/decrypts using gopenpgp
- Auto-refresh — refreshes expired tokens automatically
| Service | Encrypt with | Sign with |
|---|---|---|
| Calendar events | Calendar key (session key) | Address key |
| Drive files | Node key (session key per block) | Address key |
| Drive names | Parent node key | Address key |
| Contacts | User key | User key |
| Session key | Address key | |
| Pass items | AES-256-GCM (item key) | N/A (symmetric) |
| Pass vaults | AES-256-GCM (vault key) | N/A (symmetric) |
See openapi.yaml for the complete API spec covering ~740 endpoints. To regenerate from the latest Proton source:
cd scripts && npm install && npm run generate-openapiSee scripts/README.md for details on the generator.
direnv allow
go build .
go test ./...MIT