macOS voice layer for AI coding agents — wake word, STT, TTS, HUD, media control
Project description
HeyVox — Voice Coding, not Vibe Coding
Beta — HeyVox is under active development. It works, but expect rough edges. If something breaks, please open an issue — your feedback shapes what gets fixed next. See heyvox.dev for the full picture.
Your AI coding agent doesn't just listen — it talks back. HeyVox adds a voice layer to any MCP-compatible AI coding agent (Claude Code, Cursor, Windsurf, Continue.dev). Wake word detection, speech-to-text, text-to-speech with configurable verbosity, and browser media control — all running locally on your Mac.
How It Works
Voice IN — Speak to your agent:
- Say the wake word (or hold your push-to-talk key)
- HeyVox records and transcribes your speech locally (MLX Whisper / sherpa-onnx)
- Your words are pasted into the agent's input field and sent
Voice OUT — Your agent speaks back:
- Claude Code responses with
<tts>blocks trigger Herald (TTS orchestration) - Herald generates speech locally via Kokoro TTS and plays it
- System media (YouTube, Spotify) auto-pauses during playback via Hush
- Alternatively, agents can call
voice_speak()via MCP
HUD — See what's happening:
- Menu bar icon shows current state (idle/recording/transcribing/speaking)
- Frosted-glass pill overlay shows live waveform during recording
- Recent transcript history in dropdown menu
What's Included
HeyVox is a monorepo with three integrated components:
| Component | What it does |
|---|---|
| HeyVox Core | Wake word detection, push-to-talk, local STT, text injection, HUD overlay, MCP server |
| Herald | TTS orchestration — Kokoro speech generation, playback queue, audio ducking, workspace-aware delivery |
| Hush | Browser media control — Chrome extension that pauses/resumes YouTube, Spotify Web, etc. |
One install gets everything. One setup command wires it all up.
Requirements
- macOS 14+ (Apple Silicon recommended for MLX Whisper)
- Python 3.12+
- Microphone access, Accessibility, and Screen Recording permissions
- PortAudio (
brew install portaudio)
Install
From source (for development)
# Prerequisites
brew install portaudio
# Clone and install
git clone https://github.com/heyvox-dev/heyvox.git
cd heyvox
pip install -e ".[apple-silicon,chrome]"
# Run the setup wizard
heyvox setup
From PyPI (recommended)
pip install heyvox # core
pip install 'heyvox[apple-silicon]' # + MLX Whisper (Apple Silicon STT acceleration)
pip install 'heyvox[tts]' # + Kokoro/Qwen TTS (Herald voice output)
# then run the setup wizard
heyvox setup
What heyvox setup does
- Checks macOS permissions (Accessibility, Microphone, Screen Recording)
- Installs PortAudio if missing
- Downloads the Kokoro TTS model (~300 MB)
- Tests your microphone
- Creates config at
~/.config/heyvox/config.yaml - Installs launchd service (auto-start at login)
- Installs Herald TTS hooks for Claude Code (
~/.claude/settings.json) - Registers the MCP voice server with your AI agent
- Shows setup summary
Usage
Core commands
heyvox start # Start in foreground
heyvox start --daemon # Start as background service (launchd)
heyvox stop # Stop the service
heyvox restart # Restart the service
heyvox status # Show status
heyvox logs # Tail service logs
heyvox doctor # Diagnose permissions, models, and dependencies
heyvox commands # List the built-in voice commands
Voice output (TTS)
heyvox speak "Hello" # Speak text via Kokoro TTS
heyvox skip # Skip current TTS playback
heyvox mute # Toggle TTS mute
heyvox quiet # Verbosity → short (first sentence only)
heyvox verbose full # Get/set verbosity (full | short | skip)
# Herald CLI (advanced TTS control)
herald status # Queue, hold, playing, muted, paused
herald pause # Pause TTS playback
herald resume # Resume TTS playback
herald queue # Show queued messages
herald skip # Skip current message
Transcription history
heyvox history # Show recent transcriptions
heyvox history -c # Copy last transcript to clipboard
Diagnostics & maintenance
heyvox doctor # Permissions, model presence, and dependency check
heyvox debug # Recent STT recordings + why each was kept/discarded
heyvox log-health # Daily digest of wake/STT/TTS log signals
heyvox calibrate # Calibrate mic noise floor + silence threshold
heyvox bugreport # Bundle logs + config into a GitHub-issue report
MCP registration
heyvox register # Register the MCP server with detected AI agents
heyvox register cursor # ...or just one agent
heyvox setup also offers to do this. See MCP Tools below.
Anonymous telemetry (opt-in, off by default)
heyvox telemetry # Show status
heyvox telemetry preview # Show exactly what would be sent
heyvox telemetry enable # Opt in (opt out with: heyvox telemetry disable)
Telemetry sends only a version string, a hashed hostname, and five numeric counters — never transcripts, logs, or paths. See Privacy.
Vocabulary learning (advanced, opt-in, off by default)
heyvox learn-vocab # Improve STT recognition of your recurring terms
This sends recent dictation transcripts (text, not audio) to the Anthropic API, so it is off by default and only runs when you invoke it. See Privacy.
Browser media control (Hush)
Hush is a Chrome extension that pauses browser media during recording and TTS.
- Open Chrome →
chrome://extensions/ - Enable Developer mode
- Click "Load unpacked" → select the
heyvox/hush/extension/folder - Run the install script to set up native messaging:
bash heyvox/hush/scripts/install.sh
Hush is optional — without it, HeyVox falls back to native MediaRemote for Spotify/Apple Music, or media key simulation.
MCP Tools
Once registered, your AI agent gets these voice tools:
| Tool | Description |
|---|---|
voice_speak(text, verbosity) |
Speak text aloud (full/summary/short/skip) |
voice_status() |
Get current state (idle/recording/speaking) |
voice_queue(action) |
Manage TTS queue (list/skip/stop/mute/unmute) |
voice_config(action, key, value) |
Get or set voice settings at runtime |
Configuration
Edit ~/.config/heyvox/config.yaml:
wake_words:
start: hey_jarvis_v0.1 # Wake word model (custom "hey_vox" coming soon)
threshold: 0.5
silence_timeout_secs: 5.0
stt:
backend: local
local:
engine: mlx # mlx (Apple Silicon GPU) or sherpa (CPU)
mlx_model: mlx-community/whisper-small-mlx
tts:
enabled: true
voice: af_heart # Kokoro voice (af_sarah, af_nova, af_sky, etc.)
speed: 1.0
verbosity: full # full | short (first sentence only) | skip (mute)
style: detailed # detailed | concise | technical | casual
pause_media: true # Pause YouTube/Spotify during TTS
target_mode: last-agent # last-agent | pinned | generic
agents: # Apps to track for last-agent mode
- Claude
- Conductor
- Cursor
- Terminal
push_to_talk:
enabled: true
key: fn # Push-to-talk key
mic_priority: # Preferred mics (checked in order)
- Jabra
- G435
- MacBook Pro Microphone
Supported Agents
HeyVox works with any app that supports MCP (Model Context Protocol):
| Agent | Voice IN | Voice OUT (MCP) | Voice OUT (Herald hooks) | Auto-register |
|---|---|---|---|---|
| Claude Code | Yes | Yes | Yes | Yes |
| Cursor | Yes | Yes | — | Yes |
| Windsurf | Yes | Yes | — | Yes |
| Continue.dev | Yes | Yes | — | Yes |
| Any focused app | Yes | — | — | — |
Voice IN works with any app — HeyVox pastes transcribed text into whatever's focused.
Voice OUT via MCP — the agent calls voice_speak() to talk back.
Voice OUT via Herald — Claude Code hooks automatically speak <tts> blocks in responses.
Pairs Well With Visual MCPs
HeyVox is at its best when combined with external MCP servers that emit visual artifacts. Voice keeps the discussion flowing; visuals anchor it — together they make architecture conversations dramatically easier to follow.
Example: external Mermaid MCP
Pair HeyVox with a Mermaid MCP server (any MCP that renders Mermaid diagrams to images or SVG) and your agent gains a synchronized visual side-channel:
- You discuss a design change out loud — wake word → STT → agent receives the question
- Your agent narrates the answer via Herald TTS, so your eyes stay on the diagram
- In parallel, the agent calls the Mermaid MCP to regenerate the diagram with the proposed change
- You see the delta at a glance — boxes added/removed, edges rerouted — instead of holding every structural change in your head while listening
This pattern generalizes to any external MCP that returns images, SVGs, or diagrams (PlantUML, Excalidraw, mind-map tools, even slide generators). HeyVox owns the conversation channel; the visual MCP owns the artifact. They don't need to know about each other — your AI agent orchestrates both.
Why it feels good: voice-only design reasoning forces you to remember every change as you hear it. Visual-only design reasoning makes you keep typing to drive updates. With both, you can talk and look — and a 10-minute design discussion finishes with an up-to-date diagram already in front of you.
Architecture
┌──────────────────────────────────────────────────┐
│ Your AI Agent (Claude Code, Cursor, etc.) │
│ ┌────────────┐ ┌─────────────────────────┐ │
│ │ MCP Client │ │ Claude hooks (on-response)│ │
│ └─────┬──────┘ └──────────┬──────────────┘ │
└────────┼────────────────────┼────────────────────┘
│ stdio │ <tts> blocks
┌────────┼────────────────────┼────────────────────┐
│ HeyVox │ │
│ ┌───────────┐ ┌──────────▼──────────┐ │
│ │ MCP Server│ │ Herald │ │
│ │ (TTS out) │ │ (Kokoro → queue → │ │
│ └───────────┘ │ play → duck audio) │ │
│ └──────────┬──────────┘ │
│ ┌───────────┐ │ pause/resume │
│ │ Wake Word │ ┌──────────▼──────────┐ │
│ │ (mic in) │ │ Hush (browser media)│ │
│ └─────┬─────┘ └────────────────────┘ │
│ │ │
│ ┌─────▼───────┐ ┌───────────┐ │
│ │ Local STT │ │ HUD │ │
│ │ (MLX Whisper│ │ (overlay +│ │
│ │ sherpa-onnx│ │ menu bar)│ │
│ └─────┬───────┘ └───────────┘ │
│ │ │
│ ┌─────▼───────┐ │
│ │ Text Inject │ │
│ │ (osascript) │ │
│ └─────────────┘ │
└──────────────────────────────────────────────────┘
All processing runs locally.
No audio leaves your machine.
System Requirements
| Resource | Idle | Active (recording + TTS) |
|---|---|---|
| RAM | ~150 MB | ~900 MB peak |
| GPU (Metal) | — | ~500 MB (Whisper STT) |
| Disk | ~800 MB (models) | — |
| CPU | <1% | ~15% during STT |
- Whisper STT runs on Apple Silicon GPU via MLX (not system RAM)
- Kokoro TTS runs on Metal GPU via mlx-audio (~5-10x faster than CPU), auto-unloads after idle timeout
- Wake word model is tiny (~5 MB), always loaded
- Memory watchdog auto-restarts if RSS exceeds 1 GB
Platform Support
- macOS (Apple Silicon) — fully supported, primary target
- macOS (Intel) — supported via sherpa-onnx STT (no MLX)
- Windows / Linux — coming soon (core engine is cross-platform Python; only UI and system integration need porting)
Audio Devices
| Device Type | Mic Quality | Playback Quality | Notes |
|---|---|---|---|
| 2.4 GHz wireless (USB dongle) | High | High | Best option — bypasses Bluetooth entirely |
| USB/3.5mm wired headset | High | High | Great option |
| Built-in Mac mic | Good | N/A | Works fine for voice input |
| Bluetooth headset (incl. AirPods) | Reduced | Reduced | Works — with automatic mitigations (see below) |
Bluetooth and HFP mode: Bluetooth can either stream high-quality audio (A2DP) or do bidirectional mic+speaker (HFP) — not both simultaneously. When the mic activates, audio quality drops to phone-call level (~16 kHz). This is a macOS/Bluetooth limitation, not a HeyVox bug.
HeyVox mitigations: Bluetooth headsets work in practice because HeyVox handles the rough edges automatically:
- Dead device filtering — CoreAudio queries skip paired-but-disconnected Bluetooth devices
- Silent mic recovery — detects when a Bluetooth mic goes silent and auto-switches to an alternative (with exponential backoff)
- Echo suppression — TTS echo buffer strips recently spoken text from STT output, preventing feedback loops in speaker mode
For best results: Headsets with a 2.4 GHz USB dongle (Logitech G435, SteelSeries Arctis, Jabra) bypass Bluetooth entirely and appear as standard USB audio — no codec switching, no quality drop.
Privacy
HeyVox processes everything locally by default:
- Wake word detection: openwakeword (on-device)
- Speech-to-text: MLX Whisper or sherpa-onnx (on-device)
- Text-to-speech: Kokoro (on-device)
- No audio is sent to any server, ever — under any configuration.
Two optional features are off by default and only send non-audio data if you
explicitly enable them: anonymous telemetry (version + hashed hostname + numeric
counters) and learn-vocab (sends dictation transcripts to the Anthropic API).
Full details in the privacy policy.
Development
# Install with dev extras
pip install -e ".[dev,apple-silicon,chrome]"
# Run tests
pytest tests/ -k "not e2e"
# Lint
ruff check heyvox/ tests/
Troubleshooting
Run heyvox doctor first — it checks permissions, model presence, and
dependencies, and points at most of the issues below.
heyvox startexits immediately / wake word never fires. Usually a missing model or a permission. Re-runheyvox setup, thenheyvox doctor. Grant Microphone, Accessibility, and Screen Recording to your terminal in System Settings → Privacy & Security.- Dictation does nothing on an Intel Mac. MLX Whisper needs Apple Silicon.
Set
stt.local.engine: sherpain your config (HeyVox now defaults to this on Intel automatically). - No speech / TTS silent. Install the TTS extra:
pip install 'heyvox[tts]'. Check it isn't muted (heyvox mutetoggles) and inspectherald status. - Wrong microphone or output device. See Audio Devices; pick the device in the menu-bar HUD. A closed MacBook lid mutes the built-in mic.
- Something's wrong and you want to report it.
heyvox bugreportbundles logs and config (redacted) for a GitHub issue;heyvox logstails the live log.
Uninstall
bash scripts/uninstall.sh # remove HeyVox, keep nothing extra
bash scripts/uninstall.sh --keep-config --yes # keep ~/.config/heyvox, no prompts
This removes the HeyVox virtualenv, CLI symlinks, the launchd agent, the Herald
Claude-Code hooks, and the Hush native-messaging host. Shared system packages
(Homebrew, portaudio, Python) are left alone; config and model caches are removed
unless you pass --keep-config. Remove the Hush Chrome extension separately from
chrome://extensions/.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file heyvox-1.1.0.tar.gz.
File metadata
- Download URL: heyvox-1.1.0.tar.gz
- Upload date:
- Size: 5.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
33f0e775cc0fd39394958c28d9bce6381b421ac62b7721431769659e22afa1fe
|
|
| MD5 |
61597707c116c258d46dee52518a23c9
|
|
| BLAKE2b-256 |
8fbd5117355c762f01417d3e28933b854adb840061065e1c1a5d8663eb6bd1f1
|
Provenance
The following attestation bundles were made for heyvox-1.1.0.tar.gz:
Publisher:
publish.yml on heyvox-dev/heyvox
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
heyvox-1.1.0.tar.gz -
Subject digest:
33f0e775cc0fd39394958c28d9bce6381b421ac62b7721431769659e22afa1fe - Sigstore transparency entry: 2061232439
- Sigstore integration time:
-
Permalink:
heyvox-dev/heyvox@c4f700151172da3a0637a689c1d12507cc34549a -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/heyvox-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c4f700151172da3a0637a689c1d12507cc34549a -
Trigger Event:
push
-
Statement type:
File details
Details for the file heyvox-1.1.0-py3-none-any.whl.
File metadata
- Download URL: heyvox-1.1.0-py3-none-any.whl
- Upload date:
- Size: 5.3 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1711050c3da82d39fa8c9d8f9029e1fe93149ae605afe39ca2827947710d3c2b
|
|
| MD5 |
a0a20658545abaa2bb460846cba376d6
|
|
| BLAKE2b-256 |
abcf37cca57d3a4d8f1a11cd212b10a6692321aeaf40b0bb1d542091d3d2c13a
|
Provenance
The following attestation bundles were made for heyvox-1.1.0-py3-none-any.whl:
Publisher:
publish.yml on heyvox-dev/heyvox
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
heyvox-1.1.0-py3-none-any.whl -
Subject digest:
1711050c3da82d39fa8c9d8f9029e1fe93149ae605afe39ca2827947710d3c2b - Sigstore transparency entry: 2061232683
- Sigstore integration time:
-
Permalink:
heyvox-dev/heyvox@c4f700151172da3a0637a689c1d12507cc34549a -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/heyvox-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c4f700151172da3a0637a689c1d12507cc34549a -
Trigger Event:
push
-
Statement type: