Skip to content
Back to skills

Soundbox Voice Story

ASecurity

Write, voice and arrange spoken audio locally through the Soundbox MCP server — one-off narration with soundbox.speak, or a persistent multi-track "story" (create_story / add_lines / speak_story / export_story). Use whenever the user wants dialogue, narration, a voiceover, a scripted scene, a podcast segment, character lines for a game, or asks to "read this aloud", "make a voiceover", "write a scene with two characters". Produces WAV files on disk with absolute paths.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 20, 2026
ai-agentsapiperformance

Works with

  • cli
  • api
  • mcp

Security analysis

A100/100

Scanned October 20, 2026

npx -y skills add Gadurp1/soundbox --skill soundbox-voice-story --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Soundbox Voice Story?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Soundbox Voice Story
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/gadurp1-soundbox-voice-story/badge)](https://www.skillsdirectory.com/skills/gadurp1-soundbox-voice-story)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: soundbox-voice-story
description: Write, voice and arrange spoken audio locally through the Soundbox MCP server — one-off narration with soundbox.speak, or a persistent multi-track "story" (create_story / add_lines / speak_story / export_story). Use whenever the user wants dialogue, narration, a voiceover, a scripted scene, a podcast segment, character lines for a game, or asks to "read this aloud", "make a voiceover", "write a scene with two characters". Produces WAV files on disk with absolute paths.
---

# Soundbox: speech, scripts and stories

Soundbox runs text-to-speech models on the user's machine and exposes them over
MCP. No API key; their hardware does the work. Every result is a WAV on disk and
the response gives you its absolute `path`.

This is the *spoken* half of Soundbox. `soundbox.generate` makes sound effects
and music and will not say words — asking it for "a man saying hello" gets you a
texture. For anything with words in it, use the tools below.

## Which shape of job is this

**One read, nothing to keep** → `soundbox.speak`. A line, or several lines with
different voices for a dialogue. Comes back as one joined sound.

**Something you will revise** → a story. A story persists, every line can be
re-read on its own without touching the others, and the lines carry a place in
time so they can be arranged and mixed down. Use it for a scene, a narration
over other audio, a podcast segment, anything where the user will say "the
third line sounds wrong".

If in doubt, build a story. Re-reading one line of a story costs seconds;
re-running `soundbox.speak` on a changed script re-reads all of it.

## Tools

| Tool | Use it for |
|---|---|
| `soundbox.list_voices` | The cast. Do this first — lines need real voice ids |
| `soundbox.speak` | One-off read, no story kept |
| `soundbox.create_story` | Start a script that persists |
| `soundbox.list_stories` / `soundbox.get_story` | Find and inspect what exists |
| `soundbox.add_lines` | Append lines, pauses, or existing library sounds |
| `soundbox.update_line` | Reword, recast, or move a line in time |
| `soundbox.speak_story` | Read every line that has no audio yet. **Slow** |
| `soundbox.export_story` | Mix the arrangement down to one sound |
| `soundbox.open_in_studio` | Put an existing library sound on a timeline, split into stems |
| `soundbox.delete_line` / `soundbox.split_line` | Remove a line, or cut a voiced one in two |
| `soundbox.mix_track` | Name, mute, solo or set the level of a whole lane |
| `soundbox.remove_track` | Delete a lane and the clips on it |

## The workflow

1. `soundbox.list_voices`. Note the ids and which are `builtin` — a builtin
   belongs to one model family and fails with any other model.
2. `soundbox.create_story` with a title that says what it is.
3. `soundbox.add_lines` — the whole script in one call. Give every line a
   `speaker` even when the voice is the same; it is what makes the script
   readable back to the user.
4. `soundbox.speak_story`. This is the minutes-long step: one subprocess per
   line. Tell the user before you start.
5. `soundbox.get_story` to see what landed, then `soundbox.update_line` for
   anything wrong, then `speak_story` again — it only re-reads silent lines
   unless you pass `regenerate: true`.
6. `soundbox.export_story` when the user wants one file.

## Casting

A line with no `voice_id` uses the model's default voice, and some families
(Chatterbox and other cloning-only models) have no default at all — those lines
fail. Cast every line explicitly unless you have checked otherwise.

Two characters should get two voices. A dialogue read entirely in one voice is
the most common way this comes out wrong, and it is invisible until playback.

## Timing

Lines lay out end to end as they are voiced, which is right for dialogue and
wrong for anything overlapping. To place audio deliberately:

- `track_index` is the lane. Different lanes play at once — narration on 0,
  music bed on 1.
- `start_s` is when it starts. Omit it and the line follows whatever is already
  on its track.
- `duration_s` with `trim_start_s` shortens a clip without destroying audio, so
  a clip can always be lengthened again.
- A `kind: "pause"` line is a written beat of silence; its length is
  `duration_s`. Prefer it to padding text with full stops.

`soundbox.add_lines` also takes a `sound_id`, which drops an existing library
sound onto the timeline — a music bed under narration, or an effect from
`soundbox.generate`.

## Mixing

`soundbox.mix_track` controls a whole lane: name, mute, solo, level. These
belong to the lane, not the clips on it, so muting a track does not forget
which individual clips you had silenced. Solo beats mute — the moment anything
is soloed, only soloed lanes are heard.

Name your lanes when a story has more than one. "Track 1" tells the user
nothing; "Narration" and "Music bed" tell them what they are looking at.

`soundbox.remove_track` deletes the lane *and its clips*, and lanes above slide
down. Check `soundbox.get_story` first if you are not certain what is on it —
this is not something undo covers.

## Delivery

How a line is *performed* is a separate lever from what it says, and it is not
in the text. Writing `(whispering)` into a line makes the model say the word
"whispering" out loud. Pass `delivery` instead:

- `soundbox.create_story` — for the whole script. Usually the right place: one
  delivery throughout, exceptions on a line or two.
- `soundbox.add_lines` — per line, when you already know one line differs.
- `soundbox.update_line` — for the exception you found afterwards. `{}` puts a
  line back on the story's. Either way the line has to be re-read before the
  change is audible.

**The names differ per model family, and `soundbox.list_models` is the
authority.** A text-to-speech model returns a `delivery` list — each entry with
its range, its default, and which group it belongs to. `delivery` entries in
the `"delivery"` group change the performance; `"sampling"` and `"quality"`
change how hard the model works at it.

Two things make guessing expensive:

- **An unknown name is ignored silently.** Not an error — a setting that does
  nothing. `exaggeration` is real on Chatterbox; `emotion`, `speaking_rate` and
  `instruct` are not, and passing them looks identical to passing nothing.
- **A model with no `delivery` list has no knobs at all.** Its words and its
  voice are the only controls. Say so rather than pretending otherwise.

Worked example — Chatterbox, whose one real performance knob is `exaggeration`
(0–2, default 0.5):

```json
{ "title": "Interrogation", "delivery": { "exaggeration": "1.4" } }
```

## Getting the read right

Delivery knobs are a small lever; the words are a large one. The model reads
what you write, including punctuation, so rewrite for the ear before reaching
for settings:

- Spell out what should be spoken: "twenty sixteen", not "2016"; "THQ Nordic",
  not "THQ."
- Commas and full stops become pauses. A comma where you want a beat is more
  reliable than hoping.
- Keep a line to a sentence or two. Long paragraphs drift in delivery and cost
  you the whole line when one word is wrong.

## Reporting back

The story tools answer with a short summary — how many lines, how many are
voiced, how long it runs — and an `open_in_studio` link. Hand the user that
link. A timeline is a thing to look at, and listing its clips back at them in
chat is not the same as showing it; it is also how you fill a conversation with
JSON nobody reads.

Say what changed and give the link. "Six lines, all voiced, 41s — open it in
the studio: <link>" is the whole report. Reach for `soundbox.get_story` only
when you need the lines to reason about them.

## Say what it cost

Speaking is slow and runs on the user's GPU. Before a long `speak_story`, say
roughly how many lines are about to be read. After exporting, give the absolute
path — that is the thing they actually wanted.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.