Repository navigation
Releases: dmoore-dwmmholdings/scribe-local
Release list
v0.1.5 — Scribe
Far better speaker detection and transcription on long, real meetings.
Measured on a real 2 h 49 min meeting with five main speakers, against a professional transcript of the same audio:
| word error rate | speaker accuracy | speakers found | |
|---|---|---|---|
| v0.1.4 | 64.5% | 27% | 1 |
| v0.1.5 | 15.1% | 85% | 5 |
Speakers
- Long meetings no longer collapse to one speaker. The count was read from every merge in the clustering, and on a long recording thousands of tiny fragments drowned out the few merges between real people. It now reads the merges between clusters that each hold a person's worth of speech. The old rule still runs alongside it, and whichever finds more speakers wins, so short recordings are unaffected. The full regression suite passes.
- One refinement pass after clustering moves each fragment to the speaker it sounds most like.
Transcription
- sherpa-onnx 1.13.2 → 1.13.8. The old version dropped half the words on the same audio and model. The upgrade also fixes a crash on some single-voice recordings.
- Full-precision Parakeet. The compressed int8 model dropped about three quarters of the remaining missing words, so the installer now downloads the full-precision one: 2.6 GB, up from 0.7 GB.
- Gaps are transcribed again. Any stretch of 1.5 s or more with no words is decoded on its own, which recovers speech the transcriber skipped mid-window.
Upgrading
Re-run the installer in Git Bash started as Administrator. It keeps your database, recordings and settings, and downloads the new model.
curl -fsSL https://raw.githubusercontent.com/dmoore-dwmmholdings/scribe-local/master/install.sh | bash -s -- --service
Recordings processed before the upgrade keep their old transcripts. To redo one, open it in the app and choose Reprocess.
v0.1.4 — Scribe
Your meetings in Claude Code, and an installer that checks the phone can actually connect.
Meetings over MCP
The server has an MCP endpoint at /mcp. Connect Claude Code to it once:
claude mcp add --transport http scribe https://<server>.ts.net/mcp
On a computer signed in to Tailscale as the account that owns the server, that is all. Elsewhere, add --header "Authorization: Bearer <device token>".
| Tool | What it does |
|---|---|
list_recordings |
Meetings, newest first, with id, date, title, length and status |
get_transcript |
One meeting's speakers and its transcript, as timestamped lines |
get_summary |
The generated summaries, decisions and action items |
search |
Passages from every transcript that match a query |
ask |
An answer from the server's own model, with sources |
list_speakers |
The enrolled voices |
set_participants |
State the number of speakers and run speaker detection again |
rediarize |
Run speaker detection again with the current settings |
set_participants and rediarize keep the words, and run speaker detection and the stages after it again.
Install
- No device key on your own phone. The installer trusts the Tailscale account that owns the server, so a phone signed in to that account pairs with Find server alone. Everyone else on the tailnet still needs the key. Use
--no-tailnet-authto turn this off. - The installer checks the server answers at its tailnet URL, the way the phone will. If it does not, it says so and names the usual causes: Tailscale Serve, HTTPS certificates, or MagicDNS turned off. Before, a failed
tailscale servewas hidden, and the phone reported only "Network request failed".
Upgrading
Re-run the installer in Git Bash started as Administrator. It keeps your database, recordings, models, secrets and ports.
curl -fsSL https://raw.githubusercontent.com/dmoore-dwmmholdings/scribe-local/master/install.sh | bash -s -- --service
v0.1.3 — Scribe
Better speaker labels, transcripts that no longer lose stretches of a noisy recording, easier phone pairing, and an installer that sets up an always-on server by itself.
Speakers
- New speaker-embedding model. 3D-Speaker's ERes2Net replaces NeMo TitaNet-large. It scores the same or better on every fixture but one, and is a quarter of the size. A speaker who moves around the room no longer splits into several people.
- Speaker counts are more reliable. A speaker's turns are weighed together, and phantom participants are no longer counted.
- Fix a wrong speaker count without re-transcribing. State the number of people and redo speaker detection from the app. Only diarization and the stages after it run again.
- Manage voiceprints. Re-learn a voice, remove a voice that was not a participant, and get a warning when one person is enrolled twice.
- Dictation. A recording with one stated participant skips segmentation. That avoids a segmentation-model crash on about one in five single-voice recordings, and it is ten times faster.
- Speakers reach search, answers and summaries. The speaker filter returns what that speaker said, and long recordings keep their speaker names in the summary.
Transcripts
- No more lost minutes in noisy recordings. The decoder could drop close to a minute from the middle of a recording, with no error. The decode window is fixed.
- Dictation is split into lines. An utterance now also ends at the end of a sentence, so a voice memo is no longer one paragraph.
- Turns split at the pauses between speakers.
- Faster. The speech models are no longer capped at 8 threads. The pipeline is about 1.24x faster on a 15-core machine, at the same accuracy.
- Hotwords say they do nothing. They need a vocabulary file that the default model does not publish. The worker now warns at startup instead of silently ignoring the list.
Pairing and install
- Pair by QR. The installer prints a QR code, or a
scribe://pairlink. Withauth.trust_tailscale_identityon, a phone on your tailnet needs no device token. - Find server. The server announces itself on the local network, and the app's Find server fills in the URL. The installer turns this on when the server has a tailnet URL, and adds a firewall rule when run as Administrator. Use
--no-lanto opt out. --serviceinstalls NSSM itself. It checks for Administrator and NSSM before downloading anything, and installs NSSM with winget if it is missing.- Docker Desktop starts on login. The installer turns this on, because Postgres runs in Docker and is not there after a reboot otherwise.
- Re-running the installer is a real update. If an update fails, it stops instead of reporting success.
- Windows bundles are built in CI, from a tag push.
Upgrading
Re-run the installer in Git Bash. It keeps your database, recordings, models, secrets and ports, and downloads the new speaker model.
curl -fsSL https://raw.githubusercontent.com/dmoore-dwmmholdings/scribe-local/master/install.sh | bash
For an always-on server, run it from Git Bash started as Administrator, and add -s -- --service.
v0.1.2 — Scribe
Fixes transcripts that stop partway through a recording, or drop blocks of speech
in the middle, while the audio itself plays back complete.
What was wrong
The ASR sometimes stops emitting words partway through a clip and returns a
short result with no error. On one 65-second recording it produced words only up
to 29.2 seconds; on a 94-second one, only to 83.6 seconds.
The audio was never the problem. Diarization read the same file all the way
through, and playback serves that same file — so the speech was there, and
nothing downstream could tell a truncated decode from a person who stopped
talking.
What changed
The transcribe stage now measures how far the emitted word timings actually
reach. If they fall short of the clip, it decodes the uncovered remainder and
appends it. Audio that decodes normally is untouched and keeps its single
full-file pass, which gives better text and punctuation.
The retry loop is bounded: the cursor must advance, a pass that emits nothing
ends it, remainders under 4 seconds are ignored, and there are at most 6 extra
passes.
Upgrading
Re-run the installer. It keeps your database, models, secrets, and ports.
curl -fsSL https://raw.githubusercontent.com/dmoore-dwmmholdings/scribe-local/master/install.sh | bash -s -- --serviceExisting recordings are not re-transcribed automatically. To redo one, open it
in the app and reprocess it, or:
curl -s -X POST -H "Authorization: Bearer <device-token>" \
http://127.0.0.1:8444/recordings/<id>/reprocessv0.1.1 — Scribe
A fix for recordings that upload fine and then sit at 0/6 forever.
What was wrong
The worker builds the text embedder at startup. fastembed downloads that model
from Hugging Face the first time it runs, and the download was treated as fatal
— so a blip, a rate limit, or an offline boot killed the whole worker process.
That takes down transcription too, which needs nothing from Hugging Face. The
API stays healthy, uploads keep succeeding, and every recording sits at 0/6 with
the reason in one line of a log you have no reason to open.
What changed
- The embedder is now built on first use and cached once it succeeds. A failure
fails only theembedjob, which the queue retries with backoff. Transcode,
diarization, transcription, and the merged transcript all finish regardless.
It does not fall back to the stub embedder — that would write vectors into the
database that no search could ever match. - The installer now checks that the worker is still alive after it loads its
models, and prints the last line ofworker.logif it is not. - New
scripts/diagnose.sh: one command on the server that dumps the processes,
health,doctor, the jobs table, the schedule, and both logs, with the device
token and signing secret redacted.
Upgrading
Re-run the installer. It keeps your database, models, secrets, and ports.
curl -fsSL https://raw.githubusercontent.com/dmoore-dwmmholdings/scribe-local/master/install.sh | bashIf a recording is already stuck, it resumes on its own once the worker is
running again — the job is still queued.
v0.1.0 — Scribe
Scribe records meetings on your phone, then transcribes them, labels the
speakers, and makes the archive searchable. All of it operates on your own
hardware. No audio goes to a cloud service.
This is the first release. It puts all the parts in one repository, and it makes the
install one command.
Install
On Windows, in Git Bash:
curl -fsSL https://raw.githubusercontent.com/dmoore-dwmmholdings/scribe-local/master/install.sh | bashOn Linux or macOS, in a terminal:
curl -fsSL https://raw.githubusercontent.com/dmoore-dwmmholdings/scribe-local/master/install.sh | bashThe command does all of these steps:
- It downloads the server, or it makes the container image.
- It installs a current ffmpeg, because builds before 2025 cannot read the audio
that current phones write. - It makes the URL signature secret and the device token for the phone.
- It starts Postgres and applies the migrations.
- It downloads the ASR models (about 750 MB).
- It publishes the API on your tailnet.
- It starts the API and the worker.
At the end it shows the server URL and the device token. Put the two values in
the app.
No setup is necessary before the command, and the command has no questions for
you. To start again safely, do the command again: it keeps your secrets, your
models, and your database.
These alternatives go after bash -s --. An example:
curl -fsSL https://raw.githubusercontent.com/dmoore-dwmmholdings/scribe-local/master/install.sh | bash -s -- --service--service— install always-on Windows services. Start Git Bash as
Administrator, and install NSSM first withwinget install NSSM.NSSM.--dir PATH— install to a different directory (default~/scribe).--model NAME—parakeet-tdt-0.6b-v3(default) orwhisper-large-v3-turbo.--no-tailscale— do not publish the API on your tailnet.--docker— use the containers on Windows, not the server bundle.
If a port is in use, the installer moves to the next free port and tells you.
What operates
- Segmented recording on the phone, with background audio and resumable upload.
- Transcription with Parakeet-TDT-0.6B-v3, and speaker diarization.
- Speaker names, tags, marks, and audio playback with word highlighting.
- Hybrid search across the full archive: text and embeddings together.
- Summaries and the
/askendpoint, with an LLM that you supply. - A weekly processing schedule that you set from the phone.
- Backend self-update from a package with an ed25519 signature.
Two install procedures
The containers do the transcription on the CPU. Parakeet on a CPU is faster than
the recorded time, thus this is sufficient for daily use.
For an NVIDIA GPU, use the Windows bundle below. It has no Rust toolchain and no
Visual Studio prerequisite. Download the models on the server with
scribe.exe models pull, then add the GPU libraries with scripts\setup-gpu.ps1.
More information
- The API accepts
Authorization: Bearer <device_token>only. - Do not publish the API on the internet. Use Tailscale.
- The data stays in three Docker volumes.
docker compose down -verases them.
Full procedure: docs/install.md. For the mobile app, refer to
docs/install-iphone.md.