say_ttsLABSCO SUMMARY
Five voices, one decision per call.
Because each backend is its own tool, the cheap local one and the expensive hosted one sit side by side and you choose per message. The serialisation is the quiet good idea: several agents speaking at once is unintelligible, so by default they queue.
What it is
A Go MCP server that adds text-to-speech to Claude Desktop, Claude Code, Cursor and others. Five backends are registered as separate tools, so you pick per call whether the voice is local and free or hosted and better.
What you get
say_tts— the macOSsaybinary and its built-in system voices, with no key of any kindvoice_tts— Qwen3-TTS through MLX via the localvoice-sayCLI, keeping text and audio on the Mac; it reloads the model each call, so it suits summaries rather than time-critical alerts, and takesvoice,tier,styleanddescribeelevenlabs_tts— ElevenLabs voices, defaulting to the premade voiceEXAVITQu4vr4xnSDxMaLgoogle_tts— Gemini TTS with 30 named voices, from Achernar to Zubenelgenubiopenai_tts— named voices fromalloythroughverseacrossgpt-4o-mini-tts,tts-1andtts-1-hd, with speed from 0.25x to 4.0x and free-text delivery instructions- One voice at a time by default — a mutex serialises speech inside the process and across multiple Claude Desktop windows through a system-wide file lock;
MCP_TTS_ALLOW_CONCURRENT=trueif you want them overlapping - Audio saved to disk with
MCP_TTS_OUTPUT_DIR, andMCP_TTS_NO_PLAY=trueto save without playing MCP_TTS_SUPPRESS_SPEAKING_OUTPUT=trueto stop the "Speaking:" line appearing in the transcript
Requirements
A Go binary, with Docker configurations documented too. say_tts needs macOS and nothing else. The hosted backends need their keys: ELEVENLABS_API_KEY, GOOGLE_AI_API_KEY or GEMINI_API_KEY, and OPENAI_API_KEY. voice_tts only registers when voice-say is resolvable on PATH, and it plays directly rather than writing files. Free-tier ElevenLabs keys are limited to premade voices — Voice Library voices return 402 paid_plan_required.
Setup effort
One command — go install github.com/blacktop/mcp-tts@latest
USE CASES
Being told when a long job finishes
The macOS voice speaks the notification with no key, no network and no cost.
Keeping what is spoken off other people's servers
The local MLX backend synthesises on the Mac, so neither the text nor the audio leaves it.
Recording something you will actually publish
Use a hosted voice, save the file to a directory, and skip playback while you are batching.
Choosing a voice that fits the message
Gemini's thirty voices and OpenAI's named set are both addressable by name in the call.
Running several agents that all talk
The default lock keeps them from speaking over each other, including across separate desktop windows.
Setting the delivery, not just the words
Both the OpenAI and the local backends accept free-text instructions about tone and style.
5 tools
Listed in project docs. Your client may show a different list.
voice_ttselevenlabs_ttsgoogle_ttsopenai_ttsBEFORE YOU INSTALL
What to know first
Tools you get
5 tools named in the project's documentation.
Requires
mcp-tts on PATH
Optional
- ELEVENLABS_API_KEY in your environment
- GOOGLE_AI_API_KEY in your environment
- OPENAI_API_KEY in your environment
- GEMINI_API_KEY in your environment
Where it runs
All 4 documented clients run the server on your machine.
INSTALLATION
Connect your client
Server setup
go install github.com/blacktop/mcp-tts@latestMCP Clients
Claude Desktop
{
"mcpServers": {
"say": {
"command": "mcp-tts",
"env": {
"ELEVENLABS_API_KEY": "<YOUR_ELEVENLABS_API_KEY>",
"ELEVENLABS_VOICE_ID": "EXAVITQu4vr4xnSDxMaL",
"GOOGLE_AI_API_KEY": "<YOUR_GOOGLE_AI_API_KEY>",
"OPENAI_API_KEY": "<YOUR_OPENAI_API_KEY>",
"OPENAI_TTS_INSTRUCTIONS": "Speak in a cheerful and positive tone",
"MCP_TTS_SUPPRESS_SPEAKING_OUTPUT": "true",
"MCP_TTS_ALLOW_CONCURRENT": "false"
}
}
}
}GEMINI_API_KEY is the other name the project accepts for the Google key — the configuration already sets it as GOOGLE_AI_API_KEY, so you need one or the other. Each key serves only its own tool; say_tts needs none.
Claude Code
claude mcp add say -e GOOGLE_AI_API_KEY=<YOUR_GOOGLE_AI_API_KEY> -e ELEVENLABS_API_KEY=<YOUR_ELEVENLABS_API_KEY> -e OPENAI_API_KEY=<YOUR_OPENAI_API_KEY> -- mcp-ttsGEMINI_API_KEY is the other name the project accepts for the Google key — the configuration already sets it as GOOGLE_AI_API_KEY, so you need one or the other. Each key serves only its own tool; say_tts needs none.
Codex
codex mcp add say --env GOOGLE_AI_API_KEY=<YOUR_GOOGLE_AI_API_KEY> --env ELEVENLABS_API_KEY=<YOUR_ELEVENLABS_API_KEY> --env OPENAI_API_KEY=<YOUR_OPENAI_API_KEY> -- mcp-ttsGEMINI_API_KEY is the other name the project accepts for the Google key — the configuration already sets it as GOOGLE_AI_API_KEY, so you need one or the other. Each key serves only its own tool; say_tts needs none.
Gemini CLI
{
"mcpServers": {
"say": {
"command": "mcp-tts",
"env": {
"GOOGLE_AI_API_KEY": "<YOUR_GOOGLE_AI_API_KEY>"
}
}
}
}GEMINI_API_KEY is the other name the project accepts for the Google key — the configuration already sets it as GOOGLE_AI_API_KEY, so you need one or the other. Each key serves only its own tool; say_tts needs none.