Background CLI utility that copies OTPs from Gmail to clipboard on hotkey trigger
Project description
OTPilot
Press a hotkey. Your OTP is already copied.
pip install otpilot
✈ OTPilot v2.0
The new era of private OTP fetching. Background utility that copies OTPs from Gmail to your clipboard with a single hotkey.
GitHub • Install • Quickstart • OAuth Setup • Contributing
How It Works
- OTPilot sits silently in your system tray — no windows, no polling, zero CPU usage.
- Press your hotkey (e.g.
Ctrl+Shift+O) — OTPilot fetches your last 10 emails from Gmail and extracts the OTP. - OTP is copied to your clipboard — just paste it. A desktop notification confirms the action.
Installation
pip install otpilot
Requirements
- Python 3.8+
- Gmail account
- Google Cloud project with Gmail API enabled (free — setup guide)
- OS: macOS, Windows, or Linux
Linux users: Make sure
xcliporxselis installed for clipboard support.sudo apt install xclip # Debian/Ubuntu
Quickstart
1. Get Your Credentials
Follow the steps above (or the full guide) to download your credentials.json file.
2. Run Setup
otpilot setup
The wizard will:
- Ask for the path to your
credentials.jsonfile - Open your browser for Google sign-in (one-time authorization)
- Let you set your preferred hotkey
- Save your configuration
3. Start OTPilot
otpilot start
OTPilot runs in the background with a system tray icon. Press your hotkey whenever you need an OTP.
4. Daily Use
- Receive an OTP email in Gmail
- Press your hotkey (default:
Ctrl+Shift+O) - Paste the OTP — done!
Getting Your credentials.json
Before using OTPilot, you need to download a credentials.json file from Google Cloud Console. This is a one-time, ~5 minute process.
- Go to console.cloud.google.com
- Create a new project (or use an existing one)
- Enable the Gmail API
- Go to APIs & Services → Credentials
- Create an OAuth 2.0 Client ID (Application type: Desktop app)
- Click Download JSON to save the
credentials.jsonfile
Your credentials never leave your machine. The file is stored locally at
~/.otpilot/credentials.json.
For detailed, step-by-step instructions with screenshots, see SETUP.md.
CLI Commands
| Command | Description |
|---|---|
otpilot setup |
Run or re-run the interactive setup |
otpilot start |
Start the background service |
otpilot status |
Show auth state, hotkey, and config path |
otpilot version |
Print the version number |
Configuration
OTPilot stores its configuration at ~/.otpilot/config.json:
{
"hotkey": "ctrl+shift+o",
"notify_on_copy": true,
"otp_max_age_minutes": 10,
"email_fetch_count": 10
}
| Field | Type | Default | Description |
|---|---|---|---|
hotkey |
string | ctrl+shift+o |
Global hotkey combination |
notify_on_copy |
bool | true |
Show desktop notification when OTP is copied |
otp_max_age_minutes |
int | 10 |
Ignore emails older than this (minutes) |
email_fetch_count |
int | 10 |
Number of recent emails to scan |
Files Stored Locally
| File | Purpose |
|---|---|
~/.otpilot/config.json |
Your hotkey and settings |
~/.otpilot/credentials.json |
Your Google OAuth credentials |
~/.otpilot/token.json |
OAuth session token (auto-generated) |
Platform Support
| Platform | Status | Notes |
|---|---|---|
| macOS | ✅ | Full support |
| Windows | ✅ | Full support |
| Linux | ✅ | Requires xclip/xsel for clipboard |
How OTP Extraction Works
OTPilot scans the subject line and body of your recent emails for:
- 4–8 digit standalone numbers near context words like OTP, code, verify, verification, one-time, passcode, authentication
- Only emails within the configured time window are considered
- If multiple OTPs are found, the most recent one wins
Security & Privacy
- Your credentials stay local:
credentials.jsonis stored on your machine at~/.otpilot/and is never uploaded anywhere. - Read-only access: OTPilot only reads your emails — it cannot send, delete, or modify anything.
- Local storage only: Your OAuth token is stored locally at
~/.otpilot/token.json. Nothing is sent to any third-party server. - On-demand only: Emails are fetched only when you press the hotkey. There is no background polling.
Troubleshooting
| Issue | Solution |
|---|---|
| "credentials.json not found" | Run otpilot setup and provide your credentials file |
| "Invalid credentials file" | Re-download credentials.json from Google Cloud Console |
| "Not authenticated" error | Run otpilot setup to re-authenticate |
| No OTP found | Check otp_max_age_minutes — the email might be too old |
| Clipboard not working (Linux) | Install xclip: sudo apt install xclip |
| Hotkey not working | Run otpilot setup to reconfigure the hotkey |
| Tray icon not visible | Check your system tray / menu bar settings |
Contributing
Contributions are welcome! See CONTRIBUTING.md for guidelines on setting up the development environment, running tests, and submitting pull requests.
License
MIT — use it freely.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file otpilot-2.0.0.tar.gz.
File metadata
- Download URL: otpilot-2.0.0.tar.gz
- Upload date:
- Size: 22.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8cb34bf01bf7f72d4634002422cc60cc19c999b0c4b9c3538732fb4bc16b465
|
|
| MD5 |
6848b37cde2c288cdd6e70deb72a8e17
|
|
| BLAKE2b-256 |
0f716e6db7350714eb8598bfab2775180c51c1d240ed9a6066a23c4cd68933a3
|
File details
Details for the file otpilot-2.0.0-py3-none-any.whl.
File metadata
- Download URL: otpilot-2.0.0-py3-none-any.whl
- Upload date:
- Size: 23.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28ee201651ff06965889a03869d0cdd80c2fc8d356063e8c5acead5cb13de895
|
|
| MD5 |
83a0d73334a70b1743503de633eaff86
|
|
| BLAKE2b-256 |
318c52e2413fd96ef4d9bf9ec68a502b7dd3470ac5e3cb3d3672f97629c489b6
|