Ofaudio
БесплатноНе проверенAn agent-first MCP server for generating and transforming audio (music, speech, sound effects) via ElevenLabs and Mureka, providing tools for transcription, voi
Описание
An agent-first MCP server for generating and transforming audio (music, speech, sound effects) via ElevenLabs and Mureka, providing tools for transcription, voice cloning, and multi-speaker dialogue.
README
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+.
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_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
| 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?, model?, stability?, style?, speed?, similarity_boost?, use_speaker_boost?, seed?, previous_text?, next_text?, language_code?, with_timestamps?, variants?, engine?, format?) |
Dialogue / character VO. 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 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) |
list_profiles() |
Built-in delivery presets (neutral, narrator, calm, whisper, sad, angry, excited, shout, steady, dynamic) + your saved ones |
save_speaker(name, voice, workspace?, model?, stability?, …, seed?, description?) |
Save a speaker (pinned voice + base delivery) under a workspace |
speak(speaker, text, mood?, workspace?, …, with_timestamps?, variants?) |
Speak as a saved speaker, layering a mood profile → {job_id} |
preview_voices(query?, gender?, age?, accent?, use_case?, n?) |
Search the library, return candidates with preview_urls — no generation, no slots |
add_speaker_from_library(name, public_owner_id, voice_id, workspace?, seed?) |
Add a library voice and save it as a speaker in one step |
list_speakers(workspace?) / list_workspaces() |
Saved speakers (optionally by workspace) / workspace namespaces |
search_voice_library(query?, gender?, age?, accent?, use_case?, category?, descriptives?, page_size?) |
Search ElevenLabs' shared library of thousands of voices |
add_library_voice(public_owner_id, voice_id, name) |
Add a library voice to the account and save it under name (uses a voice slot) |
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/speak pronunciation= or save_speaker(pronunciation=) |
add_pronunciation_rules(dictionary, rules) / list_pronunciation_dictionaries() |
Extend / list saved dictionaries |
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: voices, music identities, profiles, speakers, pronunciation |
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:
- 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. - Design a custom one —
design_voice("warm, measured audiobook narrator, clear articulation", save_as="narrator"). Describe it, audition the previews, keep the best. - 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 speak("narrator", text, mood="calm", workspace="projectA") speaks it — the mood
layers over the speaker (a speaker is who; a profile is what mood). preview_voices(query)
samples library candidates by preview (no slots), and add_speaker_from_library(...) adds + saves in
one step. variants=N on speak/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 numericstyleslider. 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/dynamicprofiles.
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.
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.
Установка Ofaudio
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/DuragonYama/ofaudio-mcpFAQ
Ofaudio MCP бесплатный?
Да, Ofaudio MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Ofaudio?
Нет, Ofaudio работает без API-ключей и переменных окружения.
Ofaudio — hosted или self-hosted?
Доступен hosted-вариант: Unyly запускает сервер в облаке, локальная установка не обязательна.
Как установить Ofaudio в Claude Desktop, Claude Code или Cursor?
Открой Ofaudio на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
ARA
Generate images, video and audio from any AI agent — one connector.
автор: ARAOmni Video
An MCP server that transforms LLM-enabled IDEs into professional video editors by pre-processing footage into text proxies, generating motion graphics via HTML/
автор: buildwithtazaYouTube
Transcripts, channel stats, search
автор: YouTubeEverArt
AI image generation using various models.
автор: modelcontextprotocolCompare Ofaudio with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории media
