_ registry / mcp streamable-http · checked 1h ago

doseedo

https://api.doseedo.com

Registry code: 6aafc21bf21a9f99

api record

doseedo = MUSIC & AUDIO FOR AGENTS: you write the notes, doseedo_render_midi plays them on 66 instruments (doseedo_instruments, no key) + sound effects + AI audio (stems, transcribe, cover, mix, convert 10 DAWs) + FILM SCORING (doseedo_spot_video, doseedo_score_to_picture) + DAW SESSIONS (read, edit, download a Logic project; Dø Desktop applies edits live). RULES: (1) Before a session build call doseedo_edit_ops_reference ONCE (the default view fits; op:"<name>" / section:"recipes" for detail) and copy a recipe. (2) Never drive the user's screen (no clicking in Logic, no GUI scripting);…

endpoint
https://api.doseedo.com/mcp
protocol
streamable-http ·2025-06-18
authentication
none observed
public key
none — nobody has proven they own this listing · is it yours? claim it
karma
0 · newcomer
_ is it live, free and safe measured by this hub
Is doseedo live?
Yes — it answered the hub's last check (checked 1h ago). It answered 99% of checks over the last 30 days.
Is doseedo free to use?
Partly — some of its tools are open, others need a key or payment.
What tools does doseedo have?
46 tools: doseedo_generate_music, doseedo_generate_sound, doseedo_render_score, doseedo_score_to_picture, doseedo_audio_to_session, doseedo_detect_chords, doseedo_analyze_midi, doseedo_tempo_map, ….
Is doseedo safe to connect?
The hub found no text in its card or tool descriptions aimed at the agent reading them. It measures what the server answers, not its code — grant it only the access its tools need.
reachable
live
uptime, 30 days
99.2%

90 days 99.4%· all time 99.4%

latency
396ms

last good check

priced tools
0

of 46 tools

_ answered our checks, 90 days 462 checks · signed record
  • degraded → live
  • live → degraded· timeout after 20000ms
  • degraded → live
  • live → degraded· timeout after 20000ms
  • degraded → live
_ what it is for
used for
  • generate music from text prompt
  • separate audio into stems
  • transcribe audio to notes
  • convert daw projects
  • edit daw session arrangement
takes → gives
text, audio, documents → audio, data, documents
tools
14 reads11 changes data
_ usage and payments 30 days

Calls placed through this hub's router, from its own receipts. Every caller and every payer counts the same; the chain total is counted from three payers.

accounts
0

through this hub

calls served
0

successful

paid through this hub
0 USDC

what callers paid

_ what it can do 46 tools
2 open9 auth-required 35 never probed 11 of 46 classified

Price is per tool, not per server. An agent whose handshake is open can hold tools that demand a key or a payment, and one figure for the whole agent sends callers into a wall.

  • doseedo_recipes reads open 13d ago

    The named pipelines people actually ask for — stems, session (mix → DAW project), cover, transcribe, generate, render-midi (your notes played by an instrument model), custom-instrument (train your own from a recording), timbre-transfer (your notes, a recording's tone), sound-design (SFX / foley / one-shots), analyze-song (key/tempo/sections/chords), convert, bounce, and the compose-part guide (a part in the session's key at its tempo: analyze → you write the MIDI → place or render it) — each with its inputs, the tool calls in order, outputs, a credit/time estimate and how to VERIFY success from the response. Call with no name for the index (pick by use_when), or with a name for the full recipe. Read-only.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "A recipe name or alias, e.g. \"session\" / \"stems-to-session\". Omit to list all."
        }
      },
      "additionalProperties": false
    }
    arguments 10 lines
  • doseedo_instruments open 13d ago

    The instrument list — the sound palette: every instrument doseedo can PLAY YOUR NOTES on (doseedo_render_midi) — orchestral strings, brass and winds, guitars, basses, keys, drums and percussion, and World instruments (koto, sitar, banjo, pedal steel, tabla, congas…). Each entry gives the EXACT render call (`call`: instrument, plus timbre_preset where one is needed — a koto is the acoustic_guitar model with the koto timbre), its playable range in concert MIDI pitch, whether it plays chords, its presets (pizz, muted, sax registers…) and a demo render. No args → the whole catalog; query:"warm low brass" / family / pitches:[…] (instruments whose range holds them) / chords:true narrow it; id:"cello" → one instrument in full. Read-only, free, no key needed — read it before writing a part.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "One instrument (id, alias or label, e.g. \"cello\", \"upright bass\", \"koto\") → its full entry: every preset with its own call and range, transposition, aliases, demo, page."
        },
        "query": {
          "type": "string",
          "description": "What the part needs, in words: an instrument (\"trumpet\"), a family (\"woodwinds\"), a technique (\"pizzicato\", \"muted\") or a register (\"low\", \"bright\"). Ranked best-first."
        },
        "chords": {
          "type": "boolean",
          "description": "true = only instruments one player can play chords on."
        },
        "family": {
          "enum": [
            "strings",
            "brass",
            "winds",
            "piano",
            "guitar",
            "bass",
            "drums",
            "world",
            "pitched_percussion",
            "unpitched_percussion",
            "synth"
          ],
          "type": "string",
          "description": "Only this family."
        },
        "pitches": {
          "type": "array",
          "items": {
            "type": "number"
          },
          "description": "MIDI pitches the part uses (concert, 60 = C4) — only instruments whose range holds every one."
        }
      },
      "additionalProperties": false
    }
    arguments 42 lines
  • doseedo_check_task reads auth-required 13d ago

    Check an async doseedo task once. Returns current status, and the result (file URLs / notes) when finished. A big result comes back as a brief (each row cut to its deciding fields): parts: ["<name>" or index, …] returns those rows of the job record IN FULL — a render_score part's every receipt, a mix part's strip, rides (every point) and loudness.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "kind": {
          "enum": [
            "generate_music",
            "generate_sound",
            "cover_stem",
            "fill_gap",
            "render_midi",
            "train_instrument",
            "render_score",
            "mix",
            "session_from_stems",
            "spot_video",
            "score_to_picture",
            "cover_song",
            "separate_stems",
            "split_soundtrack",
            "transcribe",
            "audio_to_session",
            "convert_project",
            "bounce_session",
            "analyze_song",
            "detect_chords",
            "beat_grid",
            "check_take",
            "analyze_midi",
            "generate",
            "sound",
            "coverstem",
            "fillgap",
            "render",
            "train",
            "score",
            "stemsess",
            "spot",
            "picture",
            "cover",
            "separate",
            "soundtrack",
            "session",
            "convert",
            "bounce",
            "analyze",
            "chords",
            "beats",
            "check",
            "harmony"
          ],
          "type": "string",
          "description": "Which job kind created the task — the registry name the submit reply carried (generate_music, generate_sound, cover_stem, fill_gap, render_midi, train_instrument, render_score, mix, session_from_stems, spot_video, score_to_picture, cover_song, separate_stems, split_soundtrack, transcribe, audio_to_session, convert_project, bounce_session, analyze_song, detect_chords, beat_grid, check_take, analyze_midi); the short codes (generate, sound, coverstem, fillgap, render, train, score, stemsess, spot, picture, cover, separate, soundtrack, session, convert, bounce, analyze, chords, beats, check, harmony) are accepted aliases."
        },
        "parts": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "description": "Optional, on a finished job: the parts to return in full, by name (as the result names them) or index — e.g. [\"Oboes\", \"Timpani\"]."
        },
        "job_id": {
          "type": "string",
          "description": "Alternatively the job_id (job_…) from a submit tool or the jobs API — replaces task_id + kind."
        },
        "task_id": {
          "type": "string",
          "description": "The task_id returned by a submit tool."
        }
      },
      "additionalProperties": false
    }
    arguments 78 lines
  • doseedo_wait_task reads auth-required 13d ago

    Wait for an async doseedo job to finish: polls server-side for up to timeout_seconds (5–50; one call can never hold longer than 50 s), then returns the result or the latest status. If it returns still_running:true, call it again — a submit reply's eta_seconds says how long the whole job usually takes (transcribe ~15 s, a render 1–3 min, audio_to_session ~4 min), so a 3-minute job is three or four calls, not one. A finished job answers with its output, artifacts (pre-signed links) and note.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "kind": {
          "enum": [
            "generate_music",
            "generate_sound",
            "cover_stem",
            "fill_gap",
            "render_midi",
            "train_instrument",
            "render_score",
            "mix",
            "session_from_stems",
            "spot_video",
            "score_to_picture",
            "cover_song",
            "separate_stems",
            "split_soundtrack",
            "transcribe",
            "audio_to_session",
            "convert_project",
            "bounce_session",
            "analyze_song",
            "detect_chords",
            "beat_grid",
            "check_take",
            "analyze_midi",
            "generate",
            "sound",
            "coverstem",
            "fillgap",
            "render",
            "train",
            "score",
            "stemsess",
            "spot",
            "picture",
            "cover",
            "separate",
            "soundtrack",
            "session",
            "convert",
            "bounce",
            "analyze",
            "chords",
            "beats",
            "check",
            "harmony"
          ],
          "type": "string",
          "description": "Which job kind created the task — the registry name the submit reply carried (generate_music, generate_sound, cover_stem, fill_gap, render_midi, train_instrument, render_score, mix, session_from_stems, spot_video, score_to_picture, cover_song, separate_stems, split_soundtrack, transcribe, audio_to_session, convert_project, bounce_session, analyze_song, detect_chords, beat_grid, check_take, analyze_midi); the short codes (generate, sound, coverstem, fillgap, render, train, score, stemsess, spot, picture, cover, separate, soundtrack, session, convert, bounce, analyze, chords, beats, check, harmony) are accepted aliases."
        },
        "job_id": {
          "type": "string",
          "description": "Alternatively the job_id (job_…) from a submit tool or the jobs API — replaces task_id + kind."
        },
        "task_id": {
          "type": "string",
          "description": "The task_id returned by a submit tool."
        },
        "timeout_seconds": {
          "type": "number",
          "description": "Max seconds to wait in this call (5–50, default 45). Start with the submit reply's suggested_next_wait."
        }
      },
      "additionalProperties": false
    }
    arguments 68 lines
  • doseedo_list_jobs reads auth-required 13d ago

    List the jobs this account submitted (generate / render_midi / cover / stems / transcribe / session / convert / bounce / the analyses), newest first — to find an earlier result, check what is still running, or resume after a lost connection. Each row names its artifacts (e.g. ["vocals", "drums", "midi_piano"]); doseedo_check_task {job_id} returns the full result with fresh links. Read-only.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "kind": {
          "type": "string",
          "description": "Only this job kind (registry name): generate_music, generate_sound, cover_stem, fill_gap, render_midi, train_instrument, render_score, mix, session_from_stems, spot_video, score_to_picture, cover_song, separate_stems, split_soundtrack, transcribe, audio_to_session, convert_project, bounce_session, analyze_song, detect_chords, beat_grid, check_take, analyze_midi. Short codes (generate, sound, coverstem, fillgap, render, train, score, stemsess, spot, picture, cover, separate, soundtrack, session, convert, bounce, analyze, chords, beats, check, harmony) are accepted aliases."
        },
        "limit": {
          "type": "number",
          "description": "How many (1–100, default 20)."
        },
        "before": {
          "type": "string",
          "description": "Page cursor: the next_cursor of a previous call."
        },
        "status": {
          "enum": [
            "queued",
            "running",
            "succeeded",
            "failed",
            "canceled"
          ],
          "type": "string"
        },
        "session_id": {
          "type": "string",
          "description": "Only jobs whose input names this session — a bounce, stems registered into it, a render of one of its tracks (filtered within the fetched page)."
        }
      },
      "additionalProperties": false
    }
    arguments 32 lines
  • doseedo_list_sessions reads auth-required 13d ago

    List the connected account's DAW sessions (most recently updated first) — their ids, names, DAW, and update time. Pages with limit + offset (the response carries total and next_offset); name_contains filters by name. Use a session id with doseedo_get_session and doseedo_edit_session; clean up old ones with doseedo_delete_sessions.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "limit": {
          "type": "number",
          "description": "How many to return (default 25, max 200)."
        },
        "offset": {
          "type": "number",
          "description": "How many to skip (default 0) — pass the previous response's next_offset to get the next page."
        },
        "name_contains": {
          "type": "string",
          "description": "Only sessions whose name contains this text (case-insensitive)."
        }
      },
      "additionalProperties": false
    }
    arguments 18 lines
  • doseedo_desktop_status reads auth-required 13d ago

    Is Dø Desktop running on the user's Mac, and can it put edits into their Logic project? Reports which sessions it holds, how it applies edits (apply_mode "reopen" = save, back up, close, apply, reopen), whether macOS lets it (logic_control), each session's last apply (reopen_results) and its applied cursor. Use it to know whether an edit will reach the project now or wait for the next session open. When it is NOT connected the result says how the user gets and pairs the app, and what still works without it. Read-only.

    mcp-tool

    {
      "type": "object",
      "properties": {},
      "additionalProperties": false
    }
    arguments 5 lines
  • doseedo_download_session reads auth-required 13d ago

    Save a session as a native Logic project (.logicx.zip), rebuilt server-side from the session state — no desktop needed. Returns a short-lived NO-AUTH download_url (plain `curl -o ~/Downloads/…`, no header) plus `replay` = what the build put in the file (per track: kind, Quick Sampler sample + sampler {mode, sample_seconds, start/end, plays_beats}, MIDI note count, audio region count; bundled media; deferred ops the offline build could not synthesize) and `warnings` (e.g. a classic-mode sampler whose notes end before its sample; an unknown sample length). Verify from replay/warnings, never by unzipping ProjectData. `place_local_files` (when present) is ACTION-REQUIRED after unzipping — for Quick Sampler samples AND audio regions from local paths: a replay track with audio_source:"place_local_files" or a "NOT bundled" warning means that file is not in the zip until you run those cp commands; then tell the user the project is complete.

    mcp-tool

    {
      "type": "object",
      "required": [
        "session_id"
      ],
      "properties": {
        "daw": {
          "enum": [
            "logic",
            "ableton",
            "fl",
            "reaper"
          ],
          "type": "string",
          "description": "Target DAW (default logic; only logic is a one-shot native download — for others use doseedo_convert_project)."
        },
        "session_id": {
          "type": "string"
        }
      },
      "additionalProperties": false
    }
    arguments 22 lines
  • doseedo_list_plugins reads auth-required 13d ago

    List the plugins you can insert on a strip with doseedo_edit_session's add_device op. Returns the stock Logic catalog (instruments + effects, always available) and — when Dø Desktop is connected — the actual plugins installed on the user's Mac (stock + third-party). Insert any of them BY NAME: add_device {channel_id, device: {name: "…"}}.

    mcp-tool

    {
      "type": "object",
      "properties": {},
      "additionalProperties": false
    }
    arguments 5 lines
  • doseedo_get_session reads auth-required 14d ago

    Read a DAW session as the arrangement an agent edits against: every track with its wire ids (track_id t_…, mixer strip channel_id ch_…), regions in BOTH beats and seconds with their MIDI notes (i, pitch, velocity, start_beats, duration_beats — i is what edit_midi_notes selects by), mixer (volume with dB, pan, mute), plugins with params[{param_id, name, value}] (set_device_param needs param_id) and sampler {mode, sample_seconds, plays_beats, …}, sends/output as ch_b_… ids, buses, tempo_bpm + tempo_map, time_signature + meter_map, key_signature when known, markers (marker_id, beat ABSOLUTE from bar 1), automation lanes, instrument, counts, length — and `sync` with live_edits:true|false + live_edits_reason (will an edit reach Logic now?). Field-by-field map: doseedo_edit_ops_reference {section:"summary"}. BUDGET (never cut mid-JSON): notes come inline when the selected tracks hold ≤200 notes, else regions carry note_count + notes_omitted:true — pass include_notes:true with tracks:[ids] for a track's notes; include_params:false / include_automation:false drop params / points; a result still too big is paginated by track with `truncated` + `next` (the exact args for the rest). Read-only. Pass the ids straight to doseedo_edit_session, or a track_id to doseedo_render_midi {session_id, track_id}.

    mcp-tool

    {
      "type": "object",
      "required": [
        "session_id"
      ],
      "properties": {
        "tracks": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Only these tracks (track_id t_… or channel_id ch_…; a track name matches too). The rest of the session (tempo, markers, buses, sync) is always included."
        },
        "session_id": {
          "type": "string",
          "description": "From doseedo_list_sessions."
        },
        "include_notes": {
          "type": "boolean",
          "description": "Include MIDI notes. Default: true when the selected tracks hold ≤200 notes in all, else false (regions then carry note_count + notes_omitted:true)."
        },
        "include_params": {
          "type": "boolean",
          "description": "Include plugin params (default true). false keeps param_count only."
        },
        "include_automation": {
          "type": "boolean",
          "description": "Include automation lanes with points (default true). false keeps a lane count per track."
        }
      },
      "additionalProperties": false
    }
    arguments 32 lines
  • doseedo_account reads auth-required 14d ago

    Check the connected doseedo account: plan tier, the monthly credit pool (generation AND DAW conversions draw it), purchased extra-usage credits, and storage. Read-only — consumes nothing. Use it before starting expensive work to confirm there is budget.

    mcp-tool

    {
      "type": "object",
      "properties": {},
      "additionalProperties": false
    }
    arguments 5 lines
  • doseedo_generate_music changes data unknown never probed

    NOT A COMPOSER: doseedo plays music, it does not write it — YOU write the piece. Background music for a video or a brand film, an instrumental, a theme, a song: compose every part yourself as notes ([{pitch, start_beats, duration_beats, velocity}], beats from bar 1 — melody, harmony, bass, in the key and at the tempo you choose), then play them: doseedo_render_score {parts} for several instruments (one stem each, then doseedo_mix) or doseedo_render_midi for one; doseedo_instruments lists the players and their ranges; the steps: doseedo_recipes name="compose-piece" (to picture: "score-a-film"; one part in a session's key: "compose-part"). THIS tool is text to music from a PROMPT alone (optionally lyrics) with NO notes behind it: the instrument model then has nothing to play, and a take is often near-silent, a drone or clicks. Nothing in it is controlled — no key control (a key in the prompt is not honoured), no MIDI input, bpm/time_signature only tag the caption. Use it only when the user explicitly asks for a prompt-only AI sketch, listen before handing a take over, and never deliver one as the music. Async: job_id → doseedo_wait_task (typically 1–3 min) → audio URLs (pre-signed: curl -OJ <url>, no auth header, valid 24 h — see expires_at). 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.

    mcp-tool

    {
      "type": "object",
      "required": [
        "prompt"
      ],
      "properties": {
        "bpm": {
          "type": "number",
          "description": "Optional tempo HINT in BPM, written into the caption (default 120). Not enforced — the output tempo can drift from it."
        },
        "name": {
          "type": "string",
          "maxLength": 80,
          "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>."
        },
        "seed": {
          "type": "number",
          "description": "Optional random seed for reproducibility."
        },
        "lyrics": {
          "type": "string",
          "description": "Optional lyrics to sing. Omit for instrumental."
        },
        "prompt": {
          "type": "string",
          "description": "Style/mood/instrumentation prompt, e.g. \"warm jazz trio, brushed drums, late-night ballad\"."
        },
        "time_signature": {
          "type": "string",
          "description": "Optional meter HINT written into the caption, e.g. \"4/4\", \"3/4\". Not enforced."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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_seconds": {
          "type": "number",
          "description": "Target length in seconds (e.g. 30–120). Omit for the model default."
        }
      },
      "additionalProperties": false
    }
    arguments 42 lines
  • doseedo_generate_sound unknown never probed

    SOUND EFFECTS (SFX) from words with Stable Audio Open — SOUND DESIGN and FOLEY for game audio, apps and video: impacts, whooshes, door slams, footsteps, UI blips, creature and sci-fi sounds, ambiences ("rain on a tin roof", "busy café"), risers, drum one-shots. A one-shot hit ("punchy house kick", "snare with a short room", "a riser into the drop"), a loop on the tempo grid ("glitchy percussion"), or a texture ("vinyl crackle", "rain"). kind picks which (hit | loop | texture); omitted, the server reads it off the words. Don't put a tempo in a hit's prompt — tempo words make it write a loop. Wrong tool for a part with notes (doseedo_render_midi) or a piece of music (you write it; doseedo_render_score plays it). Async: job_id → doseedo_wait_task (typically 15–40 s) → audio URLs (pre-signed: curl -OJ <url>, no auth header, valid 24 h). 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.

    mcp-tool

    {
      "type": "object",
      "required": [
        "prompt"
      ],
      "properties": {
        "bpm": {
          "type": "number",
          "description": "Tempo a loop is cut to (default 120)."
        },
        "kind": {
          "enum": [
            "hit",
            "loop",
            "texture"
          ],
          "type": "string",
          "description": "hit = one sound (0.5–10 s), loop = 1–4 bars tiled at bpm, texture = a bed. Default: read off the prompt."
        },
        "name": {
          "type": "string",
          "maxLength": 80,
          "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>."
        },
        "seed": {
          "type": "number",
          "description": "Optional random seed for reproducibility."
        },
        "prompt": {
          "type": "string",
          "description": "What it sounds like, e.g. \"punchy house kick drum, single hit\" or \"dusty vinyl crackle\". ≤ 300 characters."
        },
        "time_signature": {
          "type": "string",
          "description": "Meter a loop is cut to, e.g. \"4/4\" (default)."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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_seconds": {
          "type": "number",
          "description": "Length in seconds. Default: 2 s for a hit, 4 bars at bpm for a loop, 8 s for a texture."
        }
      },
      "additionalProperties": false
    }
    arguments 47 lines
  • doseedo_render_score unknown never probed

    FILM SCORING, orchestral arrangement, background music, a song or an instrumental YOU wrote: a WHOLE ARRANGEMENT in one call (a film cue, a string quartet, a big-band chart): every 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 {"<part name or index>": {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 where every hit must land: parts[].drum_engine "oneshot" (+ drum_genre). 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.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "bpm": {
          "type": "number",
          "description": "Tempo 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."
        },
        "mix": {
          "type": "boolean",
          "description": "Also bounce a summed mix of the stems (default true)."
        },
        "name": {
          "type": "string",
          "maxLength": 80,
          "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>."
        },
        "seed": {
          "type": "number",
          "description": "Random seed (reuse to re-render close to the same performance)."
        },
        "tune": {
          "type": "boolean",
          "description": "Light 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)."
        },
        "parts": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "notes"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "tune": {
                "type": "boolean",
                "description": "false = this part exactly as rendered (no light intonation pass; default true)."
              },
              "notes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "pitch",
                    "start_beats",
                    "duration_beats"
                  ],
                  "properties": {
                    "lyric": {
                      "type": "string",
                      "description": "A sung part: the syllable this note sings (\"glo-\" = more of the word follows, \"a\", \"_\" = hold the previous syllable)."
                    },
                    "pitch": {
                      "type": "number"
                    },
                    "velocity": {
                      "type": "number"
                    },
                    "start_beats": {
                      "type": "number"
                    },
                    "duration_beats": {
                      "type": "number"
                    }
                  },
                  "additionalProperties": false
                }
              },
              "lyrics": {
                "type": "string",
                "description": "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."
              },
              "vaefix": {
                "type": "boolean",
                "description": "false = this part's decode exactly as rendered (no VAE spectral corrector; default true)."
              },
              "lora_id": {
                "type": "string"
              },
              "players": {
                "type": "number",
                "description": "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."
              },
              "dynamics": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "beat",
                    "velocity"
                  ],
                  "properties": {
                    "beat": {
                      "type": "number"
                    },
                    "velocity": {
                      "type": "number"
                    }
                  },
                  "additionalProperties": false
                },
                "description": "The part's written LEVEL over time, as a DAW automation lane: [{beat, velocity 1–127}] in beat order, linear between points, a step = two points on one beat, held after the last (p 52, mf 80, f 96, ff 112). A velocity says how a note STARTS; this says how it goes on — a crescendo on a held note: [{beat: 0, velocity: 52}, {beat: 8, velocity: 96}]. Its tone follows it, through a held note too, and doseedo_mix {from_job} rides the level to it. A MusicXML score's dynamics + hairpins arrive as this lane on their own."
              },
              "drum_genre": {
                "type": "string",
                "description": "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."
              },
              "instrument": {
                "type": "string"
              },
              "drum_engine": {
                "enum": [
                  "model",
                  "oneshot"
                ],
                "type": "string",
                "description": "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."
              },
              "timbre_preset": {
                "type": "string"
              },
              "dynamics_curve": {
                "enum": [
                  "auto",
                  "off",
                  "velocity",
                  "cc11",
                  "cc1"
                ],
                "type": "string",
                "description": "What colours this part's TONE over time: auto (default) = its dynamics lane when that moves, else its note velocities when they vary — soft darker, loud brighter, on every instrument but drums; off = one colour throughout; velocity = the velocities even with a lane; cc11/cc1 = that MIDI CC lane (a midi_url part). Receipt: parts[].dynamics."
              },
              "timbre_audio_url": {
                "type": "string",
                "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."
              },
              "timbre_audio_urls": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "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."
              }
            },
            "additionalProperties": false
          },
          "description": "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)."
        },
        "vaefix": {
          "type": "boolean",
          "description": "VAE 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_url": {
          "type": "string",
          "description": "Alternative 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_key": {
          "type": "string",
          "description": "Alternative 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_url": {
          "type": "string",
          "description": "Alternative to parts: a score file URL — MIDI, MusicXML or a MuseScore .mscz / .mscx, told apart by its content."
        },
        "tempo_map": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "beat",
              "bpm"
            ],
            "properties": {
              "bpm": {
                "type": "number"
              },
              "beat": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "description": "Tempo changes [{beat, bpm}] (first point at beat 0). Overrides a file's own tempo."
        },
        "instruments": {
          "type": "object",
          "description": "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."
        },
        "musicxml_url": {
          "type": "string",
          "description": "Alternative 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_signature": {
          "type": "string",
          "description": "Meter, e.g. \"4/4\" (default, or the file's)."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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_seconds": {
          "type": "number",
          "description": "Render length (default: the last note + 2 s; ≤ 600)."
        }
      },
      "additionalProperties": false
    }
    arguments 208 lines
  • doseedo_score_to_picture unknown never probed

    SCORE TO PICTURE: the last step of scoring a film. Lays each mixed cue (and any sound effect) on the video at its SMPTE timecode, with dialogue ducking (the lines found on the video's own soundtrack by VAD, or the spans you pass; the music dips ahead of each line and comes back after it), normalises the program to a delivery loudness (web −16, streaming −14, broadcast/ebu −23, atsc −24 LUFS, or a number; true peak under the ceiling) and muxes it onto the picture untouched (no re-encode). Returns the scored video, the printmaster WAV and the music-and-effects stem, plus a report of what it MEASURED: where each track landed (and what was cut at the film's edges), how far the music sits under the lines, and the final loudness and true peak. CPU, no credits. tracks: [{audio_url (a doseedo_mix mix_url as returned, or any public https URL) | audio_key, start_timecode (in the film's timecode) | start_s, gain_db?, role?: music|dialogue|effects, duck?, name?}], ≤ 64. Keep the production audio (default) or drop it (production_audio:"drop"). A FILM THAT ALREADY HAS MUSIC: keeping its audio mixes the old music under yours — split it first (doseedo_split_soundtrack) and lay its dialogue and effects stems back (start_s 0, role dialogue / effects) with production_audio:"drop": the old music is gone, the lines are kept, and the duck reads the lines off the dialogue stem; lay the old music stem back too with duck:false to keep it (or a part of it). With dialogue tracks the delivery also returns the dialogue / music / effects stems. Up to 25 minutes of film per call (a reel). Async: job_id → doseedo_wait_task. Cancel: the plane has no stop for a running delivery — it runs to completion (credits spent), the job ends as canceled and its output is discarded. Only a job still queued at the plane is refunded by the plane's own failure refund.

    mcp-tool

    {
      "type": "object",
      "required": [
        "tracks"
      ],
      "properties": {
        "duck": {
          "type": "object",
          "properties": {
            "sfx": {
              "type": "boolean"
            },
            "enabled": {
              "type": "boolean"
            },
            "depth_db": {
              "type": "number",
              "maximum": 40,
              "minimum": 0
            },
            "attack_ms": {
              "type": "number",
              "maximum": 3000,
              "minimum": 0
            },
            "release_ms": {
              "type": "number",
              "maximum": 5000,
              "minimum": 0
            }
          },
          "description": "Dialogue ducking (on by default): depth_db (default 10), attack_ms (250: how early before a line the music is down), release_ms (700), sfx (false: duck effects too), enabled.",
          "additionalProperties": false
        },
        "name": {
          "type": "string",
          "maxLength": 80,
          "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>."
        },
        "tracks": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "duck": {
                "type": "boolean",
                "description": "false = this music track is not ducked (the film's own music laid back from doseedo_split_soundtrack was mixed under its lines already). Default true."
              },
              "name": {
                "type": "string",
                "description": "A label for the report, e.g. 1M3."
              },
              "role": {
                "enum": [
                  "music",
                  "dialogue",
                  "effects",
                  "sfx"
                ],
                "type": "string",
                "description": "music (default; ducked under the dialogue), dialogue (never ducked — the lines the rest ducks under; a split soundtrack's dialogue stem), effects / sfx (not ducked unless duck.sfx)."
              },
              "gain_db": {
                "type": "number",
                "maximum": 24,
                "minimum": -60,
                "description": "Level trim (default 0)."
              },
              "start_s": {
                "type": "number",
                "description": "Or where it starts in seconds from the first frame."
              },
              "audio_key": {
                "type": "string",
                "description": "An ingest key instead of audio_url."
              },
              "audio_url": {
                "type": "string",
                "description": "The cue's mixed audio (doseedo_mix mix_url as returned) or any public https URL."
              },
              "start_timecode": {
                "type": "string",
                "description": "Where it starts, in the film's timecode (HH:MM:SS:FF) — the cue sheet's start_timecode."
              }
            },
            "additionalProperties": false
          },
          "maxItems": 64,
          "minItems": 1,
          "description": "What to lay on the film, in any order."
        },
        "dialogue": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "start_s",
              "end_s"
            ],
            "properties": {
              "end_s": {
                "type": "number"
              },
              "start_s": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "description": "Dialogue spans [{start_s, end_s}] to duck under, instead of detecting them (use the cue sheet's dialogue, or your own)."
        },
        "loudness": {
          "anyOf": [
            {
              "enum": [
                "web",
                "streaming",
                "broadcast",
                "ebu",
                "atsc"
              ],
              "type": "string"
            },
            {
              "type": "number"
            }
          ],
          "description": "Delivery loudness: \"web\" (−16 LUFS, default), \"streaming\" (−14), \"broadcast\" / \"ebu\" (−23), \"atsc\" (−24), or a LUFS number (−36…−8)."
        },
        "video_key": {
          "type": "string",
          "description": "R2 ingest key of the video (the same upload doseedo_spot_video used)."
        },
        "video_url": {
          "type": "string",
          "description": "https URL of the video, as an alternative to video_key."
        },
        "start_timecode": {
          "type": "string",
          "description": "SMPTE timecode of the film's first frame (default: the file's own, else 00:00:00:00) — the clock the tracks' start_timecode is read on."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        },
        "production_audio": {
          "enum": [
            "keep",
            "drop"
          ],
          "type": "string",
          "description": "keep (default) mixes the video's own soundtrack — all of it, its music included — under the score; drop replaces it (lay a doseedo_split_soundtrack's dialogue + effects stems to keep the lines)."
        },
        "production_gain_db": {
          "type": "number",
          "maximum": 12,
          "minimum": -60,
          "description": "Trim on the production audio when kept (default 0)."
        }
      },
      "additionalProperties": false
    }
    arguments 162 lines
  • doseedo_audio_to_session changes data unknown never probed

    Turn an uploaded full mix into a complete multitrack DAW session (separated stems as tracks, tempo map, optional per-stem MIDI and chord guide). The result is a downloadable session zip for Logic Pro or Ableton. Async: returns a job_id — poll with doseedo_wait_task (~4 minutes). Cancel: cooperative — the build stops at its next stage boundary and the build's sound-tool unit is refunded (a GPU separation already run stays charged).

    mcp-tool

    {
      "type": "object",
      "properties": {
        "key": {
          "type": "boolean",
          "description": "Detect the key and write it into the project (default true in the full build, false with simple)."
        },
        "name": {
          "type": "string",
          "description": "Project name for the session file — it also names the download: <name>_session.zip."
        },
        "loops": {
          "type": "boolean",
          "description": "Detect repeated clips and lay them as loops (default false)."
        },
        "chords": {
          "type": "boolean",
          "description": "Add a detected-chords guide track (default false)."
        },
        "retune": {
          "type": "boolean",
          "description": "Default true: a mix sitting >35 cents off A440 is pitch-corrected onto the 12-TET grid before separation (every transcriber coin-flips otherwise). false = leave the tuning as recorded."
        },
        "simple": {
          "type": "boolean",
          "description": "Faster minimal build: meter + tempo + stems only, no MIDI (default false). Required for stem_mode orchestra/detect."
        },
        "target": {
          "enum": [
            "logic",
            "ableton"
          ],
          "type": "string",
          "description": "DAW target (default logic)."
        },
        "markers": {
          "type": "boolean",
          "description": "Add section markers (intro/verse/chorus…) (default true in the full build, false with simple)."
        },
        "dereverb": {
          "type": "boolean",
          "description": "Opt-in: lay DRY stems and recreate the room with a reverb plugin on each track (default false)."
        },
        "separate": {
          "type": "boolean",
          "description": "false = no separation: the mix lands as ONE audio track (default true)."
        },
        "audio_key": {
          "type": "string",
          "description": "R2 ingest key of an uploaded audio file (from doseedo_get_upload_url / POST /api/upload/r2/ingest-url; starts with \"ingest/\"). Provide this or audio_url."
        },
        "audio_url": {
          "type": "string",
          "description": "https URL of the audio, as an alternative to audio_key: a doseedo result URL exactly as a job returned it (a stem, a take, a bounce), or any public URL. The gateway fetches it (≤256 MB) into your account's ingest storage before the job starts. Pass audio_key OR audio_url."
        },
        "stem_mode": {
          "enum": [
            "auto",
            "6stem",
            "drumsep",
            "sections",
            "orchestra",
            "detect"
          ],
          "type": "string",
          "description": "Separation family. auto (DEFAULT): the 6 stems plus a residual cascade that peels detected orchestral sections out of \"other\" (no orchestral content → identical to 6stem). 6stem: vocals/drums/bass/guitar/piano/other. drumsep: the drum stem replaced by isolated kick/snare/hh/… tracks on a Drums bus. sections: the 6 stems with \"other\" split by the joint section model (trumpet/trombone/sax/violin/viola/cello), each transcribed per chair. orchestra / detect: the 53-instrument bank on the MIX (needs simple:true; detect auto-picks, orchestra takes `instruments`)."
        },
        "tempo_map": {
          "type": "boolean",
          "description": "false = one constant tempo instead of a tempo map (default true)."
        },
        "midi_stems": {
          "type": "string",
          "description": "Optional comma-separated stems to also add as MIDI tracks, e.g. \"piano,bass\" (include \"drums\" for a GM drum roll)."
        },
        "instruments": {
          "type": "string",
          "description": "stem_mode orchestra/detect: optional comma list restricting the orchestral set, e.g. \"violin,cello,flute\"."
        },
        "crop_silence": {
          "type": "boolean",
          "description": "Punch regions in where each stem plays instead of whole-length stems (default false)."
        },
        "drum_sampler": {
          "type": "boolean",
          "description": "Sampled kits → a one-shot sampler track + MIDI (default false)."
        },
        "guitar_split": {
          "type": "string",
          "description": "Split the guitar stem into N players, each its own track + MIDI lane on a Guitar Section bus: \"0\" (off), \"auto\" (DEFAULT — a one-vs-two probe decides), \"2\"–\"4\"."
        },
        "drum_substems": {
          "type": "boolean",
          "description": "Lay each drum piece as its own audio track on a Drums bus (default false; implied by stem_mode drumsep)."
        },
        "quantize_midi": {
          "enum": [
            "grid",
            "score"
          ],
          "type": "string",
          "description": "Snap every pitched MIDI lane: \"grid\" = to the grid its own onsets support (straight/swing 8ths, 16ths, triplets, detected per lane); \"score\" = notation positions (straight 8ths). Default off (played timing)."
        },
        "drum_midi_split": {
          "type": "boolean",
          "description": "With \"drums\" in midi_stems: one Quick Sampler track PER kit piece, each loaded with a synthesized one-shot (default false = one GM drum-roll track)."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        },
        "keep_stem_audio": {
          "type": "boolean",
          "description": "With midi_stems: keep the audio stem next to its MIDI track (default true); false = the MIDI track REPLACES the audio."
        }
      },
      "additionalProperties": false
    }
    arguments 118 lines
  • doseedo_detect_chords unknown never probed

    Chord detection on audio (a chord chart on the beat grid): chord_spans[{chord, start, end, start_beat, end_beat, confidence}], chords{"<beat>": "Am7"}, bpm, beats_per_bar, beat_map. Default = the deep ACE detector (GPU-backed, a CPU chroma detector is the automatic fallback); deep:false forces the fast CPU detector. Pass audio_key (an upload) or audio_url (a result URL from another job as returned, or any public https URL). Up to 10 minutes of audio is analyzed. Works best on a harmonic stem (piano/guitar/bass) or a clean mix. Synchronous (~5–30 s). Cancel: not applicable — the result is returned in the submit response; the job is already finished.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "deep": {
          "type": "boolean",
          "description": "true (default) = deep ACE detector; false = fast CPU chroma detector."
        },
        "audio_key": {
          "type": "string",
          "description": "R2 ingest key of an uploaded audio file (from doseedo_get_upload_url / POST /api/upload/r2/ingest-url; starts with \"ingest/\"). Provide this or audio_url."
        },
        "audio_url": {
          "type": "string",
          "description": "https URL of the audio (a doseedo result URL as returned, or any public URL). Alternative to audio_key."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        }
      },
      "additionalProperties": false
    }
    arguments 22 lines
  • doseedo_analyze_midi unknown never probed

    Check the HARMONY of notes before rendering or placing them: factor a MIDI progression into its sonorities (mode "midi", default — chord-detection-free: each segment of simultaneously sounding pitches reduced to an anchor pitch class + register-exact shape, covered with recurring shape cells) or into chord symbols (mode "chord": one estimated chord per ~2 beats + a corpus-grammar cell cover with a schedule). Input: notes[] (the rows you would give doseedo_render_midi / set_midi_notes) with bpm, or midi_url (a .mid ≤2 MiB: a doseedo result link such as a stem's MIDI, or a public URL). Synchronous (~2–10 s), CPU, no credits. Returns sonorities[] or chords[], cover, cells, compression — read chords[].chord / sonorities[].anchor to confirm the key and progression you intended. Cancel: not applicable — the result is returned in the submit response; the job is already finished.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "bpm": {
          "type": "number",
          "description": "Tempo of the notes (needed with notes; default 120)."
        },
        "mode": {
          "enum": [
            "midi",
            "chord"
          ],
          "type": "string",
          "description": "\"midi\" (default): sonority / shape factoring. \"chord\": chord symbols per segment + cell cover."
        },
        "notes": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "pitch",
              "start_beats",
              "duration_beats"
            ],
            "properties": {
              "pitch": {
                "type": "number"
              },
              "velocity": {
                "type": "number"
              },
              "start_beats": {
                "type": "number"
              },
              "duration_beats": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "description": "The notes to analyze, in beats from bar 1 (same rows as doseedo_render_midi). Needs bpm."
        },
        "midi_url": {
          "type": "string",
          "description": "Alternative to notes: https URL of a Standard MIDI File (≤2 MiB)."
        },
        "min_seg_beats": {
          "type": "number",
          "description": "mode midi: shortest sonority segment in beats (default 0.25)."
        },
        "time_signature": {
          "type": "string",
          "description": "Meter of the notes, e.g. \"4/4\" (default)."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        },
        "beats_per_segment": {
          "type": "number",
          "description": "mode chord: segment length in beats (0.25–8, default 2)."
        }
      },
      "additionalProperties": false
    }
    arguments 65 lines
  • doseedo_tempo_map unknown never probed

    Scoring to picture: turn HIT POINTS (a cut, an impact, the title card — as seconds from the cue start or SMPTE timecodes) into a TEMPO MAP that lands each hit exactly on a downbeat (or a beat / an eighth — per hit with hits[].land), staying near your tempo and inside bpm_range. A cue whose pace changes (she runs faster, then stops): give the hit where it changes a bpm, and the map moves to that tempo from there, every hit still landed. An AD or any cue that must hold ONE tempo: fixed_bpm: true (+ max_deviation_bpm, tolerance_ms) finds the tempo and the bar-1 offset (music_offset_s) landing the most hits, and says which ones it could not. Returns tempo_map [{beat, bpm}] to pass unchanged to doseedo_render_midi / doseedo_render_score / doseedo_session_from_stems, and hits[] with the beat, bar and beat-in-bar each hit lands on — write the accent, stinger or change there. Handles 23.976 / 24 / 25 / 29.97 (";" = drop-frame) / 30 / 50 / 59.94 / 60 fps timecode. Pure math: free, instant, no key needed.

    mcp-tool

    {
      "type": "object",
      "required": [
        "hits",
        "bpm"
      ],
      "properties": {
        "bpm": {
          "type": "number",
          "description": "The cue's tempo (20–300) — the map stays as close to it as the hits allow."
        },
        "fps": {
          "type": "number",
          "description": "Frame rate of the timecodes: 23.976, 24, 25, 29.97, 30, 50, 59.94, 60."
        },
        "hits": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "object",
                "properties": {
                  "land": {
                    "enum": [
                      "downbeat",
                      "beat",
                      "eighth"
                    ],
                    "type": "string"
                  },
                  "label": {
                    "type": "string"
                  },
                  "time_s": {
                    "type": "number"
                  },
                  "timecode": {
                    "type": "string"
                  }
                },
                "additionalProperties": false
              }
            ]
          },
          "description": "The moments the music must land on: [{time_s} (seconds from the cue start) or {timecode: \"01:00:12:08\"} (film timecode, with fps and start_timecode), label?, land?, bpm?}] — land = THIS hit's landing (\"downbeat\", \"beat\" or \"eighth\"; default: the request's land), e.g. the big cuts on bar lines and a quick accent on an eighth. bpm = the tempo FROM this hit on, a new section (the chase at 160 from the cut where she starts running, back to 112 when she stops), until a later hit names another; the range around it scales with it. A bare number = {time_s}."
        },
        "land": {
          "enum": [
            "downbeat",
            "beat",
            "eighth"
          ],
          "type": "string",
          "description": "Land hits on bar lines (default), on any beat, or on any eighth — the default for every hit without its own land."
        },
        "start_s": {
          "type": "number",
          "description": "Alternative: the cue start in seconds of film time (informational when hits are time_s)."
        },
        "bpm_range": {
          "type": "array",
          "items": {
            "type": "number"
          },
          "description": "Allowed tempo range [min, max] (default ±12 % of bpm)."
        },
        "fixed_bpm": {
          "type": "boolean",
          "description": "ONE tempo for the whole cue (an ad, a song-form cue): the solver picks the tempo (within max_deviation_bpm of bpm; default exactly bpm) and where bar 1 sits (music_offset_s, default within the first bar; offset_range_s) so the most hits land within tolerance_ms (default 40). Hits it cannot land come back landed:false with nearest_beat — never an error."
        },
        "tolerance_ms": {
          "type": "number",
          "description": "SOFT hits (0–250 ms): a hit within this of the grid counts as landed, and one the grid can't reach is reported (landed:false), never refused. Every hit then carries error_ms; hit_rate = landed / all."
        },
        "offset_range_s": {
          "type": "array",
          "items": {
            "type": "number"
          },
          "description": "fixed_bpm: where bar 1 may sit on the cue, [min, max] seconds (default [0, one bar])."
        },
        "start_timecode": {
          "type": "string",
          "description": "Film timecode of the cue's first downbeat (bar 1); hit timecodes are measured from it."
        },
        "time_signature": {
          "type": "string",
          "description": "Meter (default 4/4)."
        },
        "max_deviation_bpm": {
          "type": "number",
          "description": "How far the tempo may move from bpm (both modes; in place of bpm_range). A variable map at 124 ±12 % can swing 11+ bpm between hits — 3 keeps it a steady groove."
        }
      },
      "additionalProperties": false
    }
    arguments 99 lines
  • doseedo_get_project_upload_url reads unknown never probed

    Get a presigned upload for a DAW PROJECT file (for doseedo_convert_project / doseedo_import_project). Zip a project FOLDER so its audio travels with it — and a .logicx or GarageBand .band, which are folders (macOS packages). SIZE LIMITS: a single PUT takes up to 5 GB; guest and free accounts convert projects up to 2 GB, paid plans up to 12 GB (a larger one is refused as project_too_large with the cap and an upgrade link). Pass size_bytes: past 4 GB (or with multipart:true) you get a MULTIPART upload instead — a part_size, one presigned part_url per part, and the complete step (doseedo_complete_project_upload); each part is retried on its own, so a dropped connection costs one part, not the upload. Single PUT: `curl -sS -X PUT -H "Content-Type: application/zip" --data-binary @project.zip "<upload_url>"`, then pass project_key on. Multipart: `split -b <part_size_bytes> project.zip part.` then for each piece in order `curl -sS -X PUT --data-binary @part.aa "<part_url>" -D - -o /dev/null | grep -i etag` (keep each ETag), then doseedo_complete_project_upload {project_key, upload_id, parts}. Need more part URLs than one answer holds? Call this again with project_key + upload_id + part_numbers.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "filename": {
          "type": "string",
          "description": "File name including extension, e.g. \"Song Project.zip\", \"My Song.band.zip\", \"beat.flp\", \"song.cpr\", \"Mix.song\", \"set.dawproject\" or \"score.mxl\"."
        },
        "multipart": {
          "type": "boolean",
          "description": "Force a multipart upload regardless of size (resumable per part)."
        },
        "upload_id": {
          "type": "string",
          "description": "CONTINUATION: the upload_id the first call returned."
        },
        "size_bytes": {
          "type": "number",
          "description": "The file's size in bytes (stat it). Decides single PUT vs multipart and sizes the parts."
        },
        "project_key": {
          "type": "string",
          "description": "CONTINUATION of a multipart upload: the key the first call returned."
        },
        "content_type": {
          "type": "string",
          "description": "MIME type: application/zip for zips (default), application/octet-stream for bare project files."
        },
        "part_numbers": {
          "type": "array",
          "items": {
            "type": "number"
          },
          "description": "CONTINUATION: which part numbers (1-based) to sign now, ≤ 24 per call."
        }
      },
      "additionalProperties": false
    }
    arguments 37 lines
  • doseedo_complete_project_upload unknown never probed

    Finish a MULTIPART project upload started by doseedo_get_project_upload_url: pass every uploaded part's number and ETag (from the PUT response header; quotes optional). Returns the project_key to pass to doseedo_convert_project / doseedo_import_project. All parts except the last must be the same size (what `split -b` produces). abort:true discards the upload instead.

    mcp-tool

    {
      "type": "object",
      "required": [
        "project_key",
        "upload_id"
      ],
      "properties": {
        "abort": {
          "type": "boolean",
          "description": "true = abandon the upload and free its parts (no project_key results)."
        },
        "parts": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "part_number",
              "etag"
            ],
            "properties": {
              "etag": {
                "type": "string"
              },
              "part_number": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "description": "[{part_number, etag}] for EVERY part, in order."
        },
        "upload_id": {
          "type": "string"
        },
        "project_key": {
          "type": "string"
        }
      },
      "additionalProperties": false
    }
    arguments 40 lines
  • doseedo_import_project unknown never probed

    Open an uploaded DAW project (Logic .logicx.zip, Ableton .als or project zip, FL .flp, REAPER .rpp, Pro Tools .ptx — zip the folder) as an EDITABLE doseedo session: returns a session_id the session tools then work on (doseedo_get_session → doseedo_edit_session → doseedo_download_session as a native Logic project, or convert that download to another DAW with doseedo_convert_project). The session gets the project's tempo (+ tempo map), meter, markers, and every track with its name, mixer level/pan, color and MIDI notes. AUDIO IS NOT CARRIED: the import reads the project, not its media — audio tracks arrive named and positioned (audio.placements lists each clip's file and beats) and audio.next says how to supply the files. Plugins and summing buses are reported, not recreated. Upload first with doseedo_get_project_upload_url; this call parses the project (seconds to minutes for a big one) — if it answers status:"running", call it again with the returned task_id until it hands back session_id.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "daw": {
          "enum": [
            "logic",
            "ableton",
            "fl",
            "reaper",
            "protools"
          ],
          "type": "string",
          "description": "The source DAW, when the filename does not say (optional; detected otherwise)."
        },
        "name": {
          "type": "string",
          "description": "Session name (default: the project's own name)."
        },
        "task_id": {
          "type": "string",
          "description": "CONTINUATION: the task_id a previous call returned while the parse was still running."
        },
        "project_key": {
          "type": "string",
          "description": "R2 key of the uploaded project (from doseedo_get_project_upload_url; starts with \"uploads/\")."
        }
      },
      "additionalProperties": false
    }
    arguments 29 lines
  • doseedo_quote reads unknown 14d ago

    Estimate what a job will cost in credits BEFORE submitting it, and whether the connected account can afford it right now. Spends nothing. Pass the job (generate_music, generate_sound, cover_stem, fill_gap, render_midi, train_instrument, cover_song, separate_stems, split_soundtrack, transcribe, audio_to_session, convert_project, bounce_session, spot_video, score_to_picture, analyze_song, detect_chords, beat_grid, analyze_midi, render_score, mix, session_from_stems, check_take) and the same args you would give the job tool (duration_seconds, models, instruments; for render_midi: notes + bpm / tempo_map or duration_seconds, voice_split / voices, takes — takes are free, voices cost one batch per ~6; for render_score: parts + bpm / tempo_map — planned exactly as the job plans it (lines, player rows, length), and `refused` says when the job would refuse it). The estimate follows the planes' own price table; the gate is authoritative and a refusal names the exact price.

    mcp-tool

    {
      "type": "object",
      "required": [
        "job"
      ],
      "properties": {
        "job": {
          "enum": [
            "generate_music",
            "generate_sound",
            "cover_stem",
            "fill_gap",
            "render_midi",
            "train_instrument",
            "cover_song",
            "separate_stems",
            "split_soundtrack",
            "transcribe",
            "audio_to_session",
            "convert_project",
            "bounce_session",
            "spot_video",
            "score_to_picture",
            "analyze_song",
            "detect_chords",
            "beat_grid",
            "analyze_midi",
            "render_score",
            "mix",
            "session_from_stems",
            "check_take"
          ],
          "type": "string",
          "description": "Which job to price (a doseedo_ tool name or recipe verb is accepted too)."
        },
        "args": {
          "type": "object",
          "description": "The arguments you intend to pass to the job tool; only the price-relevant ones matter.",
          "additionalProperties": true
        }
      },
      "additionalProperties": false
    }
    arguments 43 lines
  • doseedo_delete_sessions unknown never probed

    Delete DAW sessions in bulk — a SOFT delete (the sessions disappear from the account and every listing; nothing on the user's disk is touched). Select by ids, or by filters (daw_kind, created_before / created_after, name_contains); filters combine with AND. SAFE BY DEFAULT: without confirm:true this is a DRY RUN that deletes nothing and returns {matched, ids}. Always run the dry run first, show the user the count (and names if few), and call again with confirm:true only after they agree. Never delete sessions the user did not ask to remove.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "ids": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Session ids to delete (up to 500), from doseedo_list_sessions."
        },
        "limit": {
          "type": "number",
          "description": "Cap on how many sessions one call may match (default and max 1000)."
        },
        "confirm": {
          "type": "boolean",
          "description": "false/omitted = dry run (nothing deleted). true = actually delete — only after the user saw the dry-run count and agreed."
        },
        "daw_kind": {
          "type": "string",
          "description": "Only sessions bound to this DAW, e.g. \"logic\", \"ableton\"."
        },
        "created_after": {
          "type": "string",
          "description": "ISO-8601 date/time: only sessions created after this."
        },
        "name_contains": {
          "type": "string",
          "description": "Only sessions whose name contains this text (case-insensitive)."
        },
        "created_before": {
          "type": "string",
          "description": "ISO-8601 date/time: only sessions created before this."
        }
      },
      "additionalProperties": false
    }
    arguments 37 lines
  • doseedo_edit_session changes data unknown never probed

    Edit a DAW session with a list of ops (regions, MIDI notes, sampler samples, tracks, mixer faders/pans/mutes, plugins, tempo, markers, key, …): ids and current values from doseedo_get_session, op arguments from doseedo_edit_ops_reference. When sync.live_edits is true Dø Desktop puts it into the user's Logic project (it saves, backs up, closes and reopens the project, ~10–20 s — tell the user); otherwise stored and applied at next open. CONTRACT: every op is validated before anything is stored; a rejection carries a code — unknown_op / unknown_plugin (with did_you_mean), unknown_id (with the valid ids), duplicate_id, forbidden_group, read_only_key — and a reason. atomic (default true): one rejection → NOTHING stored, all rejections listed; atomic:false stores the good ops. RETRY: re-send a timed-out call with the SAME batch_key and it dedups (deduped:true); without batch_key a retry duplicates. Ops apply on the desktop one at a time in order, no per-batch undo — verify with doseedo_download_session (replay).

    mcp-tool

    {
      "type": "object",
      "required": [
        "session_id",
        "ops"
      ],
      "properties": {
        "ops": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "op",
              "args"
            ],
            "properties": {
              "op": {
                "type": "string",
                "description": "The op name, e.g. \"set_track_crop\"."
              },
              "args": {
                "type": "object",
                "description": "The op arguments (see the ops reference)."
              }
            },
            "additionalProperties": false
          },
          "description": "The edits, e.g. [{\"op\":\"set_track_crop\",\"args\":{\"track_id\":\"t_…\",\"start_beats\":4,\"end_beats\":124,\"prev_start_beats\":24}}, {\"op\":\"set_channel_volume\",\"args\":{\"channel_id\":\"ch_…\",\"value\":0.6}}]. See doseedo_edit_ops_reference."
        },
        "atomic": {
          "type": "boolean",
          "description": "Default true: any rejected op means nothing is stored. Set false to store the valid ops and receive the rest as `rejected`."
        },
        "batch_key": {
          "type": "string",
          "description": "A stable id for THIS batch (e.g. \"drumkit-build-1\"). Same batch_key + same ops on a retry = the same client_op_ids = no duplicates. Always pass one for a build you might have to retry."
        },
        "session_id": {
          "type": "string"
        }
      },
      "additionalProperties": false
    }
    arguments 43 lines
  • doseedo_edit_ops_reference reads unknown never probed

    The catalog of session edit ops doseedo_edit_session accepts, served in views that each fit one answer (never cut mid-JSON). DEFAULT (no args): units, ids, applies, groups, batching/policy, the recipe NAMES and every op as {op, group, applies, summary} — read it ONCE before a build. Then fetch what you need: op:"load_quick_sampler_sample" (or ops:[…]) → those ops in full (args, units, doc; an unknown name gets did_you_mean); section:"recipes" → the full recipes (drum kit from local samples, fix note lengths, one-shots on an audio track, remote sample, submix bus, verify) — copy one instead of discovering op order; section:"ops" → every op in full; "units" / "ids" / "summary" (the get_session field map + workflow + policy + batching) / "all" (fitted, may shorten). Each op says where it lands (applies: live in the open project | next_open | state). Read-only, no key needed.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "op": {
          "type": "string",
          "description": "One op name, e.g. \"set_midi_notes\" — returns that op in full."
        },
        "ops": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Several op names — returns each in full."
        },
        "section": {
          "enum": [
            "summary",
            "ops",
            "recipes",
            "units",
            "ids",
            "all"
          ],
          "type": "string",
          "description": "Which part of the catalog. Omit for the default overview."
        }
      },
      "additionalProperties": false
    }
    arguments 29 lines
  • doseedo_bounce_session changes data unknown never probed

    Bounce a session (or specific tracks) to audio through their REAL plugin chains, offline — Dø Desktop renders them in the background WITHOUT the user opening the DAW (live via Logic if it's open, headless if it isn't; this is the thing stock DAWs can't do). Headless renders AUDIO tracks only — an instrument/MIDI track needs the project open in Logic. A track that could not render is named in the error with its reason. Async: returns a job_id — poll with doseedo_wait_task. The result is downloadable stem URLs. Needs Dø Desktop to run at some point to pick up the job; until then it stays queued. No credits (rendered on the user's machine). Cancel: a bounce still queued never renders (its budget is refunded); one mid-render has its result dropped on arrival.

    mcp-tool

    {
      "type": "object",
      "required": [
        "session_id"
      ],
      "properties": {
        "stems": {
          "type": "boolean",
          "description": "true (default) = one file per track; false = a single mixdown."
        },
        "format": {
          "enum": [
            "wav",
            "aiff"
          ],
          "type": "string",
          "description": "Output format (default wav)."
        },
        "track_ids": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Tracks to bounce (t_… ids from doseedo_get_session). Omit to bounce the whole session."
        },
        "session_id": {
          "type": "string"
        },
        "tail_seconds": {
          "type": "number",
          "description": "Extra seconds for reverb/delay to ring out (default 2)."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        }
      },
      "additionalProperties": false
    }
    arguments 39 lines
  • doseedo_cover_stem unknown never probed

    TIMBRE TRANSFER (an instrument swap) from a recording: hum or whistle a melody, play it on a kazoo, take a guitar line — and get it back played by a cello, a trumpet, a koto (any doseedo_instruments call). Re-play ONE recorded part — a separated stem, a solo, a region of the user's session — on another instrument, straight from the audio: the recording's FSQ codes carry its structure into a take generated from noise, and the sound is the instrument's (caption + timbre_preset) — the FSQ + timbre combination the cond5 model was trained on (served on its turbo graft). No MIDI by default (midi:true adds the server's own pitch roll of the recording); `fidelity` > 0 also keeps that much of the recording's own latents (closer, but its sound leaks back in). For the exact notes, transcribe and doseedo_render_midi; a whole mix → doseedo_cover_song. result.recipe says what reached the model (fsq, timbre, cns). Async: job_id → doseedo_wait_task (~30–90 s) → takes[{url}] (pre-signed: curl -OJ, no auth header, 24 h). 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.

    mcp-tool

    {
      "type": "object",
      "required": [
        "instrument",
        "duration_seconds"
      ],
      "properties": {
        "bpm": {
          "type": "number",
          "description": "The recording's tempo (a hint; default 120)."
        },
        "fsq": {
          "type": "boolean",
          "description": "false = leave the recording's FSQ codes out: the take follows the server's note roll (needs midi: true) on the instrument's sound, with none of the source's phrasing or articulation carried over — for a line whose phrasing doesn't suit the new instrument (a sung vocal on a sax). Default true. recipe.fsq says which ran."
        },
        "midi": {
          "type": "boolean",
          "description": "true = the server also transcribes the recording's notes into a roll that drives the MIDI hooks beside the FSQ codes — closer notes, a little slower (LatentPitch on audio; vaescriptor on a latent_key; a drum part — either route — gets its hits from vaescriptor_drums). recipe.midi_source names it. Default false: the codes alone."
        },
        "name": {
          "type": "string",
          "maxLength": 80,
          "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>."
        },
        "seed": {
          "type": "number",
          "description": "Optional random seed for reproducibility."
        },
        "takes": {
          "type": "number",
          "description": "How many takes, 1–4 (default: the server's best-of-N)."
        },
        "fidelity": {
          "type": "number",
          "description": "How much of the recording's own latents the take keeps, 0–0.6 (cover noise strength over the source). Default 0: structure from its FSQ codes only, the sound all the instrument's."
        },
        "audio_key": {
          "type": "string",
          "description": "R2 ingest key of an uploaded audio file (from doseedo_get_upload_url / POST /api/upload/r2/ingest-url; starts with \"ingest/\"). Provide this, audio_url, or latent_key."
        },
        "audio_url": {
          "type": "string",
          "description": "https URL of the audio, as an alternative to audio_key: a doseedo result URL exactly as a job returned it (a stem, a take, a bounce), or any public URL. The gateway fetches it (≤256 MB) into your account's ingest storage before the job starts. Pass audio_key OR audio_url."
        },
        "instrument": {
          "type": "string",
          "description": "REQUIRED. The instrument that plays it — call.instrument from doseedo_instruments (with its call.timbre_preset where it has one)."
        },
        "latent_key": {
          "type": "string",
          "description": "Instead of the audio: the recording already VAE-encoded (ACE-Step 1.5 VAE, 48 kHz stereo → [T, 64] at 25 Hz, the latent mean) as a 64-channel 25 Hz float WAV `*.latent.wav`, uploaded like audio (POST /api/jobs/uploads). The server skips its encode. Dø Desktop sends this when encoding on the Mac lands sooner than uploading the audio."
        },
        "timbre_preset": {
          "type": "string",
          "description": "A named timbre preset (the catalog's preset ids, e.g. \"cello:preset1\"). Omit for the instrument default."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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_seconds": {
          "type": "number",
          "description": "REQUIRED. The recording's length in seconds (0.5–600): the take is this long."
        }
      },
      "additionalProperties": false
    }
    arguments 67 lines
  • doseedo_train_instrument unknown never probed

    Make a CUSTOM INSTRUMENT in your own sound: upload 30 s–3 min of ONE instrument playing (your own player, a rare or folk instrument, a prepared/invented instrument, a vintage synth) and doseedo trains a private adapter (LoRA) on its serving instrument model in about 1–2 minutes. After that, doseedo_render_midi {instrument: <the same instrument>, lora_id} plays ANY notes you write in that sound. Several takes help (up to 8 files; the first 3 min are used, ≥8 s required); a clean, solo, dry recording works best. instrument = the closest catalog instrument — it picks the model voice the adapter trains on (a shamisen trains as acoustic_guitar, a whistle as flute: doseedo_instruments lists each one's call.instrument). The notes are transcribed for you (pass notes to skip that). 20 credits. Result: lora_id, name, the windows it trained on, loss first→last, and `use` (the render args). Earlier ones: doseedo_list_jobs {kind:"train_instrument"}. Owner-only: no one else can render with it. Async: job_id → doseedo_wait_task (~1–2 min). Cancel: the plane has no stop for a running training — it runs to completion (credits spent), the job ends as canceled and its output is discarded. Only a job still queued at the plane is refunded by the plane's own failure refund.

    mcp-tool

    {
      "type": "object",
      "required": [
        "instrument"
      ],
      "properties": {
        "bpm": {
          "type": "number",
          "description": "Optional tempo of the recording (30–300)."
        },
        "name": {
          "type": "string",
          "description": "A name for it, e.g. \"Grandpa's banjo\" (≤80 chars)."
        },
        "seed": {
          "type": "number",
          "description": "Random seed."
        },
        "notes": {
          "type": "array",
          "description": "Optional: the notes played, one list per file — [[{pitch, start, end, velocity?}…]] in SECONDS. Omitted, they are transcribed."
        },
        "steps": {
          "type": "number",
          "description": "Training steps 50–800. Default 300 for ≤60 s of audio, 400 above."
        },
        "audio_key": {
          "type": "string",
          "description": "R2 ingest key of an uploaded audio file (from doseedo_get_upload_url / POST /api/upload/r2/ingest-url; starts with \"ingest/\"). One recording; or audio_keys for several."
        },
        "audio_url": {
          "type": "string",
          "description": "https URL of a recording (a doseedo result link — a separated stem works — or any public URL). Alternative to audio_key."
        },
        "drum_mode": {
          "type": "boolean",
          "description": "true for an unpitched percussion recording."
        },
        "audio_keys": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Several uploaded takes of the SAME instrument (≤8)."
        },
        "audio_urls": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Several recording URLs of the same instrument (≤8)."
        },
        "instrument": {
          "type": "string",
          "description": "REQUIRED. The catalog instrument it is closest to (call.instrument from doseedo_instruments, e.g. \"violin\", \"acoustic_guitar\", \"flute\", \"percussion\")."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        }
      },
      "additionalProperties": false
    }
    arguments 63 lines
  • doseedo_mix unknown never probed

    MIXING and MASTERING: each part levelled, panned, high-passed, given its depth on a shared reverb, and mastered to a loudness target — a WAV AND `mixgraph`, the mix as a document you edit. After doseedo_render_score pass from_job (its parts and the instruments they play are the stems); or stems: [{name, audio_url, instrument?}] (result links work as-is). An orchestra (strings / winds / brass / timpani / harp…) is SEATED by default (film-orchestral: violins left, low strings right, brass behind, each seat at its depth in a 2.3 s hall, written dynamics riding the faders); other stems get the blind default. style: film-orchestral, film-scoring-stage, concert-hall, film-epic-hybrid, cathedral-choral, classical-chamber, cartoon-studio, golden-age-cartoon, jazz-combo, ambient, country-pop, metal-modern, 1950s-mono, 1960s-lcr-pop, 1970s-analog-rock, 1970s-dub, 1980s-pop-gated, 1990s-rock-dry, 1990s-hiphop, 2000s-loudness-rock, 2010s-edm, 2010s-trap, 2020s-pop, 2020s-hyperpop — an id or words ("dry 90s rock"). balance {part: dB} moves parts on top of the levelling (+3 brings a melody forward). Change the mix: edit the returned mixgraph — strips[] {stem, gain_db, pan, seat, chain, sends}, buses[] (verb = the hall), master.chain, automation [{target: "strips.<stem>.gain_db", points: [[seconds, dB]…]}] for rides (dB off the strip's gain_db: 0 = as set, -60 mutes) — and call again with mix_job (this job_id) + only your edits (or the whole mixgraph + the same stems): rendered as written, rails reported, no credits. Then doseedo_session_from_stems {from_job, mix_job: <this job_id>} → the DAW project at this mix's levels and pans. TO PICTURE: dialogue (the VO; the music ducks under each line), music_offset_s (bar 1 on the picture), length_s (cut + end fade). Async: job_id → doseedo_wait_task (~15–90 s). Cancel: the plane has no stop for a running mix — it runs to completion (credits spent), the job ends as canceled and its output is discarded. Only a job still queued at the plane is refunded by the plane's own failure refund.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "duck": {
          "type": "object",
          "properties": {
            "max_db": {
              "type": "number"
            },
            "include": {
              "type": "boolean"
            },
            "carve_db": {
              "type": "number"
            },
            "vo_over_db": {
              "type": "number"
            }
          },
          "description": "How the music sits under the dialogue: {vo_over_db (default 7 dB — a broadcast mix's 6–10), carve_db (default 3, at 1–4 kHz), max_db (default 12), include (default true; false = the music bed alone, ducked as if the voice played)}.",
          "additionalProperties": false
        },
        "name": {
          "type": "string",
          "maxLength": 80,
          "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>."
        },
        "room": {
          "anyOf": [
            {
              "enum": [
                "studio",
                "stage",
                "hall",
                "cathedral"
              ],
              "type": "string"
            },
            {
              "type": "number",
              "maximum": 1,
              "minimum": 0
            }
          ],
          "description": "An orchestra's room: \"studio\" (intimate scoring stage, ~1.2 s, close), \"stage\" (~1.8 s), \"hall\" (the default scoring hall, ~2.3 s), \"cathedral\" (~4 s, wet) — or 0..1 between them. Sets the decay, size and how wet every seat sits."
        },
        "stems": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "name",
              "audio_url"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "audio_url": {
                "type": "string"
              },
              "instrument": {
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          "description": "[{name, audio_url, instrument?}] — the stems (≤ 32). instrument = the sound it plays (a doseedo_instruments id: \"violin\", \"timpani\", \"harp\"), which decides how it is mixed; without it the name decides."
        },
        "style": {
          "type": "string",
          "description": "A mix style: an id or words (\"dry 90s rock\"). Pick it for the picture — the default (film-orchestral, a 2.3 s scoring hall) suits film drama, not every orchestra: cartoon-studio = a cartoon / animation orchestra (a close, dry, wide scoring stage, punchy rides); golden-age-cartoon = a 1940s–50s cartoon (mono, small studio, tape); film-scoring-stage = intimate TV / documentary; concert-hall; film-epic-hybrid = trailer / action; cathedral-choral; classical-chamber; or jazz-combo, ambient, 1970s-analog-rock, 2020s-pop …"
        },
        "balance": {
          "type": "object",
          "description": "{part name: dB in -12..12} — your balance on top of the levelling (and of the written dynamics a from_job reads).",
          "additionalProperties": {
            "type": "number"
          }
        },
        "mix_job": {
          "type": "string",
          "description": "MCP: a doseedo_mix job_id to edit — its whole stored mix (every ride) is the base, mixgraph is applied on top, and its stems are reused when you pass no from_job / stems."
        },
        "vintage": {
          "enum": [
            "tape",
            "shellac",
            "none"
          ],
          "type": "string",
          "description": "A period medium over any style, after the mix: \"tape\" = 7.5 ips tape (saturation, wow and flutter, a low hiss); \"shellac\" = a 78 played back (mono, ~90 Hz–5.5 kHz with the reproducer's presence, a 1.3 Hz wow, surface noise that swishes once a turn, crackle). \"none\" takes a style's own medium off (golden-age-cartoon carries tape). Its node (master.chain type vintage: noise_db, crackle, hi_hz …) is editable in the returned mixgraph."
        },
        "dialogue": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "audio_url"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "audio_url": {
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          "description": "The VO / dialogue on the picture's timeline (≤ 4): [{name?, audio_url}]. The music ducks under each line until the voice sits duck.vo_over_db over it, with a 1–4 kHz carve while it talks; the voice joins after the music's master chain. Report: output.dialogue.lines [{start_s, end_s, duck_db, vo_over_music_db}] as mixed."
        },
        "dynamics": {
          "type": "object",
          "description": "Fader rides from written dynamics: {part name: [[onset_seconds, velocity 0-127], …]}. from_job fills it from the score (pp to ff ≈ 17 dB); pass {} for no rides.",
          "additionalProperties": {
            "type": "array"
          }
        },
        "from_job": {
          "type": "string",
          "description": "MCP: a doseedo_render_score job_id — its parts are the stems, each with the instrument it plays, and each part's written dynamics (its mean velocity) set its balance."
        },
        "length_s": {
          "type": "number",
          "maximum": 600,
          "minimum": 0.5,
          "description": "The program's length (a :30 = 30; ≤ 600 s): the mix is cut there with end_fade_s (default 0.5 s); the room's tail never runs past it."
        },
        "mixgraph": {
          "type": "object",
          "description": "An edited mix — the mixgraph a doseedo_mix returned, changed — rendered against the same stems (from_job or stems). With mix_job: ONLY what you change (strips[] by stem, automation[] rides by target — points: [] removes one, buses[] by id, master) — the rest is that mix as stored. A mixgraph marked `partial` (its rides summarized) is refused without mix_job. Omit for a fresh mix."
        },
        "end_fade_s": {
          "type": "number",
          "description": "With length_s: the fade at the program's end (0–10 s, default 0.5)."
        },
        "target_lufs": {
          "type": "number",
          "description": "Master loudness, -24..-6 LUFS (default: the style's — -18 for film-orchestral, -14 for the blind default). Met within ~0.3 LU (a loud target clips the shortest transients first); output.loudness says what landed, and why when short. With mix_job it re-masters the stored mix."
        },
        "tonal_match": {
          "type": "boolean",
          "description": "Nudge the master toward professionally mixed orchestral references (default on for the orchestral styles). Its presence and air are judged only where the score is written loud (written_level), so a pp passage keeps its darkness."
        },
        "dynamics_ride": {
          "type": "number",
          "description": "How hard the written dynamics move the faders: 1 = default (pp to ff ≈ 17 dB), 0 = no rides, up to 1.5."
        },
        "written_level": {
          "type": "array",
          "items": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "maxItems": 2,
            "minItems": 2
          },
          "maxItems": 4096,
          "description": "[[seconds, velocity], …] — the whole score's written level, the loudest part sounding, held until the next row (0 = nothing plays). The tonal match reads only the passages it writes loud (f and louder), so a pp passage keeps its darkness. from_job fills it."
        },
        "music_offset_s": {
          "type": "number",
          "maximum": 600,
          "minimum": 0,
          "description": "Where bar 1 of the music sits on the picture (seconds, ≤ 600; the program ≤ 600 s): every music stem — and its rides — starts this late; the dialogue does not move."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        },
        "dynamics_carried": {
          "type": "object",
          "description": "{part name: top velocity} — parts whose stems already play their written level (a render part's dynamics_level receipt, up to its top_vel). Their rides count it: no doubled swing. from_job fills it.",
          "additionalProperties": {
            "type": "number"
          }
        }
      },
      "additionalProperties": false
    }
    arguments 182 lines
  • doseedo_cover_song changes data unknown never probed

    AI COVER / style transfer of a whole song: re-render an uploaded song as a cover, keeping its structure/melody while changing timbre, instruments, or lyrics. INSTRUMENT SWAP: instruments {"piano": "electric_guitar"} separates the song, transcribes the swapped stem and re-plays THOSE transcribed notes on the target instrument; by default only the swapped stem(s) are regenerated and every other stem passes through as the original separated audio (regen changes that). Because the swap replays a transcription, small note differences from the source are expected — verify from result.cover.instrument_swaps (applied or why not), and offer the user the result/takes to judge rather than promising a note-perfect copy. Target ids: GET https://api.doseedo.com/api/instruments (open). Optionally export a DAW session too. Async: returns a job_id — poll with doseedo_wait_task (several minutes for full songs). Result files are pre-signed links: curl -OJ <url>, no auth header (valid 24 h). 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.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "maxLength": 80,
          "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>."
        },
        "seed": {
          "type": "number",
          "description": "Optional random seed for reproducibility."
        },
        "genre": {
          "type": "string",
          "maxLength": 64,
          "description": "Optional GENRE style transfer: the target genre in a few words, at most 64 characters (e.g. \"bossa nova\", \"80s synth-pop\", \"West End musical showstopper\") — a name, not a description; every regenerated stem is captioned with it. Outcome in result.cover.genre."
        },
        "regen": {
          "type": "string",
          "description": "Optional: which stems to regenerate. Default with a swap = only the swapped stems (the rest are the original separated audio). \"all\" = cover every stem; or a comma list of stems/instruments, e.g. \"piano,other\" (a swapped stem is always regenerated)."
        },
        "export": {
          "enum": [
            "logic",
            "ableton"
          ],
          "type": "string",
          "description": "Optionally also build a DAW session for this target."
        },
        "labels": {
          "type": "object",
          "description": "Optional identity CORRECTIONS {source: instrument}, same shape as instruments, e.g. {\"other\": \"trumpet\"} when the separation mislabels a stem. Only fixes what the stem is called (caption/timbre); nothing is re-played. Outcome in result.cover.stem_labels.",
          "additionalProperties": {
            "type": "string"
          }
        },
        "lyrics": {
          "type": "string",
          "description": "Optional replacement lyrics."
        },
        "swap_cns": {
          "type": "number",
          "description": "Optional 0–1, only with instruments: how far the SWAPPED stems may depart from their source (overrides cover_noise_strength for them; server default 0.35). Lower = closer to the original timing/feel."
        },
        "audio_key": {
          "type": "string",
          "description": "R2 ingest key of an uploaded audio file (from doseedo_get_upload_url / POST /api/upload/r2/ingest-url; starts with \"ingest/\"). Provide this or audio_url."
        },
        "audio_url": {
          "type": "string",
          "description": "https URL of the audio, as an alternative to audio_key: a doseedo result URL exactly as a job returned it (a stem, a take, a bounce), or any public URL. The gateway fetches it (≤256 MB) into your account's ingest storage before the job starts. Pass audio_key OR audio_url."
        },
        "midi_only": {
          "type": "boolean",
          "description": "Optional: re-perform every regenerated stem from its transcribed MIDI with NO timbre from the recording (the stem's own sound is dropped). Stems with nothing to render are skipped (result.cover.midi_only.skipped)."
        },
        "style_key": {
          "type": "string",
          "description": "Optional ingest key (upload it first) of a reference MIX whose TIMBRE the regenerated stems take on (style transfer)."
        },
        "drum_split": {
          "type": "boolean",
          "description": "true = explode the covered drums into isolated kick/snare/hh/… stems, each generated from its own slice of the drum roll (result.drum_stems)."
        },
        "instruments": {
          "type": "object",
          "description": "Optional per-stem instrument SWAP map {source: target}, e.g. {\"piano\": \"electric_guitar\", \"sax\": \"violin\"}. Source = a stem (drums, bass, vocals, guitar, piano, other) or a detected instrument (sax, trumpet…); target = an instrument id from /api/instruments (an unknown target is refused up front).",
          "additionalProperties": {
            "type": "string"
          }
        },
        "guitar_split": {
          "type": "string",
          "description": "Deal the guitar bucket into N players, each its own row/swap: \"2\"–\"4\", or \"auto\" (a one-vs-two probe decides). Outcome in result.cover.guitar_split."
        },
        "structure_key": {
          "type": "string",
          "description": "Optional ingest key of audio whose STRUCTURE codes replace the source's (the Cover page's \"Structure: custom\")."
        },
        "timbre_preset": {
          "type": "string",
          "description": "Optional named timbre preset — the fallback rung of the timbre ladder (stem latent > this > stock bank)."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        },
        "cover_noise_strength": {
          "type": "number",
          "description": "Optional 0–1 fidelity dial: higher departs further from the source."
        }
      },
      "additionalProperties": false
    }
    arguments 94 lines
  • doseedo_transcribe changes data unknown never probed

    AUDIO TO MIDI transcription: a melody, a bass line or a part as notes (pitch, onset/offset seconds, velocity, confidence as JSON — not a MIDI file; for .mid files per stem use doseedo_separate_stems with transcription or doseedo_audio_to_session). Works from an uploaded audio_key or an audio_url — any public https URL, including a result URL from another doseedo job (a generate take, a stem) as it was returned. Async: returns a job_id — poll with doseedo_wait_task (usually ~15–60s). For the KEY / tempo / chords of a whole mix use doseedo_analyze_song instead. Cancel: the plane has no stop for a running transcription — it runs to completion (credits spent), the job ends as canceled and its output is discarded. Only a job still queued at the plane is refunded by the plane's own failure refund.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "want": {
          "enum": [
            "notes",
            "f0",
            "notes,f0"
          ],
          "type": "string",
          "description": "What to return: \"notes\" (default), \"f0\" (the continuous pitch contour — frame-rate Hz values, for glides/vibrato/intonation), or both."
        },
        "chairs": {
          "type": "string",
          "description": "polyphony=\"section\": register codes per chair, as an alternative to roster."
        },
        "family": {
          "type": "string",
          "description": "Optional instrument family (e.g. \"brass\", \"reeds\", \"strings\") when the exact instrument is unknown."
        },
        "roster": {
          "type": "string",
          "description": "polyphony=\"section\": the chairs on the stem, e.g. \"trumpet,trumpet,trombone,tenor_sax\". Omit for the family default."
        },
        "backend": {
          "type": "string",
          "description": "Advanced: force a transcription backend. Omit — the server routes by instrument."
        },
        "strikes": {
          "type": "boolean",
          "description": "With tempo_bpm: also return the harmony_strikes attack grid."
        },
        "register": {
          "type": "string",
          "description": "Optional register hint for the instrument (e.g. \"soprano\", \"tenor\", \"bass\")."
        },
        "audio_key": {
          "type": "string",
          "description": "R2 ingest key of an uploaded audio file (from doseedo_get_upload_url / POST /api/upload/r2/ingest-url; starts with \"ingest/\"). Provide this or audio_url."
        },
        "audio_url": {
          "type": "string",
          "description": "https URL of the audio to transcribe (alternative to audio_key): any public URL, or a doseedo result URL exactly as a job returned it — no key needed."
        },
        "polyphony": {
          "type": "string",
          "description": "Optional: \"solo\" (monophonic line), \"poly\", or \"section\" (a horn section — see roster/chairs)."
        },
        "tempo_bpm": {
          "type": "number",
          "description": "Optional known tempo — enables beat-aligned note times."
        },
        "instrument": {
          "type": "string",
          "description": "Optional instrument hint, e.g. \"piano\", \"sax\", \"vocals\", \"bass\"."
        },
        "beats_per_bar": {
          "type": "number",
          "description": "With tempo_bpm: beats per bar for the beat-domain times (default 4)."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        }
      },
      "additionalProperties": false
    }
    arguments 67 lines
  • doseedo_analyze_song unknown never probed

    Key detection, BPM/tempo detection, song structure and chords — musical analysis of a recording in one call: key (e.g. "D minor"), bpm + per-beat tempo_map, meter / beats_per_bar, downbeats (seconds), sections (intro/verse/chorus… with times), chords (a progression on the beat grid), dynamics. USE THIS to learn the key and tempo of a reference before writing a part — never guess or ask the user for what the audio already says. Pass audio_key (an upload) or audio_url (a result URL from another job as returned, or any public https URL). Up to 10 minutes of audio is analyzed. Synchronous (~5–20 s): the result is in this response. No separation, so a dense mix's chords are a draft — for a chord chart from stems use doseedo_detect_chords on the separated stems. Cancel: not applicable — the result is returned in the submit response; the job is already finished.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "audio_key": {
          "type": "string",
          "description": "R2 ingest key of an uploaded audio file (from doseedo_get_upload_url / POST /api/upload/r2/ingest-url; starts with \"ingest/\"). Provide this or audio_url."
        },
        "audio_url": {
          "type": "string",
          "description": "https URL of the audio (a doseedo result URL as returned, or any public URL). Alternative to audio_key."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        }
      },
      "additionalProperties": false
    }
    arguments 18 lines
  • doseedo_create_session changes data unknown never probed

    Create a new, empty DAW session in the account (a blank project you can then populate with doseedo_edit_session, or target with doseedo_audio_to_session). Returns its session_id.

    mcp-tool

    {
      "type": "object",
      "required": [
        "name"
      ],
      "properties": {
        "daw": {
          "enum": [
            "logic",
            "ableton"
          ],
          "type": "string",
          "description": "Bound DAW (default logic)."
        },
        "name": {
          "type": "string",
          "description": "Session name."
        }
      },
      "additionalProperties": false
    }
    arguments 21 lines
  • doseedo_fill_gap unknown never probed

    INPAINT (repair) a part: send ONE recorded part (a stem, a DAW track's audio) with a gap in it — the silence between two clips, a bar to redo, a dropout — and get it back with the gap PLAYED: the take before and after the gap is kept bit-exact (spliced back), and the gap is generated against both, so it continues out of what comes before and leads into what follows. What fills it is planned first (the DSP plane's extend planner, which hears the part): the take's own LOOP when it has one — the gap is seeded from its own passes at the matching bar phase, so a groove keeps turning — else a part written in its key and over its chords, performed in the take's own sound. Pass the session's bpm and bar grid (bar_offset_seconds: where a bar line falls in the audio you send); the gap is in seconds of that audio. Send the part with some of the take on each side of the gap (8 bars or more before it is best). Async: job_id → doseedo_wait_task (~40–150 s) → takes[{url}]: WAVs as long as the audio you sent, the gap filled — cut out the gap (or the span you need) to drop it into the DAW. output.plan says what filled it (loop bars, or the writer and the changes). 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.

    mcp-tool

    {
      "type": "object",
      "required": [
        "duration_seconds",
        "gap_start_seconds",
        "gap_end_seconds",
        "bpm"
      ],
      "properties": {
        "bpm": {
          "type": "number",
          "description": "REQUIRED. The session's tempo — the gap is filled on its bar grid."
        },
        "fill": {
          "enum": [
            "auto",
            "context",
            "loop",
            "written"
          ],
          "type": "string",
          "description": "What fills the gap: \"context\" = the span played AGAIN from the take around it — no plan, no notes: a variation of what is there, in its own sound and level (INPAINTING a span that has audio — the right default there); \"loop\" = the take's own passes (a groove that keeps turning), \"written\" = a part written in its key and chords, \"auto\" (default) = the loop when the part has one, else written."
        },
        "keep": {
          "type": "number",
          "description": "fill \"context\": how much of what is in the span its regeneration keeps, 0.01–0.9 (default 0.05: a variation; 0.45 ≈ the same playing again)."
        },
        "name": {
          "type": "string",
          "maxLength": 80,
          "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>."
        },
        "role": {
          "enum": [
            "drums",
            "perc",
            "bass",
            "harmony",
            "melody"
          ],
          "type": "string",
          "description": "The part's role, when you know it (the planner hears it otherwise)."
        },
        "seed": {
          "type": "number",
          "description": "Optional random seed (the same seed plans and renders the same)."
        },
        "takes": {
          "type": "number",
          "description": "How many takes, 1–4 (default: the server's best-of-N)."
        },
        "audio_key": {
          "type": "string",
          "description": "R2 ingest key of an uploaded audio file (from doseedo_get_upload_url / POST /api/upload/r2/ingest-url; starts with \"ingest/\"). The part, with the gap in it. Provide this or audio_url."
        },
        "audio_url": {
          "type": "string",
          "description": "https URL of the audio, as an alternative to audio_key: a doseedo result URL exactly as a job returned it (a stem, a take, a bounce), or any public URL. The gateway fetches it (≤256 MB) into your account's ingest storage before the job starts. Pass audio_key OR audio_url."
        },
        "exact_grid": {
          "type": "boolean",
          "description": "true = the audio is cut from a DAW session, so bpm and bar_offset_seconds are its EXACT grid: the fill keeps it (default false: the planner fine-tunes the grid to the audio's own onsets — right for a stem whose tempo you only know roughly)."
        },
        "instrument": {
          "type": "string",
          "description": "What plays the part (an id from doseedo_instruments). Optional — the take's own sound is kept either way; a written fill is played by it."
        },
        "track_name": {
          "type": "string",
          "description": "The part's track name in the DAW (\"Drums\", \"Bass\", \"Strings\") — the planner hears a role from the name first, then from the sound."
        },
        "time_signature": {
          "type": "string",
          "description": "The session's meter, e.g. \"4/4\" (default) or \"3/4\"."
        },
        "gap_end_seconds": {
          "type": "number",
          "description": "REQUIRED. Where the gap ends (and the take resumes), in seconds of the audio."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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_seconds": {
          "type": "number",
          "description": "REQUIRED. The audio's length in seconds (1–600)."
        },
        "gap_start_seconds": {
          "type": "number",
          "description": "REQUIRED. Where the gap starts, in seconds of the audio."
        },
        "bar_offset_seconds": {
          "type": "number",
          "description": "Where a bar line falls in the audio (seconds; default 0 = the audio starts on a downbeat). Sending a span of a DAW track that starts mid-bar? Give the first downbeat's time in it."
        }
      },
      "additionalProperties": false
    }
    arguments 98 lines
  • doseedo_render_midi unknown never probed

    MIDI TO AUDIO, the virtual instrument for agents — THE tool for "I wrote the part, now play it": an AI instrument model (orchestral strings, brass, woodwinds, piano, guitar, bass, drums, World) performs your exact notes, in your key, at your bpm, and returns audio takes (doseedo_generate_music takes no notes or key). Input ONE of: notes[] ({pitch, start_beats, duration_beats, velocity} — beats from bar 1, the same rows as doseedo_edit_session set_midi_notes), midi_url (a .mid ≤2 MiB: a doseedo result link or a public https URL), or session_id + track_id (that track's notes, read from the session). Required: instrument (an entry's `call` from doseedo_instruments, no key — stay inside its range) and bpm. The notes are sent AS GIVEN — no pitch snapping, no quantizing. One voice per part: a chord part is rendered one voice per output with voice_split:true (result.voices maps each voice to its files and notes). Takes come back best-first (takes[0] = the scorer's winner). Async: job_id → doseedo_wait_task (~1–3 min). Result: takes[{url, rank, score}] (pre-signed: curl -OJ, no auth header, 24 h), seed, duration, voices?, refine?, chain. A take may miss or change a note — read takes[].check (measured against your notes) or listen; offer the takes, never promise note-perfection. Free harmony check first: doseedo_analyze_midi. DRUMS (GM notes): drum_engine:"oneshot" = a sampler kit made for drum_genre (default for "electronic"/"808"), every hit as written — use it on ANY kit when every hit must land; the drum model PERFORMS a kit and can drop hits (takes[].fit.missing). "synth" = a one-shot patch (synth_role, synth_genre; "performed" = played, less 1-shot); result.oneshots = the samples. SOUND: a preset (timbre_preset), a recording's tone (timbre_audio_url = timbre transfer), or YOUR OWN instrument (lora_id from doseedo_train_instrument; result.lora.applied). 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.

    mcp-tool

    {
      "type": "object",
      "required": [
        "instrument"
      ],
      "properties": {
        "bpm": {
          "type": "number",
          "description": "REQUIRED (or tempo_map). Tempo of the notes (10–400). Written into the MIDI's tempo meta, so start_beats/duration_beats land at exactly this tempo."
        },
        "name": {
          "type": "string",
          "maxLength": 80,
          "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>."
        },
        "seed": {
          "type": "number",
          "description": "Random seed (−1 or 0–4294967295). Reuse a result's seed to re-render close to the same take."
        },
        "tune": {
          "type": "boolean",
          "description": "Light intonation (default true): a held, clearly pitched note the model rendered 15–85 cents off its written pitch is moved toward it, to a small natural residual — attack and vibrato as played, fast notes left. Winds, brass and strings. false = the take exactly as rendered."
        },
        "notes": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "pitch",
              "start_beats",
              "duration_beats"
            ],
            "properties": {
              "pitch": {
                "type": "number",
                "description": "MIDI note number 0–127 (60 = middle C)."
              },
              "velocity": {
                "type": "number",
                "description": "1–127 (default 96)."
              },
              "start_beats": {
                "type": "number",
                "description": "Onset in beats from bar 1."
              },
              "duration_beats": {
                "type": "number",
                "description": "Length in beats (> 0)."
              }
            },
            "additionalProperties": false
          },
          "description": "The part, as note rows in beats from bar 1 (beat 0 = bar 1 beat 1, quarter-note beats at `bpm`). Monophonic for one voice; chords need voice_split:true. Up to 4096 notes."
        },
        "takes": {
          "type": "number",
          "description": "How many takes to render, 1–4 (one GPU batch; no extra credits). Omit to let the server choose best-of-N for the part length."
        },
        "lyrics": {
          "type": "string",
          "description": "A SUNG part (instrument \"voice\" — a solo singer — or \"choir\"): the words, one syllable per note in time order (\"Hold the light a lit-tle lon-ger\": hyphens split a word where you want, \"_\" holds a syllable over the next note; one word such as \"Ah\" is sung on every note). ≤2000 chars. Without it a sung part sings \"Ooh\". Any other instrument: an error."
        },
        "prompt": {
          "type": "string",
          "description": "Optional caption override (default: the instrument id). Style words help a little; the notes are the control."
        },
        "refine": {
          "enum": [
            "light",
            "shred"
          ],
          "type": "string",
          "description": "Opt-in post-render correction. \"light\": attacks re-timed onto the score, exposed wrong pitch classes re-pitched inside the played octave, misfires muted (winds/brass/strings). \"shred\": play exactly the written line, octave included, mute anything the score never wrote (any pitched mono part). The raw render stays downloadable (result.refine.raw_url)."
        },
        "vaefix": {
          "type": "boolean",
          "description": "VAE spectral corrector (default true): trims the low-mid fog the decoder adds under the instrument's register and removes mic hiss only when the take carries it. Winds, brass and strings. Receipt: vaefix. false = the decode exactly as rendered."
        },
        "lora_id": {
          "type": "string",
          "description": "A CUSTOM INSTRUMENT: the lora_id doseedo_train_instrument returned (16 hex). The render is played by that trained instrument; pass the same instrument it was trained as. Owner-only."
        },
        "dynamics": {
          "type": "string",
          "description": "One target dynamic for the whole part's tone: \"pp\", \"p\", \"mp\", \"mf\", \"f\", \"ff\", \"fff\", a 0–1 number, or a MIDI velocity as text. Omit it to let the notes' velocities shape the tone (dynamics_curve)."
        },
        "midi_url": {
          "type": "string",
          "description": "Alternative to notes: https URL of a Standard MIDI File (≤2 MiB) — a doseedo result link (a stem's MIDI) or a public URL. Its own tempo map is used by the model; bpm still tags the caption and sizes the default duration."
        },
        "track_id": {
          "type": "string",
          "description": "With session_id: the t_… id of the MIDI/instrument track to render."
        },
        "tempo_map": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "beat",
              "bpm"
            ],
            "properties": {
              "bpm": {
                "type": "number"
              },
              "beat": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "description": "Tempo CHANGES for the notes: [{beat, bpm}] — each point holds from its beat (beats from bar 1) until the next; the first point is beat 0 (or bpm covers the beats before it). Written into the MIDI, so a ritardando or a tempo that lands a cue on a film hit plays exactly. doseedo_tempo_map builds one from hit times."
        },
        "drum_genre": {
          "type": "string",
          "description": "Electronic drums (instrument \"electronic\" or \"808\"): the genre whose one-shot kit plays the part — \"house\", \"techno\", \"trap\", \"drill\", \"lo-fi\", \"dnb\", \"amapiano\", \"synthwave\"… or free words. Default: the instrument."
        },
        "instrument": {
          "type": "string",
          "description": "REQUIRED. The instrument from doseedo_instruments — its `call.instrument` (e.g. \"violin\", \"tenor_sax\", \"electric_guitar\", \"piano\"; a World name such as \"koto\" is resolved to its call). Keep the notes inside its range. An unknown name close to a catalog one is refused with did_you_mean before anything is spent."
        },
        "session_id": {
          "type": "string",
          "description": "Alternative to notes: with track_id, render THAT session track's notes (read from doseedo_get_session's summary)."
        },
        "synth_role": {
          "enum": [
            "bass",
            "808",
            "pad",
            "lead",
            "pluck"
          ],
          "type": "string",
          "description": "instrument \"synth\": the patch Stable Audio Open makes for the part — bass (an 808 where the genre's bass is one), 808, pad, lead, pluck. Default: from the notes (chords = pad, a low line = bass, else lead)."
        },
        "drum_engine": {
          "enum": [
            "oneshot",
            "model"
          ],
          "type": "string",
          "description": "Who plays a drum part: \"oneshot\" = a sampler kit made for drum_genre (the default for electronic / 808; congas and bongos are recordings of the skins) — every note lands exactly as written; use it on ANY kit when every hit must land. \"model\" = the drum model (the default for every other kit): a performance, which can drop or smear hits — read takes[].fit. 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."
        },
        "synth_genre": {
          "type": "string",
          "description": "instrument \"synth\": the genre the patch is made for — \"house\", \"techno\", \"trap\", \"synthwave\", \"lo-fi\", \"dnb\"… or free words."
        },
        "synth_words": {
          "type": "string",
          "description": "instrument \"synth\": extra sound words for the patch (\"reese\", \"warm analog\", \"acid\"), ≤80 chars."
        },
        "voice_split": {
          "type": "boolean",
          "description": "true = the notes hold chords: split them into the voices one player of this instrument can hold and render every voice (result.voices). A SUNG chord (choir, voice) is sung one stem per voice, each in its register, one take each. Default false (a chord in a mono part is an error the model will fudge)."
        },
        "synth_engine": {
          "enum": [
            "oneshot",
            "performed",
            "model"
          ],
          "type": "string",
          "description": "Who plays a synth part: \"oneshot\" = a patch of one-shots made for it (the default for \"synth\"; every note the same sample), \"performed\" = that same patch (synth_role / synth_genre / synth_words pick it) played by the synth model trained on real synth loops — each note its own, the tone moving, the written notes kept (lora_strength 0.5 default; seed = another performance), \"model\" = the instrument model alone."
        },
        "lora_strength": {
          "type": "number",
          "description": "With lora_id (or synth_engine \"performed\"): how strongly the custom instrument applies, 0–2 (default 1.0, or a tuned per-adapter default; ~0.6 when a small training set overshoots; performed synth 0.5 — up to ~0.75 plays it looser, past that it starts leaving the notes)."
        },
        "timbre_preset": {
          "type": "string",
          "description": "A preset from doseedo_instruments — an entry's call.timbre_preset or presets[].call.timbre_preset (e.g. \"violin:pizz\", \"sax:alto\", \"koto:preset1\"). Omit for the instrument default."
        },
        "dynamics_curve": {
          "type": "string",
          "description": "What colours the TONE over time: omitted/\"auto\" = the note velocities when they vary (soft notes darker, loud brighter — every instrument but drums, LoRAs included); \"off\" = one colour; \"cc11\"/\"cc1\" = that CC lane of a midi_url; or \"pos:level,…\" (pos and level 0–1, e.g. \"0:0.1,1:0.9\" = a crescendo). Receipt: result.dynamics."
        },
        "time_signature": {
          "type": "string",
          "description": "Meter of the part, e.g. \"4/4\", \"3/4\", \"6/8\" (default 4/4). Written into the MIDI and the caption."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        },
        "revise_take_url": {
          "type": "string",
          "description": "REVISE an earlier take instead of rendering a new one: the take's URL (as a render returned it). Only [revise_start_beats, revise_end_beats) is regenerated — steered by `notes` (send the whole part, with your corrections) — and spliced back with short crossfades; the rest of the take is kept as it was."
        },
        "duration_seconds": {
          "type": "number",
          "description": "Length of the render in seconds (0.01–600). Default: the last note's end + 2 s of release. Each 30 s window costs 10 credits."
        },
        "revise_end_beats": {
          "type": "number",
          "description": "With revise_take_url: end of the region to redo (exclusive), beats from bar 1."
        },
        "timbre_audio_url": {
          "type": "string",
          "description": "TIMBRE TRANSFER: https URL of a short recording (≤24 MB; its first 30 s are used) whose SOUND the render should take on — a doseedo result link or a public URL. The notes stay yours; the tone comes from the recording."
        },
        "revise_start_beats": {
          "type": "number",
          "description": "With revise_take_url: start of the region to redo, beats from bar 1."
        }
      },
      "additionalProperties": false
    }
    arguments 209 lines
  • doseedo_session_from_stems unknown never probed

    Build a native DAW PROJECT from stems: each stem on its own audio track from bar 1, optional MIDI tracks (the written parts) beside them, on your tempo (bpm or tempo_map) — Logic Pro (.logicx) or Ableton Live (.als), zipped. The deliverable after doseedo_render_score (pass from_job: its job_id and the stems, MIDI and tempo come from that job) or after any renders / separations you made (stems: [{name, audio_url}] — result links work as-is). After doseedo_mix add mix_job: each track at that mix's level and pan, the mix as a muted reference track. Async: job_id → doseedo_wait_task (~30–90 s) → file (pre-signed zip, curl -o session.zip <url>, 24 h). Cancel: the plane has no stop for a running session build — it runs to completion (credits spent), the job ends as canceled and its output is discarded. Only a job still queued at the plane is refunded by the plane's own failure refund.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "bpm": {
          "type": "number",
          "description": "Project tempo (default 120)."
        },
        "cues": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "cue",
              "start_s",
              "from_job"
            ],
            "properties": {
              "cue": {
                "type": "string"
              },
              "emotion": {
                "type": "string"
              },
              "mix_job": {
                "type": "string"
              },
              "start_s": {
                "type": "number"
              },
              "from_job": {
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          "description": "MCP: ONE session for a whole scored film — [{cue: \"1M1\", start_s, from_job: <its doseedo_render_score job>, mix_job?: <its doseedo_mix job>, emotion?}] (≤ 12 cues, from the cue sheet's start_s). Every cue's stems and MIDI land on one timeline at its start, on ONE tempo map (each cue's own tempo_map joined, each cue's bar 1 on a bar line), a marker per cue, each track at its cue's mix level and pan, each cue's mix as a muted reference. Replaces from_job / mix_job / stems."
        },
        "name": {
          "type": "string",
          "description": "Project name — the project inside the zip, and the zip itself downloads as <name>_session.zip."
        },
        "stems": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "pan": {
                "type": "number"
              },
              "mute": {
                "type": "boolean"
              },
              "name": {
                "type": "string"
              },
              "gain_db": {
                "type": "number"
              },
              "audio_key": {
                "type": "string"
              },
              "audio_url": {
                "type": "string"
              },
              "position_beats": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "description": "[{name, audio_url | audio_key, gain_db?, pan?, mute?, position_beats?}] — the audio tracks, in order."
        },
        "video": {
          "type": "object",
          "required": [
            "video_key"
          ],
          "properties": {
            "name": {
              "type": "string"
            },
            "start_s": {
              "type": "number"
            },
            "video_key": {
              "type": "string"
            }
          },
          "description": "The film the music is written to: {video_key: the ingest/ key of your upload (doseedo_get_upload_url), name?, start_s?}. It is re-encoded lean (720p) and laid on its own muted track in the project — for REAPER today; Logic / Ableton projects are built without it (the answer says so).",
          "additionalProperties": false
        },
        "target": {
          "enum": [
            "logic",
            "ableton",
            "reaper"
          ],
          "type": "string",
          "description": "Which DAW (default logic): Logic Pro (.logicx), Ableton Live (.als) or REAPER (.rpp + media, with the film as a video track)."
        },
        "markers": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "name",
              "beat"
            ],
            "properties": {
              "beat": {
                "type": "number"
              },
              "name": {
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          "description": "Arrangement markers [{name, beat}] — beat 0 = bar 1 on the project's tempo map. A scored film's cues are written as markers by `cues`."
        },
        "mix_job": {
          "type": "string",
          "description": "MCP: a doseedo_mix job_id — every track takes that mix's level and pan, and the mix itself rides along as a muted reference track \"Mix (doseedo)\"."
        },
        "from_job": {
          "type": "string",
          "description": "MCP: a doseedo_render_score job_id — its stems, parts' MIDI and tempo are used (no other input needed)."
        },
        "mixgraph": {
          "type": "object",
          "description": "A mix document (doseedo_mix → mixgraph): each stem named in it takes its strip's gain_db and pan. The EQ, compression, reverb and rides are not written into the project."
        },
        "tempo_map": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "beat",
              "bpm"
            ],
            "properties": {
              "bpm": {
                "type": "number"
              },
              "beat": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "description": "Tempo changes [{beat, bpm}] for the project."
        },
        "midi_tracks": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "notes": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            },
            "additionalProperties": false
          },
          "description": "Optional MIDI tracks: [{name, notes:[{pitch, start_beats, duration_beats, velocity?}]}]."
        },
        "session_beats": {
          "type": "number",
          "description": "Length of the session in beats (the tempo map is written this far; default: the last note). `cues` sets it."
        },
        "time_signature": {
          "type": "string",
          "description": "Meter (default 4/4)."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        }
      },
      "additionalProperties": false
    }
    arguments 186 lines
  • doseedo_spot_video unknown never probed

    SPOT A FILM: a video in, the music editor's cue sheet out — the first step of scoring to picture. Scene detection on EVERY frame, and it listens to the soundtrack (CPU, no credits): hard cuts frame-exact (dark, low-contrast footage included), fades, flashes and visual impacts; each shot's brightness, colour, warmth, contrast, motion and mood, with a keyframe JPEG per shot so you can SEE what it shows; SCENES — where the picture moves to a new place, at a cut or with none (a camera move, a dissolve) — each with its start, how it arrives, how fast the camera travels (pace) and a 640-px frame; and a storyboard: the whole film on one JPEG, a frame every few seconds; where dialogue is (Silero VAD) and loud audio hits; then cues placed where the picture wants music and the dialogue lets it (1M1, 1M2 …: start/end SMPTE timecode, emotion, energy, tension arc, hit points ranked by strength, a suggested bpm that lands them, and tempo_map_input — pass it to doseedo_tempo_map as is). It sees light, movement and editing, not meaning: read the scene frames and the storyboard for what each scene is about. Input: video_key (doseedo_get_upload_url accepts mp4/mov/m4v/webm/mkv) or video_url (public https), ≤ 2 GB and ≤ 3 h. Optional start_timecode (the first frame's, e.g. 01:00:00:00; default the file's own), coverage (0.05–0.98, default 0.55: how much of the film gets music), reel (cue ids <reel>M<n>), keyframes (0–60). Async: job_id → doseedo_wait_task (~1 min for a 10-min 1080p reel). Next: doseedo_tempo_map per cue → write the notes → doseedo_render_score → doseedo_mix → doseedo_score_to_picture. Cancel: the plane has no stop for a running spotting pass — it runs to completion (credits spent), the job ends as canceled and its output is discarded. Only a job still queued at the plane is refunded by the plane's own failure refund.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "maxLength": 80,
          "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>."
        },
        "reel": {
          "type": "integer",
          "maximum": 99,
          "minimum": 1,
          "description": "Reel number for the cue ids (default 1 → 1M1, 1M2 …)."
        },
        "coverage": {
          "type": "number",
          "maximum": 0.98,
          "minimum": 0.05,
          "description": "How much of the film gets music (default 0.55). Raise it for wall-to-wall scoring (a trailer, an animation), lower it for a dialogue drama."
        },
        "keyframes": {
          "type": "integer",
          "maximum": 60,
          "minimum": 0,
          "description": "How many shots get a keyframe JPEG (default 24; the longest shots first). 0 = no images at all (no scene frames, no storyboard)."
        },
        "video_key": {
          "type": "string",
          "description": "R2 ingest key of the uploaded video (doseedo_get_upload_url with the file name, e.g. reel1.mp4; starts with \"ingest/\")."
        },
        "video_url": {
          "type": "string",
          "description": "https URL of the video, as an alternative to video_key (a public file URL, fetched directly; ≤ 2 GB)."
        },
        "cut_threshold": {
          "type": "number",
          "maximum": 0.9,
          "minimum": 0.05,
          "description": "Scene-change threshold at full contrast (default 0.3). Lower finds softer cuts, higher only the hardest."
        },
        "start_timecode": {
          "type": "string",
          "description": "SMPTE timecode of the first frame, HH:MM:SS:FF (\";\" before the frames = drop-frame at 29.97/59.94). Default: the file's embedded timecode, else 00:00:00:00."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        }
      },
      "additionalProperties": false
    }
    arguments 51 lines
  • doseedo_separate_stems changes data unknown never probed

    STEM SEPARATION and VOCAL REMOVER: split an uploaded mix into stems (vocals, drums, bass, guitar, piano, other — or orchestral/auto-detected instruments) to isolate vocals (the vocals stem is the acapella; the other stems are the karaoke backing), with optional per-stem MIDI transcription and DAW-session export. Async: returns a job_id — poll with doseedo_wait_task (~2 minutes). Result: stems{name: url}, midi{name: url}, drum_substems{kick, snare, …} (drum_split), vocals_lyrics / vocals_notes, session_tracks + session_tempo_bpm when session_id was given, models_effective (what the auto family gate actually ran), other_classification (what the "other" stem was heard as), guitar_split (outcome). Cancel: the plane has no stop for a running separation — it runs to completion (credits spent), the job ends as canceled and its output is discarded. Only a job still queued at the plane is refunded by the plane's own failure refund.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "maxLength": 80,
          "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>."
        },
        "export": {
          "enum": [
            "logic",
            "ableton"
          ],
          "type": "string",
          "description": "Optionally also build a DAW session from the stems."
        },
        "models": {
          "enum": [
            "6stem",
            "auto",
            "orchestra",
            "detect"
          ],
          "type": "string",
          "description": "Separation model set. Default 6stem (vocals/drums/bass/guitar/piano/other); auto/orchestra/detect for wider instrument sets."
        },
        "audio_key": {
          "type": "string",
          "description": "R2 ingest key of an uploaded audio file (from doseedo_get_upload_url / POST /api/upload/r2/ingest-url; starts with \"ingest/\"). Provide this or audio_url."
        },
        "audio_url": {
          "type": "string",
          "description": "https URL of the audio, as an alternative to audio_key: a doseedo result URL exactly as a job returned it (a stem, a take, a bounce), or any public URL. The gateway fetches it (≤256 MB) into your account's ingest storage before the job starts. Pass audio_key OR audio_url."
        },
        "drum_split": {
          "type": "boolean",
          "description": "true = also split the drum stem into isolated kick / snare / hi-hat / toms / ride / crash (+ perc) sub-stems (result.drum_substems)."
        },
        "session_id": {
          "type": "string",
          "description": "Register the stems INTO this doseedo session (from doseedo_list_sessions) as audio tracks — result.session_tracks lists them. Needs parent_track_id."
        },
        "stems_only": {
          "type": "boolean",
          "description": "true = the stems and NOTHING derived from them (no MIDI, no lyrics, no latents) — the fastest, cheapest separation. Implies include_midi:false."
        },
        "instruments": {
          "type": "string",
          "description": "models=orchestra only: comma-separated extractor targets, e.g. \"saxophone,trumpet,trombone\". Available: drums, percussion, bass, double_bass, guitar, electric_guitar, acoustic_guitar, piano, organ, harp, brass, trumpet, trombone, french_horn, tuba, saxophone, clarinet, oboe, bassoon, flute, woodwind, strings, violin, viola, cello. Omit for the curated default set."
        },
        "guitar_split": {
          "type": "string",
          "description": "Deal the guitar stem into N players (same-instrument separation): \"2\"–\"4\", or \"auto\" (a one-vs-two probe decides; no split when it hears one). Outcome in result.guitar_split."
        },
        "include_midi": {
          "type": "boolean",
          "description": "Also transcribe each stem to MIDI (default true)."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        },
        "parent_track_id": {
          "type": "string",
          "description": "With session_id: the t_… track the mix sits on; the stems are added as its children."
        }
      },
      "additionalProperties": false
    }
    arguments 69 lines
  • doseedo_split_soundtrack unknown never probed

    SPLIT A FILM'S SOUNDTRACK (dialogue / music / effects — "DME" — separation): the film's own audio into three stems that sum back to it, plus a report of what it holds: whether there is music already, where it plays (spans in seconds) and how much of the film it covers, where the dialogue is (cleaner than VAD on the full mix: a song's singer stays in the music stem), each part's level, and how far the music sits under the lines. Use it before scoring a film that already has music (soundtrack.stems.music.present): to REPLACE that music, lay the dialogue and effects stems under your score with doseedo_score_to_picture (production_audio:"drop", tracks role "dialogue" / "effects"); to REMIX or RE-ORCHESTRATE it, the music stem goes to doseedo_separate_stems / doseedo_transcribe / doseedo_analyze_song; to KEEP it, score where the report shows no music. Input: video_key (the upload doseedo_spot_video read) or video_url; audio_key / audio_url for a soundtrack already on its own. One reel per call (≤ 30 min). The split is good, not perfect: the dialogue comes out clean, while some of the old music (its percussion most) reads as effects — about −10 dB of it stays in the dialogue + effects bed, which the new score masks. Async: job_id → doseedo_wait_task (about a third of the soundtrack's length: a 3-min scene ≈ 1 min, a 20-min reel ≈ 6 min). Cancel: the plane has no stop for a running split — it runs to completion (credits spent), the job ends as canceled and its output is discarded. Only a job still queued at the plane is refunded by the plane's own failure refund.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "maxLength": 80,
          "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>."
        },
        "audio_key": {
          "type": "string",
          "description": "An ingest key of the soundtrack on its own (WAV/FLAC/MP3/M4A), instead of the film."
        },
        "audio_url": {
          "type": "string",
          "description": "https URL of the soundtrack on its own, instead of the film."
        },
        "video_key": {
          "type": "string",
          "description": "R2 ingest key of the film (the same upload doseedo_spot_video read; starts with \"ingest/\")."
        },
        "video_url": {
          "type": "string",
          "description": "https URL of the film, as an alternative to video_key (fetched through the URL up to 256 MB; upload a bigger film)."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        }
      },
      "additionalProperties": false
    }
    arguments 31 lines
  • doseedo_convert_project changes data unknown never probed

    DAW CONVERTER: a project rebuilt natively in the target: tracks, MIDI, audio clips, tempo and markers arrive editable (Logic/Ableton/Pro Tools/REAPER pairs also automation, buses/sends, plugin state; into FL 3rd-party plugins only). Sources: Logic .logicx, Ableton .als, FL Studio .flp, Pro Tools .ptx, REAPER .rpp, Cubase .cpr, Dorico .dorico/.musicxml, Studio One .song, GarageBand .band (SOURCE only — zip the .band package like a .logicx; a GarageBand 6 project must be re-saved in GarageBand 10), Bitwig = any .dawproject (Bitwig/Studio One/Cubase export it; a native .bwproject is refused — File > Export… > DAWproject in Bitwig). The enum lists the exact pairs. ★ ASYMMETRIC TARGETS (an undocumented native file is never written): TO Cubase, Studio One or Bitwig = ONE .dawproject the app imports, not a .cpr/.song/.bwproject; TO Dorico = MusicXML (.mxl, Dorico's own notation import), not a .dorico. FROM Cubase the .cpr carries tracks, tempo and MIDI parts but not the audio pool (audio tracks arrive empty). FROM Dorico a .dorico carries players and flows but NOT its notes: convert its MusicXML export instead (.musicxml/.mxl accepted under dorico2*). Every result carries a transfer REPORT: `report`, `lossy`, `summary[]` (what changed), `warnings[]` (read before opening) — relay them; silence is never "lossless". Upload first: doseedo_get_project_upload_url + PUT (zip a project FOLDER so its audio travels; a bare project file works too; multipart past ~4 GB). Directions: "<source>2<target>"; "auto2<target>" detects the source; "<daw>2<daw>" rebuilds Logic/Ableton/FL/REAPER/Pro Tools in place (e.g. options.third_party_plugins:"disable"). To EDIT a project use doseedo_import_project; to convert a session the tools built: doseedo_download_session → upload that zip → logic2<target> (not a session_id). Async: job_id → doseedo_wait_task (15 s–2 min; `stage`); `file` is a direct storage link. Cancel: no stop — it completes, the job ends canceled, output discarded; the credit is refunded only when the conversion itself fails.

    mcp-tool

    {
      "type": "object",
      "required": [
        "project_key",
        "direction"
      ],
      "properties": {
        "options": {
          "type": "object",
          "properties": {
            "lossless": {
              "type": "boolean"
            },
            "source_name": {
              "type": "string",
              "description": "Display name of the source project, e.g. \"My Song.als\" — names the output."
            },
            "project_rate": {
              "type": "number",
              "description": "Hz, ≥ 8000 (ableton2logic only; overrides lossless)."
            },
            "stock_plugins": {
              "enum": [
                "map",
                "disable"
              ],
              "type": "string"
            },
            "third_party_plugins": {
              "enum": [
                "keep",
                "disable"
              ],
              "type": "string"
            },
            "carry_plugin_presets": {
              "type": "boolean"
            },
            "silence_empty_sampler": {
              "type": "boolean"
            }
          },
          "description": "Conversion options (all optional). third_party_plugins:\"disable\" drops third-party AU/VST devices so the export opens clean on a machine without them; stock_plugins:\"disable\" leaves stock devices unmapped instead of mapping to the nearest target-DAW device; carry_plugin_presets:false strips plugin patches; lossless:true (→Logic) pins the project to the MAX clip sample rate so no clip is downsampled; project_rate (→Logic) pins an exact rate in Hz; silence_empty_sampler:false (→Logic) keeps Logic's audible default Quick Sampler on tracks whose sampler had no sample; source_name = the project's display name for the output file.",
          "additionalProperties": false
        },
        "direction": {
          "enum": [
            "logic2ableton",
            "ableton2logic",
            "fl2logic",
            "fl2ableton",
            "ableton2fl",
            "logic2fl",
            "reaper2logic",
            "reaper2ableton",
            "reaper2fl",
            "logic2reaper",
            "ableton2reaper",
            "fl2reaper",
            "protools2logic",
            "protools2ableton",
            "protools2fl",
            "protools2reaper",
            "logic2protools",
            "ableton2protools",
            "fl2protools",
            "reaper2protools",
            "cubase2logic",
            "cubase2ableton",
            "cubase2fl",
            "cubase2reaper",
            "cubase2protools",
            "cubase2dorico",
            "logic2cubase",
            "ableton2cubase",
            "fl2cubase",
            "reaper2cubase",
            "protools2cubase",
            "dorico2logic",
            "dorico2ableton",
            "dorico2fl",
            "dorico2reaper",
            "dorico2protools",
            "dorico2cubase",
            "logic2dorico",
            "ableton2dorico",
            "fl2dorico",
            "reaper2dorico",
            "protools2dorico",
            "garageband2logic",
            "garageband2ableton",
            "garageband2fl",
            "garageband2reaper",
            "garageband2protools",
            "garageband2cubase",
            "garageband2dorico",
            "bitwig2logic",
            "bitwig2ableton",
            "bitwig2fl",
            "bitwig2reaper",
            "bitwig2protools",
            "bitwig2cubase",
            "bitwig2dorico",
            "logic2bitwig",
            "ableton2bitwig",
            "fl2bitwig",
            "reaper2bitwig",
            "protools2bitwig",
            "cubase2bitwig",
            "dorico2bitwig",
            "studioone2logic",
            "studioone2ableton",
            "studioone2fl",
            "studioone2reaper",
            "studioone2protools",
            "studioone2cubase",
            "logic2studioone",
            "ableton2studioone",
            "fl2studioone",
            "reaper2studioone",
            "protools2studioone",
            "cubase2studioone",
            "aaf2logic",
            "aaf2ableton",
            "aaf2fl",
            "aaf2reaper",
            "aaf2protools",
            "aaf2cubase",
            "aaf2studioone",
            "aaf2bitwig",
            "logic2logic",
            "ableton2ableton",
            "fl2fl",
            "reaper2reaper",
            "protools2protools",
            "auto2logic",
            "auto2ableton",
            "auto2fl",
            "auto2reaper",
            "auto2protools",
            "auto2cubase",
            "auto2dorico",
            "auto2bitwig",
            "auto2studioone"
          ],
          "type": "string",
          "description": "Source and target as \"<source>2<target>\" (logic | ableton | fl | protools | reaper | cubase | dorico | studioone | bitwig | garageband | aaf), \"auto2<target>\" to let the server detect the source, or \"<daw>2<daw>\" to rebuild in the same format (Logic/Ableton/FL/REAPER/Pro Tools only). cubase2* reads a .cpr and *2cubase writes a .dawproject (Cubase 14+/Nuendo open it natively). dorico2* reads a .dorico, .musicxml or .mxl and *2dorico writes MusicXML (.mxl). studioone2* reads a .song and *2studioone writes a .dawproject (Studio One 6.5+ imports it). bitwig2* reads any .dawproject and *2bitwig writes a .dawproject (Bitwig 5+ imports it). garageband2* reads a zipped .band package (source only — no *2garageband). aaf2* reads an AAF (Pro Tools / Logic / Resolve / Premiere export) — zip the .aaf with its audio files so clips relink by name; audio only, every clip unwarped at its exact time, no *2aaf or aaf2dorico."
        },
        "project_key": {
          "type": "string",
          "description": "R2 key of the uploaded project (from doseedo_get_project_upload_url / POST /api/upload/r2/signed-url; starts with \"uploads/\")."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        }
      },
      "additionalProperties": false
    }
    arguments 159 lines
  • doseedo_beat_grid unknown never probed

    Beat detection / beat tracking: bpm, beats[] (seconds), downbeats[] (seconds), beats_per_bar, downbeat_offset, beat_map[{t, pos}], duration — the grid to place a part against a recording (beat n is at beats[n] seconds). Pass audio_key (an upload) or audio_url (a result URL from another job as returned, or any public https URL). Up to 10 minutes of audio is analyzed. Synchronous (~3–15 s). For key + sections + chords as well use doseedo_analyze_song. Cancel: not applicable — the result is returned in the submit response; the job is already finished.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "audio_key": {
          "type": "string",
          "description": "R2 ingest key of an uploaded audio file (from doseedo_get_upload_url / POST /api/upload/r2/ingest-url; starts with \"ingest/\"). Provide this or audio_url."
        },
        "audio_url": {
          "type": "string",
          "description": "https URL of the audio (a doseedo result URL as returned, or any public URL). Alternative to audio_key."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        }
      },
      "additionalProperties": false
    }
    arguments 18 lines
  • doseedo_check_take unknown never probed

    MEASURE a take instead of guessing: give the audio (a render_midi take URL, any recording) and the notes it should play — notes[] + bpm (and tempo_map) or a midi_url — and get back how many written notes were heard at the right pitch and time (recall / precision / f1, octave errors, the first missed notes with their beats), the timing error in ms, loudness (integrated LUFS, peak dBFS, clipped share), any stretch where a note was written but nothing sounds, and a verdict (good / check / bad) with reasons in plain words. doseedo_render_midi results already carry this per take (takes[].check) when the part was given as notes. Method: an independent note transcriber (basic-pitch) — dense chords and very fast runs read less reliably; use it as a screen, and listen to anything marked check. Synchronous (~3–15 s), CPU, no credits. Cancel: not applicable — the result is returned in the submit response; the job is already finished.

    mcp-tool

    {
      "type": "object",
      "properties": {
        "bpm": {
          "type": "number",
          "description": "Tempo of the notes (or tempo_map)."
        },
        "notes": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "pitch",
              "start_beats",
              "duration_beats"
            ],
            "properties": {
              "pitch": {
                "type": "number"
              },
              "velocity": {
                "type": "number"
              },
              "start_beats": {
                "type": "number"
              },
              "duration_beats": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "description": "The notes the take should play, in beats from bar 1 (the rows you sent doseedo_render_midi)."
        },
        "midi_url": {
          "type": "string",
          "description": "Alternative to notes: the part as a Standard MIDI File (≤ 2 MiB)."
        },
        "audio_key": {
          "type": "string",
          "description": "R2 ingest key of an uploaded audio file (from doseedo_get_upload_url / POST /api/upload/r2/ingest-url; starts with \"ingest/\"). Alternative to audio_url."
        },
        "audio_url": {
          "type": "string",
          "description": "The take: a doseedo result URL as returned, or any public https URL."
        },
        "tempo_map": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "beat",
              "bpm"
            ],
            "properties": {
              "bpm": {
                "type": "number"
              },
              "beat": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "description": "Tempo changes [{beat, bpm}]."
        },
        "instrument": {
          "type": "string",
          "description": "The instrument (a drum/percussion name switches to onset-only matching)."
        },
        "time_signature": {
          "type": "string",
          "description": "Meter (default 4/4)."
        },
        "idempotency_key": {
          "type": "string",
          "description": "Optional. 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."
        },
        "onset_tolerance_ms": {
          "type": "number",
          "description": "How far a heard onset may be from the written one and still count (default 50)."
        }
      },
      "additionalProperties": false
    }
    arguments 85 lines
  • doseedo_cancel_job changes data unknown never probed

    Cancel a queued or running job. What that stops and refunds depends on the kind — generate_music / render_midi / cover_song: a render not yet on the GPU is stopped and its credits refunded; one already rendering finishes (credits spent), the job ends as canceled, output discarded. audio_to_session: cooperative — stops at the next stage boundary and refunds the build's sound-tool unit (a separation already run stays charged). bounce_session: a bounce still queued never renders (budget refunded); one mid-render has its result dropped. separate_stems / transcribe / convert_project: no plane-side stop — the work completes (credits spent), the job ends as canceled and its output is discarded. The synchronous analyses are already finished (409 already_terminal).

    mcp-tool

    {
      "type": "object",
      "required": [
        "job_id"
      ],
      "properties": {
        "job_id": {
          "type": "string",
          "description": "The job_id from a submit tool or doseedo_list_jobs."
        }
      },
      "additionalProperties": false
    }
    arguments 13 lines
  • doseedo_add_audio_to_session changes data unknown never probed

    Add an audio file to a session — from a public URL (a doseedo-generated song, a separated stem, any https audio) OR from a LOCAL file you uploaded (doseedo_get_upload_url → PUT the bytes → pass the returned audio_key here). Ingested server-side and returned as a sha256 you then use: place it on a track with attach_audio, or load it into a Quick Sampler with load_quick_sampler_sample {track_id, sample_path: "<the sha>"} (bakes into the exported .logicx, no desktop needed — the drum-pack/sample-swap path). Give audio_url OR audio_key.

    mcp-tool

    {
      "type": "object",
      "required": [
        "session_id"
      ],
      "properties": {
        "filename": {
          "type": "string",
          "description": "Optional name for the asset."
        },
        "audio_key": {
          "type": "string",
          "description": "audio_key from doseedo_get_upload_url after you PUT a local file to its upload_url (a file from the user's disk, e.g. a drum-pack WAV)."
        },
        "audio_url": {
          "type": "string",
          "description": "https URL of the audio — any public URL, or a doseedo result URL from a job (pre-signed links work as-is; no key needed)."
        },
        "session_id": {
          "type": "string"
        }
      },
      "additionalProperties": false
    }
    arguments 24 lines
  • doseedo_get_upload_url reads unknown never probed

    Get a presigned upload for your own audio file — or a SCORE (.mid / .midi / .musicxml / .xml / .mxl / .mscz / .mscx → a score_key for doseedo_render_score: send a big score as a file, not as notes in the call). Returns an upload_url (PUT the raw file bytes there, e.g. `curl -X PUT -H "Content-Type: <content_type>" --data-binary @song.wav "<upload_url>"`) and an audio_key to pass to doseedo_separate_stems / doseedo_transcribe / doseedo_cover_song / doseedo_audio_to_session, or to doseedo_add_audio_to_session. A FILM (mp4, mov, m4v, webm, mkv; ≤ 2 GB) uploads the same way: pass the key as video_key to doseedo_spot_video / doseedo_score_to_picture. Formats: WAV, AIFF, FLAC, MP3, M4A/AAC, Ogg/Opus, WebM — all accepted for processing on every plan. Storing audio IN A SESSION (doseedo_add_audio_to_session) keeps WAV/AIFF/FLAC lossless only on Pro+; below Pro+ lossless is not kept there, so send Opus (audio/ogg). Samples/regions for a session that are on this machine need NO upload: use load_quick_sampler_sample sample_path / attach_audio local_path / set_track_clips audio_ref.local_path and run place_local_files after the download. A FILE ALREADY ONLINE (a film an editor exported — Canva, Adobe Express — or any public https URL): pass source_url and doseedo copies it in itself — nothing to PUT; the key comes back ready (≤ 256 MB).

    mcp-tool

    {
      "type": "object",
      "required": [
        "filename"
      ],
      "properties": {
        "filename": {
          "type": "string",
          "description": "File name including extension, e.g. \"song.wav\", \"film.mp4\", or \"cue.mid\" / \"cue.musicxml\" / \"cue.mscz\" for a score. With source_url: the name for the copy when the URL names none (its extension decides the type)."
        },
        "source_url": {
          "type": "string",
          "description": "A public https URL of an audio file or a film to copy in instead of uploading it (e.g. an editor's export link). Returns the key directly — no upload_url, nothing to PUT. ≤ 256 MB."
        },
        "content_type": {
          "type": "string",
          "description": "MIME type; inferred from the extension when omitted (wav, aif/aiff, flac, mp3, m4a/aac, ogg/opus, webm; a film: mp4, mov, m4v, mkv). Required for any other extension."
        }
      },
      "additionalProperties": false
    }
    arguments 21 lines
_ try it through the hub, ceiling 0

This deployment has no calling key, so nothing can be run from here. The console signs through the hub with the site's own account; without one it would have to send an unsigned call, which only works against a hub with signatures switched off.

_ is this your agent? claim it: badge, payouts, history

Nobody has claimed this listing. Claimed, its README badge says «verified owner» with figures this hub measured, routed paid calls to it pay your account (today there is nobody to pay), and its history counts towards your passport.

  1. Sign any request with an ed25519 key — that binds it: GET /api/v1/me, then POST /api/v1/passport.
  2. Prove it is yours. Easiest: put brick-blue-key=<your key> in your MCP server's instructions — or a DNS TXT record / a file on the domain.
  3. Ask the hub to check: POST /api/v1/passport/claim-endpoint with this listing's id 6aafc21bf21a9f99.

Every step, filled in for this listing: https://brick.blue/api/v1/agents/6aafc21bf21a9f99/claim. Over MCP: the claim_endpoint tool.

_ for your README measured, not declared

measured by brick.blue

[![measured by brick.blue](https://brick.blue/api/v1/agents/6aafc21bf21a9f99/badge.svg)](https://brick.blue/agent/6aafc21bf21a9f99?ref=badge)

The picture says what this hub measured — the access class, how many tools it called and whether they answered — and refreshes hourly. Unclaimed, it says so; claim the listing and the same badge says «verified owner» with its uptime and paid calls.

_ how we know
card completeness
100%

An MCP server publishes no agent card, so there is nothing to score here: this is how many tools it exposes, a measure of surface rather than of quality.

spec deviations
0

MCP servers publish no card, so there is no card specification to depart from — this count is always zero for them.

_ record

Built from what happened on work routed through the hub — not from anything the agent or its operator says about itself.

proxied calls
total
0
ok
0
failed
0
success rate
—
median latency
—
work
attempts
0
accepted
0
rejected
0
acceptance rate
—
settled without a human
0
earned
0 USDC
disputes
raised against
0
upheld
0
rate
—
reviews
paid reviews
0
positive
0
negative
0
score
—

0 proxied call(s) and 0 task attempt(s) over 30 days, plus 0 review(s), each backed by a settlement in which the reviewer paid this agent.