
Tts
- 1 repo stars
- Updated July 25, 2026
- cadrianmae/claude-marketplace
Speak Claude Code assistant responses aloud via a Stop hook with three modes (full/truncate/summary), interrupt-on-type, and multi-speaker voices on Linux/Piper.
About
TTS gives Claude Code Piper-based text-to-speech, speaking assistant responses aloud through a Stop hook and interrupting on typing via a UserPromptSubmit hook. It offers three speak modes (full, truncate, or Haiku-summarized) and multi-speaker voice support through name:speaker syntax, all from one unified interactive command. It needs Linux, PipeWire (paplay), and the piper binary with voices installed locally.
- Piper TTS via a Stop hook
- Interrupt-on-type via UserPromptSubmit hook
- Three speak modes: full/truncate/summary
- Multi-speaker voice support
- Requires Linux + PipeWire + piper
Tts by the numbers
- Data as of Jul 26, 2026 (Skillselion catalog sync)
/plugin marketplace add cadrianmae/claude-marketplace/plugin install tts@cadrianmae-claude-marketplaceAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| repo stars | ★ 1 |
|---|---|
| Last updated | July 25, 2026 |
| Repository | cadrianmae/claude-marketplace ↗ |
What it does
Speak Claude Code assistant responses aloud via a Stop hook with three modes (full/truncate/summary), interrupt-on-type, and multi-speaker voices on Linux/Piper.
README.md
TTS Plugin v0.1.5
Piper-based text-to-speech for Claude Code. Speaks Claude's responses aloud via Stop hook, interrupts speech on user input via UserPromptSubmit hook. Replacement for AgentVibes with fewer dependencies and no MCP server.
Overview
TTS plugin v0.1 is a minimal bash-based Piper wrapper for Claude Code. It calls piper directly (never through speech-dispatcher) and plays raw PCM through paplay. A single /tts skill handles all user-facing commands; two hooks handle speech and interrupt behavior.
Key features:
- Unified
/ttsskill — one interactive entry point, subcommand grammar, follows cron/track plugin pattern - Stop hook — speaks each assistant response automatically when
TTS_ENABLED=true - UserPromptSubmit hook — kills in-flight
paplayso typing interrupts Claude mid-sentence - Three speak modes —
full,truncate(default),summary(via Claude Haiku with JSON schema) - Off by default — no surprise audio on install; user runs
/tts auto onto enable - Global config — voice / volume / mode live at
~/.claude/.tts-config, not per-project - Multi-voice support — use any Piper voice installed at
~/.local/share/piper-voices/ - Multi-speaker voices —
name:speakersyntax for voices with multiple speakers (e.g.semaine:poppy)
Prerequisites
| Requirement | Why | How to verify |
|---|---|---|
| Linux + PipeWire | paplay --raw is PipeWire-native on Fedora/modern distros |
paplay --version |
piper binary on PATH |
Called directly, not via speech-dispatcher | which piper && piper --version |
At least one voice at ~/.local/share/piper-voices/*.onnx |
Voices are not bundled | ls ~/.local/share/piper-voices/ |
pandoc (optional) |
Cleaner markdown-to-plain-text than sed fallback | which pandoc |
Command
A single unified interactive command:
/tts— Interactive entry point for speak / test / voices / voice / config / auto / help. Uses AskUserQuestion to walk through each workflow. Accepts arguments to skip prompts (e.g./tts voice lessac,/tts auto on).
See the subcommand grammar below for the full argument form.
Quick Start
# 1. Install and enable
/tts auto on
# Creates ~/.claude/.tts-config with defaults and enables hooks
# 2. Pick a voice
/tts voices # List installed voices (annotated with speakers)
/tts voice lessac # Set default voice (single-speaker)
/tts voice semaine:poppy # Set default voice + speaker (multi-speaker)
# 3. Test it
/tts test # Play a canned sample
# 4. Work normally — responses are spoken automatically
# - Interrupt by typing anything (kills in-flight paplay)
# - Adjust verbosity with /tts config SPEAK_MODE=full
# 5. Pause when you need silence
/tts auto off # Stop hook becomes a no-op until re-enabled
Configuration
Global config file: ~/.claude/.tts-config
| Key | Default | Values | Purpose |
|---|---|---|---|
VOICE |
aru |
any installed voice name | Which Piper voice to use |
VOLUME |
40000 |
0–65536 | paplay --volume=N attenuation level |
SPEAK_MODE |
truncate |
full / truncate / summary |
How to handle Claude's response |
MAX_CHARS |
1000 |
integer | Char cap for truncate and summary modes |
TTS_ENABLED |
false |
true / false |
Master on/off switch |
INTERRUPT_ON_TYPE |
true |
true / false |
Kill in-flight paplay on UserPromptSubmit |
SPEED |
1.0 |
0.1-3.0 (float) | Speech rate. Inverted: <1.0 = faster, >1.0 = slower |
EXPRESSIVENESS |
0.667 |
0.0-1.0 (float) | Generator noise. Higher = more expressive |
PRONUNCIATION_VARIATION |
0.8 |
0.0-1.0 (float) | Phoneme width noise. Higher = more variation |
SENTENCE_SILENCE |
0.0 |
0.0-5.0 (float) | Seconds of silence between sentences |
Speak modes
full— Entire assistant response. Markdown stripped (viapandoc -f markdown -t plainif available, elsesed). Code blocks removed. Can be 30+ seconds for long answers; interrupt by typing.truncate(default) — Same pipeline asfull, but hard-cut atMAX_CHARSwith…suffix. Safer default.summary— Only activates when text exceedsMAX_CHARS. Calls Claude Haiku (viaclaude --printwith--json-schemafor structured output, no tools, no session persistence) to rewrite the response for spoken delivery while preserving detail. Falls back totruncatesilently on failure. Responses underMAX_CHARSpass through as-is with just markdown stripped.
Subcommand Grammar
/tts → fully interactive (action AUQ first)
/tts speak <text> → manually speak a one-off string
/tts test → play a canned sample with current voice
/tts voices → list installed voices
/tts voice <name> → set VOICE config value
/tts config [KEY=VALUE ...] → view or update global config
/tts auto [on|off] → toggle TTS_ENABLED
/tts help → subcommand grammar + voice list
Architectural notes
Why no MCP server?
AgentVibes used an MCP server for voice management. That introduced a separate npm install, a separate hook directory, and a command/script mismatch bug (voice-manager.sh sample not being a valid subcommand). A pure-bash plugin that shells out to piper directly has a much smaller attack surface.
Why paplay --raw instead of pw-play?
pw-play and pw-cat use libsndfile which requires a file header. Piper's --output-raw produces headerless s16le PCM at 22050 Hz mono. paplay --raw --format=s16le --rate=22050 --channels=1 is the only working pipe target.
Why attenuation-only volume control?
Piper raw output is already at −13.8 LUFS with +0.8 dBFS true peak. There is zero headroom for amplification. Any gain via sox -v or similar causes clipping and a loud "earrape" incident. Volume is controlled exclusively via paplay --volume=N attenuation.
Why setsid detach in the Stop hook?
The Stop hook fires when Claude's response completes. If Claude Code is killed mid-speech (user closes terminal, signal to process group), a foreground child would be killed too. setsid bash -c "…" </dev/null & disown detaches audio from the process group so speech completes even if Claude Code exits.
See Also
- CHANGELOG.md — Version history
/tts help— In-app subcommand reference- Piper TTS — Upstream project
plugins/cron/,plugins/track/— Other consolidated-skill plugins in this marketplace that share thebin/wrapper + unified-skill pattern