An open-source desktop app for taking notes, transcribing meetings, and chatting with your documents. Runs entirely on your machine — the only network calls are to whichever LLM you choose to connect, and only when you ask a question.
Download for macOS · platypusnotes.com · MIT license
Platypus_Github.mp4
- Capture meetings — auto-detects Zoom and Teams calls; transcribes locally via Whisper or via OpenAI's API
- Organize notes and documents — rich editor with PDF/DOCX/TXT import, project grouping, full-text search, and AI-assisted polish
- Chat with everything you've written — per-project HNSW vector search, with Claude, OpenAI, Gemini, or any local Ollama model. Answers are grounded in your notes with inline
[n]citations you can click to jump to the source passage, and each project greets you with suggested questions generated from its content - Generate from any note — turn a meeting transcript or document into structured meeting notes with decisions and action items, a follow-up email, a slide deck, or an audio podcast (via ElevenLabs)
Data stays on disk in SQLite. In local transcription mode, audio never leaves your machine.
| Platypus | Granola | NotebookLM | Otter.ai | |
|---|---|---|---|---|
| Stores data on your machine | ✅ | ❌ | ❌ | ❌ |
| Meeting transcription | ✅ | ✅ | ❌ | ✅ |
| RAG over your notes/docs | ✅ | partial | ✅ | ❌ |
| Bring your own LLM | ✅ | ❌ | ❌ | ❌ |
| Open source | ✅ | ❌ | ❌ | ❌ |
| Free | ✅ | partial | partial | ❌ |
| Native desktop | ✅ | ✅ | ❌ | ❌ |
Two modes, switchable in Settings.
Local Whisper (default) — on-device transcription via whisper.cpp.
- Real-time: live transcript streams during recording
- Works offline, no API key required
- Hardware-accelerated via Metal on macOS, CPU fallback elsewhere
- Models (selectable in Settings): Large v3 (~3.1GB, default, best quality), Large v3 Turbo (~1.6GB), Distil Large v3.5 (~1.5GB, fastest)
- Model auto-downloads on first use
OpenAI API — records WAV, uploads to OpenAI's Whisper endpoint.
- Requires an OpenAI API key
- Transcribes after recording finishes (not real-time)
| Layer | Technology |
|---|---|
| Desktop shell | Tauri v1 (1.5.2) |
| Backend | Rust |
| Frontend | React + TypeScript + Vite |
| UI | Chakra UI + styled-components |
| Editor | TipTap |
| AI providers | Claude, OpenAI, Gemini, Ollama |
| Transcription | whisper-rs v0.16 (local) / OpenAI Whisper API (cloud) |
| Audio | CPAL (recording), nnnoiseless (denoising), rubato (resampling) |
| Database | SQLite (rusqlite) |
| Vector search | HNSW (hnswlib-rs) |
- Node 18+ (recommended via nvm)
- Rust
- cmake — required by
whisper-rs-systo compile whisper.cpp- macOS:
brew install cmake - Windows:
winget install Kitware.CMake
- macOS:
- LLVM / libclang (Windows only — required by
bindgenwhen buildingwhisper-rs-sys; macOS ships this via Xcode Command Line Tools)winget install LLVM.LLVM- Then set
LIBCLANG_PATHsobindgencan findlibclang.dll:Open a new terminal afterward so the env var is picked up.setx LIBCLANG_PATH "C:\Program Files\LLVM\bin"
npm install
npm run tauri devIf you hit dependency issues, delete package-lock.json and re-run npm install.
Add your LLM API keys in Settings before use.
npm install
npm run tauri buildFor a signed + notarized macOS build that uploads to your S3 bucket, see scripts/build-mac.sh — requires Apple Developer credentials in .env.build.
A few of the less-obvious decisions:
- Audio pipeline: CPAL capture → energy-based VAD on raw samples → nnnoiseless denoising at 48kHz → rubato resample to 16kHz → whisper.cpp via whisper-rs. VAD runs before denoise because RNNoise crushes signal amplitude ~100x and every chunk would otherwise look silent.
- Meeting detection: Zoom is detected by presence of the
CptHostprocess; Teams by CPU usage on itsaudio.mojom.AudioServicesub-process. No Zoom/Teams API access required. - Vector search: per-project HNSW indices (hnswlib-rs); documents chunked and embedded on save when vectorization is enabled.
- Grounded chat with inline citations: retrieved chunks are numbered
[1]..[n]in the system prompt, the LLM is instructed to cite every claim and refuse to invent answers, and the same numbering is emitted to the UI so each[n]in the response is a clickable chip that opens the supporting passage.
See CONTRIBUTING.md.
Platypus stands on the shoulders of:
- whisper.cpp and whisper-rs — local speech-to-text
- Distil-Whisper by HuggingFace — the distilled Whisper variants
- nnnoiseless — pure-Rust port of Mozilla's RNNoise
- rubato — sample-rate conversion
- hnswlib-rs — HNSW vector index
MIT.