{
  "markdown": "# supertone-mcp\n\n<!-- ⚠️ SERVICE DISCONTINUATION NOTICE — paste at the very top of the README, right below the title -->\n\n> [!CAUTION]\n> ## ⚠️ Service Discontinuation Notice\n>\n> **The Supertone API will be permanently shut down on August 31, 2026.**\n> After this date, all API requests will stop being served and this package will no longer work.\n>\n> 👉 For the full timeline, refund policy, and details, see the **[End-of-Life Guide](https://docs.supertoneapi.com/en/docs/sunset)**.\n\n\n\n<!-- mcp-name: io.github.supertone-inc/supertone-mcp -->\n\nA **composable MCP toolkit** for the [Supertone](https://supertone.ai) TTS API. Rather than a single \"speak this text\" command, it exposes Supertone's SDK as a set of building-block tools — synthesis, voice discovery, preview, duration/credit prediction, usage tracking, and full voice-cloning CRUD — that an LLM assembles to fulfill a request. Works in Claude Desktop, Cursor, or any MCP-compatible client.\n\n[![supertone-inc/supertone-mcp MCP server](https://glama.ai/mcp/servers/supertone-inc/supertone-mcp/badges/score.svg)](https://glama.ai/mcp/servers/supertone-inc/supertone-mcp)\n\nCovers Korean, English, Japanese, and **31 languages** total. Speed (0.5x–2.0x), pitch shift (-24 to +24 semitones), emotion styles, per-call output mode, streaming, and model selection.\n\n## Features\n\n**Synthesis**\n- **`text_to_speech`** — Convert text to audio. Per-call control of `output_mode` (files / resources / both), `autoplay`, `streaming`, `model`, plus `include_phonemes` / `normalized_text`. Long text is auto-chunked by the SDK.\n- **`predict_duration`** — Estimate audio length (and credit cost) without synthesizing.\n\n**Voice discovery (preset)**\n- **`search_voice`** — Filter the catalog by language, gender, age, use_case, style, model, name, or description.\n- **`get_voice`** — Full detail for one voice.\n- **`preview_voice`** — Sample audio URLs for a voice (filterable by language/style/model).\n\n**Custom voice cloning**\n- **`clone_voice`** — Create a cloned voice from a local WAV/MP3 (≤3MB).\n- **`search_custom_voice`** — List/filter cloned voices.\n- **`get_custom_voice`** — Full detail for one cloned voice.\n- **`edit_custom_voice`** — Update name and/or description.\n- **`delete_custom_voice`** — Permanently delete (irreversible).\n\n**Audio assembly**\n- **`merge_audio_files`** — Concatenate two or more local audio files (mp3/wav) into one via a bundled ffmpeg. Supports plain concat, silence gaps between clips (`gap_ms`), or crossfade blending (`crossfade_ms`). Output format auto-detected (mixed → mp3) or forced via `output_format`. No system ffmpeg required.\n\n**Usage & credits**\n- **`get_credit_balance`** — Remaining credits.\n- **`get_usage_history`** — Usage over a time window.\n- **`get_voice_usage`** — Usage for a specific voice.\n\n## Breaking changes & migration (0.2.0)\n\n0.2.0 moves behavior control **out of environment variables and into per-call tool parameters** — so the LLM decides per request, not the server config.\n\n| Before (env var) | After (per-call parameter) | Note |\n|------------------|----------------------------|------|\n| `SUPERTONE_MCP_OUTPUT_MODE=files\\|resources\\|both` | `text_to_speech(output_mode=...)` | Default still `files` |\n| `SUPERTONE_MCP_AUTOPLAY=true` | `text_to_speech(autoplay=...)` | **Default changed `true` → `false`** (playback is now explicit) |\n| *(always streamed)* | `text_to_speech(streaming=...)` | **New, default `false`** (one-shot). `streaming=true` requires `model=\"sona_speech_1\"` |\n\nOther changes:\n- **Default model** changed `sona_speech_1` → **`sona_speech_2_flash`**.\n- **`list_voices` was removed** (since the discovery release) and replaced by `search_voice` — call it with no arguments to reproduce the old \"list everything\" behavior.\n- No more hard 300-character limit — longer text is auto-chunked by the SDK (credit/latency scale with length).\n\nIf you previously set `SUPERTONE_MCP_OUTPUT_MODE` or `SUPERTONE_MCP_AUTOPLAY`, remove them from your client config and pass `output_mode` / `autoplay` per call instead. (The server prints a one-time stderr notice if it sees the removed vars.)\n\n## Installation\n\n```bash\n# Using uvx (recommended)\nuvx supertone-mcp\n\n# Using pip\npip install supertone-mcp\n```\n\n## Configuration\n\n### Claude Desktop\n\nAdd to `claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"supertone-tts\": {\n      \"command\": \"uvx\",\n      \"args\": [\"supertone-mcp\"],\n      \"env\": {\n        \"SUPERTONE_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n### Cursor\n\nAdd to your Cursor MCP settings (same JSON shape as above).\n\n## Environment Variables\n\nOnly authentication and stable defaults are configured via the environment — all behavior is controlled per call.\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `SUPERTONE_API_KEY` | Yes | — | Your Supertone API key |\n| `SUPERTONE_MCP_VOICE_ID` | No | preset voice (Aiden, multilingual) | Default `voice_id` for `text_to_speech` / `predict_duration` (override per call) |\n| `SUPERTONE_OUTPUT_DIR` | No | `~/supertone-tts-output/` | Directory where audio files are saved (used by `output_mode=files`/`both`) |\n\n> Removed in 0.2.0: `SUPERTONE_MCP_OUTPUT_MODE` and `SUPERTONE_MCP_AUTOPLAY` — see [Migration](#breaking-changes--migration-020).\n\n### Output modes (`text_to_speech` `output_mode`)\n\n| Mode | Returns | Use when |\n|------|---------|----------|\n| `files` *(default)* | Plain text with the saved file path + metadata | You want the file on disk |\n| `resources` | MCP `AudioContent` + `TextContent` (no file written) | The client renders audio inline (e.g., Claude.ai chat) |\n| `both` | File on disk **and** `AudioContent`/`TextContent` | You want both — preview inline, keep the file |\n\n## Usage Examples\n\nThe MCP client routes natural-language requests across these tools — the value of the toolkit is **composition**: the LLM chains several tools to satisfy one request.\n\n### Example 1 — Discover → preview → estimate cost → synthesize\n\n> \"Find a calm Korean female voice, let me hear a sample, check the cost, then make this announcement as an mp3.\"\n\nThe LLM assembles:\n```\nsearch_voice(language=\"ko\", gender=\"female\", style=\"neutral\")   # find candidates\n  → preview_voice(voice_id)                                       # sample URLs to confirm the voice\n  → predict_duration(text, voice_id) + get_credit_balance()       # gauge cost before spending\n  → text_to_speech(text, voice_id, output_format=\"mp3\",\n                   output_mode=\"files\")                           # synthesize\n```\n\n### Example 2 — Clone my voice → use it right away\n\n> \"Make a cloned voice from ~/recordings/sample.wav named MyVoice, then read this greeting with it and play it for me.\"\n\nThe LLM assembles:\n```\nclone_voice(name=\"MyVoice\", audio_path=\"~/recordings/sample.wav\")   # create the cloned voice\n  → get_custom_voice(voice_id)                                       # confirm it was created\n  → text_to_speech(text, voice_id=<cloned>, autoplay=true)           # synthesize, then play immediately\n```\n\n> `autoplay` is a per-call parameter (default `false`), so playback happens only when explicitly requested.\n\n## Tool Parameters\n\n### `text_to_speech`\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `text` | string | Yes | — | Text to convert (long text is auto-chunked by the SDK) |\n| `voice_id` | string | No | env or preset | Voice identifier (browse via `search_voice`) |\n| `language` | string | No | `ko` | Language code — one of 31 (`ko`, `en`, `ja`, …) |\n| `output_format` | string | No | `mp3` | `mp3` or `wav` |\n| `model` | string | No | `sona_speech_2_flash` | `sona_speech_1`, `sona_speech_2`, `sona_speech_2_flash`, `sona_speech_2t`, `sona_speech_3t`, `supertonic_api_1`, `supertonic_api_3` |\n| `speed` | float | No | `1.0` | 0.5–2.0 |\n| `pitch_shift` | int | No | `0` | -24 to +24 semitones |\n| `style` | string | No | — | Emotion style (varies by voice) |\n| `output_mode` | string | No | `files` | `files`, `resources`, or `both` (see [Output modes](#output-modes-text_to_speech-output_mode)) |\n| `autoplay` | bool | No | `false` | Play the audio locally after synthesis (macOS `afplay`) |\n| `streaming` | bool | No | `false` | Stream synthesis. Only supported by `model=\"sona_speech_1\"` |\n| `include_phonemes` | bool | No | `false` | Return phoneme timing data alongside the audio |\n| `normalized_text` | string | No | — | Pre-normalized text (only used by `sona_speech_2` / `sona_speech_2_flash`) |\n\n### `predict_duration`\n\nSame core parameter schema as `text_to_speech` (long text auto-chunked). Returns `\"Predicted duration: 2.34s (credit usage is proportional to duration).\"`.\n\n### `search_voice`\n\nAll parameters optional. With no filters → full catalog. With any filter → first response line is `Filters applied: ...`.\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `language` | string | e.g., `ko`, `en`, `ja` |\n| `gender` | string | e.g., `male`, `female` |\n| `age` | string | e.g., `young_adult`, `child` |\n| `use_case` | string | e.g., `narration`, `advertisement` |\n| `style` | string | e.g., `neutral`, `happy` |\n| `model` | string | e.g., `sona_speech_2_flash` |\n| `name` | string | partial match |\n| `description` | string | partial match |\n\n### `get_voice` / `preview_voice`\n\n| Tool | Required | Optional |\n|------|----------|----------|\n| `get_voice` | `voice_id` | — |\n| `preview_voice` | `voice_id` | `language`, `style`, `model` (filter samples) |\n\n### `clone_voice`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `name` | string | Yes | Display name (non-empty) |\n| `audio_path` | string | Yes | Local WAV or MP3 path (≤3MB). Supports `~` expansion |\n| `description` | string | No | Optional note |\n\n### Custom voice CRUD\n\n| Tool | Required | Optional |\n|------|----------|----------|\n| `search_custom_voice` | — | `name`, `description` (partial match) |\n| `get_custom_voice` | `voice_id` | — |\n| `edit_custom_voice` | `voice_id` | `name`, `description` (at least one required) |\n| `delete_custom_voice` | `voice_id` | — *(IRREVERSIBLE)* |\n\n### Usage & credits\n\n| Tool | Required | Optional |\n|------|----------|----------|\n| `get_credit_balance` | — | — |\n| `get_usage_history` | — | — (reports a recent default window) |\n| `get_voice_usage` | `voice_id` | — |\n\n### `merge_audio_files`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `input_paths` | string[] | Yes | Two or more local mp3/wav paths (`~` expansion supported). A single file is returned as-is |\n| `gap_ms` | int | No | Silence (ms) inserted at each junction. Default `0`. Mutually exclusive with `crossfade_ms` |\n| `crossfade_ms` | int | No | Crossfade blend (ms) at each junction. Default `0`. Mutually exclusive with `gap_ms` |\n| `output_format` | string | No | Force `mp3` or `wav`. If omitted: all-same-ext → that ext; mixed → `mp3` |\n\n## Development\n\n```bash\n# Clone and install\ngit clone https://github.com/supertone-inc/supertone-mcp.git\ncd supertone-mcp\nuv sync\n\n# Run tests\nuv run pytest -q\n\n# Run with coverage\nuv run pytest --cov=src --cov-report=term-missing\n```\n\n## License\n\nMIT\n",
  "bytes": 11230,
  "sha": "618460f6fed37d1e0c5992b56c9c8faf86773ee548b090903b240f1eec4b9f5e",
  "repo_slug": "supertone-inc/supertone-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_supertone_inc_supertone_mcp_05c40fc1/readme"
}