Skip to main content
Glama

hold_under

DestructiveIdempotent

Plays a film clip's audio beneath a specified span of voiceover words, lowering it below the VO level. Replaces or adds a music bed without gaps, and supports planning before writing.

Instructions

Play a film clip's own audio under a span of the VO, under LU below it (default 13) — no gap, unlike hold_add. The span is VO words (word_index_start/word_index_end, or phrase_start/phrase_end), and the audio reads from wherever the shot showing asset has got to at the span's first word, so asset must be on screen there — cue it first. A second call at the same (clip_id, word_index_start) replaces the entry; the music bed goes out across it. plan resolves without writing. Both boundary words are echoed with neighbours — check them.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
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.
assetYesThe film clip whose audio plays under the voice. It has to be on screen across the span — the audio reads from wherever the shot showing it has got to — so cue it first.
underNoHow far below the VO the film audio sits, in LU. 13 by default.
clip_idYesThe VO track whose words the span is measured in.
fade_inNoSeconds of fade as the film audio comes in.
fade_outNoSeconds of fade as it goes out.
occurrenceNoDisambiguate `phrase_start`/`phrase_end` by count, **1-based**. Unset, an ambiguous phrase is refused rather than guessed at.
phrase_endNoSet the span's end by wording instead.
phrase_startNoSet the span's start by wording instead.
word_index_endNoLast VO word of the span.
word_index_startNoFirst VO word of the span. With `clip_id` it is the entry's address; a second call at the same address replaces it.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed45 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"
    • addedInput schema / properties / asset / description
      Added value: +"The film clip whose audio plays under the voice. It has to be on screen across the span — the audio reads from wherever the shot showing it has got to — so cue it first."
    • removedInput schema / properties / asset / title
      Removed value: -"Asset"
    • addedInput schema / properties / clip_id / description
      Added value: +"The VO track whose words the span is measured in."
    • removedInput schema / properties / clip_id / title
      Removed value: -"Clip Id"
    • removedInput schema / properties / fade_in / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / fade_in / description
      Added value: +"Seconds of fade as the film audio comes in."
    • 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 as it goes out."
    • 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 / 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 span's end by wording instead."
    • 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 span's start by wording instead."
    • 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"
    • removedInput schema / properties / under / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / under / description
      Added value: +"How far below the VO the film audio sits, in LU. 13 by default."
    • 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: +"Last VO word of the span."
    • 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: +"First VO word of the span. With `clip_id` it is the entry's address; a second call at the same address replaces it."
    • 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: -"hold_underArguments"
  2. First observedv0.24.0

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already mark the tool as idempotent and destructive, but the description adds concrete behavior: a second call with the same `(clip_id, word_index_start)` replaces the entry, the music bed goes out across it, and `plan` resolves without writing. This goes beyond the structured hints and describes the actual effects an agent would care about.

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

Conciseness4/5

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

The description is dense but every clause earns its place: main action, differentiation, span selection, asset precondition, replacement semantics, dry-run option, and output echo. It is front-loaded with the core purpose. Slightly on the longer side for a single paragraph, but justified for a 13-parameter tool.

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

Completeness4/5

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

For a complex tool with 13 parameters and an output schema, the description covers the major operational points: span selection, asset on-screen requirement, replacement, plan behavior, and output echo. It is complete enough for correct invocation; the only minor omission is further elaboration of the music-bed behavior, which is not essential.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3. The description adds extra meaning: `word_index_start` serves as the entry's address, the span can be set via words or phrases, `under` defaults to 13 LU, and `asset` must be on screen. It also notes that boundary words are echoed with neighbours, which helps the agent verify results.

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 the specific action — “Play a film clip's own audio *under* a span of the VO” — and immediately distinguishes it from hold_add (“no gap, unlike `hold_add`”). This makes its purpose and uniqueness clear without needing to open the schema.

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 provides clear context: when to use (`under` a span, no gap), preconditions (`asset` must be on screen, cue it first), and a safe dry-run option (`plan`). It does not explicitly state when *not* to use it or point to hold_add as the alternative for gapped holds, but the contrast is implicit enough for an agent to infer routing.

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