WellSaid Claude Connector
# WellSaid Claude Connector
Generate lifelike [WellSaid Labs](https://wellsaidlabs.com) voiceover from text — right inside Claude.
This is a [Model Context Protocol](https://modelcontextprotocol.io) server that wraps the WellSaid Labs text-to-speech API and exposes it as Claude tools. Ask Claude to "list WellSaid voices" or "voice this script with Wade C., a little slower and deeper," and it renders audio (plus captions if you want them).
Runs as a **local stdio connector** (Claude Desktop custom connectors + Claude Code) or as a **remote Streamable-HTTP connector**. No build step — plain Node ESM.
---
## What Claude can do with it
| Tool | What it does |
| --- | --- |
| `wellsaid_list_voices` | List voice avatars and their `speaker_id` (name, style, accent, gender, language), with optional search. |
| `wellsaid_list_voice_criteria` | Summarize the distinct styles/accents/genders/languages to narrow a search. |
| `wellsaid_generate_speech` | Convert text → audio with a chosen voice. Supports model (`legacy`/`caruso`), AI Director prosody (pitch/tempo/loudness), output format, and replacement libraries. |
| `wellsaid_generate_speech_with_timing` | Render speech **plus** word timing and SRT/VTT captions — the API's zip is extracted to individual files. |
| `wellsaid_create_clip_async` | Start an async TTS job (good for long or batched scripts). |
| `wellsaid_get_clip` | Check a clip's status and download it when ready. |
| `wellsaid_list_clips` | List recent clips on the account. |
| `wellsaid_combine_clips` | Stitch multiple clips into one file with custom pauses. |
| `wellsaid_get_respelling_suggestions` | Get pronunciation respellings for a tricky name/term. |
| `wellsaid_request` | Advanced escape hatch — call any WellSaid endpoint directly. |
Generated files are written to your output folder (default `./output`, or set `WELLSAID_OUTPUT_DIR`).
### Prosody & pronunciation (AI Director)
WellSaid's expressive controls run on the **`caruso`** model via [AI Director](https://docs.wellsaidlabs.com/reference/using-ai-director-with-the-api) tags embedded in the text. `wellsaid_generate_speech` exposes them two ways:
- **Whole-line convenience:** pass `pitch`, `tempo`, and/or `loudness` — the connector wraps your text in the right tags and automatically selects the `caruso` model. Approximate ranges: pitch `[-45, 100]`, tempo `[0.7, 2.3]`, loudness `[-15, 9]`.
- **Fine control:** embed tags directly in `text`, e.g. `The <emphasis>best</emphasis> value is <respell value="PEET-suh">pizza</respell>.` Use `wellsaid_get_respelling_suggestions` to find respelling values.
Output `format` can be `mp3` (default), `wav`, or `s16le`, with an optional `sample_rate`.
---
## Prerequisites
- **Node.js ≥ 18.17** (uses the built-in `fetch`). Developed on Node 24. `.env` auto-loads via a built-in on Node ≥ 20.12, with a manual fallback on older versions.
- **A WellSaid API key** — create one at [wellsaidlabs.com](https://wellsaidlabs.com) (Studio → API) or the [Developer Portal](https://developer.wellsaidlabs.com). Sent as the `X-Api-Key` header. Default keys are rate-limited to ~3 requests/second and 1,000 characters per synchronous request.
## Install & verify
```bash
cd wellsaid-connector
npm install
cp .env.example .env # then paste your key into WELLSAID_API_KEY
npm run doctor # checks config + connectivity to /tts/avatars
```
`npm run doctor` prints your config and, if the key works, the number of available voices.
---
## Add it to Claude
### Claude Code
```bash
claude mcp add wellsaid --env WELLSAID_API_KEY=YOUR_KEY -- node /absolute/path/to/wellsaid-connector/src/index.js
```
Then in a session: *"List my WellSaid voices"* → *"Generate speech for '…' with speaker_id 3, a little deeper."*
### Claude Desktop (config file)
Settings → Developer → **Edit Config**, and merge the `mcpServers` block from
[`claude_desktop_config.example.json`](claude_desktop_config.example.json). **Replace the API key, the
`args` path, and the output dir** with your own install location. Fully quit and reopen Claude Desktop;
the tools then appear under the 🔌 connector menu.
### Claude Desktop (one-click extension)
The repo ships a [`manifest.json`](manifest.json) so it can be packaged as a Desktop Extension
(`.mcpb`) that prompts for the API key in the UI — no JSON editing:
```bash
npx @anthropic-ai/mcpb pack . # produces wellsaid.mcpb
```
Drag `wellsaid.mcpb` into Claude Desktop → Settings → Extensions, and paste your key when prompted.
The extension defaults the output folder to your **Downloads** folder (see the config note below).
### Remote / hosted connector — public, OAuth (`src/remote.js`)
This is the path to a **public** connector anyone can add by URL. `src/remote.js` is an OAuth 2.1–protected
MCP server (Dynamic Client Registration + PKCE) that shows a consent page where each user pastes **their
own** WellSaid key; that key is bound to their token and used only for their requests.
```bash
npm run start:remote # OAuth MCP server on http://localhost:8788/mcp
```
Deploy it to a public HTTPS URL, then in Claude → **Settings → Connectors → Add custom connector** →
paste `https://your-url/mcp`. Full instructions (Docker / Render / Fly / tunnel) are in
[DEPLOY.md](DEPLOY.md). This hosted server is also the prerequisite for a
[Connectors Directory](https://claude.com/docs/connectors/building/submission) submission — see
[PRIVACY.md](PRIVACY.md) for the required privacy policy template.
> There's also an **authless** local HTTP mode for quick testing (`npm run start:http`, port 8787) —
> stateless, no auth, 4 MB body cap. Use `start:remote` (OAuth) for anything shared.
---
## Configuration
All configuration is via environment variables (or `.env`):
| Variable | Required | Default | Purpose |
| --- | --- | --- | --- |
| `WELLSAID_API_KEY` | ✅ | — | Your WellSaid key (`X-Api-Key`). |
| `WELLSAID_API_BASE` | | `https://api.wellsaidlabs.com/v1` | Override the API base URL. |
| `WELLSAID_OUTPUT_DIR` | | `./output` | Where audio/caption files are saved (see note). |
| `MCP_TRANSPORT` | | `stdio` | `stdio` or `http`. |
| `PORT` | | `8787` | Port for HTTP transport. |
> **Output-dir note:** the code default is the connector's `./output` folder, used when
> `WELLSAID_OUTPUT_DIR` is unset (Claude Code / `.env` installs). The one-click Desktop Extension
> (`.mcpb`) and the example Claude Desktop config instead default to your **`~/Downloads`** folder,
> because a packaged extension has no writable `./output`. Any tool call can override with `output_dir`.
---
## Development
```bash
npm test # unit + in-process + stdio + http suites
node test/unit.test.js # client helpers, safe file writing, zip reader
node test/inmemory.test.js # tool behavior against a mocked API (real body-building)
node test/stdio.smoke.js # spawns the real process, exercises the MCP handshake
node test/http.smoke.js # Streamable-HTTP transport
npm run inspect # opens the MCP Inspector against the server
```
## Notes on API coverage
- `wellsaid_list_voices` (`GET /v1/tts/avatars`) and `wellsaid_generate_speech`
(`POST /v1/tts/stream`) are built against WellSaid's documented request/response shapes, including the
integer `speaker_id`, `model`, `audio_configs`, and `library_ids` fields and inline AI Director tags.
- `wellsaid_generate_speech_with_timing` posts to `/v1/tts/word-timing` and unpacks the returned zip.
- `wellsaid_combine_clips` uses `clip_ids` + `pause_durations` per the combine endpoint.
- If WellSaid changes a field, `wellsaid_request` lets Claude call any endpoint directly while this
connector is updated.
## Security
- Your API key stays in your local environment / MCP client config; it is only sent to
`api.wellsaidlabs.com` (or your `WELLSAID_API_BASE`) as `X-Api-Key`, and is never logged or written to disk.
- Output filenames are reduced to a bare basename, so a tool call can never write outside your
configured output folder.
## License
MIT
TDQS
Scored across 10 tools
Most tools have clearly distinct purposes (listing voices, summarizing criteria, generating speech, managing clips, combining clips, respelling suggestions, and a request escape hatch). However, the three generation tools—generatespeech, generatespeech_with_timing, and createclip_async—overlap in function, though descriptions clearly distinguish sync vs async and timing output.
All tool names follow a consistent wellsaid_verb_noun snake_case pattern (e.g., wellsaid_list_voices, wellsaid_generate_speech, wellsaid_combine_clips). No mixing of styles or inconsistent verb choices.
10 tools is well within the ideal range, covering the full TTS workflow—voice discovery, generation (sync/async/timing), clip management, combination, and respelling—without unnecessary bloat.
The tool surface is comprehensive for TTS generation and clip management, including sync/async rendering, timing/captions, and clip combination. Minor gaps like no dedicated update/delete for clips are mitigated by the wellsaid_request escape hatch, but the core lifecycle lacks these operations.