A lightweight macOS menubar application that automatically copies OTP codes from your Gmail to your clipboard.
- Real-time monitoring — Polls Gmail every 8 seconds for new OTP codes
- Auto-copy — Detected OTPs are automatically copied to your clipboard
- Privacy-focused — OTP codes redacted from logs, message IDs hashed, tokens stored in macOS Keychain
- Smart notifications — Desktop notifications when OTP is detected (3-second cooldown)
- Recent codes — Quick access to your last 10 OTP codes via menubar dropdown
- Provider recognition — Recognizes 80+ service providers (Google, Apple, Microsoft, etc.)
- macOS 10.13 or later
- Rust (latest stable)
- Node.js 18+
- Xcode Command Line Tools
git clone https://github.com/tanRdev/otpbar.git
cd otpbar
npm install
cp .env.example .env- Go to Google Cloud Console
- Create a new project
- Enable the Gmail API
- Create OAuth 2.0 credentials (Desktop app)
- Add
http://localhost:8234as an authorized redirect URI - Copy your client ID and secret to
.env:
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secretnpm run tauri devThe app will appear in your menubar. Click the icon to sign in with Google.
npm run tauri buildCreates a DMG at src-tauri/target/release/bundle/dmg/.
- Click the OTPBar icon in your menubar
- Sign in with your Google account
- OTP codes sent to your Gmail will be automatically detected and copied
- Access recent codes from the dropdown menu
- Click "Sign Out" to disconnect
- Backend: Rust + Tauri 2
- Frontend: React 19 + TypeScript
- Styling: Tailwind CSS 4
- Build: Vite
- Storage: macOS Keychain
- OAuth tokens stored in macOS Keychain
- OTP codes redacted from logs
- Message IDs hashed before logging
- Read-only Gmail API scope (
gmail.readonly) - Local-only processing (no external data transmission)
otpbar/
├── src/ # React frontend
│ ├── components/ # UI components
│ ├── lib/ # Utilities and Tauri API wrapper
│ ├── types/ # TypeScript type definitions
│ └── App.tsx # Main React component
├── src-tauri/ # Rust backend
│ ├── src/
│ │ ├── main.rs # App entry, tray setup, polling loop
│ │ ├── gmail.rs # Gmail API client, OAuth flow
│ │ ├── otp.rs # OTP extraction logic
│ │ ├── keychain.rs # Keychain storage
│ │ └── oauth_server.rs # Local OAuth callback server
│ ├── Cargo.toml # Rust dependencies
│ └── tauri.conf.json # Tauri configuration
└── package.json # Node.js dependencies
Make sure the app built successfully. Check src-tauri/target/release/bundle/dmg/ for the built app.
Ensure you added http://localhost:8234 as an authorized redirect URI in Google Cloud Console.
- Verify Gmail API is enabled in Google Cloud Console
- Check that your account has unread emails containing OTP codes
- Review logs in Console for any errors
