Automatic TTS (text-to-speech) integration for Claude Code using the Kokoro TTS model. This project provides voice feedback that reads Claude's responses aloud as you work.
- Automatic TTS Playback: Claude's responses are automatically read aloud using Kokoro TTS
- Smart Interruption: Audio stops automatically when you submit a new message
- Non-Blocking: Audio plays in the background without interfering with your workflow
- Clean Speech: Automatically strips markdown and technical formatting for clear audio
- TTS Summary Mode: Optional summary extraction for concise audio feedback
- Audio Ducking (macOS): Automatically lowers Apple Music volume while TTS speaks, like Google Maps in CarPlay
This repository contains:
install.sh- Automated installation script for setting up hookshooks/- Reference copies of the TTS hook scriptsdocs/TTS_HOOK_DOCUMENTATION.md- Comprehensive documentation and troubleshooting guideCLAUDE.md- Repository context for Claude Code
Note: Model files are excluded. When you run ./install.sh, it will automatically download them from the kokoro-onnx GitHub releases if they're not present.
- Claude Code - Get it from claude.ai/code
- uv - Fast Python package installer (get it from astral.sh/uv)
- kokoro-tts CLI - Will be installed via uv
- jq - JSON processor (usually pre-installed on Linux/Mac)
- curl or wget - For downloading model files (usually pre-installed)
# Install using uv (recommended)
uv tool install kokoro-tts
# Verify installation
kokoro-tts --help-
Clone this repository:
git clone <repository-url> cd claude-code-tts
-
Run the installer:
./install.sh
The installer will:
- Check for required dependencies
- Download model files if not present
- Set up TTS hooks in
~/.claude/hooks/ - Configure Claude Code settings
- Add TTS summary instructions to
~/.claude/CLAUDE.md(preserves existing content)
-
Start using Claude Code: The TTS system will automatically activate and read responses aloud.
The system uses Claude Code's hook system to automatically:
- Capture responses: When Claude finishes responding, a Stop event triggers
- Extract text: The hook extracts Claude's text from the conversation transcript
- Process for TTS: Strips markdown formatting and technical elements
- Play audio: Streams to kokoro-tts with the af_sky voice
- Handle interruptions: Kills TTS playback when you submit a new prompt
After installation, hooks are located at:
~/.claude/hooks/tts-stop-hook.sh- Main TTS playback hook (Stop event)~/.claude/hooks/tts-pretooluse-hook.sh- Pre-tool narration (PreToolUse event)~/.claude/hooks/tts-interrupt-hook.sh- Interruption handler (UserPromptSubmit event)~/.claude/hooks/tts-session-end-hook.sh- Session cleanup (SessionEnd event)
Set the KOKORO_VOICE environment variable in ~/.claude/settings.json:
{
"env": {
"KOKORO_VOICE": "af_bella"
}
}The default voice is af_sky. Changes take effect on the next Claude Code session.
American English:
- Female:
af_alloy,af_aoede,af_bella,af_heart,af_jessica,af_kore,af_nicole,af_nova,af_river,af_sarah,af_sky - Male:
am_adam,am_echo,am_eric,am_fenrir,am_liam,am_michael,am_onyx,am_puck
British English:
- Female:
bf_alice,bf_emma,bf_isabella,bf_lily - Male:
bm_daniel,bm_fable,bm_george,bm_lewis
Other Languages:
- French:
ff_siwis - Italian:
if_sara,im_nicola - Japanese:
jf_alpha,jf_gongitsune,jf_nezumi,jf_tebukuro,jm_kumo - Mandarin:
zf_xiaobei,zf_xiaoni,zf_xiaoxiao,zf_xiaoyi,zm_yunjian,zm_yunxi,zm_yunxia,zm_yunyang
See Kokoro VOICES.md for the complete list
Audio ducking automatically lowers your music volume when TTS speaks, then restores it when done - just like Google Maps does in CarPlay.
How it works:
- When TTS starts, Apple Music volume drops to 5% of its current level
- When TTS finishes, volume is restored to the original level
- If you interrupt TTS by sending a new message, volume is also restored
Configuration via environment variables in ~/.claude/settings.json:
{
"env": {
"AUDIO_DUCK_ENABLED": "true",
"DUCK_LEVEL": "5"
}
}| Variable | Default | Description |
|---|---|---|
AUDIO_DUCK_ENABLED |
true |
Set to false to disable audio ducking |
DUCK_LEVEL |
5 |
Percentage of original volume during TTS (lower = quieter music) |
Note: Audio ducking currently supports Apple Music on macOS. It uses AppleScript to control the app's volume directly, so other audio (including TTS) remains at full volume.
The installer automatically adds TTS summary instructions to ~/.claude/CLAUDE.md. This enables Claude to provide concise, spoken summaries at the end of each response.
The configuration tells Claude to include a special TTS-friendly summary:
<!-- TTS_SUMMARY
Brief, natural language summary of what you did. No URLs, no technical jargon.
TTS_SUMMARY -->The hook automatically detects and reads only the summary portion, providing shorter and more focused audio feedback.
- Check if kokoro-tts is installed:
kokoro-tts --help - Check hook logs:
tail -f /tmp/kokoro-hook.log - Verify hooks are executable:
ls -l ~/.claude/hooks/
Increase the character limit in the hook (default: 5000 characters):
# In tts-stop-hook.sh
' | head -c 10000) # Increased to 10000Check that the interrupt hook is properly installed:
cat ~/.claude/hooks/tts-interrupt-hook.shSee docs/TTS_HOOK_DOCUMENTATION.md for comprehensive troubleshooting steps.
If you prefer manual setup instead of using install.sh:
-
Copy model files:
# Models can stay in this directory or be moved elsewhere # The hooks don't need to reference them directly
-
Create hook directory:
mkdir -p ~/.claude/hooks -
Create TTS hook (
~/.claude/hooks/tts-stop-hook.sh): Seedocs/TTS_HOOK_DOCUMENTATION.mdfor the full hook script. -
Create interrupt hook (
~/.claude/hooks/tts-interrupt-hook.sh): Seedocs/TTS_HOOK_DOCUMENTATION.mdfor the full hook script. -
Make hooks executable:
chmod +x ~/.claude/hooks/tts-stop-hook.sh chmod +x ~/.claude/hooks/tts-interrupt-hook.sh
-
Configure hooks in
~/.claude/settings.json:{ "hooks": { "Stop": [{"hooks": [{"type": "command", "command": "bash ~/.claude/hooks/tts-stop-hook.sh", "timeout": 10}]}], "UserPromptSubmit": [{"hooks": [{"type": "command", "command": "bash ~/.claude/hooks/tts-interrupt-hook.sh", "timeout": 5}]}] } }
claude-code-tts/
├── README.md # This file
├── LICENSE # MIT License
├── install.sh # Automated setup script
├── CLAUDE.md # Repository context for Claude Code
├── pyproject.toml # Python project config (uv)
├── .pre-commit-config.yaml # Pre-commit hooks config
├── docs/ # Documentation directory
│ └── TTS_HOOK_DOCUMENTATION.md # Detailed technical documentation
├── hooks/ # Reference copies of hook scripts
│ ├── tts-stop-hook.sh # Main TTS playback hook
│ ├── tts-pretooluse-hook.sh # PreToolUse narration hook
│ ├── tts-interrupt-hook.sh # Interrupt handler hook
│ └── tts-session-end-hook.sh # Session cleanup hook
├── scripts/ # Utilities
│ ├── strip_markdown.py # Markdown stripping with mistune
│ └── audio-duck.sh # Audio ducking helper (macOS)
├── tests/ # Test suite
│ └── test_strip_markdown.py # Pytest tests for markdown stripping
├── kokoro-v1.0.onnx # TTS model (310MB, not in git)
├── voices-v1.0.bin # Voice embeddings (25MB, not in git)
└── .gitignore # Git ignore rules
This project uses uv for Python package management and pre-commit with shellcheck for shell scripts, ruff for Python linting/formatting, and pymarkdown for markdown linting.
# Install dev dependencies
uv sync --dev
# Install pre-commit hooks
uv run pre-commit install# Run all linters (shellcheck, ruff, pymarkdown)
uv run pre-commit run --all-files# Run pytest test suite
uv run pytest tests/ -vContributions are welcome. For bugs, issues, or feature requests, please submit a ticket at todo.sr.ht/~cg/claude-code-tts.
If you find this integration useful, consider supporting me to build more cool things in the future:
This project is licensed under the ISC License - see the LICENSE file for details.
- Kokoro TTS - hexgrad/kokoro
- Claude Code - Anthropic
Thanks to the Kokoro TTS team for creating an open-source text-to-speech model.