proton-vpn-cli
v0.3.1
Published
Unofficial Proton VPN CLI for macOS and Windows (WireGuard + interactive TUI)
Maintainers
Readme
proton-vpn-cli
Unofficial Proton VPN command-line client for macOS and Windows.
Authenticates with Proton’s VPN API, creates a WireGuard certificate, and connects through the system WireGuard tools. Includes an interactive TUI.
Not an official Proton product. For the supported apps, use Proton VPN. Proton’s official CLI is Linux-only.
Install
Requires Bun ≥ 1.1 at runtime (including when you install with npm).
Bun
bun add -g proton-vpn-cliOr from GitHub:
bun install -g github:brandonkramer/proton-vpn-clinpm
npm install -g proton-vpn-cliRun
protonvpn # interactive TUI (TTY only)
protonvpn status --json # agent / scripting
protonvpn --helpFrom a clone
git clone https://github.com/brandonkramer/proton-vpn-cli.git
cd proton-vpn-cli
bun install
bun link # optional: puts `protonvpn` on your PATHRequirements
- Bun ≥ 1.1
- Proton account in Single Password Mode
- TOTP if you use 2FA (FIDO2/security keys are not supported)
- WireGuard tools (install tries this automatically via Homebrew / winget; or run
protonvpn setup)- macOS: Homebrew →
wireguard-tools(sudo for connect/disconnect) - Windows: WireGuard app via winget (Administrator terminal for connect/disconnect)
- macOS: Homebrew →
Close the Proton VPN desktop app before connecting so tunnels do not conflict.
On macOS, connect/disconnect may ask for your Mac login password (sudo), not your Proton password.
Usage
Interactive TUI
protonvpn
# or
protonvpn tui↑↓ + enter to choose · q / Esc to quit.
Commands
protonvpn signin [username]
protonvpn signin --pass "pass://Personal/Proton" # optional: Proton Pass CLI
protonvpn signout
protonvpn update # upgrade the CLI itself
protonvpn update --check # only check npm for a newer version
protonvpn countries
protonvpn servers --country US
protonvpn connect --country US
protonvpn connect --city "New York"
protonvpn connect US#23
protonvpn status
protonvpn disconnectSign in with Proton Pass (optional)
If you use Proton Pass CLI (pass-cli),
you can pull username/password (and TOTP when present) from a login item instead
of typing them:
pass-cli login # once, if needed
protonvpn signin --pass "pass://Personal/Proton"
# or:
export PROTONVPN_PASS="pass://Personal/Proton"
protonvpn signinVault/Item works too (the pass:// prefix is optional). A username argument
still overrides the Pass username. Interactive prompts remain the default when
--pass / PROTONVPN_PASS is unset.
| Flag | Meaning |
|------|---------|
| --country <code> | Exit country (e.g. NL) |
| --city <name> | City name |
| --p2p | P2P servers |
| --securecore | Secure Core |
| --tor | Tor over VPN |
| --free-only | Free-tier only |
Country availability depends on your Proton plan.
Scripting / agents
protonvpn status --json
protonvpn connect --json --country US
protonvpn signin --json --pass "pass://Personal/Proton"Use --json (or PROTONVPN_JSON=1 / PROTONVPN_AGENT=1) for machine-readable stdout. Errors go to stderr. Global -y/--yes skips confirms; --sudo allows an interactive macOS sudo prompt (by default agents use passwordless sudo -n only).
Exit codes: 0 ok · 1 error · 2 usage · 3 not signed in · 4 privilege needed.
Bare protonvpn with no args opens the TUI only in an interactive terminal; otherwise it prints usage and exits 2.
How it works
- SRP login to
https://vpn-api.proton.me(session cached in your OS config dir) - Pick a server (lowest Proton
Score, thenLoad) - Create an Ed25519 → X25519 WireGuard certificate
- Write a local
.confunder~/.config/proton-vpn-cli/(macOS/Linux) or%APPDATA%\proton-vpn-cli\(Windows) - Bring the tunnel up with
wg-quickorwireguard.exe
Session tokens and WireGuard configs stay on your machine in those config dirs — they are not part of this repository.
Development
bun install
bun run typecheck
bun test
bun run src/index.ts --helpLicense
GPL-3.0-or-later (required by @protontech/crypto).
