Hear Claude Code respond. A Claude Code plugin that speaks each assistant turn aloud through macOS's say command, controlled by slash commands. Pairs naturally with Claude Code's built-in voice input for a hands-free coding loop.
Quick install (copy-paste in Claude Code):
/plugin marketplace add https://github.com/Noushir/claudecodetts.git /plugin install claude-code-ttsRestart Claude Code, then
/tts-onand you're listening.
Claude Code already supports voice input. With this plugin, the loop closes — you talk, it talks back, you keep your eyes on the diff. Set your system voice to a Siri voice (Arthur, Stephanie, etc.) and you have a Jarvis-like coding assistant.
- macOS (the plugin shells out to
/usr/bin/sayand/usr/bin/python3) - Claude Code
In Claude Code, run these two slash commands:
/plugin marketplace add https://github.com/Noushir/claudecodetts.git
/plugin install claude-code-tts
Then restart Claude Code once so the Stop hook is loaded.
Why the full HTTPS URL? Claude Code's
<owner>/<repo>shorthand clones via SSH, which fails with a host-key error on machines that have never connected to GitHub over SSH. The HTTPS URL works for everyone with no setup.
Out of the box say uses the basic Daniel voice, which sounds robotic. To get a Siri-quality voice:
- Open System Settings → Accessibility → Spoken Content → System Voice → Manage Voices
- Pick an English Siri voice (e.g., Voice 1 — Arthur, en-GB) and check it to download (~200 MB)
- Set it as the System Voice and close settings
The plugin's hook calls say without a -v argument, so it uses whatever you've set as your system voice — including Siri voices, which Apple otherwise blocks from third-party processes. This is the only known way to make a Siri voice reachable from say.
| Command | What it does |
|---|---|
/tts-on |
Enable speaking |
/tts-off |
Disable + stop any in-flight speech |
/tts-brief |
Speak only the last sentence of each response (terse) |
/tts-full |
Speak the entire response |
/tts-status |
Show current state |
State persists across sessions in ~/.claude/tts-state.json.
A Stop hook fires when each assistant turn completes. The hook:
- Reads the last assistant message from the conversation transcript
- Strips markdown, code blocks, URLs, and file paths so
sayonly reads prose - Pipes the cleaned text to
say(system default voice)
Slash commands flip flags in the state file, which the hook checks on each fire.
- macOS only. No Linux/Windows support —
saydoesn't exist there. - Apple Siri voice availability. Apple keeps Siri voices in a private framework. The "set as system voice" route is the only way third-party processes can use them. If a future macOS release closes that loop, this plugin falls back to whatever
saycan reach. - One in-flight
sayat a time. If you receive two assistant responses in quick succession, both speak — the second won't interrupt the first. Use/tts-offif you want to silence it immediately.
Logs at ~/.claude/tts-speak.log show every hook fire with the chosen text and PID. Helpful if you ever notice a turn was skipped.
MIT