Skip to main content
Glama

Doseedo: Film Scoring, AI Instruments, Sound Effects & Stems

Render a whole score

doseedo_render_score

Plays a whole arrangement you wrote in one call — film scoring, orchestral arrangement, background music, a song or instrumental (a film cue, a string quartet, a big-band chart): each part played by its doseedo instrument, one stem per part from bar 1 at your tempo, plus a summed mix. Input ONE of: parts[] ({name, instrument, timbre_preset?, lora_id?, players?, notes[]} — doseedo_instruments calls), midi_url (multi-track SMF), or musicxml_url (notation played as marked, at concert pitch). A file's parts are matched by name, then GM program; name any part with instruments {"": {instrument, timbre_preset?, players?}}. A chord on a one-line instrument is split into voices (one stem each). ★ SECTIONS: an instrument is ONE player; give a part players: N (2–8) and its line is played by N different players, summed into ONE section stem — an orchestra = violins I / II, violas, cellos, basses as five parts with players 6 / 6 / 4 / 4 / 3, horns 2–4 in unison; a choir = S/A/T/B parts on "choir" (Carmen, "choir:hp", "choir:m2" or YOUR singer: parts[].timbre_audio_url), which SINGS parts[].lyrics ("Ooh" without), players 4–8 (recipe "choir"); a solo: no players. The WHOLE orchestra in one call: ≤ 32 lines and ≤ 96 player rows (players: N = N rows), any instruments together, ≤ 600 s. Drums: the drum model is a real kit, drum_engine "oneshot" a drum machine. Synth parts: doseedo_render_midi. Timing: bpm and/or tempo_map ([{beat, bpm}]; doseedo_tempo_map lands film hits on downbeats). Result: parts[{name, instrument, url, fit, timbre, lora, players}] — fit.verdict / coverage = did it PLAY its notes (a failed part is re-rolled once; fit.rolls.missed = a roll not played as one), lora.applied = its adapter played — plus mix_url. Next: doseedo_mix {from_job}, then doseedo_session_from_stems {from_job, mix_job}. Async: job_id → doseedo_wait_task (~1–4 min). Cancel: a render that has not reached the GPU yet is stopped and its credits refunded; one already rendering finishes on the GPU (its credits are spent), the job ends as canceled and the output is discarded.

Input Schema

NameRequiredDescriptionDefault
bpmNoTempo of the parts (10–400). Required with parts[] unless tempo_map is given; on a file it sets the speed and keeps the score's fermatas / rit. / tempo changes.
mixNoAlso bounce a summed mix of the stems (default true).
nameNoOptional: a name for this job's files, e.g. "rainy-loop-3". Every file it returns downloads as <name>_<part>.<ext> (rainy-loop-3_Celesta.wav, rainy-loop-3_rough-mix.wav; one take: rainy-loop-3.wav), so the user can find them. Give each job its own name (a second take: "rainy-loop-3b"). Default: doseedo-<last 6 characters of the job id>.
seedNoRandom seed (reuse to re-render close to the same performance).
tuneNoLight intonation on every winds / brass / strings part (default true): held, clearly pitched notes the model rendered 15–85 cents off are moved toward their written pitch, to a small natural residual — attacks, vibrato and fast notes as played. Receipt: parts[].tune. false = every part as rendered (or parts[].tune false for one).
partsNoThe parts you wrote: [{name?, instrument, timbre_preset?, lora_id?, players?, lyrics?, notes:[{pitch, start_beats, duration_beats, velocity?, lyric?}], dynamics?}] — beats from bar 1, concert pitch. lyrics / lyric: a choir part's words. instrument/timbre_preset = a doseedo_instruments call. players = how many play the line: 1 (default) a soloist, 2–8 a SECTION (e.g. Violins I players 6).
vaefixNoVAE spectral corrector on every winds / brass / strings part (default true): the decoder's low-mid fog under each instrument's register is trimmed, mic hiss removed only where present. Receipt: parts[].vaefix. false = every decode as rendered (or parts[].vaefix false for one).
midi_urlNoAlternative to parts: a multi-track Standard MIDI File (≤ 2 MiB) — a doseedo result link or a public https URL. Channel 10 = drums: the kit, or the one percussion instrument a part is named for (Bass Drum, Cymbals, Bass Drum & Cymbals, Triangle…). A track's CC11 lane (CC1 on a wind / brass / string / bass part) is its written dynamics: a held note swells as it says.
score_keyNoAlternative to parts: a score file on YOUR machine — doseedo_get_upload_url {filename: "cue.mid" | "cue.musicxml" | "cue.mscz"} → PUT the file → its score_key (kept 24 h). A big score sent as a file, not as notes in this call.
score_urlNoAlternative to parts: a score file URL — MIDI, MusicXML or a MuseScore .mscz / .mscx, told apart by its content.
tempo_mapNoTempo changes [{beat, bpm}] (first point at beat 0). Overrides a file's own tempo.
instrumentsNoName the instrument for any part: {"Violin I": {"instrument": "violin", "players": 6}, "2": {"instrument": "acoustic_guitar", "timbre_preset": "koto:preset1"}, "Choir": {"instrument": "choir", "players": 6, "lyrics": "Glo-ri-a"}} — key = the part name or its 0-based index; players makes a MIDI / MusicXML part a section, lyrics gives a sung part its words (as parts[].lyrics), timbre_audio_url / timbre_audio_urls its own singer or sound (as parts[]: {"Soprano": {"timbre_audio_url": "https://…/singer.wav"}}), drum_engine "oneshot" (+ drum_genre) plays a file's drum part on a one-shot kit ({"Drums": {"drum_engine": "oneshot"}} — no instrument keeps the part's own). Wins over the name/program match.
musicxml_urlNoAlternative to parts: a MusicXML score (.musicxml / .xml / .mxl, ≤ 8 MiB) exported from Dorico, Sibelius, Finale, MuseScore, or written by you — or a MuseScore file itself (.mscz / .mscx), read with all its markings.
time_signatureNoMeter, e.g. "4/4" (default, or the file's).
idempotency_keyNoOptional. Any unique string for THIS request (e.g. a UUID). Re-sending the same call with the same key after a timeout returns the same job instead of starting a second one.
duration_secondsNoRender length (default: the last note + 2 s; ≤ 600).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / parts / items / properties / drum_engine / description
      Previous value: -"A drum / percussion part: \"model\" (default) = the drum model — a drummer playing the kit in a room (cymbals ring, hits vary, ghost notes speak): the sound for any acoustic kit, rock to jazz to a film cue. A take may drop or add a hit (parts[].fit.voices: missing / extra): render the part again for another take. \"oneshot\" = a one-shot kit generated for drum_genre, one sample per drum: every written hit lands exactly as written (a half-time bar stays half-time, a stop-time hit stays a hit), but it sounds programmed — the kit for electronic / drum-machine genres only (house, trap, 808). An acoustic kit (drum_kit: rock, punk, jazz, soul, a band seen playing) stays on the model, never oneshot: a take that drops a hit is rendered again. Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81."New value: +"A drum / percussion part: \"model\" (default) = the drum model — a drummer playing the kit in a room (cymbals ring, hits vary, ghost notes speak): the sound for any acoustic kit, rock to jazz to a film cue. A take may drop or add a hit (parts[].fit.voices: missing / extra): render the part again for another take. \"oneshot\" = a one-shot kit generated for drum_genre, one sample per drum: every written hit lands exactly as written (a half-time bar stays half-time, a stop-time hit stays a hit), but it sounds programmed — the kit for electronic / drum-machine genres only (house, trap, 808). An acoustic kit (drum_kit: rock, punk, jazz, soul, a band seen playing) stays on the model, never oneshot — and a kit whose drum_genre is real drums (funk, boom bap, lo-fi, breakbeat: a sampled break is a drummer; its dust comes from the mix, doseedo_mix style \"1990s-hiphop\" / \"lofi-hiphop\") plays on drum_kit whatever is asked (warnings say so). A take that drops a hit is rendered again. Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81."
    • changedInput schema / properties / parts / items / properties / drum_genre / description
      Previous value: -"With drum_engine \"oneshot\": the kit's genre / words, e.g. \"house\", \"techno\", \"trap\", \"synthwave\": a dry drum-machine kit. Default: the instrument."New value: +"With drum_engine \"oneshot\": the kit's genre / words, e.g. \"house\", \"techno\", \"trap\", \"synthwave\": a dry drum-machine kit. A real-drums genre (\"boom bap\", \"lo-fi\", \"breakbeat\", \"funk\") puts the part on the drum model's drum_kit. Default: the instrument."
  2. Changed1 schema field changed
    • changedInput schema / properties / parts / items / properties / timbre_audio_url / description
      Previous value: -"This part's OWN timbre: a recording of the singer (a choir part) or sound it should take on — an https URL, or the audio_key doseedo_get_upload_url returned for a file on your machine. The first 30 s are used; a clean solo take of the voice, 10–30 s, works best. Wins over the preset's voice; a choir part keeps the choir's adapter and sings in THIS voice. receipt: parts[].timbre."New value: +"This part's OWN timbre: a recording of the singer (a choir part) or sound it should take on (a drum part too: a kit, a ride or a snare recording on the drum model — not drum_engine \"oneshot\" or a sampled instrument, which play their own samples) — an https URL, or the audio_key doseedo_get_upload_url returned for a file on your machine. The first 30 s are used; a clean solo take of the voice, 10–30 s, works best. Wins over the preset's voice; a choir part keeps the choir's adapter and sings in THIS voice. receipt: parts[].timbre."
  3. Changed2 schema fields changed
    • changedInput schema / properties / parts / items / properties / drum_engine / description
      Previous value: -"A drum / percussion part: \"model\" (default) = the drum model — a drummer playing the kit in a room (cymbals ring, hits vary, ghost notes speak): the sound for any acoustic kit, rock to jazz to a film cue. A take may drop or add a hit (parts[].fit.voices: missing / extra): render the part again for another take. \"oneshot\" = a one-shot kit generated for drum_genre, one sample per drum: every written hit lands exactly as written (a half-time bar stays half-time, a stop-time hit stays a hit), but it sounds programmed — the kit for electronic / drum-machine genres (house, trap, 808), or the fallback for an acoustic part whose takes keep losing a hit that must land. Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81."New value: +"A drum / percussion part: \"model\" (default) = the drum model — a drummer playing the kit in a room (cymbals ring, hits vary, ghost notes speak): the sound for any acoustic kit, rock to jazz to a film cue. A take may drop or add a hit (parts[].fit.voices: missing / extra): render the part again for another take. \"oneshot\" = a one-shot kit generated for drum_genre, one sample per drum: every written hit lands exactly as written (a half-time bar stays half-time, a stop-time hit stays a hit), but it sounds programmed — the kit for electronic / drum-machine genres only (house, trap, 808). An acoustic kit (drum_kit: rock, punk, jazz, soul, a band seen playing) stays on the model, never oneshot: a take that drops a hit is rendered again. Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81."
    • changedInput schema / properties / parts / items / properties / drum_genre / description
      Previous value: -"With drum_engine \"oneshot\": the kit's genre / words, e.g. \"country rock, acoustic kit\", \"jazz brushes\", \"house\", \"trap\". An acoustic genre gets an acoustic kit in a small room; an electronic one a dry drum-machine kit. Default: the instrument."New value: +"With drum_engine \"oneshot\": the kit's genre / words, e.g. \"house\", \"techno\", \"trap\", \"synthwave\": a dry drum-machine kit. Default: the instrument."
  4. Changed1 schema field changed
    • changedInput schema / properties / parts / items / properties / drum_engine / description
      Previous value: -"A drum / percussion part: \"oneshot\" = played through a one-shot kit generated for drum_genre — every written hit lands exactly as written (a half-time bar stays half-time, a stop-time hit stays a hit); \"model\" (default) = the drum model, a live performance that may drop or add hits (check parts[].fit.voices: missing / extra). Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81."New value: +"A drum / percussion part: \"model\" (default) = the drum model — a drummer playing the kit in a room (cymbals ring, hits vary, ghost notes speak): the sound for any acoustic kit, rock to jazz to a film cue. A take may drop or add a hit (parts[].fit.voices: missing / extra): render the part again for another take. \"oneshot\" = a one-shot kit generated for drum_genre, one sample per drum: every written hit lands exactly as written (a half-time bar stays half-time, a stop-time hit stays a hit), but it sounds programmed — the kit for electronic / drum-machine genres (house, trap, 808), or the fallback for an acoustic part whose takes keep losing a hit that must land. Its pads (GM): kick 35/36, snare 38/40, rim 37, clap 39, hats 42/44/46, toms 41–50, crash 49/57, ride 51/59, tambourine 54, cowbell 56, bongos 60/61, congas 62–64, shaker 69/70/82, guiro 73/74, claves 75, woodblock 76/77, triangle 80/81."
  5. Changed1 schema field changed
    • addedInput schema / properties / name
      Added value: +{
      +  "description": "Optional: a name for this job's files, e.g. \"rainy-loop-3\". Every file it returns downloads as <name>_<part>.<ext> (rainy-loop-3_Celesta.wav, rainy-loop-3_rough-mix.wav; one take: rainy-loop-3.wav), so the user can find them. Give each job its own name (a second take: \"rainy-loop-3b\"). Default: doseedo-<last 6 characters of the job id>.",
      +  "maxLength": 80,
      +  "type": "string"
      +}
  6. Changed3 schema fields changed
    • changedInput schema / properties / instruments / description
      Previous value: -"Name the instrument for any part: {\"Violin I\": {\"instrument\": \"violin\", \"players\": 6}, \"2\": {\"instrument\": \"acoustic_guitar\", \"timbre_preset\": \"koto:preset1\"}, \"Choir\": {\"instrument\": \"choir\", \"players\": 6, \"lyrics\": \"Glo-ri-a\"}} — key = the part name or its 0-based index; players makes a MIDI / MusicXML part a section, lyrics gives a sung part its words (as parts[].lyrics), drum_engine \"oneshot\" (+ drum_genre) plays a file's drum part on a one-shot kit ({\"Drums\": {\"drum_engine\": \"oneshot\"}} — no instrument keeps the part's own). Wins over the name/program match."New value: +"Name the instrument for any part: {\"Violin I\": {\"instrument\": \"violin\", \"players\": 6}, \"2\": {\"instrument\": \"acoustic_guitar\", \"timbre_preset\": \"koto:preset1\"}, \"Choir\": {\"instrument\": \"choir\", \"players\": 6, \"lyrics\": \"Glo-ri-a\"}} — key = the part name or its 0-based index; players makes a MIDI / MusicXML part a section, lyrics gives a sung part its words (as parts[].lyrics), timbre_audio_url / timbre_audio_urls its own singer or sound (as parts[]: {\"Soprano\": {\"timbre_audio_url\": \"https://…/singer.wav\"}}), drum_engine \"oneshot\" (+ drum_genre) plays a file's drum part on a one-shot kit ({\"Drums\": {\"drum_engine\": \"oneshot\"}} — no instrument keeps the part's own). Wins over the name/program match."
    • addedInput schema / properties / parts / items / properties / timbre_audio_url
      Added value: +{
      +  "description": "This part's OWN timbre: a recording of the singer (a choir part) or sound it should take on — an https URL, or the audio_key doseedo_get_upload_url returned for a file on your machine. The first 30 s are used; a clean solo take of the voice, 10–30 s, works best. Wins over the preset's voice; a choir part keeps the choir's adapter and sings in THIS voice. receipt: parts[].timbre.",
      +  "type": "string"
      +}
    • addedInput schema / properties / parts / items / properties / timbre_audio_urls
      Added value: +{
      +  "description": "Several recordings (≤ 6): a section's players (players: N) and a split chord's voices take them in turn — a choir section of several singers of your own.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  7. Changed1 schema field changed
    • changedInput schema / properties / parts / items / properties / lyrics / description
      Previous value: -"A SUNG part (instrument \"choir\"): the words it sings, ONE SYLLABLE PER NOTE in time order — a chord's notes share an onset, so every voice sings that syllable. Hyphens split a word's syllables (\"Glo-ri-a in ex-cel-sis De-o\"), \"_\" alone holds the previous syllable over the next note (a melisma), one word (\"Ah\", \"Mm\") is sung on every note. Omit = \"Ooh\" on every note. notes[].lyric places syllables one by one instead (it wins). Other instruments ignore it."New value: +"A SUNG part (instrument \"choir\"): the words it sings, ONE SYLLABLE PER NOTE in time order, a new line per sung phrase — a chord's notes share an onset, so every voice sings that syllable. Hyphens split a word's syllables (\"Glo-ri-a in ex-cel-sis De-o\"), \"_\" alone holds the previous syllable over the next note (a melisma), one word (\"Ah\", \"Mm\") is sung on every note. Omit = \"Ooh\" on every note. notes[].lyric places syllables one by one instead (it wins). Other instruments ignore it."
  8. Changed5 schema fields changed
    • changedInput schema / properties / instruments / description
      Previous value: -"Name the instrument for any part: {\"Violin I\": {\"instrument\": \"violin\", \"players\": 6}, \"2\": {\"instrument\": \"acoustic_guitar\", \"timbre_preset\": \"koto:preset1\"}} — key = the part name or its 0-based index; players makes a MIDI / MusicXML part a section, drum_engine \"oneshot\" (+ drum_genre) plays a file's drum part on a one-shot kit ({\"Drums\": {\"drum_engine\": \"oneshot\"}} — no instrument keeps the part's own). Wins over the name/program match."New value: +"Name the instrument for any part: {\"Violin I\": {\"instrument\": \"violin\", \"players\": 6}, \"2\": {\"instrument\": \"acoustic_guitar\", \"timbre_preset\": \"koto:preset1\"}, \"Choir\": {\"instrument\": \"choir\", \"players\": 6, \"lyrics\": \"Glo-ri-a\"}} — key = the part name or its 0-based index; players makes a MIDI / MusicXML part a section, lyrics gives a sung part its words (as parts[].lyrics), drum_engine \"oneshot\" (+ drum_genre) plays a file's drum part on a one-shot kit ({\"Drums\": {\"drum_engine\": \"oneshot\"}} — no instrument keeps the part's own). Wins over the name/program match."
    • changedInput schema / properties / parts / description
      Previous value: -"The parts you wrote: [{name?, instrument, timbre_preset?, lora_id?, players?, notes:[{pitch, start_beats, duration_beats, velocity?}], dynamics?}] — beats from bar 1, concert pitch. instrument/timbre_preset = a doseedo_instruments call. players = how many play the line: 1 (default) a soloist, 2–8 a SECTION (e.g. Violins I players 6)."New value: +"The parts you wrote: [{name?, instrument, timbre_preset?, lora_id?, players?, lyrics?, notes:[{pitch, start_beats, duration_beats, velocity?, lyric?}], dynamics?}] — beats from bar 1, concert pitch. lyrics / lyric: a choir part's words. instrument/timbre_preset = a doseedo_instruments call. players = how many play the line: 1 (default) a soloist, 2–8 a SECTION (e.g. Violins I players 6)."
    • addedInput schema / properties / parts / items / properties / lyrics
      Added value: +{
      +  "description": "A SUNG part (instrument \"choir\"): the words it sings, ONE SYLLABLE PER NOTE in time order — a chord's notes share an onset, so every voice sings that syllable. Hyphens split a word's syllables (\"Glo-ri-a in ex-cel-sis De-o\"), \"_\" alone holds the previous syllable over the next note (a melisma), one word (\"Ah\", \"Mm\") is sung on every note. Omit = \"Ooh\" on every note. notes[].lyric places syllables one by one instead (it wins). Other instruments ignore it.",
      +  "type": "string"
      +}
    • addedInput schema / properties / parts / items / properties / notes / items / properties / lyric
      Added value: +{
      +  "description": "A sung part: the syllable this note sings (\"glo-\" = more of the word follows, \"a\", \"_\" = hold the previous syllable).",
      +  "type": "string"
      +}
    • changedInput schema / properties / parts / items / properties / players / description
      Previous value: -"How many players play this line: 1 (default) = a soloist; 2–8 = a SECTION — the line played by that many different players (each its own recording and performance), summed into ONE section stem. A string section = violins I, violins II, violas, cellos, basses with players 4–8 each. Each player renders (and costs) like a part."New value: +"How many players play this line: 1 (default) = a soloist; 2–8 = a SECTION — the line played by that many different players (each its own recording and performance), summed into ONE section stem. A string section = violins I, violins II, violas, cellos, basses with players 4–8 each; a choir section = singers (Soprano players 6 = six sopranos). Each player renders (and costs) like a part."
  9. First observed

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, it discloses hard caps (≤32 lines, ≤96 player rows, ≤600 s), cost behavior ('Each player renders (and costs) like a part'), a failed part being re-rolled once, and a precise cancellation policy distinguishing jobs not yet on GPU (refunded) from in-flight renders (credits spent, output discarded). It even describes the result object's receipt fields, which no output schema provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded and the ★ SECTIONS marker helps, but the body is a single very long paragraph with dense em-dash clauses and abbreviations that a reader must re-parse. Several passages duplicate schema descriptions (GM drum pads, lyrics syllable rules, dynamics automation) rather than adding value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 16-parameter, deeply nested, no-output-schema render tool, it covers what is needed: input alternatives, limits, timing, per-part result fields with fit.verdict/coverage and lora.applied, mix_url, and the async/cancel lifecycle. Almost nothing an agent needs to call this correctly is left unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already carries per-parameter semantics; the description nevertheless adds cross-parameter meaning it cannot express — file parts matched by name then GM program, instruments{} keyed by name or 0-based index winning over that match, and a chord on a one-line instrument splitting into one stem per voice. Some sections (lyrics, dynamics lane, drum pad map) merely restate schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb and resource ('plays a whole arrangement you wrote in one call') and immediately scopes it with concrete genres. It also names the boundary case explicitly ('Synth parts: doseedo_render_midi'), so an agent can separate this from the MIDI and generic-generation siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It spells out the alternative input paths (parts[], midi_url, musicxml_url) and when each applies, plus concrete selection rules: players 2–8 for a section versus a soloist, drum_engine 'model' for acoustic kits versus 'oneshot' for drum machines, and real-drum genres that must stay on the model. It also hands off the next steps (doseedo_mix then doseedo_session_from_stems) and the async path (doseedo_wait_task).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources