Soundbox is a local server with a browser front end. Everything the app does goes through the HTTP API documented below, and an agent can drive the same pipeline over MCP. Every example here points at this instance, so a copied command works as-is.
1 · Check the server and see what is loaded
curl http://127.0.0.1:17494/api/health2 · Submit a generation
curl -X POST http://127.0.0.1:17494/api/generate \
-H 'Content-Type: application/json' \
-d '{"model":"audiocpp-stable-audio-3-sfx","prompt":"heavy wooden door slam, dry room","duration_s":3}'Returns { "job_id": "…" } immediately with 202. The audio does not exist yet. If the model isn't loaded, the job loads it first. That is the loading phase, and it can take a while the first time.
3 · Follow the job, then fetch the sound
# poll — done, error or cancelled ends it
curl "http://127.0.0.1:17494/api/jobs/$JOB_ID"
# …or stream every change as server-sent events
curl -N -H 'Accept: text/event-stream' "http://127.0.0.1:17494/api/jobs/$JOB_ID/events"
# on "status":"done", result.sounds holds the new ids
curl "http://127.0.0.1:17494/api/sounds/$SOUND_ID"The Sound you get back has a file field like /files/<id>.wav. Fetch that from this same origin to get the audio, or add ?format=mp3 to have it transcoded.
Describe the physical sound. “Scary sound” produces noise; “low metallic groan of a ship's hull under pressure, distant, reverberant” produces something usable. Short clips layered in an editor work better than one long generation.
http://127.0.0.1:17494/mcp. There is no second daemon to start, but this app must be running for any of it to work.Before connecting a client, install at least one model on the Models page. An agent calling soundbox.generate with nothing installed gets an error telling the user to go there.
claude mcp add --transport http soundbox http://127.0.0.1:17494/mcp--scope user to make it available in every project instead of only this one.claude, then type /mcp. Soundbox should be listed as connected, with its 21 tools.soundbox.generate; approve it, and the reply comes back with a file path.claude mcp list shows what is registered and whether it connects. claude mcp remove soundbox undoes step 2.
Make a sound effect and find it again. Every sound-shaped result carries an absolute path to a WAV on this machine, so the agent can use its ordinary file tools from there.
soundbox.generateblocksRenders one or more sounds from a text description and saves them to the library. Blocks until the audio is on disk.
Arguments
soundbox.enhance_promptTurns a vague prompt (“scary sound”) into a concrete one, optionally several. Requires the local prompt assistant to be enabled; if it is off, the tool says so.
Arguments
soundbox.list_modelsAvailable models with status and licence. Also lists each speech model's delivery options. A misspelled option is ignored silently, with no error.
No arguments.
soundbox.list_soundsSearch what has already been made. Call it before generating; the sound may already exist.
Arguments
soundbox.get_soundFetch a single sound by id, including its absolute file path.
Arguments
soundbox.separateblocksSplits a sound into vocals, drums, bass and other, each saved as its own sound with its own path. You can keep some and merge the rest back into one sound: the original minus the stems you kept.
Arguments
soundbox.delete_sounddeletesPermanently deletes a sound and its audio file.
Arguments
Spoken words take a separate path: soundbox.generate will not say them. speak is the one-off read. Put anything you want to keep and rework in a story.
soundbox.list_voicesThe voices a script can be read in. Call it before writing one, so lines can be cast to real voice ids.
No arguments.
soundbox.speakblocksReads text aloud in a saved voice and saves it to the library. Pass one line, or several with different voices. Blocks until the audio is on disk.
Arguments
A story is a script that persists. Each line has a position in time, can be re-read on its own, and persists after the conversation that made it.
soundbox.create_storyCreates the empty script everything else in this group operates on.
Arguments
soundbox.list_storiesExisting stories, most recently worked on first.
Arguments
soundbox.get_storyReturns the whole script line by line: text, voice, timing, and whether each line has been voiced yet. Use it to inspect what the agent built.
Arguments
soundbox.add_linesAppends spoken lines, pauses, or existing library sounds to the script. Add many at once; give a line its own delivery if it should be read differently.
Arguments
soundbox.update_lineChanges a line's words, voice, delivery, or where it sits in time. Changing words or delivery means the line has to be re-read before it is heard.
Arguments
soundbox.speak_storyblocksReads every line that has no audio yet, in its assigned voice, one at a time. This is the slowest tool.
Arguments
soundbox.delete_linedeletesRemoves one line from a story. Its audio stays in the library.
Arguments
soundbox.split_lineCuts a voiced line at a point in its own audio, giving two clips. The words stay with the first half, because Soundbox cannot tell which words fell on either side of the cut.
Arguments
soundbox.export_storyblocksMixes the whole arrangement to one sound, honouring where each clip sits, its trim, its gain, and whether it is muted.
Arguments
The timeline underneath a story: which lane a clip is on, how loud it is, and what the studio shows when you open it.
soundbox.open_in_studioLays a library sound out on a timeline, split into stems on separate tracks where that is possible. If the sound already has stems, it reuses them.
Arguments
soundbox.mix_trackControls one lane of a story. These settings belong to the lane; the clips on it keep their own.
Arguments
soundbox.remove_trackdeletesDeletes a lane and the clips on it; lanes above slide down. Call soundbox.get_story first if you are not certain what is on it.
Arguments
What a sound looks like coming back
{
"id": "987a0eae-6c0e-45e8-b777-81cfe4d15af3",
"name": "Door slam 01",
"path": "C:\\Users\\you\\.soundbox\\sounds\\987a0eae-….wav",
"url": "/files/987a0eae-6c0e-45e8-b777-81cfe4d15af3.wav",
"model": "stable-audio-open-small",
"prompt": "heavy wooden door slam, dry room",
"duration_s": 3.0,
"sample_rate": 44100,
"channels": 2,
"seed": 752071476,
"tags": ["door", "impact"]
}Every sound-shaped result carries path: an absolute filesystem path to the WAV on this machine. The agent can hand it straight to ffmpeg, copy it into a game project's assets folder, or attach it, without knowing anything about the Soundbox server or its HTTP port.
Generation is serialised (one GPU, one job at a time), so five parallel soundbox.generate calls queue and run one after another. Use variations for several takes of one idea. If no model is installed, generate returns an actionable error naming the Models screen: surface it, do not retry.
You
“Make me a door slam for my game: heavy wooden door, stone corridor. Put it in assets/audio/ as a 48k mono wav.”
Agent
Checks the library first, finds nothing close, and calls the generate tool. It writes a physical description of material, action and space instead of repeating your words back.
Tool call
soundbox.generate({
"prompt": "heavy wooden door slamming shut in a stone corridor, hard impact, long tail",
"duration_s": 3,
"variations": 2,
"tags": ["door", "impact", "game"]
})Tool result
{
"sounds": [
{
"id": "987a0eae-6c0e-45e8-b777-81cfe4d15af3",
"name": "Door slam 01",
"path": "C:\\Users\\you\\.soundbox\\sounds\\987a0eae-….wav",
"url": "/files/987a0eae-6c0e-45e8-b777-81cfe4d15af3.wav",
"duration_s": 3.0,
"sample_rate": 44100,
"channels": 2,
"seed": 752071476
},
{ "id": "b1f4…", "name": "Door slam 02", "path": "C:\\Users\\you\\.soundbox\\sounds\\b1f4….wav" }
],
"model": "stable-audio-open-small",
"elapsed_s": 4.71
}Agent
The path is absolute, so the next step is ordinary file work, with no HTTP and no knowledge of the Soundbox port. It converts to the format the project wants and drops it in:
ffmpeg -i "C:/Users/you/.soundbox/sounds/987a0eae-….wav" \
-ac 1 -ar 48000 assets/audio/door_slam.wavThen it plays both takes back to you by path, or keeps the one whose seed it can reuse later for a matching variant. The sounds are also in the Library here, so you can audition them without leaving the conversation.
The agent needed no Soundbox-specific code: it called a tool, got JSON with a path, and used its normal file tools. A URL relative to the Soundbox server would have made this turn three steps longer.
curl http://127.0.0.1:17494/api/health405 or 400 means the endpoint is there and speaking MCP, 404 means it is not mounted, and connection-refused means the port is wrong.curl -i http://127.0.0.1:17494/mcpnpx @modelcontextprotocol/inspectorIn the Inspector, pick transport Streamable HTTP and URL http://127.0.0.1:17494/mcp, then Connect → List Tools. You should see all 21 tools; run soundbox.list_models as the cheapest end-to-end check, since it needs no GPU.
0.0.0.0 and connect by LAN address or container name. Set SOUNDBOX_ALLOWED_HOSTS to a comma-separated list of the hosts you use./mcp, not /api/mcp. Clients that do not follow 307 redirects on POST fail in a confusing way otherwise.SOUNDBOX_URL in the client's env block (http://127.0.0.1:17494 for this instance).GET /api/logs?lines=200 returns the same thing as JSON.Read the full API reference for every route with its method, purpose and key fields. It is kept in the repository as docs/API.md beside the code it describes. Mutating requests need a JSON body or an X-Soundbox header; see the reference for why.