Skip to main content
Glama

ofaudio-mcp

An agent-first MCP server for any audio an AI agent needs — generate (music, sound effects, speech, multi-speaker dialogue) and transform (transcribe, caption, isolate/denoise, voice-convert/dub) — behind one intent-shaped tool surface. It wraps ElevenLabs (speech, dialogue, SFX, voice library/design/cloning, music, transcription, isolation, speech-to-speech) and Mureka (music, lyrics), does the work in-process, and writes files to the local filesystem. Games, audiobooks, podcasts, video, ads, accessibility, localization — all one MCP.

Built to be driven by an agent, never a human clicking a UI. Every generation call returns a job_id instantly and runs in the background, so an agent can fan out many variants without blocking, then collect them with check_jobs.

Install

# from a checkout
pip install -e .
ofaudio-mcp            # or:  python -m ofaudio_mcp

Only hard dependency is the mcp SDK. Python 3.10+.

Related MCP server: minimax-omni

Configure (environment)

Copy .env.example to .env and fill in your keys (.env is gitignored). Set at least one provider's key. Keys accept a singular or plural form; the plural is comma-separated and becomes a multi-account pool (see Parallelism).

Env var

Default

Purpose

ELEVENLABS_API_KEY / ELEVENLABS_API_KEYS

—

ElevenLabs key(s) — voice + SFX. Works with a subscription tier or pure pay-as-you-go.

MUREKA_API_KEY / MUREKA_API_KEYS

—

Mureka key(s) — music. Prepaid API credits.

OFAUDIO_OUT_DIR

./ofaudio-out

Where audio files are written.

OFAUDIO_STATE_DIR

<OUT_DIR>/.state

Job records (JSON) + presets.json.

OFAUDIO_TOOLS

all

Comma-separated tool groups to mount (generate,speakers,voices,account,transform,pronunciation) — fewer tools, less client context. See Context cost.

OFAUDIO_ELEVENLABS_LANES

3

Concurrent requests per ElevenLabs key.

OFAUDIO_MUREKA_LANES

1

Concurrent requests per Mureka key (Mureka caps at 1/account).

OFAUDIO_POLL_INTERVAL

5

Seconds between polls for async (Mureka) jobs.

OFAUDIO_JOB_TIMEOUT

300

Max seconds to wait for one generation.

OFAUDIO_MUREKA_MODEL

auto

Pin a Mureka model (e.g. the V9 flagship string) once confirmed on a live key.

OFAUDIO_ELEVENLABS_MODEL

eleven_v3

TTS model; drop to eleven_multilingual_v2 if v3 isn't on the key's tier.

OFAUDIO_ELEVENLABS_VOICE

Rachel

Default voice id when a call doesn't specify one.

ELEVENLABS_BASE_URL / MUREKA_BASE_URL

official

Override API base URLs.

A key entry may be label:key to name the lane in logs and job results (e.g. MUREKA_API_KEYS="acct-a:ak_...,acct-b:ak_...").

Tools

27 tools in six groups (generate, speakers, voices, account, transform, pronunciation); mount a subset with OFAUDIO_TOOLS. Every parameter is documented in the tool schema itself, so an agent needs nothing beyond tools/list.

Tool

What it does

generate_music(prompt, duration?, instrumental?, reference?, lyrics?, engine?, format?, count?, composition_plan?, store_for_inpainting?, respect_sections_durations?)

Themes, BGM, songs, instrumentals. Soft-defaults to Mureka (prompt→song writes its own lyrics; pass lyrics for your own; reference = local/URL track → vibe-match; format defaults to lossless flac; count 1–3). engine="elevenlabs" = Eleven Music (composition_plan replaces prompt; store_for_inpainting → song_id) → {job_id}

generate_lyrics(prompt)

Write song lyrics from a theme (Mureka) — synchronous {title, lyrics}; review/edit before spending song credits

transcribe(audio, language?, diarize?, captions?)

Speech-to-text (ElevenLabs Scribe). audio = local path or a URL (YouTube/TikTok); diarize labels speakers; captions="srt"/"vtt" writes a subtitle file → {text, language_code, words, captions_path?}

forced_alignment(audio, text, captions?)

Align a known script to existing audio → exact per-word timings (+ optional SRT/VTT) — for captioning recordings you already have the transcript for

isolate_audio(audio)

Remove background noise / isolate the voice → {path}

convert_voice(audio, voice, remove_background_noise?, format?, seed?)

Speech-to-speech: re-voice a recording onto another voice, keeping delivery (dubbing/ADR) → {path}

generate_sfx(prompt, duration_seconds?, loop?, prompt_influence?, model?, engine?, format?)

One-shots, ambience, seamless loops → {job_id}

generate_speech(text, voice?, profile?, speaker?, mood?, workspace?, model?, stability?, style?, speed?, similarity_boost?, use_speaker_boost?, seed?, previous_text?, next_text?, language_code?, with_timestamps?, variants?, pronunciation?, engine?, format?)

Dialogue / character VO. Identity = a voice or a saved speaker (+ mood layered over its base delivery); shape delivery with a profile and/or precision knobs; inline v3 tags like [whispers] work; with_timestamps=True emits a per-character alignment sidecar (lip-sync/captions); variants=N (1–8) fans out N takes to audition → {job_id} (or {job_ids})

generate_dialogue(lines=[{voice, text}], model?, seed?, language_code?, apply_text_normalization?, engine?, format?)

Multi-speaker scene in one call (≤10 voices, ~2000 chars) with natural turn-taking → {job_id}

save_profile(name, voice?, model?, stability?, style?, speed?, …, tag?, seed?, description?)

Save a reusable persona/mood preset (a preset over the speech knobs)

save_speaker(name, voice, workspace?, model?, stability?, …, seed?, description?)

Save a speaker (pinned voice + base delivery) under a workspace

list_speakers(workspace?)

Saved speakers (optionally by workspace), each with its workspace

search_voice_library(query?, gender?, age?, accent?, use_case?, category?, descriptives?, page_size?)

Search ElevenLabs' shared library of thousands of voices; every result carries a preview_url to audition — no generation, no slots (keep query to a word or two)

add_library_voice(public_owner_id, voice_id, name, speaker?, workspace?, seed?, description?)

Add a library voice to the account and save it under name (uses a voice slot); speaker= also saves it as a speaker in one step

design_voice(description, save_as?, text?, model?, guidance_scale?, loudness?, seed?)

Synthesize a custom voice from a text description; returns previews to audition

save_voice(name, generated_voice_id, description?)

Keep a designed preview as a permanent, reusable voice (uses a voice slot)

clone_voice(name, audio_paths, description?, remove_background_noise?)

Instant Voice Cloning from your audio file(s) → saved, reusable voice (uses a slot)

delete_voice(voice, confirm=False)

Delete a custom voice and free its slot (fresh name→id, blocks premade, warns on profile/speaker refs)

account_status()

Both providers, one call — ElevenLabs (tier, char quota, voice slots, cloning, + quality/formats the tier allows) and Mureka (credit balance, concurrency limit). Check before fan-out

list_models()

ElevenLabs models available on the account + capability flags

check_jobs(job_ids)

Batch-poll — returns status + file path per id

list_jobs(status?, limit?)

Recent jobs, newest first

create_pronunciation_dictionary(name, rules, description?)

Lock how words/lore-names are said — rules = {word: say_as} map or EL rule objects. Apply via generate_speech(pronunciation=) or save_speaker(pronunciation=)

add_pronunciation_rules(dictionary, rules)

Extend a saved dictionary (mints a new version)

list_voices()

ElevenLabs voices on the account ({account, profiles}) — resolve a voice by name or id

get_voice(voice)

One voice's details (category, labels, description, preview_url)

list_presets()

Everything saved, one call: voice aliases, music presets, profiles (built-in + custom), speakers, pronunciation dictionaries, workspaces

Each generate_* has a soft-pinned provider (music→Mureka, SFX/speech→ElevenLabs) and an optional engine= override. A result is {job_id, status, path, duration, format, seed, provider} once succeeded.

Voices, speakers & delivery

The voice is the speaker's identity — pick or make one, don't dial it out of parameters. Three ways to get a voice, all reusable by name afterwards:

  1. Use one of ElevenLabs' many — search_voice_library(query="warm narrator", age="middle_aged") → add_library_voice(public_owner_id, voice_id, "narrator"). Thousands of ready-made voices.

  2. Design a custom one — design_voice("warm, measured audiobook narrator, clear articulation", save_as="narrator"). Describe it, audition the previews, keep the best.

  3. Reuse what's on the account — list_voices() shows the premade voices already there.

Then just generate_speech("...", voice="narrator") — the voice stays consistent.

Make it a first-class Speaker, grouped by workspace. For a whole cast across several projects, save_speaker("narrator", voice, workspace="projectA", ...) saves the identity (pinned voice + base delivery), and generate_speech(text, speaker="narrator", mood="calm", workspace="projectA") speaks it — the mood layers over the speaker (a speaker is who; a profile is what mood). search_voice_library(query) returns candidates with a preview_url each (no slots), and add_library_voice(..., speaker="narrator", workspace="projectA") adds + saves in one step. variants=N on generate_speech fans out N takes so a human picks the best.

Delivery (mood/tone) is a separate layer on top. Shape it with a profile and/or the precision knobs. Built-in profiles: neutral, narrator, calm, whisper, sad, angry, excited, shout (v3, emotion via audio tags) and steady, dynamic (v2, consistency axis). Save your own persona/mood presets with save_profile.

Two facts worth knowing (both handled for you, but they explain the design):

  • Eleven v3 (default for speech) does emotion via inline audio tags ([whispers], [angry], [snorts], …) and a 3-mode stability (creative/natural/robust) — it ignores the numeric style slider. Tags only land on an expressive voice; a flat narration voice mutes them.

  • Eleven v2 uses the numeric sliders, but those control consistency (dynamic ↔ steady), not a specific emotion. Use it via the steady/dynamic profiles.

Parallelism

Mureka caps concurrency at 1 request per prepaid account and it doesn't stack, so the way to run music generation in parallel is multiple accounts. This server treats keys as a pool: supply N keys and it runs N jobs in parallel, one per key, automatically routing around a key that hits its rate limit (back-off) or runs out of balance. Supplying one key is just the N=1 case. (ElevenLabs scales concurrency within a single key by tier, so a lane count > 1 per key is the norm there.)

Mount it

Claude Code

claude mcp add ofaudio \
  --env ELEVENLABS_API_KEY=xi_... --env MUREKA_API_KEY=ak_... \
  -- python -m ofaudio_mcp

Cursor — .cursor/mcp.json:

{
  "mcpServers": {
    "ofaudio": {
      "command": "python",
      "args": ["-m", "ofaudio_mcp"],
      "env": { "ELEVENLABS_API_KEY": "xi_...", "MUREKA_API_KEY": "ak_..." }
    }
  }
}

Self-hosted / server — add the server to your MCP client's config and put the keys in a .env next to it (they stay on the box):

ELEVENLABS_API_KEYS=xi_...
MUREKA_API_KEYS=acct-a:ak_...,acct-b:ak_...
OFAUDIO_OUT_DIR=/var/audio/ofaudio-out

The intended usage pattern is fan-out: fire many generate_* calls, then check_jobs.

Context cost

Most MCP clients load every tool schema into the model's context on every turn, so the size of tools/list is a real cost. Claude Code defers schemas until a tool is used, but truncates any tool description longer than 2048 characters. The surface is shaped around both:

  • Each tool's docstring is ≤ 700 chars; every parameter is documented in its own schema description (nothing gets cut, and schema-rendering clients see real docs, not titles).

  • Tools carry MCP annotations (readOnlyHint, destructiveHint) so clients can skip approval prompts on reads and warn on delete_voice.

  • The advertised schemas are compacted at startup (pydantic's title / anyOf null / default: null noise stripped; validation unchanged).

  • OFAUDIO_TOOLS=generate,account mounts only the groups a project needs.

  • The usage guide is served in-band as the MCP resource ofaudio://guide (text/markdown) for clients that support resources; the same text ships as the skills/ofaudio skill.

Surface

Tools

tools/list

≈ tokens

before this shaping

33

42.3 KB

12.1k

all six groups

27

33.7 KB

9.6k

OFAUDIO_TOOLS=generate,account

9

13.7 KB

3.9k

Measure it with python scripts/tool_surface.py (honours OFAUDIO_TOOLS; exits 1 if any description exceeds 2048 chars).

Status

Both providers work end-to-end. ElevenLabs: speech (+ timestamps, mood profiles, variants), multi-speaker dialogue, SFX, Eleven Music, voice library / design / instant cloning, voice lifecycle, account introspection, the speaker/workspace layer, and the transform tools (transcribe, forced alignment, isolate, voice-convert). Mureka: instrumental + song, prompt→song (easy-generate), user-supplied lyrics, standalone generate_lyrics, reference-track vibe-match, and lossless flac-default output.

Design

See CLAUDE.md for the architecture, module map, tool surface, and the verified provider facts that shape the design.

License

Source-available under PolyForm Noncommercial 1.0.0, with a licensor carve-out that draws the line at the tool, not the audio:

  • ✅ Run it freely for any purpose — including to generate audio you use commercially. This MCP is only a client; it claims no rights in what you generate. Your rights to the generated audio are governed by ElevenLabs' and Mureka's terms and your own accounts with them.

  • ❌ Don't commercialize the tool itself — you may not sell this software, host it as a paid service, or turn it (or a derivative) into a commercial product.

In short: make whatever audio you want, sell it if your provider terms allow — just don't sell the MCP. See LICENSE for the full terms.

Available Tools

33 tools
account_statusA

Credits + quotas for ALL configured providers in one call — check before fan-out.

Returns a section per available provider (only those with a configured key):

  • "elevenlabs": tier, characters used/limit/remaining, voice slots, cloning entitlements, next quota reset, and "quality" (which audio formats this tier can request — lossless wav/pcm need Pro+, mp3_192 needs Creator+).

  • "mureka": prepaid credit balance, total recharge/spending, and concurrent_request_limit (=1 on the $30 tier — drives how many music jobs run at once).

Use it to avoid mid-batch failures (out of credits / voice slots) and to pick a supported audio format for the account's tier. A provider that errors is reported under its own key rather than failing the whole call.

Inputs: no named parameters.

add_library_voiceA

Add a shared Voice Library voice to the account and save it under name.

Take public_owner_id + voice_id from search_voice_library. After this, generate_speech(voice="") uses that character. NOTE: consumes one custom-voice slot on the ElevenLabs account (tiers cap how many you can hold).

Returns: {"voice_id": , "name": ...} or {"error": ...}.

Inputs: name (required), voice_id (required), public_owner_id (required).

add_pronunciation_rulesB

Add rules to an existing pronunciation dictionary (by saved name or id).

Args: dictionary: A saved dictionary name (or an ElevenLabs dictionary id). rules: {word: say_as} map or a list of EL rule objects (see create_pronunciation_dictionary).

Returns: {"id", "version_id", "added": } or {"error"}.

Inputs: rules (required), dictionary (required).

add_speaker_from_libraryA

Add a Voice Library voice to the account AND save it as a speaker, in one step.

Combines add_library_voice + save_speaker. Consumes a voice slot. After this, speak('', text, workspace=...) uses it.

Args: name: Speaker/voice handle to save under. public_owner_id, voice_id: From a preview_voices candidate. workspace: Workspace namespace (default "default"). seed: Optional base seed for the speaker. description: Human note.

Inputs: name (required), voice_id (required), public_owner_id (required), seed, +2 more.

check_jobsA

Batch-poll jobs by id. This is the companion to fan-out generation.

Returns one status record per id: {job_id, kind, status, provider, and — when done — path, duration, format, seed}. status is one of queued/running/succeeded/failed; failed records include an "error". Unknown ids come back with status "unknown".

Inputs: job_ids (required). Returns: result

clone_voiceA

Clone a voice from audio sample(s) — ElevenLabs Instant Voice Cloning.

A human provides the audio FILES on the machine ofaudio runs on; pass their paths. ~1-2 minutes of clean, single-speaker audio clones best. The result is saved under name and usable immediately as generate_speech(voice=""). Consumes one voice slot, and needs a tier that allows instant cloning (see account_status).

IMPORTANT: only clone a voice you have the rights/consent to use.

Args: name: Handle to save the cloned voice under. audio_paths: Path(s) to audio files (mp3/wav/…) readable on this machine. description: Optional description stored on the voice. remove_background_noise: Run ElevenLabs' denoiser on the samples first.

Inputs: name (required), audio_paths (required), description, remove_background_noise.

convert_voiceA

Re-voice a recorded performance onto another voice (ElevenLabs speech-to-speech).

Keeps the delivery/timing of the input recording but swaps the voice — for dubbing, ADR, or turning your own take into a character's voice.

Args: audio: Local path to the source audio (the performance to convert). voice: Target voice — a saved name or an ElevenLabs voice id. remove_background_noise: Clean the input before converting. format: Output format ("mp3"/"wav"; wav auto-downgrades to mp3 on sub-Pro tiers). seed: Optional determinism hint.

Returns: {"path": } or {"error"}.

Inputs: audio (required), voice (required), seed, format, +1 more.

create_pronunciation_dictionaryA

Create a pronunciation dictionary so specific words/names are ALWAYS said a fixed way.

Great for a game/story cast: lock how lore names, places, and invented terms are pronounced, then apply it to any speech so every character says them consistently. Save it once (by name), then pass pronunciation=<name> to generate_speech/speak, or pin it to a speaker (save_speaker(pronunciation=)).

Args: name: A name to save this dictionary under (reuse it later by name). rules: The easy form is a {word: say-it-like-this} map, e.g. {"Kaelthas": "kal-thass", "Y'ffre": "iffray"} (alias rules). For precise IPA control, pass a list of ElevenLabs rule objects ({"type":"phoneme","string_to_replace":"...","phoneme":"...","alphabet":"ipa"}). description: Optional note.

Returns: {"name", "id", "version_id", "rules": } or {"error"}.

Inputs: name (required), rules (required), description.

delete_voiceA

Delete a custom voice from the ElevenLabs account, freeing a voice slot.

DESTRUCTIVE and irreversible — you must pass confirm=True. Resolves a name to its id first and refuses if the name is ambiguous (pass the exact voice_id then). Premade voices can't be deleted. Also removes local nickname aliases and warns if a saved profile still pins the voice.

Args: voice: The voice name or id to delete. confirm: Must be True to actually delete.

Inputs: voice (required), confirm.

design_voiceA

Design a brand-new custom voice from a text description (ElevenLabs Voice Design).

Describe the character ("elderly gruff grandfather, warm but gravelly, slight wheeze") and get back a few preview clips saved to the output dir. Audition them, then keep one with save_voice(name, generated_voice_id) — or pass save_as to auto-keep the first.

Args: description: The voice to synthesize, in plain language. save_as: If set, immediately save the first preview as a permanent voice under this name (consumes one custom-voice slot). text: Optional preview line (100-1000 chars); omit to auto-generate suitable text. model: Voice-design model ("eleven_multilingual_ttv_v2" default, or "eleven_ttv_v3"). guidance_scale: 0-100ish; higher sticks closer to the prompt (default ~5). loudness: -1 (quiet) to 1 (loud), default 0.5. seed: Fix generation for reproducible previews.

Returns: {"previews": [{generated_voice_id, path, duration}], "preview_text": ..., optionally "saved": {name, voice_id}} or {"error": ...}.

Inputs: description (required), seed, text, model, +3 more.

forced_alignmentA

Align a KNOWN script to existing audio → exact per-word timings (ElevenLabs).

Use when you already have the exact transcript (a recorded VO + its script) and want precise timings for captions/lip-sync/cut timing. (Unlike transcribe, which discovers the words — this snaps your given text to the audio.)

Args: audio: Local audio file path. text: The exact transcript/script spoken in the audio. captions: "srt" or "vtt" to also write a subtitle file from the aligned words.

Returns: {"words": , "characters": , "loss", "captions_path"?} or {"error"}.

Inputs: text (required), audio (required), captions.

generate_dialogueA

Generate a multi-speaker dialogue scene in a single call (ElevenLabs Text-to-Dialogue).

One request renders all turns with natural back-and-forth timing — better than stitching N separate generate_speech calls. Up to 10 distinct voices, ~2000 characters total.

Args: lines: Ordered turns, each {"voice": , "text": }. An optional "speaker" label is allowed for your own clarity. v3 audio tags work in the text (e.g. "[laughs] no way!"). model: Dialogue model id (default eleven_v3). seed: Best-effort determinism for the whole scene. language_code: ISO 639-1 language pin. apply_text_normalization: "auto" | "on" | "off". engine: Provider override (defaults to ElevenLabs). format: Output format ("mp3" default).

Returns: {"job_id": ..., "status": "queued", "engine": ...} or {"error": ...}. check_jobs returns the mixed dialogue audio path.

Inputs: lines (required), seed, model, engine, +3 more.

generate_lyricsA

Write song lyrics from a theme/description (Mureka) — returns text, not audio.

Synchronous: returns immediately with the lyrics so an agent can read/review or edit them before spending song credits, then pass them to generate_music(lyrics=...). Great for getting the words right first, or generating lyrics on their own.

Args: prompt: The theme/brief ("a hopeful song about starting over in a new city").

Returns: {"title": ..., "lyrics": ...} or {"error": ...}.

Inputs: prompt (required).

generate_musicA

Generate music — a theme, background track, song, or instrumental bed.

Returns immediately with a job_id; the audio is produced in the background. Poll it with check_jobs([job_id]) to get the file path when it's ready. Fire several calls to mass-produce variants without waiting.

Args: prompt: What to make, in plain language ("uplifting orchestral intro, soaring strings" / "warm lo-fi study loop"). For a sung song, this is the theme/style and Mureka writes the lyrics; pass lyrics to supply your own. Give either this OR composition_plan (Eleven Music), not both. duration: Target length in seconds, if you care (else the model decides). instrumental: True for no vocals (BGM/underscore); False allows sung vocals. reference: Optional path (local audio file) or URL to a reference track to steer style (Mureka only — we upload it and match its vibe; Eleven Music has no such input). lyrics: Mureka song only — supply exact lyrics (incl. [Verse]/[Chorus] tags) instead of letting Mureka write them from the prompt. When set, prompt is treated as an optional style descriptor ("r&b, slow, male vocal"). engine: Provider override. Soft-defaults to Mureka; pass "elevenlabs" to use Eleven Music instead (honours prompt, duration, instrumental; ignores reference/count). format: Output format. Mureka defaults to flac (lossless, highest quality, ~half the size of wav) and also offers "wav" (lossless, uncompressed) and "mp3" (smaller) — all free from the same generation. ElevenLabs: "mp3"/"wav". count: How many tracks to generate this call, 1–3 (Mureka only). composition_plan: Eleven Music only — a structured multi-section plan (intro/verse/ chorus with per-section prompts and durations) instead of a free-text prompt. Mutually exclusive with prompt; auto-routes the job to ElevenLabs. store_for_inpainting: Eleven Music only — persist the generated song so later calls can condition on / inpaint sections of it. Surfaces a song_id in the job result (via check_jobs) to reference it later. respect_sections_durations: Eleven Music + composition_plan only — enforce each section's requested duration strictly.

Returns: {"job_id": ..., "status": "queued", "engine": ...} or {"error": ...}. When a job finishes, check_jobs also returns song_id if store_for_inpainting was set.

Inputs: count, engine, format, lyrics, +7 more.

generate_sfxA

Generate a sound effect — a one-shot, ambience, or seamless loop.

Returns a job_id immediately; poll with check_jobs([job_id]) for the file path.

Args: prompt: The sound to make ("heavy wooden door creak", "sci-fi UI blip", "rain on a tin roof, distant thunder"). duration_seconds: Length 0.5–30, or None to let the model choose. loop: True to produce a seamlessly loopable clip (great for ambience/BGM beds). prompt_influence: 0–1 (default ~0.3) — higher sticks closer to the prompt, lower gives the model more creative latitude. model: SFX model id override (default the current text-to-sound model). engine: Provider override. Defaults to ElevenLabs for SFX. format: Output format ("mp3" default, "wav" where supported).

Returns: {"job_id": ..., "status": "queued", "engine": ...} or {"error": ...}.

Inputs: prompt (required), loop, model, engine, +3 more.

generate_speechA

Generate spoken dialogue / character voice acting.

Returns a job_id immediately; poll with check_jobs([job_id]) for the file path. Fire several calls to voice a whole scene without waiting.

Two ways to shape delivery, and they combine:

  • A profile — a saved persona/mood preset. Built-ins: neutral, narrator, calm, whisper, sad, angry, excited, shout (see list_profiles). Save your own with save_profile. A profile just presets the knobs below.

  • The precision knobs — any of these override the profile for this one line. Emotion can also be written inline as Eleven v3 audio tags, e.g. "[whispers] they're coming... [shouts] run!".

Args: text: The line(s) to speak, optionally with inline v3 audio tags. voice: An ElevenLabs voice name (see list_voices) or a voice id. Overrides any voice pinned by the profile. Omit for the default voice. profile: A saved/built-in profile name to preset delivery. model: Model id (default eleven_v3 for expressive character acting). stability: v3 delivery mode — "creative" (most expressive/tag-responsive), "natural" (balanced), or "robust" (locked-in) — or a 0-1 float. style: 0-1, amplifies the speaker's stylistic character (default 0). speed: Playback speed, 1.0 = normal (roughly 0.7-1.2 is usable). similarity_boost: 0-1, adherence to the reference voice (default 0.75). use_speaker_boost: Boost speaker similarity (slightly higher latency). seed: Fix sampling (0-4294967295) for more reproducible takes. Best-effort, NOT bit-exact (especially on v3) — a character's identity comes from its voice and settings, not the seed. previous_text / next_text: Surrounding lines, for prosody continuity in a scene. language_code: ISO 639-1 code to pin the language (not for multilingual_v2). with_timestamps: Also return per-character alignment (word/char timings) as a sidecar JSON next to the audio — for lip-sync, captions, and cut timing. variants: Generate N takes of this line in parallel (2-8) so a human can pick the best — v3 varies run-to-run. Returns {"job_ids": [...]} instead of one job_id. pronunciation: One or more pronunciation-dictionary names (or ids) to apply so lore names/terms are said a fixed way — up to 3. Create one with create_pronunciation_dictionary. engine: Provider override. Defaults to ElevenLabs for speech. format: Output format ("mp3" default, "wav"/PCM where the tier supports it).

Returns: {"job_id": ..., "status": "queued", "engine": ...} or {"error": ...}.

Inputs: text (required), seed, model, speed, +14 more.

get_voiceA

Details for one voice (by name or id): category, labels, description, preview_url.

Inputs: voice (required).

isolate_audioA

Remove background noise / isolate the voice from an audio file (ElevenLabs).

For cleaning up field recordings, podcast takes, or noisy clips before further use.

Args: audio: Local path to the audio file to clean.

Returns: {"path": } or {"error"}.

Inputs: audio (required).

list_jobsA

List recent jobs (newest first), optionally filtered by status.

Args: status: Filter to one of queued/running/succeeded/failed, or omit for all. limit: Max records to return (default 50).

Inputs: limit, status. Returns: result

list_modelsA

List ElevenLabs models available on the account, with capability flags.

Each: {model_id, name, can_do_tts, can_do_voice_conversion, max_characters, languages}. Use to pick or confirm a model id before pinning it via model=.

Inputs: no named parameters. Returns: result

list_presetsA

List everything saved in the presets registry: speaker voices and music identities.

Inputs: no named parameters.

list_profilesA

List speech profiles — built-in delivery presets plus any saved via save_profile.

Each entry shows its name, whether it's built-in, and the delivery settings it presets. Use a name as generate_speech(profile="").

Inputs: no named parameters. Returns: result

list_pronunciation_dictionariesA

List saved pronunciation dictionaries (name → id/version). Apply one via generate_speech/speak pronunciation= or save_speaker pronunciation=.

Inputs: no named parameters. Returns: result

list_speakersA

List saved speakers (voice + base delivery), optionally within one workspace.

Inputs: workspace. Returns: result

list_voicesA

List the ElevenLabs voices available on the account, plus saved speech profiles.

Returns {"account": [ {voice_id, name, category, labels, description}, ... ], "profiles": [ ... ]}. Use a voice name (or id) as generate_speech(voice=...), or a profile name as generate_speech(profile=...).

Inputs: no named parameters.

list_workspacesA

List workspace namespaces that currently hold speakers.

Inputs: no named parameters. Returns: result

preview_voicesA

Preview voices for a role — search the Voice Library and return top candidates, each with a ready-made preview_url to listen to. No generation, no voice slots consumed.

Pick one, then add_speaker_from_library(name, public_owner_id, voice_id) to add + save it as a speaker. (Library voices sound better than designed ones — search here first.)

Args: query: Short role term ("narrator", "villain", "host") — one or two words. gender / age / accent / use_case: Optional label filters. n: How many candidates to return (default 5).

Inputs: n, age, query, accent, +2 more.

save_profileA

Save a reusable speech profile (a persona/mood preset) under name.

A profile bundles delivery settings so generate_speech(profile="") reproduces it. Pin voice + a seed to lock a character's exact sound line-to-line, or leave voice out for a voice-agnostic mood you can lay over any voice. Saving a name that matches a built-in shadows it. Everything here maps to the same knobs generate_speech accepts.

Args: name: Handle to save under (e.g. "kael", "villain-calm"). voice: ElevenLabs voice name or id to pin (optional). model: Model id to pin (optional). stability: "creative"/"natural"/"robust" or a 0-1 float. style: 0-1. speed: Playback speed (1.0 = normal). similarity_boost: 0-1. use_speaker_boost: Boost speaker similarity. tag: An audio tag prepended to every line, e.g. "angry" → "[angry] ...". seed: Fix sampling for consistency (0-4294967295). description: Human note shown in list_profiles.

Inputs: name (required), tag, seed, model, +7 more.

save_speakerA

Save a reusable SPEAKER — a pinned voice + its base delivery — under a workspace.

A speaker is the identity ("narrator"); a profile is a mood ("angry"). Speak one with speak(speaker, text, mood?) and the mood layers on top. Group speakers by workspace so casts for different projects don't collide.

Args: name: Speaker handle (e.g. "narrator"). voice: The voice to pin — an ElevenLabs voice name/id, or a saved voice/clone name. workspace: Workspace namespace (default "default"). model / stability / style / speed / similarity_boost / use_speaker_boost / seed: The speaker's BASE delivery (all optional; each overridable per line). pronunciation: A pronunciation-dictionary name/id (or list) to apply automatically whenever this speaker talks — so it always says lore names the same way. description: Human note.

Inputs: name (required), voice (required), seed, model, +8 more.

save_voiceA

Save a designed voice preview (from design_voice) as a permanent, reusable voice.

Consumes one custom-voice slot on the account. After this, generate_speech(voice="") uses it.

Args: name: Handle to save under. generated_voice_id: The preview id from design_voice. description: Optional description stored on the voice.

Inputs: name (required), generated_voice_id (required), description.

search_voice_libraryA

Search ElevenLabs' shared Voice Library — thousands of ready-made voices.

This is how you pick a voice instead of dialing one out of parameters: search for "warm narrator", "raspy villain", "friendly host", filter by age/gender/accent, then add the one you like with add_library_voice(...) and use it by name in generate_speech.

Keep query SHORT — one or two words ("narrator", "villain", "host"). Long sentences over-match and return almost nothing; lean on the label filters to narrow instead.

Args: query: Short free-text term ("narrator", "host", "villain"). One or two words. gender / age / accent: Label filters (e.g. age="old", gender="male"). use_case: e.g. "characters_animation", "narrative_story", "video_games". category: "professional", "famous", or "high_quality". descriptives: Extra descriptive terms (e.g. ["raspy", "gruff"]). page_size: Max results (1-100, default 20).

Returns: {"voices": [{public_owner_id, voice_id, name, description, gender, age, accent, preview_url, ...}], "count": N}. Pass public_owner_id + voice_id to add_library_voice.

Inputs: age, query, accent, gender, +4 more.

speakA

Speak a line as a saved SPEAKER, optionally in a MOOD.

Resolves the speaker (voice + base delivery), layers a mood profile if given, then applies any per-line overrides. Returns a job_id like generate_speech (or job_ids if variants > 1).

Args: speaker: A saved speaker name (see list_speakers). text: The line (v3 audio tags work). mood: Optional profile name (built-in like "angry"/"whisper", or a saved one) to layer over the speaker's base delivery for this one line. workspace: Which workspace's speaker (default "default"). stability / style / speed / seed: Per-line overrides (win over speaker + mood). with_timestamps: Also emit an alignment sidecar (lip-sync/captions). variants: Generate N takes (2-8) to preview and pick the best. engine / format: as generate_speech.

Inputs: text (required), speaker (required), mood, seed, +9 more.

transcribeA

Transcribe speech to text (ElevenLabs Scribe) — for podcasts, meetings, captions, dubbing prep.

Args: audio: A local audio/video file path, OR a URL (hosted file, YouTube, TikTok). language: ISO code (639-1 or -3) to force; omit to auto-detect. diarize: True to label speakers (who said what). captions: "srt" or "vtt" to also write a subtitle file (from word timings) and return its path.

Returns: {"text", "language_code", "words": , "captions_path"?} or {"error"}.

Inputs: audio (required), diarize, captions, language.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 33 tools

    Disambiguation2/5

    Several voice-related tools have overlapping responsibilities, such as preview_voices vs search_voice_library and add_speaker_from_library vs add_library_voice. These overlaps create ambiguous boundaries, even with detailed descriptions, making it hard for an agent to pick the correct tool confidently.

    Naming Consistency4/5

    The majority of tools follow a clear verb_noun pattern (generate_*, list_*, save_*, delete_*). Minor deviations include standalone verbs like 'speak' and 'transcribe', plus noun-based names like 'account_status' and 'forced_alignment', but the overall style is recognizable and mostly consistent.

    Tool Count2/5

    With 33 tools, the server feels overloaded. Many are small variations on voice management (add, save, list, preview, search, clone, delete), inflating the count well beyond the typical 3-15 tool range for a focused server.

    Completeness4/5

    The domain is broad and well covered: music and speech generation, voice cloning/design/library management, speech customization (profiles, speakers, pronunciation), transcription, forced alignment, noise isolation, voice conversion, and job tracking. Minor gaps include no delete for speakers/profiles, but these can be worked around by overwriting.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers