Voice & Audio
Text to speech, podcasts, and voice selection — ListenHub and ElevenLabs.
Turn text into spoken audio: single-voice narration, or a two-host podcast. Two providers cover different strengths.
What you can do
- Narrate text in one voice (text-to-speech) — Chinese voices via ListenHub, or 29 languages with fine control via ElevenLabs.
- Produce a two-host podcast — ListenHub generates script + audio with one or two speakers (unique to ListenHub).
- Pick from a voice library — browse available voices/speakers and choose by language, gender, and style.
- Control delivery (ElevenLabs) — emotion, pacing, and pauses via voice settings and inline tags.
Choosing a provider
ListenHub (listenhub_*) | ElevenLabs (elevenlabs_*) | |
|---|---|---|
| Best at | Chinese voices, multi-host podcasts | 29 languages, single-voice expressiveness |
| Speakers per clip | 1–2 (podcast) | 1 |
| Fine voice control | — | stability / similarity / style / speed |
| Emotion & pauses | — | <break> + tags like [laughs] (with eleven_v3) |
Rule of thumb: Chinese, or a multi-host podcast → ListenHub. English/other languages, or when you need emotion, pacing, and pauses → ElevenLabs.
ListenHub tools
| Tool | What it does | Key inputs |
|---|---|---|
listenhub_get_speakers | List available speakers (with previews) | language (zh default / en) |
listenhub_create_flowspeech | Text or URL → single-voice narration | sourceType (text/url), sourceContent, speakerId, mode (smart/direct) |
listenhub_create_podcast | Text or URL → 1–2 host podcast (script + audio) | query or sources, speakers (1–2), mode (quick/deep/debate) |
listenhub_create_podcast_text_only | Generate the script only — review before audio | same, plus language |
listenhub_generate_podcast_audio | Turn an (edited) script into audio | episodeId, customScripts (optional edits) |
listenhub_get_podcast_status / listenhub_get_flowspeech_status | Check a job's status | episodeId |
listenhub_get_user_subscription | Check your quota | — |
The create_* tools return the finished audio — they wait until generation completes, so you don't poll. Use the *_status tools only to re-check after an exception, or to look up an earlier episode.
For speakerId, you can pass the speaker's name directly (from listenhub_get_speakers) — it's resolved for you.
ElevenLabs tools
| Tool | What it does | Key inputs |
|---|---|---|
elevenlabs_search_voices | Browse available voices | — |
elevenlabs_text_to_speech | Text → speech in a chosen voice | text, voice_id, model_id, voice_settings, output_format |
elevenlabs_list_models | List TTS models | — |
elevenlabs_check_subscription | Check your quota | — |
voice_id must be the exact ID returned by elevenlabs_search_voices — not a human name.
model_id options: eleven_multilingual_v2 (default, 29 languages), eleven_v3 (best for emotion tags), eleven_turbo_v2_5 / eleven_flash_v2_5 (low latency).
voice_settings (optional, fine-tuning): stability (0–1, lower = more expressive), similarity_boost (0–1), style (0–1), speed (0.7–1.2).
Using it in a Skill
- Look up a voice first. Call
listenhub_get_speakersorelevenlabs_search_voices, then pass the ID. Don't make the user guess a voice name. - Don't write a polling loop. ListenHub
create_*tools already wait until done. Telling the agent to "check status every few seconds" is an anti-pattern. - Inline markup is ElevenLabs-only. Put it directly in
text: pausesHello.<break time="1.5s"/>World.; emotion/sfx[laughs][whispers](pair withmodel_id: "eleven_v3"). ListenHub voices read these literally — don't insert them there. - Batch narration in one call. For many sentences, request them together in a single call to keep the audio continuous, rather than one call per sentence.
Example prose for a SKILL.md:
For expressive English narration, use elevenlabs_text_to_speech. First call
elevenlabs_search_voices to choose a voice_id matching the tone. For emotional
delivery, set model_id to "eleven_v3" and embed tags like [laughs] or
<break time="1s"/> directly in the text.