tts-mcp
by imaimai86
README.md
# text-to-speech-mcp
A local text-to-speech [MCP](https://modelcontextprotocol.io) server for Claude and other MCP clients.
- **English** narration with [Kokoro](https://huggingface.co/hexgrad/Kokoro-82M) (optional extra).
- **Malayalam** narration with Indic Parler-TTS, IndicF5 (including voices cloned from a sample you
have permission to use), Piper, or MMS.
- **Edit-ready output:** Malayalam comes out as 48 kHz mono WAV, loudness-normalised to −14 LUFS
with true peak ≤ −1 dBTP, with optional MP3.
- **Malayalam text front end:** expands numbers, ₹/AED amounts, % and acronyms to words; normalises
Unicode chillu characters; supports your own pronunciation lexicon.
- **Async job queue:** one job at a time. A job can return a `job_id` immediately so agents can poll
for progress, which avoids tool-call timeouts on long narrations.
- **CPU/GPU detection:** picks CUDA, Apple Silicon (MPS) or CPU and **asks you to confirm**, falling
back to CPU if the accelerator isn't usable.
- **Runs entirely on your machine.** Models download from Hugging Face on first use.
## Install
macOS (Apple Silicon or Intel) and Linux:
```bash
curl -LsSf https://raw.githubusercontent.com/imaimai86/text-to-speech-mcp/main/install.sh | bash
```
The installer:
1. checks your system (OS, CPU, free disk);
2. installs [uv](https://docs.astral.sh/uv/), ffmpeg and espeak-ng if they're missing (**asks first**);
3. installs the server (`tts-mcp`) and the setup tool (`tts-mcp-setup`);
4. detects your CPU/GPU and **asks you to confirm** which device to use;
5. offers to register the server with Claude Desktop and Claude Code, backing up their config first;
6. runs a self-test.
It's safe to re-run. Useful flags:
| Flag | Effect |
|---|---|
| `--yes` | Unattended: accept every prompt |
| `--device cpu\|mps\|cuda` | Skip detection |
| `--no-english` | Malayalam only; avoids the GPL-licensed English phonemizer |
| `--no-claude` | Don't register the server with Claude |
| `--from .` | Install from a local checkout |
| `--upgrade` | Reinstall even if already installed |
**Gated models:** Parler and IndicF5 need a Hugging Face login, plus accepting their terms on
[indic-parler-tts](https://huggingface.co/ai4bharat/indic-parler-tts) and
[IndicF5](https://huggingface.co/ai4bharat/IndicF5):
```bash
uv tool run --from huggingface_hub hf auth login
```
## Use
Restart Claude Desktop, then ask, for example:
> *Narrate this in Malayalam with indicf5, voice anas, 20 steps, and export MP3:* …
### Tools
| Tool | What it does |
|---|---|
| `narrate_malayalam` | Malayalam text to WAV/MP3. Key inputs: `engine`, `voice`, `steps` (IndicF5 16–32, default 20), `speed`, `run_async`, `overwrite`, `filename` |
| `narrate` | English (Kokoro) text to WAV/MP3. Inputs: `voice`, `speed`, `pause`, `run_async`, `overwrite` |
| `estimate_narration` | Predicted audio length and runtime; `recommend_async` |
| `get_job_status` / `wait_for_job` | Progress, ETA, `poll_after_s`, result paths |
| `list_jobs` / `cancel_job` | Manage the queue |
| `list_voices` / `list_malayalam_engines` | Voices, per-job options with ranges, licence status |
**Sync or async:** `run_async=true` validates the request and returns a `job_id` in under a second.
A synchronous call whose estimated runtime exceeds about 45 s is queued automatically and also
returns a `job_id`, so it never times out. Invalid input (unknown voice, out-of-range `steps`, a file
that already exists without `overwrite`) returns an error immediately and queues nothing.
### Your data
Everything lives in `~/tts-mcp/` (override with `TTS_MCP_HOME`):
```
config.json device and settings (written by tts-mcp-setup configure)
output/ generated audio; output/jobs/ holds job records
voices/ saved IndicF5 voices: <name>.wav (6–12 s of clean speech) + <name>.txt (exact transcript)
lexicon.json your pronunciation overrides
```
### Setup commands
```bash
tts-mcp-setup configure [--device auto|cpu|mps|cuda] [--yes] # re-detect and confirm the device
tts-mcp-setup register | unregister # Claude Desktop / Claude Code
tts-mcp-setup doctor # show config, check dependencies
tts-mcp-setup uninstall [--purge] # remove the tool (--purge also deletes ~/tts-mcp)
tts-mcp --self-test [--full] # end-to-end check (--full also synthesises English)
```
## Performance
Measured on an Apple M1 with 16 GB RAM. RTF is synthesis time ÷ audio length; lower is faster.
| Engine | RTF |
|---|---|
| IndicF5 on MPS, 16 / 20 / 32 steps | ≈ 1.2 / 1.5 / 2.6 |
| IndicF5 on CPU, 32 steps | ≈ 7 |
| Parler (Malayalam) | ≈ 3.9 |
| MMS | ≈ 0.13 |
| Piper | ≈ 0.02 |
The job queue refines its time estimates from your machine's actual runs.
## Licences
The code is MIT. Dependencies and models have their own licences, and **not every engine is safe for
monetised content**: see [THIRD_PARTY_LICENSES.md](THIRD_PARTY_LICENSES.md). In short, Parler is
fine, IndicF5 needs review (a non-commercial runtime dependency), and Piper and MMS are not allowed.
## Development
```bash
uv sync --locked --extra dev
uv run pytest
uv run python scripts/licence_report.py --check # licence audit of the core install
```
### Limitations
- The CUDA path is covered by unit tests with mocks; it hasn't been run on NVIDIA hardware.
- Windows isn't supported.
- Cancelling a running job takes effect after the current chunk. For IndicF5 a chunk is one paragraph.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues