WhisperNotes
Manual
FastAPI wrapper around whisper.cpp – native on macOS (Apple Silicon, Metal) or as a Docker container on Linux with an AMD, NVIDIA or no GPU (docker.en.md). Original specification (German): spezifikation.md.
- OpenAI-compatible:
POST /for Discord, Home Assistant and others (any API key)v1/ audio/ transcriptions - On demand:
whisper-starts with the first request (Metal) and stops after 120 s of idle timeserver - Sequential: parallel requests are queued; batch jobs give live requests priority between their chunks
- Dashboard (
/): upload long recordings → 5-minute chunks → master transcript → map-reduce summarydashboard/ - Ollama: in the settings you can pick a fixed model from the installed models (
/), or by default always use the model that is currently loaded (api/ tags /)api/ ps - Speaker detection (optional): by default sherpa-onnx
(pyannote segmentation 3.0 + CAM++, CPU, in parallel to Whisper), alternatively
pyannote.audio community-1 (
DIARIZATION_, needsENGINE=pyannote HF_). Detected voices are assigned to names in the dashboard by listening to samples;TOKEN tools/compares engines and models on a real recordingdiarize_ benchmark. py - D&D tab: campaigns with a group (players/characters/DM) and a glossary; sessions are transcribed with speakers and, once the voices are assigned, summarised as a session recap (story, NPCs & places, fights, loot, open plot threads, quotes). The recap of the previous session is used as context.
Installation on a Mac
git clone https://github.com/Poldion/WhisperNotes.git ~/WhisperNotes && cd ~/WhisperNotes
bash deploy/setup_mac.sh
The script installs cmake ffmpeg uv node via Homebrew, builds whisper- with Metal, downloads
ggml-, creates backend/, runs the tests, builds the dashboard and sets up the
LaunchAgent com. (autostart, logs in ~/).
Update: git pull && bash deploy/
Restart the service:
launchctl kickstart -k gui/$(id -u)/com.whispernotes
Connecting clients
| Client | Setting |
|---|---|
| Home Assistant | e.g. the HACS integration “OpenAI Whisper Speech-to-Text API”: URL http:/, model whisper-, API key = API_ (anything if access protection is off) |
| Your own scripts | openai SDK with base_, api_ |
For short voice commands a separate, fast model for the API is worth it: Settings → Transcription →
“Model for the /v1 API” (or API_).
Optional headers per request:
| Header | Effect |
|---|---|
X-, X-, X-, X- | stored together with the text in / |
X- | additionally post-process the text with Ollama → / |
Results of dashboard jobs are stored in /.
Data folder
Recordings, transcripts, campaigns, voice profiles and the settings changed in the dashboard (settings.) live in
the data folder DATA_. Default:
| System | Location |
|---|---|
| Docker | / in the volume (docker/) |
| macOS | ~/ |
| Linux | ~/ (or $XDG_) |
| Windows | %LOCALAPPDATA%\WhisperNotes |
Older installations had it in backend/. If that folder exists, it is still used.
Access
Without further settings WhisperNotes is open. That is meant for a home network. For running it behind a reverse proxy, a VPN or on the internet there are two settings, in the dashboard under Settings → Access or via the environment:
| Variable | Effect |
|---|---|
API_ | / and / require Authorization: Bearer – Home Assistant (API key), Discord bot (WHISPERNOTES_), scripts |
DASHBOARD_ | sign-in to the dashboard; empty = sign in with the API key |
The sign-in is a signed cookie (30 days). If the password or key changes, all sign-ins become invalid. / stays
open but without sign-in only reveals the language and whether sign-in is required. Links from BasaltNotes lead to the
sign-in page first and then to the document. On the internet, put HTTPS in front (reverse proxy).
Language and templates
LANGUAGE (de or en, Settings → General) applies to the dashboard, status messages and summaries. What is spoken
in the recordings is set by WHISPER_. With en the D&D glossary uses the English rules terms.
The document templates (summary, session recap, recap per player character, world & lore) can be adjusted under
Settings → Templates: sections, length, tone. Empty means the built-in template of the language applies
(backend/). WhisperNotes always appends its rules: invent nothing, resolve time references, use
character names instead of player names. In the session recap the heading “Previously” (German: „Was bisher geschah“)
should stay – its section is carried into the next session as a look back.
API overview
| Method | Path | Purpose |
|---|---|---|
| POST | / | Transcription (file, optional language, prompt, response_) |
| GET | / | Wrapper, Whisper and Ollama status incl. ollama_ (without sign-in only language, auth_) |
| POST | / · / | Dashboard sign-in ({"password": …}), sets or clears the cookie |
| POST | / | Upload a file for batch processing |
| GET | / | Progress as server-sent events |
| GET | / | Raw transcript |
| GET | / | AI summary (Markdown) |
| POST | / | Create the summary again (e.g. after a model was loaded) |
Discord bot
The bot (discord-) records conversations in voice channels – every person as a separate track – and
sends them to WhisperNotes as a normal recording. The speakers are therefore known (no speaker detection needed), the
names come from Discord. The finished summary appears in the dashboard and is also posted to the Discord channel in
which the recording was started. D&D recaps go to the channel selected in the campaign.
The slash commands are currently German:
| Command | Effect |
|---|---|
/ | start recording in your own voice channel |
/ | stop and process it (automatically when the channel is empty or after 6 h) |
/ | is a recording running? |
Setup:
- Discord Developer Portal → New Application → Bot →
Reset Token (copy the token). Invite the bot with the scopes
botandapplications.and the permissions View Channels, Send Messages, Embed Links, Attach Files and Connect (commands permissions=1099776). - Docker: create
docker/and start withdiscord. env -(see docker.en.md). On a Mac (Node ≥ 22.12): create- profile discord discord-frombot/ . env ., enterenv. example DISCORD_(andTOKEN WHISPERNOTES_if access protection is on), then runAPI_ KEY bash deploy/– the bot then runs as the LaunchAgentsetup_ mac. sh com.(log:whispernotes. discord ~/).Library/ Logs/ whispernotes/ discord- bot. log
Recording works with Discord's end-to-end encryption (DAVE, mandatory since March 2026) using @discordjs/;
npm run probe (/) checks this in isolation if there are problems.
Only record conversations with the consent of everyone present – the bot announces every recording in the channel.
Development on Windows
Without a Mac, whisper- is replaced by backend/:
pip install uv && cd backend && uv sync
cd backend && uv run pytest -q
cd backend && .venv/Scripts/python -m uvicorn app.main:app --port 8000 --env-file .env.dev
Frontend with hot reload (proxy to port 8000): cd frontend && npm install && npm run dev, then
http:/. Dashboard jobs need ffmpeg/ffprobe in the PATH locally.
Important settings (backend/.env )
| Variable | Default | Meaning |
|---|---|---|
IDLE_ | 120 | seconds of idle time until whisper- is stopped |
INFERENCE_ | 180 | max. seconds per request/chunk, then the process is killed and HTTP 500 returned |
CHUNK_ / CHUNK_ | 300 / 10 | slicing of long files |
AUDIO_ | 10 | storage limit for audio uploads; the oldest audio files are deleted, transcripts stay. 0 = unlimited |
OLLAMA_ | – | fixed model for summaries; empty = automatically the model that is currently loaded |
OLLAMA_ | – | only used with “automatic” when no model is loaded in Ollama |
LOGBOOK_ | metadata | off, metadata (only requests with metadata headers) or all |
LANGUAGE | de | language of dashboard, messages and summaries (de, en) |
API_ / DASHBOARD_ | – | access protection, see Access |
DATA_ | per system | see Data folder |
OLLAMA_ | http:/ | Ollama or a proxy in front of it |
Full list: backend/.env.example, backend/app/config.py.