Privacy-first AI meeting assistant with local transcription and self-hosted cloud summarization.
Privote records meetings, transcribes audio locally using Whisper.cpp, and generates AI-powered summaries via your own Cloudflare Worker. Your audio never leaves your device, and you control all your data.
- Record meeting audio or upload existing files (only .wav files are supported)
- Whisper.cpp runs locally for speech-to-text processing
- All audio processing stays on your device
- Easy model switching - choose from Tiny, Base, Small, Medium, or Large models
- One-click model downloads directly from the app settings
- Self-hosted Cloudflare Worker processes transcripts
- Llama 3.3 generates concise summaries and extracts action items
- View all meetings with summaries and action items
- Export meetings as Markdown
- Node.js 18+ and npm
- Cloudflare account (free tier works)
- macOS (Windows and Linux coming soon)
git clone https://github.com/aaaaayushh/cf_ai_privote.git
cd cf_ai_privotecd privote-desktop
npm install
# Start the app (development mode)
npm startThe app runs Whisper.cpp locally. You will need to download a model before you can start recording.
Use the built-in model manager
- Open the app and go to Settings → Whisper Model
- Select your preferred model from the dropdown
- Click Download Model to get additional models (Small, Medium, Large)
- The app automatically detects available models and shows their status
cd ../privote-worker
# Login to Cloudflare
npx wrangler login
# Install dependencies
npm install
# Create database and initialize schema
npx wrangler d1 create privote-db
# the cli output will ask you if you want to add the database config to wrangler.jsonc, say yes.
# Initialize database schema
npx wrangler d1 execute privote-db --remote --file=./src/schema.sql
# Deploy to Cloudflare
npm run deploy
# Save the Worker URL from output!Protect your Worker with an API key:
# Generate a secure API key
openssl rand -hex 32Save the API key! You'll need it in the next step.
# Set the name of the secret only (do NOT include your API key on the command line!)
npx wrangler secret put PRIVATE_API_KEY
# When prompted, paste your API key (the long hex string you generated above) and press Enter
# Redeploy with the secret
npm run deploy- Open the desktop app
- Go to Settings tab
- Enter your Worker URL:
https://privote-worker.<your-subdomain>.workers.dev - Enter your API Key (the one you generated in Step 4) . Click Save Settings
- Go to Record tab
- Check the model indicator - shows which Whisper model will be used
- Click Start Recording (or Upload Audio)
- Speak for a few seconds
- Click Stop Recording
- Wait for local transcription using your selected model
- Review and upload to Worker
- View AI-generated summary and action items!
Pro tip: Switch between models in Settings to find the best balance of speed vs. accuracy for your needs!
Note: If you skipped Step 4 (API key setup), your Worker is publicly accessible. See API Key Authentication to add authentication later.
For most users: The cloned repository already includes:
- Whisper.cpp binaries
- Built-in model manager for easy switching and downloading
- Ready to use immediately after downloading a whisper model
Just run npm start! Transcription works out of the box.
- Visual model selector in Settings → Whisper Model
- One-click downloads for additional models
- Binaries:
privote-desktop/lib/(.dylib, .dll, or .so files) - Models:
privote-desktop/models/(.bin files)
cd privote-desktop
# Install dependencies (if not already done)
npm install
# Build for macOS (creates DMG and ZIP files)
npm run build:macThis will create the following files in the dist/ directory:
Privote-0.1.0.dmg- macOS installerPrivote-0.1.0-mac.zip- Portable ZIP archive
Option 1: Using the DMG installer (Recommended)
- Double-click
Privote-0.1.0.dmgto mount it - Drag
Privote.appto yourApplicationsfolder - Eject the DMG when done
- Launch
Privotefrom Applications or Spotlight
Option 2: Using the ZIP archive
- Extract
Privote-0.1.0-mac.zip - Move
Privote.appto yourApplicationsfolder - Launch
Privotefrom Applications or Spotlight
- Grant microphone permissions when prompted
- Download a Whisper model in Settings → Whisper Model
- Configure your Worker in Settings → Cloudflare Worker Configuration
App won't launch:
- Check macOS security settings in System Preferences → Security & Privacy
- Click "Open Anyway" if macOS blocks the app
Microphone access denied:
- Go to System Preferences → Security & Privacy → Privacy → Microphone
- Enable Privote in the list
Model downloads fail:
- Check your internet connection
- Ensure the app has network permissions
cd privote-worker
npm install- Create D1 database:
npx wrangler d1 create privote-db
# The CLI output will ask if you want to add the database config to wrangler.jsonc. Say yes, unless you want to add it manually.- (Optional) If you did not add the config automatically, update
wrangler.jsoncmanually with your database ID from the output:
- Initialize schema:
npx wrangler d1 execute privote-db --file=./src/schema.sqlnpm run devTest endpoints:
# Health check
curl http://localhost:8787/health
# Upload transcript
curl -X POST http://localhost:8787/api/transcripts \
-H "Content-Type: application/json" \
-d '{
"transcript": "Test meeting. John will prepare the report by Friday.",
"title": "Test Meeting"
}'
# List meetings
curl http://localhost:8787/api/meetingsnpm run deploySave the Worker URL! You'll need it for the desktop app:
https://privote-worker.<your-subdomain>.workers.dev
Note: API key authentication is recommended for production use. If you haven't already set this up, follow the instructions in API Key Authentication.
Configure in Settings tab:
- Worker URL: Your deployed Cloudflare Worker
- API Key: Optional authentication (see API Key Authentication)
- Whisper Model: Select and download Whisper models for transcription
- Auto Upload: Automatically upload after transcription
- Keep Local Copies: Save recordings on device
Protect your Worker with API key authentication.
If you followed the Quick Start guide: You already set this up in Step 4.
To set up API key authentication manually:
- Generate API key:
openssl rand -hex 32- Set as Cloudflare secret:
cd privote-worker
npx wrangler secret put API_KEY
# Paste your key when prompted- Deploy Worker:
npm run deploy- Configure desktop app:
- Open Settings
- Enter the same API key
- Save settings
How it works:
- The worker checks for the
X-API-Keyheader on all/api/*requests - If
API_KEYsecret is set but header is missing/wrong, returns 401 Unauthorized - If
API_KEYsecret is not set, authentication is disabled (development mode)
Enable in Cloudflare Dashboard:
- Workers & Pages > Your Worker > Settings
- Add rate limiting rule: 100 requests/10 min per IP
In Cloudflare Dashboard, add WAF rules to block unauthorized IPs.
MIT License © 2025
Built with privacy in mind. Your data stays yours.
{ // ... existing config "d1_databases": [ { "binding": "privote_db", "database_name": "privote-db", "database_id": "your-database-id-here" } ] // ... existing config }