@jleelove/voice-mcp
v0.4.0
Published
Local MCP server for the Voice API (Chatterbox TTS + Whisper STT). Runs on your machine, reads local audio files, and streams them to the HTTP API — so large files never pass through the model's context.
Maintainers
Readme
@jleelove/voice-mcp
A local MCP server for the Voice API
(Chatterbox TTS + Whisper large-v3 STT).
Why a local server?
The Voice API itself runs remotely (on the GPU box). A remote MCP server can't touch your machine — it can neither read your local files nor play audio on your speakers. So transcribing a local recording through it means base64-encoding the audio into a tool call (megabytes through the model's context, breaks past a few seconds), and synthesized speech has to be piped back yourself.
This server runs on your machine, so it can:
- Transcribe a local file by path — streamed straight to the API as a multipart upload; the audio never passes through the model, so files of any length work.
- Play synthesized speech on your speakers itself —
synthesizeauto-plays by default; the model just asks for audio. - Add or clone voices from local clips —
upload_voiceregisters a local audio file as a permanent named voice, andsynthesize'ssample_pathreads text in a one-off voice from a clip without saving it.
Requirements
- Node 18+ (for
npx—npx -yfetches and runs the server, no install step). - A reachable Voice API and credentials for it (username/password — the same
accounts as the web login / the API's
users.json). - An audio player for local playback (optional; transcription works without one):
- macOS —
afplayis built in, nothing to install. - Linux/Windows — install
ffmpeg(providesffplay):apt install ffmpeg,brew install ffmpeg,dnf install ffmpeg, orchoco install ffmpeg.
- macOS —
Configure your MCP client
Every client launches the same stdio command — npx -y @jleelove/voice-mcp — with
the environment variables below. The only required vars are the API URL and your
credentials; everything else has sensible defaults (see Configuration).
Claude Code
Project-scoped — create .mcp.json in your repo root:
{
"mcpServers": {
"voice": {
"command": "npx",
"args": ["-y", "@jleelove/voice-mcp"],
"env": {
"VOICE_API_URL": "https://voice.codingbutter.com",
"VOICE_API_USER": "admin",
"VOICE_API_PASSWORD": "your-password"
}
}
}
}Or via the CLI (user-scoped, available in every project):
claude mcp add voice \
-e VOICE_API_URL=https://voice.codingbutter.com \
-e VOICE_API_USER=admin \
-e VOICE_API_PASSWORD=your-password \
-- npx -y @jleelove/voice-mcpClaude Desktop
Edit the config file (create it if missing), then restart the app:
- macOS —
~/Library/Application Support/Claude/claude_desktop_config.json - Windows —
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"voice": {
"command": "npx",
"args": ["-y", "@jleelove/voice-mcp"],
"env": {
"VOICE_API_URL": "https://voice.codingbutter.com",
"VOICE_API_USER": "admin",
"VOICE_API_PASSWORD": "your-password"
}
}
}
}Cursor / Windsurf / other MCP clients
Any client that speaks MCP over stdio uses the same shape: command npx, args
["-y", "@jleelove/voice-mcp"], and the same env block. Add it to that client's
MCP servers config.
Verify
After adding it, your client should list four tools — transcribe,
synthesize, upload_voice, list_voices. Try: "list the
voices" or "say hello".
Local development: to run your own checkout instead of the published package, point
command/argsat the file directly:"command": "node", "args": ["/path/to/voice-mcp/src/index.mjs"]— edits take effect on the next client reconnect, no republish needed.
Configuration
| Env var | Default | Purpose |
|---|---|---|
| VOICE_API_URL | https://voice.codingbutter.com | Base URL of the Voice API. |
| VOICE_API_USER / VOICE_API_PASSWORD | (none) | Credentials for the API (HTTP Basic — same accounts as the web login / users.json). Required if the API has auth enabled. |
| VOICE_API_KEY | (none) | Sent as X-API-Key if you also gate the API at the edge. |
| VOICE_AUTOPLAY | true | Whether synthesize plays audio by default. Set false on headless/CI/SSH hosts. |
| VOICE_BLOCK | false | Default for wait — block until playback finishes. |
| VOICE_PLAYER | (auto) | Force a player command (e.g. mpv), bypassing detection. |
| VOICE_OVERLAP | interrupt | interrupt (newest line wins) or queue (play in order). |
| VOICE_VOLUME | 1.0 | Default linear gain for ffplay/mpv (the API already loudness-normalizes). synthesize's per-call volume arg overrides it for one utterance. |
| VOICE_DEFAULT_VOICE | (server default) | Voice used when voice is omitted. |
| VOICE_FORMAT | wav | Default container when neither format nor an output_path extension is given. |
| VOICE_TMPDIR / VOICE_TEMP_TTL | <tmp>/voice-mcp / 3600 | Where play-only temp files go, and how long (seconds) before the startup sweep reaps them. |
Tools
| Tool | What it does |
|---|---|
| transcribe | Speech → text. Pass a local path (streamed) or a url. Supports language, task (transcribe/translate), and timestamps. |
| synthesize | Text → speech. Plays on your speakers by default (play), and/or saves to output_path (WAV/MP3). wait blocks until playback ends. Set volume (linear gain, ~1.0) to override VOICE_VOLUME for one utterance — louder/softer without changing the saved file. With no output_path it plays from an auto-deleting temp file. Pass sample_path (or sample_url) to clone a one-off voice from a clip for that utterance only — not saved. |
| upload_voice | Add a permanent named voice from a local path (or url). The clip is transcoded to mono 24 kHz MP3 server-side and becomes selectable by name in later synthesize calls. |
| list_voices | List available voices, emotions, and tuning ranges. |
Examples (natural language to your agent)
- "Say 'the build is green' in the Will_Wheaton voice." → plays on your speakers.
- "Read this paragraph aloud and also save it as
note.mp3." - "Add
~/clips/jamie.wavas a voice called Jamie." →upload_voice. - "Read this in the voice from
/tmp/grandpa.m4a." → one-offsample_path, not saved. - "Transcribe
~/recordings/standup.m4a." - "Transcribe this Spanish clip and translate it to English:
/tmp/es.mp3."
License
MIT
