Skip to main content
Glama

music

DestructiveIdempotent

Set or read the background music bed under a project: place it by voice-over words or events, and control levels, fades, ducking, and additional passages.

Instructions

Read or change the A2 music bed this project mixes under its edit.

Call with no arguments to read what is in force. The bed stores word indices and an asset, never a length: it starts where word_index_start of clip_id (the VO transcript) lands on the timeline and runs to where word_index_end ends — or to the end of the edit — so a cut before either boundary moves both. Duration is derived at build time. On a recording with no words, event/until_event (and a passage's event) address its logged events instead.

The first set needs asset, clip_id and a start (word_index_start or phrase_start) together; after that each field updates on its own. A field set by phrase stores the phrase beside the index it resolved to, so cue_reresolve can re-derive it; set by plain index, the stored phrase is cleared. Both boundaries are echoed with their resolved words and neighbours — check them.

Beyond one asset from its head: passages (more pieces, each from its own word), rotate (assets in turn), crossfade, src_in; under levels the bed below the voice, or loudness to a LUFS where there is no voice; duck dips it while the voice speaks, keyed off the edit's own audio, audible insets and ducks sounds at export; over_tail plays it on under the end card. export's music field says what the render carried. clear_* and reset undo each; plan validates without writing.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
duckNoPull the bed this many dB down while the voice is speaking and let it back up in the pauses. It is keyed off the timeline's own audio at export rather than the transcript's word timings, which were measured against a bed recovered from a real render and beaten: 2.72 dB off for the audio gate against a word-span duck's 3.39. It also hears audible insets and sounds placed with `ducks`.
pathNoThe project directory to act on. Omit it — the usual case — when this server is bound to a project (started as `proofcut -C DIR mcp`, or inside a project; `ping` says which): it then resolves to that one bound project, a relative path resolves against it, and a path outside it is refused by name. Unbound, `path` is the whole address and omitting it refuses rather than guessing.
planNoResolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it.
afterNoA forward cursor over the matches of `phrase_start`/`phrase_end`: any match at or before this word index is skipped. -1, the default, means from the start.
assetNoThe bed's own music, as a registered clip id — never `card:name`, since a held frame has no sound. It plays from its own head; shorter than its span pads with real silence, longer is trimmed.
eventNoStart the bed on this event of clip_id instead of a word: `name`, or `name#k` when the name repeats. Replaces a start word.
resetNoDrop the bed entirely.
underNoLevel the whole bed this many LU below the voice, measured. It is a fixed offset; `duck` is the moving one.
rotateNoFurther assets to play in turn as each one runs out, overlapping by `crossfade`. `[]` clears them.
src_inNoWhere inside the bed's own asset it starts, in seconds.
clip_idNoThe clip whose words (or events) the bed addresses — the VO, not the music.
fade_inNoSeconds of fade at the bed's start. The fades ride the bed's own entry, so a fade-out ends where the music audibly ends.
fade_outNoSeconds of fade at the bed's end. A fade pair the bed cannot hold refuses at build time rather than being clamped.
loudnessNoLevel the whole bed to this many LUFS, measured — for a film with no voice for `under` to sit below, such as a screen recording. Setting it drops `under`, and `under` drops it. The launch clip's approved bed reads -23.3.
passagesNoReplace the list of passages after the bed's own asset: each `{asset, word_index_start | phrase_start | event, src_in?, crossfade?, rotate?}`. `[]` clears them.
clear_endNoDrop the end word, returning the bed to running to the end of the edit.
crossfadeNoSeconds two pieces overlap by. A crossfade edge is equal-power rather than the straight dB line an ordinary fade draws — two straight fades crossing sum to a hole.
over_tailNoTrue runs a bed with no end boundary on under the tail's card, so the card is not silent and `fade_out` ends with it. False ends it with the edit, the default.
clear_duckNoReturn the bed to one level, with no ducking.
occurrenceNoDisambiguate `phrase_start`/`phrase_end` by count, **1-based**. Unset, an ambiguous phrase is refused rather than guessed at.
phrase_endNoSet the out-point by wording instead; it binds the phrase's last word. Each boundary is independent — one can be a phrase and the other an index.
clear_underNoReturn every asset to its own level.
until_eventNoEnd the bed on this event of clip_id. Replaces an end word; `clear_end` drops it.
phrase_startNoSet the in-point by wording instead; it binds the phrase's first word. The resolved phrase is stored beside the index, so `cue_reresolve` can re-derive it after a re-record.
clear_loudnessNoDrop the `loudness` level.
word_index_endNoWhere the bed goes out. Unset means *to the end of the edit*, so a tail holds over silence unless `over_tail`.
word_index_startNoWhere the bed comes in, as a word of `clip_id`. The bed stores words and never a length, so a cut before either boundary moves it automatically.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed9 schema fields changedv0.37.0
    • addedInput schema / properties / clear_loudness
      Added value: +{
      +  "default": false,
      +  "description": "Drop the `loudness` level.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / clip_id / description
      Previous value: -"The transcript the bed's word indices address — the VO, not the music."New value: +"The clip whose words (or events) the bed addresses — the VO, not the music."
    • changedInput schema / properties / duck / description
      Previous value: -"Pull the bed this many dB down while the voice is speaking and let it back up in the pauses. It is keyed off the timeline's own audio at export rather than the transcript's word timings, which were measured against a bed recovered from a real render and beaten: 2.72 dB off for the audio gate against a word-span duck's 3.39."New value: +"Pull the bed this many dB down while the voice is speaking and let it back up in the pauses. It is keyed off the timeline's own audio at export rather than the transcript's word timings, which were measured against a bed recovered from a real render and beaten: 2.72 dB off for the audio gate against a word-span duck's 3.39. It also hears audible insets and sounds placed with `ducks`."
    • addedInput schema / properties / event
      Added value: +{
      +  "default": null,
      +  "description": "Start the bed on this event of clip_id instead of a word: `name`, or `name#k` when the name repeats. Replaces a start word.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / loudness
      Added value: +{
      +  "default": null,
      +  "description": "Level the whole bed to this many LUFS, measured — for a film with no voice for `under` to sit below, such as a screen recording. Setting it drops `under`, and `under` drops it. The launch clip's approved bed reads -23.3.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / over_tail
      Added value: +{
      +  "default": null,
      +  "description": "True runs a bed with no end boundary on under the tail's card, so the card is not silent and `fade_out` ends with it. False ends it with the edit, the default.",
      +  "type": [
      +    "boolean",
      +    "null"
      +  ]
      +}
    • changedInput schema / properties / passages / description
      Previous value: -"Replace the list of passages after the bed's own asset: each `{asset, word_index_start | phrase_start, src_in?, crossfade?, rotate?}`. `[]` clears them."New value: +"Replace the list of passages after the bed's own asset: each `{asset, word_index_start | phrase_start | event, src_in?, crossfade?, rotate?}`. `[]` clears them."
    • addedInput schema / properties / until_event
      Added value: +{
      +  "default": null,
      +  "description": "End the bed on this event of clip_id. Replaces an end word; `clear_end` drops it.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • changedInput schema / properties / word_index_end / description
      Previous value: -"Where the bed goes out. Unset means *to the end of the edit*, so a tail holds over silence."New value: +"Where the bed goes out. Unset means *to the end of the edit*, so a tail holds over silence unless `over_tail`."
  2. Changed75 schema fields changedv0.25.0
    • addedInput schema / properties / after / description
      Added value: +"A forward cursor over the matches of `phrase_start`/`phrase_end`: any match at or before this word index is skipped. -1, the default, means from the start."
    • removedInput schema / properties / after / title
      Removed value: -"After"
    • removedInput schema / properties / asset / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / asset / description
      Added value: +"The bed's own music, as a registered clip id — never `card:name`, since a held frame has no sound. It plays from its own head; shorter than its span pads with real silence, longer is trimmed."
    • removedInput schema / properties / asset / title
      Removed value: -"Asset"
    • addedInput schema / properties / asset / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • addedInput schema / properties / clear_duck
      Added value: +{
      +  "default": false,
      +  "description": "Return the bed to one level, with no ducking.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / clear_end / description
      Added value: +"Drop the end word, returning the bed to running to the end of the edit."
    • removedInput schema / properties / clear_end / title
      Removed value: -"Clear End"
    • addedInput schema / properties / clear_under / description
      Added value: +"Return every asset to its own level."
    • removedInput schema / properties / clear_under / title
      Removed value: -"Clear Under"
    • removedInput schema / properties / clip_id / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / clip_id / description
      Added value: +"The transcript the bed's word indices address — the VO, not the music."
    • removedInput schema / properties / clip_id / title
      Removed value: -"Clip Id"
    • addedInput schema / properties / clip_id / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / properties / crossfade / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / crossfade / description
      Added value: +"Seconds two pieces overlap by. A crossfade edge is equal-power rather than the straight dB line an ordinary fade draws — two straight fades crossing sum to a hole."
    • removedInput schema / properties / crossfade / title
      Removed value: -"Crossfade"
    • addedInput schema / properties / crossfade / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • addedInput schema / properties / duck
      Added value: +{
      +  "default": null,
      +  "description": "Pull the bed this many dB down while the voice is speaking and let it back up in the pauses. It is keyed off the timeline's own audio at export rather than the transcript's word timings, which were measured against a bed recovered from a real render and beaten: 2.72 dB off for the audio gate against a word-span duck's 3.39.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • removedInput schema / properties / fade_in / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / fade_in / description
      Added value: +"Seconds of fade at the bed's start. The fades ride the bed's own entry, so a fade-out ends where the music audibly ends."
    • removedInput schema / properties / fade_in / title
      Removed value: -"Fade In"
    • addedInput schema / properties / fade_in / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedInput schema / properties / fade_out / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / fade_out / description
      Added value: +"Seconds of fade at the bed's end. A fade pair the bed cannot hold refuses at build time rather than being clamped."
    • removedInput schema / properties / fade_out / title
      Removed value: -"Fade Out"
    • addedInput schema / properties / fade_out / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedInput schema / properties / occurrence / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / occurrence / description
      Added value: +"Disambiguate `phrase_start`/`phrase_end` by count, **1-based**. Unset, an ambiguous phrase is refused rather than guessed at."
    • removedInput schema / properties / occurrence / title
      Removed value: -"Occurrence"
    • addedInput schema / properties / occurrence / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedInput schema / properties / passages / anyOf
      Removed value: -[
      -  {
      -    "items": {
      -      "additionalProperties": true,
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / passages / description
      Added value: +"Replace the list of passages after the bed's own asset: each `{asset, word_index_start | phrase_start, src_in?, crossfade?, rotate?}`. `[]` clears them."
    • addedInput schema / properties / passages / items
      Added value: +{
      +  "additionalProperties": true,
      +  "type": "object"
      +}
    • removedInput schema / properties / passages / title
      Removed value: -"Passages"
    • addedInput schema / properties / passages / type
      Added value: +[
      +  "array",
      +  "null"
      +]
    • removedInput schema / properties / path / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / path / description
      Added value: +"The project directory to act on. Omit it — the usual case — when this server is bound to a project (started as `proofcut -C DIR mcp`, or inside a project; `ping` says which): it then resolves to that one bound project, a relative path resolves against it, and a path outside it is refused by name. Unbound, `path` is the whole address and omitting it refuses rather than guessing."
    • removedInput schema / properties / path / title
      Removed value: -"Path"
    • addedInput schema / properties / path / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / properties / phrase_end / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / phrase_end / description
      Added value: +"Set the out-point by wording instead; it binds the phrase's last word. Each boundary is independent — one can be a phrase and the other an index."
    • removedInput schema / properties / phrase_end / title
      Removed value: -"Phrase End"
    • addedInput schema / properties / phrase_end / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / properties / phrase_start / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / phrase_start / description
      Added value: +"Set the in-point by wording instead; it binds the phrase's first word. The resolved phrase is stored beside the index, so `cue_reresolve` can re-derive it after a re-record."
    • removedInput schema / properties / phrase_start / title
      Removed value: -"Phrase Start"
    • addedInput schema / properties / phrase_start / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • addedInput schema / properties / plan / description
      Added value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it."
    • removedInput schema / properties / plan / title
      Removed value: -"Plan"
    • addedInput schema / properties / reset / description
      Added value: +"Drop the bed entirely."
    • removedInput schema / properties / reset / title
      Removed value: -"Reset"
    • removedInput schema / properties / rotate / anyOf
      Removed value: -[
      -  {
      -    "items": {
      -      "type": "string"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / rotate / description
      Added value: +"Further assets to play in turn as each one runs out, overlapping by `crossfade`. `[]` clears them."
    • addedInput schema / properties / rotate / items
      Added value: +{
      +  "type": "string"
      +}
    • removedInput schema / properties / rotate / title
      Removed value: -"Rotate"
    • addedInput schema / properties / rotate / type
      Added value: +[
      +  "array",
      +  "null"
      +]
    • removedInput schema / properties / src_in / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / src_in / description
      Added value: +"Where inside the bed's own asset it starts, in seconds."
    • removedInput schema / properties / src_in / title
      Removed value: -"Src In"
    • addedInput schema / properties / src_in / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedInput schema / properties / under / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / under / description
      Added value: +"Level the whole bed this many LU below the voice, measured. It is a fixed offset; `duck` is the moving one."
    • removedInput schema / properties / under / title
      Removed value: -"Under"
    • addedInput schema / properties / under / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedInput schema / properties / word_index_end / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / word_index_end / description
      Added value: +"Where the bed goes out. Unset means *to the end of the edit*, so a tail holds over silence."
    • removedInput schema / properties / word_index_end / title
      Removed value: -"Word Index End"
    • addedInput schema / properties / word_index_end / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedInput schema / properties / word_index_start / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / word_index_start / description
      Added value: +"Where the bed comes in, as a word of `clip_id`. The bed stores words and never a length, so a cut before either boundary moves it automatically."
    • removedInput schema / properties / word_index_start / title
      Removed value: -"Word Index Start"
    • addedInput schema / properties / word_index_start / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • removedInput schema / title
      Removed value: -"musicArguments"
  3. First observedv0.24.0

TDQS

A4.8/5.0
Behavior5/5

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

The description goes well beyond annotations: it explains that the bed stores words not lengths, cuts move both boundaries, duration is derived at build time, phrase-set boundaries store phrases for cue_reresolve, `under` and `loudness` drop each other, and ambiguous phrases are refused. These behaviors are not visible in the annotations or schema alone.

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

Conciseness5/5

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

The description is dense but front-loaded: the core read/write purpose and no-arg read behavior come first, then dependencies, then optional features. Every sentence contributes a distinct fact, with no filler, and the organization is appropriate for a 27-parameter tool.

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

Completeness5/5

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

For a high-complexity tool with an output schema, the description covers the read path, setup prerequisites, edge cases (no words, no voice, ambiguous phrases, cuts), side effects, and validation via `plan`. Nothing needed to invoke it correctly is missing.

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

Parameters5/5

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

Even though schema coverage is 100%, the description adds crucial cross-parameter meaning: first-set dependencies, boundary independence, event addressing on wordless recordings, phrase storage/clearing behavior, and the effect of `clear_*` and `reset`. It clarifies how parameters interact rather than merely restating types.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Read or change the A2 music bed this project mixes under its edit.' This clearly identifies what the tool operates on and distinguishes it from the many sibling tools by its focus on the music bed.

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

Usage Guidelines4/5

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

It explicitly states 'Call with no arguments to read what is in force,' gives the first-set requirement ('needs asset, clip_id and a start together'), and recommends `plan` over executing. It covers when event-based addressing is needed, but it does not name alternative sibling tools or state explicit when-not-to-use conditions.

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

Deploy Server

Other Tools