What is VLab
VLab (Voice Lab) is a text-to-speech bridge for AI coding agents. Instead of silently finishing a long task and hoping you notice, your agent can speak — announcing completions, surfacing errors, asking for your attention — without interrupting your flow.
It exposes an MCP speak tool that any MCP-compatible agent can call. The agent passes text; VLab speaks it aloud on your Mac — locally by default, with no API key and nothing leaving the machine (xAI Grok and ElevenLabs are opt-in cloud upgrades). You set the persona, mood, and snark level. You can mute it or stop mid-sentence when you're on a call — and if you miss an alert, vlab replay plays it back.
Install
# 1. Install vlab
curl -fsSL https://vlab.daystra.com/install.sh | sh
# 2. Download the local voice (one time, ~310MB, runs on your Mac)
vlab models pull kokoro
# 3. Speak from your terminal — no key, no account
vlab speak "Build complete. All tests passed."
# 4. Wire vlab into Claude Code (registers the MCP server + installs the skill)
vlab install
# 5. Verify everything's wired (voice model, audio, config)
vlab doctor
# 6. (Optional) Talk back — local voice input. Pull a speech model once (~466MB, on-device):
vlab models pull small.en
vlab listen # chirp, speak, and it transcribes locally — audio never leaves your machine
# 7. (Optional) Prefer a cloud voice? Store a key, then point vlab at it.
security add-generic-password -s GROK_API_KEY -a "$USER" -w "your-grok-key"
# ~/.vlab/config.toml: [defaults] provider = "xai" persona = "rex"
Tip: vlab doctor checks the voice model, audio, and any cloud keys. Cloud engines are entirely optional — the local voice needs no account. (Env vars $GROK_API_KEY / $ELEVENLABS_API_KEY also work if you prefer the Keychain alternative.)
Features
- MCP tool:
speak— agents call it with text; VLab synthesizes it on-device and plays audio locally. Works from Claude Code, Cursor, Windsurf, or any MCP client. - A voice per project — every project is automatically given its own stable voice from 28 local English speakers, so you hear which project is talking. Errors arrive in that same voice, just sterner.
- Personas — or pick a character yourself: local Kokoro speakers, Grok's
rex,ara,leo,eve,sal, or ElevenLabs'veda,jarvis. Set globally or per-call. - Mood & snark dials — tune the delivery. Set the mood (neutral, upbeat, urgent) and snark level (0–10) so the voice matches the moment.
- Mute / stop —
vlab mutesilences output;vlab stopcuts the current utterance mid-sentence. Both take effect immediately. - Replay — looked away and missed an alert?
vlab replay(orvlab repeat) re-plays the exact last spoken alert from cached audio — no re-synthesis, no API cost. Also an MCPreplaytool. - Talk back:
listen— walkie-talkie voice input. Your agent speaks a question, then calls the MCPlistentool (or you runvlab listen); it chirps, opens the mic only during the call, and transcribes locally via whisper.cpp — no third-party STT, audio never leaves the machine. Hardvlab mic offkill switch. Pull a model once withvlab models pull small.en. - Self-update & one-command setup —
vlab updateupgrades to the latest release in place;vlab installwires the MCP server + skill into Claude Code for you. - Spoken notifications —
vlab install --hooksregisters a Notification hook that speaks what Claude is waiting on. Things blocked on you (permission prompts, agents needing input) always speak; informational ones (idle, agent finished) speak only when you're available — gated by macOS Focus/Do Not Disturb, an hour-window backstop, and a rate limit, so unattended background sessions stay quiet. Tunable per session withVLAB_NOTIFY_SILENT. - Doctor check —
vlab doctorverifies your voice model, audio device, any cloud keys, and config in one command.
Wiring into Claude Code
One command registers the global MCP server and installs the agent skill into ~/.claude:
vlab install
Then restart Claude Code. Prefer to wire it by hand (or use another MCP client)? Add this to your project's .mcp.json:
{
"mcpServers": {
"vlab": {
"command": "vlab",
"args": ["mcp-server"]
}
}
}
Once wired, your agent can call vlab__speak any time it wants to surface something audibly — task done, build failed, waiting for your input.
Dictate into any prompt (iTerm2)
The MCP listen tool is agent-initiated — it opens the mic when your agent asks you something. This is the other direction: you press a key, talk, and your words are typed into whatever prompt has focus — Claude Code, a REPL, a commit message. Nothing is submitted; you read it and press Enter yourself.
Save this as ~/.local/bin/vlab-dictate and chmod +x it:
#!/bin/sh
# Press ^Space, talk, your words get typed into the focused prompt.
PATH="$HOME/.local/bin:/usr/bin:/bin"; export PATH
# iTerm2 raises a modal dialog on ANY byte written to stderr — log it instead.
mkdir -p "$HOME/.vlab"; exec 2>>"$HOME/.vlab/dictate.log"
# iTerm2 pipes the session's screen output into our stdin; drain it so a
# burst of output can't back-pressure the terminal.
cat >/dev/null &
# stdout is TYPED into your session, so ONLY the transcript may go there:
# --json keeps status text off stdout, jq passes only a clean transcript, and
# newlines are stripped because a bare newline would submit the line for you.
vlab listen --json --max-seconds 30 --silence-ms 1500 \
| jq -j 'select(.outcome == "ok") | .transcript' \
| tr '\n\r' ' '
Then bind it: iTerm2 → Settings → Keys → Key Bindings → +, press ^Space, set Action to Run Coprocess, and paste the absolute path /Users/you/.local/bin/vlab-dictate as the Parameter. (Uses jq — recent macOS ships one at /usr/bin/jq; otherwise brew install jq.)
- Hold it down all you like. Key bindings fire on key-down, and macOS auto-repeat turns a held key into a stream of them.
vlab listenholds an exclusive lock on the microphone, so a held key still gives you exactly one capture — every other invocation returnsbusyat once and types nothing. - Nothing to clean up. That lock is an OS advisory lock rather than a PID file, so it releases the instant the process ends. An interrupted capture leaves no stale state behind; the next press just works.
- Works with AirPods. Bluetooth headsets take a moment to switch into microphone mode, so VLab opens the input and waits for it to come up before the chirp invites you to speak. You get the whole sentence, starting from the first word. Built-in mics are live immediately and wait for nothing.
--silence-ms 1500is the dictation fuse. The 800ms default is tuned for short spoken replies to an agent; dictating a full sentence wants a longer pause before the mic closes. Raise it further if you think mid-sentence.- Scripting it?
busyexits75(EX_TEMPFAIL) — distinct from1, so a wrapper can tell "someone else has the mic, retry" from "this failed" without parsing output.
CLI Reference
vlab speak "<text>"— speak text immediatelyvlab say "<text>"— alias for speak;--stdinreads raw text (hook-safe),--verbatimskips the project prefix; machine-ID tokens are stripped before speaking (--keep-idsto opt out)vlab mute/vlab stop— silence output / cut the current utterancevlab replay/vlab repeat— re-play the last spoken alert (exact cached audio)vlab listen— walkie-talkie voice input; transcribe your speech locally (whisper.cpp).--silence-ms <n>sets how long a pause ends the capture (default 800; raise it for dictation),--max-seconds <n>caps the window. Refuses a second concurrent capture with outcomebusy/ exit75.vlab models pull|list|rm— manage local speech models (defaultsmall.en)vlab mic on|off|status— microphone kill switch forlistenvlab install— wire the MCP server + skill into Claude Code, and install the Notification hook scriptvlab install --hooks— also register that hook, so Claude speaks when it needs youvlab update— upgrade VLab to the latest releasevlab voices [--search <q>]— list voices or search the libraryvlab usage— this month's TTS character spendvlab doctor— check keys, audio device, and configvlab mcp-server— start the MCP server (used by.mcp.json)vlab --version— print installed version
macOS (Apple Silicon) · Apache-2.0 / MIT · No API key required · llms.txt
A Cybercussion Interactive, LLC project