From claude-speak
Configure claude-speak TTS - set up API key, choose voices, test playback, fix PATH issues, and manage settings
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-speak:setupThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Help the user configure voice feedback for Claude Code.
Help the user configure voice feedback for Claude Code.
echo "=== claude-speak Status ==="
echo ""
# Check binary location
if [ -f "$HOME/.local/bin/speak" ]; then
version=$("$HOME/.local/bin/speak" --version 2>/dev/null || echo "unknown")
echo "✓ Binary installed: ~/.local/bin/speak (v$version)"
else
echo "✗ Binary not found at ~/.local/bin/speak"
fi
# Check if in PATH
if command -v speak >/dev/null 2>&1; then
echo "✓ speak command available in PATH"
echo " Location: $(which speak)"
else
echo "✗ speak command NOT in PATH"
fi
# Check API key
if [ -n "$ELEVENLABS_API_KEY" ]; then
echo "✓ ELEVENLABS_API_KEY is set"
else
echo "✗ ELEVENLABS_API_KEY is not set"
fi
# Check worker daemon
if [ -f ~/.claude/tts/worker.pid ]; then
pid=$(cat ~/.claude/tts/worker.pid)
if kill -0 "$pid" 2>/dev/null; then
echo "✓ Worker daemon running (PID: $pid)"
else
echo "⚠️ Stale PID file (daemon not running)"
fi
else
echo "ℹ️ No worker running (starts automatically on first speak command)"
fi
Based on the status, proceed with the relevant section below.
If speak is installed but not in PATH, fix it based on your platform:
Check if ~/.local/bin is in your PATH:
echo "$PATH" | grep -q "$HOME/.local/bin" && echo "✓ ~/.local/bin is in PATH" || echo "✗ ~/.local/bin NOT in PATH"
If not in PATH, add it to your shell profile:
Bash:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Zsh:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
Fish:
fish_add_path ~/.local/bin
On Windows, the binary is at %USERPROFILE%\.local\bin\speak.exe. Add this directory to your user PATH:
PowerShell (run as Administrator):
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
$newPath = "$env:USERPROFILE\.local\bin"
if ($userPath -notlike "*$newPath*") {
[Environment]::SetEnvironmentVariable("Path", "$userPath;$newPath", "User")
Write-Host "Added to PATH. Restart your terminal."
}
Or via GUI:
%USERPROFILE%\.local\binAfter fixing PATH, verify:
speak --version
voices_read for listing voices)Recommended: Claude Code settings (never committed to git)
# Determine which settings file to use
if [ -f .claude/settings.local.json ]; then
SETTINGS_FILE=".claude/settings.local.json"
elif [ -f ~/.claude/settings.json ]; then
SETTINGS_FILE="$HOME/.claude/settings.json"
else
# Create project-local settings
mkdir -p .claude
SETTINGS_FILE=".claude/settings.local.json"
echo '{}' > "$SETTINGS_FILE"
fi
echo "Using settings file: $SETTINGS_FILE"
# Add API key (replace 'sk-...' with your actual key)
jq '.env.ELEVENLABS_API_KEY = "sk-your-api-key-here"' "$SETTINGS_FILE" > "$SETTINGS_FILE.tmp" && mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE"
echo "✓ API key added to $SETTINGS_FILE"
Ensure .gitignore protects it:
if [ "$SETTINGS_FILE" = ".claude/settings.local.json" ]; then
# Check if already in .gitignore
if git check-ignore -q .claude/settings.local.json 2>/dev/null; then
echo "✓ .claude/settings.local.json is already in .gitignore"
else
echo "⚠️ Adding .claude/settings.local.json to .gitignore"
if [ -f .gitignore ]; then
if ! grep -q "\.claude/settings\.local\.json" .gitignore; then
echo ".claude/settings.local.json" >> .gitignore
echo "✓ Added to .gitignore"
fi
else
echo ".claude/settings.local.json" > .gitignore
echo "✓ Created .gitignore"
fi
fi
fi
Alternative: Shell profile (simpler but less secure)
# Add to ~/.bashrc or ~/.zshrc
echo 'export ELEVENLABS_API_KEY="sk-your-api-key-here"' >> ~/.bashrc
source ~/.bashrc
On Windows PowerShell:
[Environment]::SetEnvironmentVariable("ELEVENLABS_API_KEY", "sk-your-api-key-here", "User")
Test the API key works:
curl -s "https://api.elevenlabs.io/v1/voices" \
-H "xi-api-key: $ELEVENLABS_API_KEY" | \
python3 -c 'import json,sys; d=json.load(sys.stdin); print("✓ API key valid - found", len(d.get("voices", [])), "voices") if "voices" in d else print("✗ Error:", d.get("detail", {}).get("message", "Unknown error"))'
curl -s "https://api.elevenlabs.io/v1/voices" \
-H "xi-api-key: $ELEVENLABS_API_KEY" | \
python3 << 'PYEOF'
import json, sys
data = json.load(sys.stdin)
print(f"{'ID':<26} {'Name':<45} {'Gender':<10} {'Age':<15} {'Accent'}")
print("-" * 110)
for v in data["voices"]:
labels = v.get("labels", {})
name = v["name"]
vid = v["voice_id"]
gender = labels.get("gender", "")
age = labels.get("age", "")
accent = labels.get("accent", "")
print(f"{vid:<26} {name:<45} {gender:<10} {age:<15} {accent}")
PYEOF
Or browse voices in your browser: https://elevenlabs.io/voice-library
# Test with a specific voice ID (replace with any ID from the list above)
ELEVENLABS_VOICE_ID="IKne3meq5aSn9XLyUdCD" speak "Hello, this is a voice test"
Test multiple voices to compare:
# Replace these IDs with ones from your list
for vid in "IKne3meq5aSn9XLyUdCD" "cjVigY5qzO86Huf0OWal" "nPczCjzI2devNBz1zQrb"; do
echo "Testing voice: $vid"
ELEVENLABS_VOICE_ID="$vid" speak "This is a voice preview. Testing the sound quality."
sleep 8 # Wait for audio to finish
done
In Claude Code settings:
jq '.env.ELEVENLABS_VOICE_ID = "IKne3meq5aSn9XLyUdCD"' "$SETTINGS_FILE" > "$SETTINGS_FILE.tmp" && mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE"
echo "✓ Voice ID saved to $SETTINGS_FILE"
Or in shell profile:
echo 'export ELEVENLABS_VOICE_ID="IKne3meq5aSn9XLyUdCD"' >> ~/.bashrc
source ~/.bashrc
# Default: eleven_flash_v2_5 (fastest)
# Alternative: eleven_multilingual_v2 (better for non-English)
jq '.env.ELEVENLABS_MODEL = "eleven_multilingual_v2"' "$SETTINGS_FILE" > "$SETTINGS_FILE.tmp" && mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE"
Check file permissions:
ls -la ~/.local/bin/speak
chmod +x ~/.local/bin/speak
Manual download:
# Replace {VERSION} and {PLATFORM} with your values
curl -fsSL "https://github.com/dkmaker/claude-speak/releases/download/v{VERSION}/speak-{PLATFORM}" \
-o ~/.local/bin/speak
chmod +x ~/.local/bin/speak
Example for Linux:
curl -fsSL "https://github.com/dkmaker/claude-speak/releases/download/v1.0.0/speak-linux-amd64" \
-o ~/.local/bin/speak
chmod +x ~/.local/bin/speak
tail -50 ~/.claude/tts/speak.log
speak --stop # Kill current worker
speak "Test message" # Starts fresh daemon
speak "Testing one two three"
If you hear audio, it's working. If not:
~/.claude/tts/speak.logpaplay /usr/share/sounds/alsa/Front_Center.wav)Run through this if setting up from scratch:
~/.local/bin/speak --version)which speak)speak "hello")npx claudepluginhub dkmaker/my-claude-plugins --plugin claude-speakInstalls and configures VoiceMode MCP server for voice interactions in Claude Code using local Kokoro TTS and Whisper STT, with bash commands for uvx install, MCP addition, and endpoint config.
Enables voice output in Claude Code by speaking text wrapped in <say> tags while claudio proxy runs. Narrate explanations, tool calls, updates, and findings aloud.
Enables voice conversations with Claude Code using speech-to-text and text-to-speech. Includes setup, diagnostics, and MCP-based voice interaction.