Skip to main content
Glama

add_captions

DestructiveIdempotent

Generate word-timed ASS captions for your edited timeline, keeping captions aligned after cuts. Optionally burn them into a video render.

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 always written to output — Kdenlive loads it and it stays restylable. Pass burn (a render of THIS timeline) to burn the captions into a video as well, written to burn_output; against any other video the timings will not line up.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
burnNoAlso burn the captions into this video with ffmpeg; the sidecar is still written to `output`. 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 — always, burning or not. Never a video path: a media suffix is refused. The burned video goes to `burn_output`.
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, when `burn` is set. Unset, it is derived from `burn`'s own name in the project's renders folder.
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. Changed3 schema fields changedv0.37.0
    • changedInput schema / properties / burn / description
      Previous 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."New value: +"Also burn the captions into this video with ffmpeg; the sidecar is still written to `output`. 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."
    • changedInput schema / properties / burn_output / description
      Previous value: -"Where the burned video goes. Unset, it is derived from `burn`'s own name."New value: +"Where the burned video goes, when `burn` is set. Unset, it is derived from `burn`'s own name in the project's renders folder."
    • changedInput schema / properties / output / description
      Previous value: -"Where to write the `.ass` sidecar, or the burned video under `burn`."New value: +"Where to write the `.ass` sidecar — always, burning or not. Never a video path: a media suffix is refused. The burned video goes to `burn_output`."
  2. 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"
  3. First observedv0.24.0

TDQS

A4.7/5.0
Behavior5/5

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

The description richly discloses behavior beyond the annotations: timings follow the timeline rather than the original recording, cut words are counted as `words_cut`, style overrides are not written back to the project, and the sidecar is always written to `output` and stays restylable in Kdenlive. This aligns with the annotations and adds substantial operational context.

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 every sentence earns its place: purpose, timing behavior, style semantics, sidecar behavior, and burn constraints are all relevant. It front-loads the core purpose before diving into caveats, with no filler.

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?

Given the high parameter count, rich schema, annotations, and existing output schema, the description covers all decision-relevant behavior: what is written, where, when burning is safe, and how styling works. Nothing essential is missing for an agent to select and invoke this tool correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents each parameter thoroughly. The description adds some high-level context about one-off overrides and the `burn` constraint, but it does not need to compensate for missing parameter documentation; a baseline 3 is appropriate.

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?

Openly states a specific verb and resource: 'Write word-timed ASS captions for the current timeline to `output`.' It also differentiates itself from siblings by clarifying the relationship to `caption_style`, `caption_view`, and `export --render`, so an agent can distinguish this tool from nearby alternatives.

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?

The description gives explicit when-to-use guidance: style should be set with `caption_style` and viewed with `caption_view`, while the arguments here are described as one-off overrides. It also warns when not to pass `burn` — only a render of this timeline will have matching timings — and notes 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.

Deploy Server

Other Tools