Skip to main content
Glama

add_captions

DestructiveIdempotent

Generate word-timed ASS subtitle files that follow the editing timeline, so captions stay accurate after cuts; optionally burn them directly into a rendered video.

Instructions

Write word-timed ASS captions for the current timeline to output.

Timings follow the timeline, not the original recording, so captions stay correct after cuts; words that were cut are omitted and counted as words_cut.

The look comes from the project — set it with caption_style, see it with caption_view. The arguments here override it for this one file and are not written back, so regenerating after a cut is styled the project's way again. Leave them unset unless you specifically want a one-off.

The sidecar .ass is the default exit — Kdenlive loads it and it stays restylable. Pass burn (a render of THIS timeline) to burn the captions in with ffmpeg instead; against any other video the timings will not line up.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
burnNoBurn the captions into this video with ffmpeg instead of writing a sidecar. It must be a render of **this** timeline — against any other video the timings will not line up. `export --render` does not burn captions, and nothing else reports a render that was made without them.
holdNoHow long a cue lingers after its last word, in seconds.
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.
outputYesWhere to write the `.ass` sidecar, or the burned video under `burn`.
presetNoOverride the project's base look for this one file — `clean`, `karaoke` or `boxed`. Nothing here is written back to the project.
clip_idNoCaption one transcript's words rather than every clip's.
max_gapNoStart a new cue when the silence between two words exceeds this many seconds.
max_wordsNoMost words in one caption cue.
burn_outputNoWhere the burned video goes. Unset, it is derived from `burn`'s own name.
max_durationNoLongest a single cue stays on screen, in seconds.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed39 schema fields changedv0.25.0
    • removedInput schema / properties / burn / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / burn / description
      Added value: +"Burn the captions into this video with ffmpeg instead of writing a sidecar. It must be a render of **this** timeline — against any other video the timings will not line up. `export --render` does not burn captions, and nothing else reports a render that was made without them."
    • removedInput schema / properties / burn / title
      Removed value: -"Burn"
    • addedInput schema / properties / burn / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / properties / burn_output / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / burn_output / description
      Added value: +"Where the burned video goes. Unset, it is derived from `burn`'s own name."
    • removedInput schema / properties / burn_output / title
      Removed value: -"Burn Output"
    • addedInput schema / properties / burn_output / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / properties / clip_id / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / clip_id / description
      Added value: +"Caption one transcript's words rather than every clip's."
    • removedInput schema / properties / clip_id / title
      Removed value: -"Clip Id"
    • addedInput schema / properties / clip_id / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / properties / hold / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / hold / description
      Added value: +"How long a cue lingers after its last word, in seconds."
    • removedInput schema / properties / hold / title
      Removed value: -"Hold"
    • addedInput schema / properties / hold / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedInput schema / properties / max_duration / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / max_duration / description
      Added value: +"Longest a single cue stays on screen, in seconds."
    • removedInput schema / properties / max_duration / title
      Removed value: -"Max Duration"
    • addedInput schema / properties / max_duration / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedInput schema / properties / max_gap / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / max_gap / description
      Added value: +"Start a new cue when the silence between two words exceeds this many seconds."
    • removedInput schema / properties / max_gap / title
      Removed value: -"Max Gap"
    • addedInput schema / properties / max_gap / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedInput schema / properties / max_words / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / max_words / description
      Added value: +"Most words in one caption cue."
    • removedInput schema / properties / max_words / title
      Removed value: -"Max Words"
    • addedInput schema / properties / max_words / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • addedInput schema / properties / output / description
      Added value: +"Where to write the `.ass` sidecar, or the burned video under `burn`."
    • removedInput schema / properties / output / title
      Removed value: -"Output"
    • 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 / preset / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / preset / description
      Added value: +"Override the project's base look for this one file — `clean`, `karaoke` or `boxed`. Nothing here is written back to the project."
    • removedInput schema / properties / preset / title
      Removed value: -"Preset"
    • addedInput schema / properties / preset / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / title
      Removed value: -"add_captionsArguments"
  2. First observedv0.24.0

TDQS

A4.5/5.0
Behavior4/5

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

Annotations (readOnlyHint=false, destructiveHint=true) already mark this as a mutating write, and the description's 'Write...' matches — no contradiction. The description adds valuable nuance: timings follow the timeline not the recording, cut words are omitted and counted as words_cut, and override args are not written back so regeneration returns to project styling. It doesn't explicitly state what destructive action occurs (e.g., overwriting an existing output file), leaving a small gap against the destructiveHint.

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?

Three tight paragraphs, purpose front-loaded in the opening sentence. Each paragraph earns its place: core behavior, timing/cut nuance, look/override semantics, and the sidecar-vs-burn exit decision. Dense but efficient with no wasted words.

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 10-parameter tool with an output schema present, the description covers the key decision points an agent needs: what it writes, the timeline-vs-recording timing behavior, cut handling, one-off override semantics, and the sidecar/burn tradeoff. It references related tools (caption_style, caption_view, export) for cross-navigation. The only omission is explicit disclosure of destructive/overwrite behavior.

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 baseline is 3. The description adds meaning beyond the schema: it explains the one-off, not-written-back semantics of the override args and reinforces the burn timing constraint against a render of this timeline. These points complement rather than repeat the schema field descriptions.

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?

First sentence states a specific verb, resource, and target: 'Write word-timed ASS captions for the current timeline to `output`.' It distinguishes itself from sibling caption tools by explicitly naming caption_style (sets the look) and caption_view (sees it), so an agent can tell this tool apart without opening their schemas.

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

Usage Guidelines5/5

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

Gives explicit decision guidance: the sidecar .ass is the default exit and stays restylable; `burn` is only correct against a render of THIS timeline, with a direct warning that any other video will misalign. It also tells the agent when not to use the override args ('Leave them unset unless you specifically want a one-off') and clarifies that `export --render` does not burn captions.

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