Hands-free vibe coding with Claude Code — 100% local voice, built for many sessions at once.
Dictate into any app with a push-to-talk key, hear what Claude Code is asking, in which project and window — and answer or jump there by voice. Your voice never leaves your Mac: transcription (NVIDIA Parakeet) and speech (Kokoro) run locally on Apple Silicon via MLX.
Also available in Spanish: README.es.md · Responde y dicta en español con
LANGUAGE=es.
- Dictation: tap a key (Right ⌘ by default), speak, and stop talking — recording ends on silence and the text is pasted into the frontmost app. End with the send word ("send" / "enviar") to also press Enter.
- Spoken notifications: when any Claude Code session asks for permission you hear "Hey, in project X, Claude wants to run a command: install dependencies. It's the window 'Fix login bug'. Accept or reject?" — plus a macOS popup. You're also told when a session finishes or waits for input.
- Voice session switching: with ten sessions open, say "take me" to focus the window that just notified, or "take me to <project>" for any recent session (fuzzy-matched, tolerant of STT mangling) or app ("browser", "terminal"...). Review what's on screen, then decide.
- Voice approval: say "accept" or "reject" and the daemon focuses the exact terminal window of that session and presses Enter/Escape. Only works while a permission is actually pending — and it talks back when there's nothing to act on.
- Personal dictionary:
dictionary.txtfixes the words your STT always gets wrong (project names, tools). Hot-reloaded.
Everything is language-driven: lang/en.json and lang/es.json define the
command vocabulary, spoken messages and default voices. Add your own.
- macOS on Apple Silicon (MLX). ~3 GB disk for the local models, ~3 GB RAM.
- Python 3.11+ and Claude Code.
- No API keys needed. Optional: a Mistral key
as cloud fallback (
voxtralengines).
git clone <this-repo> && cd susurro
./install.shThe installer creates a venv, registers the Claude Code hooks (merging into
your ~/.claude/settings.json, with backup) and starts a background daemon
via launchd. Two manual macOS steps remain — granting Input Monitoring
and Accessibility to .venv/bin/python — the installer walks you
through them. Models download on first use.
Set your language in .env (LANGUAGE=en or es).
| You want to… | Say / do |
|---|---|
| Dictate | Tap Right ⌘, speak, go quiet (2 s) |
| Dictate and submit | End with "send" |
| Jump to the session that notified | "take me" |
| Jump to a session or app | "take me to my web app" · "take me to the browser" |
| Accept a pending permission | "accept" (presses Enter in that window) |
| Reject it | "reject" (presses Escape) |
| Pick among several pending | "accept <project or window>" |
you ──key──▶ voice_daemon ──▶ Parakeet (MLX, local STT)
│ │
│ ▼
│ dictionary + command parser
│ │
│ paste ⌘V / Enter / focus window (AXRaise by title)
│
Claude Code ──hooks──▶ claude_hook.py ──▶ event queue (/tmp)
│
▼
daemon HTTP :8765/speak ──▶ Kokoro (MLX, local TTS) 🔊
The window-title trick: Claude Code sets the terminal title to the session topic, which is recoverable from the session transcript — so the daemon can focus the exact window of the session that asked, by title.
Fallback chain everywhere: local model → Voxtral API (if key) → macOS say.
A unified timestamped log lives at ~/Library/Logs/susurro.log.
All options in .env.example: language, engines, hotkey,
terminal app, silence timeout, models and voices. Terminal apps other than
Ghostty should work for pasting/keys; window-by-title focusing is tested on
Ghostty (reports welcome).
With the default engines nothing you say leaves your machine. The optional Mistral fallback and Claude Code itself do talk to their APIs — this project only guarantees the voice pipeline is local.