kesha-voice-kit
About
Local-first voice toolkit: STT (25 langs, ~19x faster than Whisper on Apple Silicon via CoreML, ONNX fallback), TTS (Kokoro + Vosk-TTS + 180 macOS voices, SSML), VAD, language detection (107 langs). Rust engine, OpenClaw skill. No cloud, no API keys.
Details
- Author
- drakulavich
- Categories
- Other
Jump to
Setup
Install kesha-voice-kit in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/drakulavich/kesha-voice-kit
Follow the installation instructions in the repository README, then restart your MCP client.
Give your local tools and LLM agents a voice.
Fast speech-to-text, text-to-speech, voice-activity detection, and language detection in one local-first CLI — CoreML on Apple Silicon, ONNX on Linux and Windows.
- Transcribe locally—25 languages, up to ~19x faster than Whisper on Apple Silicon, ~2.5x on CPU
- Speak back— text-to-speech in9 languages
- Plug into agents— ship voice workflows as CLI commands, an MCP server, anOpenClawskill, or aHermesagent
- Small Rust engine— single ~65MB binary, no ffmpeg, no Python, no native Node addons
# 1. Install Bun (skip if you have it) curl -fsSL https://bun.sh/install | bash # macOS/Linux — or: brew install oven-sh/bun/bun powershell -c "irm bun.sh/install.ps1 | iex" # Windows # 2. Install Kesha bun add -g @drakulavich/kesha-voice-kit kesha --version # confirms kesha resolved on PATH # 3. Download the engine and models — pick one path kesha init # guided: TTS languages and optional VAD / diarization kesha install --plan && kesha install # manual: preview the sizes, then download # 4. Transcribe kesha audio.ogg # transcript to stdout
kesha installpulls ~2.5 GB on Linux/Windows and ~0.6 GB on Apple Silicon, whose CoreML engine reads a smaller model set. It is always explicit — nothing downloads behind your back — and reports download progress on stderr. Ifbun --versionfails right after step 1, reload your PATH:exec $SHELL -l.
Prefer Homebrew or Docker? SeeOther install methods. Air-gapped or behind a corporate mirror? Seedocs/model-mirror.md.
All three targets transcribe, detect the spoken language, run VAD, and speak. The macOS-only rows need Apple frameworks — they are not a missing port. Windows is a tested path rather than a published binary nobody ran: CI does a coldkesha installonwindows-latest, transcribes a fixture, and round-trips a synthesis (#216,#667).
Intel Macs get no published engine binary. Full matrix with maturity labels:docs/product-positioning.md.
kesha audio.ogg # transcribe (plain text) kesha --format transcript audio.ogg # text + language/confidence kesha --format json audio.ogg # full JSON with lang fields kesha --json --timestamps audio.ogg # JSON with timestamped segments kesha --itn audio.ogg # spelled-out numbers -> digits kesha --toon audio.ogg # compact LLM-friendly TOON kesha status # show installed backend info kesha status --disk # + recursive cache disk usage kesha status --json # machine-readable, for scripts
Multiple files gethead-style headers; stdout is the transcript, stderr is errors — pipe-friendly:
$ kesha freedom.ogg tahiti.ogg === freedom.ogg === Свободу попугаям! Свободу! === tahiti.ogg === Таити, Таити! Не были мы ни в какой Таити! Нас и тут неплохо кормят.
- Record from the mic (macOS):kesha record --out hello.wavwrites microphone audio to a WAV file (kesha hello.wavtranscribes it). macOS prompts for microphone access on first use — grant it under System Settings → Privacy & Security → Microphone if it was denied. On Linux/Windows or headless boxes, pass any existing audio file straight tokeshainstead.
- Dictate straight to text (darwin-arm64):kesha record --livetranscribes the mic as it captures and prints the transcript to stdout — no WAV in between, so it pipes (kesha record --live | pbcopy). To end after trailing silence, explicitly install VAD then opt in:kesha install --vad && kesha record --live --auto-stop. The defaults are 1,000 ms of silence after 250 ms of speech; tune them with--auto-stop-silence-ms,--auto-stop-min-speech-ms, and--auto-stop-threshold. Progress goes to stderr. Linux and Windows do not capture the microphone; pass an existing audio file tokeshato transcribe it. An interruption is recoverable: Ctrl-C (or SIGTERM) stops the session, still prints what you dictated, and exits 130/143, and the audio is spilled to a recovery WAV under~/.cache/kesha/recordings/— named on stderr when the session starts, deleted once the transcript has actually been delivered, kept if anything — a signal, a crash, a closed terminal, a dead pipe — got in the way first (#962).
- Long / silence-heavy audio:install VAD (kesha install --vad); Kesha auto-uses it past 120 s. Without VAD, long audio falls back to fixed ASR chunks. Seedocs/vad.md.
- Speaker diarization(darwin-arm64):kesha install --diarize(which installs VAD too), thenkesha --json --speakers meeting.m4astamps each segment with aspeakerid.--speakersengages VAD windowing itself at any duration, so it cannot be combined with--no-vad. Linux/Windows return a clear "darwin-arm64 only" error (#199).
- Word-level timestamps(every platform):kesha --json --timestamps audio.oggadds awordsarray to each segment —{ "word": "email", "start": 0.72, "end": 1.12 }— on the same file-relative clock as the segment, so a word always lies inside the segment carrying it. Read them off the decoder's own frame grid, so: times are quantised to 0.08 s, consecutive spans may overlap (eachendis a per-word duration prediction, not the next word'sstart),end >= startrather than strictly greater, and punctuation stays attached to its word. The key is simply absent where a segment has none — any segment--itnrewrote, for one — so check thetranscribe.wordscapability rather than expecting an empty array (#720).
- Text-language detection:JSON and TOON results includetextLanguagewith a language code, confidence, and itssource. On macOS Kesha uses AppleNLLanguageRecognizer; elsewhere it uses the bundledtinyldfallback, whose confidence scale is different. This is separate fromaudioLanguage, which identifies the spoken audio when available.
- Written-form numbers:--itnrewrites what the model spells out —"two hundred thirty two"→"232","five dollars and fifty cents"→"$5.50". Opt-in, every platform, timestamps untouched. English-only in practice; Russian and the rest pass through unchanged. Spoken punctuation names stay words ("dot","comma","the period of growth") because Kesha transcribes speech rather than dictation — so"example dot com"keeps its words too (#822). A sentence"and"survives the number that follows it ("cats and three dogs"→"cats and 3 dogs"), while an"and"the number owns still joins it ("three hundred and five"→"305") (#1000) — and no longer splits the number around it ("two hundred and thirty two"→"232", not"230 2") (#1006). A hyphenated number reads the same as the spaced form ("twenty-five apples"→"25 apples"), while a hyphen between ordinary words is left alone ("well-known","state-of-the-art","twenty-something") ([#1004).
…
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.



