Skip to main content
Glama

proofcut

An AI video editor that proves its cuts. Your recordings in, a finished, mastered film out: cut by transcript, with b-roll, cards, music and captions, and every step an agent can call. proofcut renders on your own machine, then transcribes the render and checks that it says what the edit says.

https://github.com/user-attachments/assets/4153d180-3d7c-4c70-af5f-54d63d0a8bd5

Above: an agent cutting a demo video, unattended. The two runs it was cut from, uncut (silent: the recorder took frames only, and the voice is in the film the agent cut): the workspace (2:26) and Claude Code with the proofcut plugin (3:09).

That is not a staged run. TRIAL.md scores three unattended ones, each handed a goal and no steps, and each passed every one of its checks.

  • The demo cut, the one above.

  • Real footage: 96 seconds of narration with its fluffed takes left in, plus four clips of film footage. The agent cut it to 45 seconds, chose footage by what each line was about, burned captions, and checked its own render: all 123 expected words heard back.

  • A whole film: the demo material plus a score, briefed as a finished film ready to upload. In 192 seconds and $2.27 the agent cut it, laid the music under the voice, ended on a card, mastered it to −16 LUFS, and checked it. The score, the level and the end card were each measured in the delivered file, not taken from the project.

Have a Mac or a Windows PC and half an hour? Nobody has run proofcut on a Mac yet, and on Windows only its author has. One script runs the whole test and removes what it installed: § Help wanted.

Try it

Check your machine first, before cloning anything. proofcut doctor probes every tool proofcut uses and prints the fix for anything missing (§ Requirements has the list). With uv installed:

uvx proofcut doctor

The first run downloads Python 3.13 if uv has none, plus proofcut's dependencies, about 230 MB together.

On Linux, proofcut setup installs whatever doctor marked ✗, for you alone and with no sudo, and proofcut setup --uninstall removes exactly what it added. It says what it will download and asks first; whisper is about 1.9 GB of it. On a Mac or a Windows PC, follow the fix doctor prints under each ✗.

uvx proofcut setup

The demo and your own recordings run from a checkout:

git clone https://github.com/tydude001/proofcut && cd proofcut
uv sync

The two-minute demo

No footage needed. docs/DEMO.md generates a voiceover with a real retake, b-roll and a score, then walks a whole small film: cut the retake by naming its words, hang b-roll off a phrase, lay the score under the voice, render and master it, end on a card, and check the render against the timeline.

uv run python scripts/make_demo.py ~/proofcut-demo

In Claude Code

The plugin registers proofcut's MCP server, so all 93 tools are available with no setup of your own:

/plugin marketplace add tydude001/proofcut
/plugin install proofcut@proofcut

The first start downloads about 175 MB of Python dependencies, and Claude Code gives a server 30 seconds to connect. On a slow connection, start that first session as MCP_TIMEOUT=300000 claude, or reconnect proofcut in /mcp once the download has finished.

Any other MCP client runs the same server, from a checkout or with no checkout at all:

uv run --project /path/to/proofcut proofcut mcp
uvx proofcut mcp

On your own recording

uv run proofcut init myproject
uv run proofcut -C myproject import VO.wav --clip-id vo
uv run proofcut -C myproject transcribe vo                  # whisper, word-timed
uv run proofcut -C myproject seed vo                        # auto-editor strips silences
uv run proofcut -C myproject transcript vo --search "here's the thing"
uv run proofcut -C myproject cut vo 111:114 --plan          # what do those indices say?
uv run proofcut -C myproject cut vo 111:114 --pad 0.1       # inclusive word range
uv run proofcut -C myproject export final.mp4 --render      # or a .kdenlive to finish in an NLE
uv run proofcut -C myproject verify final.mp4               # did the render say what you edited?

To watch the edit instead, open the workspace. It plays the source through the edit, so seeing a cut costs no render:

uv run proofcut -C myproject open        # server plus an app window
uv run proofcut -C myproject web --open  # the same page in a browser tab

Related MCP server: CutPilot

From recordings to a finished film

One project, and proofcut's own commands from the first import to the delivered file. No NLE finishes the film, and nothing else touches the render. Each stage is one command, and each row links the section of the manual that walks it.

Two video essays of five to six minutes have been rebuilt this way and measured against their originals, which had been finished outside proofcut. One came out the same length to the frame. The other matched its original's 63 voiceover ranges to the millisecond, with the voice aligned to the sample, starting from a retake pass made in Kdenlive. Both master at the original's −16 LUFS (HISTORY.md § The Lambs/Longlegs native rebuild, § The Scream native rebuild).

proofcut makes no footage and writes no script. It takes what you recorded to a film, and proves the film matches the edit.

Beyond the stages above, one line each:

  • The workspace. Edit (transcript, preview, drag-trim and razor), Frame (review every crop in place) and Finish (presets, verify, and the finished file). The truth strip warns while you edit if the film would ship wrong.

  • An agent that can look. shot-sheet draws the whole picture track as one labelled grid, and footage-sheet browses a clip you haven't cut yet. Both return the image itself over MCP.

  • Transcript self-checks. Retake seams, invented words, swallowed repeats and suspect durations are reported when a transcript is attached, and unspoken lets the render itself testify to words nobody said.

  • B-roll by description. describe writes what is on screen in each ~10-second window of footage, so an agent can choose a clip by what a line is about.

  • Reframing. Per-shot crop windows for aspect changes, face-aware proposals (reframe-detect), a review sheet, and stacked splits for two speakers. Cards are redrawn at the new frame size, never stretched.

  • Derived reels. reel cuts part of the film into a new project, such as a vertical teaser. It reports every picture it dropped and pins the ones it kept.

  • NLE round-trip. Export to Kdenlive or OTIO, finish elsewhere, and import-edit the trim back.

Frame mode: a shot list beside the selected shot's windows — each crop
drawn as a rect on three of the source's own frames, over a filmstrip of the
whole shot with the sampled instants ticked on it, the window's rect quoted
in source pixels, Approve/Re-frame beside it, and coverage chips for stale
framing and unexplained steps

proofcut is 0.x software. A project from an older version is refused rather than guessed at, and proofcut migrate brings it forward.

Why proofcut

  • It checks its own work. verify transcribes the finished file and diffs it word by word against the timeline, so a retake left in the film is caught before anyone watches it. Frame counts and the picture are measured too, because ffmpeg, melt and auto-editor all exit 0 on some failures.

  • Cuts stay addressable. Every word in a recording keeps a fixed index that never renumbers, so cut vo 111:114 names the same words however many cuts came before it. --plan prints what a range says before anything changes, and restore and undo walk it back.

  • Built for agents. 93 MCP tools with typed inputs and structured returns, so Claude Code, Codex or your own agent can drive it. Tools like shot-sheet return an image of the edit, not a file path the agent can't open.

  • One engine, three ways in. The MCP server, the proofcut command line and a browser workspace all call the same operations. Every tool has a matching command (the test suite enforces it), so anything an agent does, you can script or re-run by hand.

  • Local-first. Commercial AI editors are apps around a metered cloud service. proofcut transcribes, edits and renders on your machine, and calls no cloud service of its own: no account, no per-minute billing. The only thing that talks to a model provider is the agent you choose to run (the optional footage-description and voice models download once, on first use).

  • No lock-in. The timeline is OpenTimelineIO. Export a .kdenlive or OTIO file, finish in Resolve, Premiere or Kdenlive, and bring your trim back with import-edit.

The proofcut workspace on the demo project: the transcript with a retake struck
through, the preview drawing the shot under the playhead with its captions, the
side rail on its agent tab reporting a finished render against the timeline,
and the layered timeline below — picture, waveform and captions as three
projections of one edit

Help wanted: a Mac or a Windows run

GitHub's macOS and Windows runners take the demo to a checked render, but a runner never reads the instructions. No person has run proofcut on a Mac. On Windows, the author's own Windows 11 laptop has, twice, and nobody else's PC; Windows 10 and ARM64 PCs have not been tried at all. If you have one of these machines and half an hour, one script installs what proofcut needs, makes a short test video, has proofcut cut, score, master and check it, and puts a report on your Desktop. It asks before it starts, records what it added, and removes exactly that on request, nothing you already had. A run that stops at the first step is just as useful, because where it stops is the finding.

On a Mac:

git clone https://github.com/tydude001/proofcut
bash proofcut/scripts/mac_trial.sh

It installs uv, ffmpeg-full, espeak-ng and auto-editor with Homebrew (and Homebrew itself if you have none), plus the Shotcut app for its renderer and whisper. bash proofcut/scripts/mac_trial.sh --uninstall removes them. Then file the report.

On Windows, from PowerShell:

git clone https://github.com/tydude001/proofcut
powershell -ExecutionPolicy Bypass -File proofcut\scripts\windows_trial.ps1

It downloads uv, ffmpeg, auto-editor, espeak-ng, Shotcut's renderer and whisper into one folder under %LOCALAPPDATA%. Nothing is installed system-wide and it needs no administrator rights. The same command with -Uninstall deletes that folder. It puts proofcut-windows-report.zip on your Desktop with your home folder's name taken out; file the report.

Requirements

proofcut is developed on Linux (a Fedora-based desktop). On macOS and Windows the test suite passes on CI and GitHub's runners take the demo to a checked render. On Windows one person's PC has too, the author's; no person has run it on a Mac yet. Where each OS stands is in docs/plans/PORTABILITY.md.

Every hard part of an editor already exists as mature open source, and proofcut is the layer that lets an agent drive those tools and check what they produced. Run uv run proofcut doctor to check everything below at once. On Linux, uv run proofcut setup installs any of the last four that doctor marks ✗: a static ffmpeg, whisper, auto-editor's release binary and Shotcut's portable melt, which renders with no display at all (docs/plans/INSTALL.md).

You need

For

Notes

Python 3.13 and uv

everything

uv sync installs the Python side. The only runtime dependencies are mcp and OpenTimelineIO, which holds the timeline and exports it to other editors.

ffmpeg / ffprobe built with libx264, freetype and libass

cutting, concatenating, captions, rendering

Fedora's default ffmpeg-free has no libx264: use RPM Fusion's ffmpeg. On a Mac, Homebrew's ffmpeg lacks freetype and libass: install ffmpeg-full and put $(brew --prefix ffmpeg-full)/bin first on PATH (it is keg-only).

auto-editor 31+

silence and bad-take removal, single-source renders

Install the upstream binary. The PyPI package is a stale 29.x.

whisper

word-timed transcription (30+ languages), render verification

Any openai-whisper install. uv tool install --python 3.12 openai-whisper is the short route (3.12 because torch's Intel-Mac builds stop there); add --torch-backend cpu without an NVIDIA GPU (1.9 GB instead of 5.5 GB). Found via PROOFCUT_WHISPER, then PATH. The CPU build transcribed the demo's 19-second voiceover in 33 seconds.

MLT (melt)

layered renders (b-roll, cards, music)

Your distribution's MLT package (mlt on Fedora, whose melt package is an unrelated compression tool), or Kdenlive, whose flatpak copy is found automatically. PROOFCUT_MELT overrides both.

Optional. Each unlocks one feature, proofcut doctor reports whether it is available, and everything else works without it:

Optional

Unlocks

Notes

ImageMagick 7 (magick)

title and end cards, rendered from SVG templates

ImageMagick 6's convert is not used, so distributions that still ship 6 (Ubuntu 24.04) need ImageMagick's own build.

Claude Code (claude, logged in)

the agent pane in the workspace

proofcut mcp works with any MCP client; only the pane runs claude itself.

PROOFCUT_VLM

describe (b-roll search by what's on screen)

The python of a venv with torch, transformers, bitsandbytes and Pillow, on a CUDA GPU. The Qwen2.5-VL model downloads on first use.

PROOFCUT_FACE

reframe-detect (face-aware crops)

The python of a venv with insightface, onnxruntime and opencv-python.

PROOFCUT_TTS, PROOFCUT_TTS_MODEL, PROOFCUT_TTS_VOICE

vo-synth (a line in a cloned voice)

A python with qwen-tts and a CUDA torch, a local Qwen3-TTS snapshot, and a directory holding a reference clip of the voice. There is no default voice, on purpose.

Working on proofcut

Whether you're a person or a coding agent, start with CLAUDE.md. It holds the rules and the traps this repo has already hit, and Claude Code loads it automatically. CONTRIBUTING.md is the short version a pull request is checked against, and SECURITY.md says how to report a vulnerability.

Where things live:

Path

What it is

src/proofcut/ops.py

Every operation. The MCP tools, the CLI and the web UI all call these.

src/proofcut/server.py

The MCP server. Register tools with @_tool(), never @mcp.tool().

src/proofcut/cli.py

The proofcut command: one subcommand per tool, printing JSON.

src/proofcut/webui.py, src/proofcut/web/

The workspace. It posts to ops and renders what comes back; it never decides anything itself.

src/proofcut/project.py, timeline.py

The project manifest (proofcut.json) and the OTIO timeline.

tests/

test_server_stdio.py drives a real proofcut mcp subprocess; test_webui_http.py a real socket.

scripts/

The demo maker, the Mac and Windows trial kits, screenshot capture.

docs/

The manual, the demo, and the design record (below).

Run the checks:

uv sync
uv run ruff check .      # never `ruff format`; see CONTRIBUTING.md
uv run pytest

The suite talks to a real proofcut mcp subprocess, so it is slower than a pure unit suite. Tests that need whisper, auto-editor, melt or ImageMagick skip when the tool is missing. Tests that render through melt also need a display: on a headless machine use QT_QPA_PLATFORM=offscreen or xvfb-run -a (proofcut doctor tells you which your MLT needs). Without one they fail with "no display for MLT's Qt module to open", which is the environment, not a regression.

The documentation:

proofcut's reasoning is part of what it ships, so the design record is public:

  • PLAN.md: architecture, stack decisions, open questions.

  • HISTORY.md: the dated record of what shipped and what the evidence said.

  • PRIOR-ART.md: what else exists in this space, and what proofcut does that they don't.

  • NEXT.md: the directions after the queues closed, ranked.

  • TRIAL.md: an agent cutting a video end to end, unattended and scored.

  • docs/plans/: the plans, in progress and finished. A step that landed says "Shipped" and names its HISTORY.md section.

License

PolyForm Shield 1.0.0. proofcut is source-available, not open source: you can read, run, change and redistribute it for any purpose except building a product that competes with it. Cutting your own videos, running it for clients, building on it and forking it to fix a bug are all fine. For a commercial licence, ask.

The bundled typefaces are not proofcut's to relicense. The caption face in src/proofcut/fonts/ and the three browser faces in src/proofcut/web/ are OFL-1.1, each with its licence text beside it and its source in that directory's FONTS.md.

Say thanks

If proofcut cut a video for you, you can buy me a coffee on Ko-fi.

Available Tools

93 tools
add_captionsA
DestructiveIdempotent

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.

ParametersJSON 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

ParametersJSON Schema
NameRequiredDescription

No output parameters

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.

assetsA
Read-onlyIdempotent

Every asset a cue can point at — clip or card — for an assets pane.

The cue vocabulary is clip_id or card:name, so this lists both: each clip with its probe metadata, transcript/description presence, role and media.playability verdict; each card with what it was made from, whether its files exist, and whether it has a re-author record. Every entry carries cues, how many cues reference it — "is this used" is the question an assets pane exists to answer. Read-only.

ParametersJSON 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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false; the description repeats 'Read-only' but adds no further behavioral traits such as rate limits, auth needs, or side effects. It does describe output composition (probe metadata, playability, re-author record), but that is more output semantics than behavior, and with annotations covering safety, the extra value is limited.

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?

Two sentences with the purpose front-loaded and supporting details following. The second sentence is long but dense and information-bearing; there is no fluff, though it could be slightly tightened.

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?

Given the output schema exists and the tool is a read-only list with no required parameters, the description sufficiently covers what the agent needs to know. It explains the main output categories (clip/card fields and cue counts), though it does not cover when to prefer this over sibling tools, which is already handled in usage guidelines.

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?

The single parameter `path` is fully documented in the input schema with detailed resolution semantics. The tool description adds nothing about `path`, so per the rule for >80% schema coverage, a baseline of 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?

The description opens with 'Every asset a cue can point at — clip or card — for an assets pane,' which is a specific verb-resource statement. It clearly distinguishes itself from siblings like list_media by covering both clips and cards and including cue reference counts, so an agent can tell it apart without opening schemas.

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?

The phrase 'the question an assets pane exists to answer' provides clear context for when to use this tool. However, it does not explicitly mention alternatives or state when not to use it, so it stops short of full routing guidance.

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

attach_transcriptA
DestructiveIdempotent

Ingest an existing word-timed whisper JSON as this clip's transcript.

Checks the transcript against itself for near_duplicates — adjacent runs of words that sound like the same line said twice. That is a retake verify can never catch once both takes are cut into the edit, since nothing then disagrees with the timeline. A hit is not a verdict: a deliberate callback line looks the same as a swallowed retake here.

Also reports suspect_durations, overlaps and repeats. An overlaps seam is a retake splice whisper read straight across, interleaving both takes and inventing words nobody said — check it before drawing anything derived from this transcript. repeats is a back-to-back duplicated phrase, the shape a retake makes when it survives as distinct words rather than as a seam — a different subset of retakes than overlaps finds, not a smaller one. Use transcript_checks to see all four again later.

ParametersJSON 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.
clip_idYesThe clip this transcript belongs to. Its words become `(clip_id, word_index)`, which is how every cue, mark and caption addresses them afterwards.
transcript_pathYesThe whisper JSON to ingest. It has to carry word-level timings — proofcut addresses words, not segments.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the annotations, the description explains that the tool runs self-checks (near_duplicates, suspect_durations, overlaps, repeats), warns that a hit is not a verdict, and cautions about overlaps seams inventing words. This is rich, non-obvious behavioral context that materially helps an agent trust and interpret results.

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 purpose is front-loaded in the first sentence, and the subsequent paragraphs each explain a distinct behavioral check or caveat. The description is longer than minimal, but every sentence adds operational value and there is no fluff.

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?

Given the output schema exists and annotations flag destructive/idempotent behavior, the description is largely complete: it defines input requirements, explains all four diagnostic checks, and warns about interpretation. A small gap is that it does not explicitly state that ingesting replaces any existing transcript, but annotations and the meaning of 'as this clip's transcript' cover it.

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, but the description adds meaningful detail: clip_id words become (clip_id, word_index) and are used by every cue, mark, and caption afterward. This explains the downstream impact of the parameter beyond the schema's simple field documentation.

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 first sentence states a specific action ('Ingest an existing word-timed whisper JSON') and target ('as this clip's transcript'), clearly distinguishing it from tools like transcribe. It names the exact resource and the ownership outcome in a way an agent can act on.

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?

The description makes clear this tool is for ingesting an already-existing whisper JSON rather than generating one, which implicitly routes an agent away from transcribe. It also gives follow-up guidance ('Use transcript_checks to see all four again later'), but it does not explicitly name alternatives or state when not to use it.

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

attenuate_noisesA
DestructiveIdempotent

Pull down short loud non-speech events instead of cutting them out.

An event only qualifies automatically when it is both short (max_event_seconds) and sitting in a word-map gap narrow enough to prove the map is dense around it (max_gap_seconds) — a wide gap disqualifies even a very short event, which is the false-positive class this exists to prevent (speech sitting in a hole the transcript never wrote down). Qualifying events are pulled down db via one ffmpeg pass, never cut, and written as a new derived copy that media_path() picks up automatically everywhere downstream; the original is always what a re-run reads from, so repeated calls never compound gain.

Unlike cut_by_transcript/cut_by_time, nothing here ever raises on what the scan finds — this is an automatic multi-candidate scan, not a handful of explicit ranges, so withholding is done per event rather than refusing the whole call. suspect_neighbours (a bounding word itself has a suspect duration — withheld unless confirm_suspect=True or plan=True) and disqualified (too long, or too wide a gap — never written, no override) are always reported in full, not only under plan=True.

ParametersJSON Schema
NameRequiredDescriptionDefault
dbNoHow far to pull each qualifying event down, in dB. Negative is quieter.
padNoSeconds added either side of each event before it is pulled down.
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.
clip_idYesThe clip to scan. It always reads that clip's **original** media, never a previous attenuated copy, so repeated calls never compound gain.
confirm_suspectNoGo ahead even though a boundary word claims a suspect duration. Read the echoed words first — a suspect duration usually means whisper hid a retake inside that word, so the edge is not where it reads.
max_gap_secondsNoHow wide the word-map gap around an event may be. A wide gap disqualifies even a very short event — that is the false-positive class this exists to prevent, speech sitting in a hole the transcript never wrote down.
max_event_secondsNoLongest an event may run and still qualify automatically. Anything longer is reported as `disqualified` and never written.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

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

Beyond the annotations, the description explains the exact write behavior: a new derived copy is written, the original is always read first, repeated calls never compound gain, and nothing ever raises on scan findings. It also documents per-event withholding versus whole-call refusal, and the behavior of suspect_neighbours and disqualified events.

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 contributes: it front-loads the core purpose, explains the qualification rule, discloses write behavior, and then distinguishes this tool from siblings. Despite its length, it is efficiently structured with clear paragraphs and 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 tool's complexity, the description fully covers the qualification criteria, the no-compound-gain guarantee, the difference from sibling tools, and the reporting behavior for suspect and disqualified events. The output schema handles return value specifics, so nothing essential is missing.

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?

The input schema already covers all parameters with detailed descriptions (100% coverage), so the baseline is 3. The tool description adds value by explaining how db, max_event_seconds, max_gap_seconds, confirm_suspect, and plan work together in the qualification and withholding logic, going beyond individual schema comments.

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 states a specific verb and resource: 'Pull down short loud non-speech events instead of cutting them out.' It clearly distinguishes itself from cut_by_transcript/cut_by_time by describing the difference in granularity and failure mode, so an agent can select it correctly.

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 explicitly contrasts this tool with cut_by_transcript/cut_by_time, explaining that this is an automatic multi-candidate scan rather than explicit ranges. It also clarifies when plan=True should be preferred and how confirm_suspect gates a specific case.

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

attribute_speakersA
Idempotent

Label each word with the mic that was loudest while it was spoken.

For a co-hosted recording captured on one mic per speaker. It is one pass over the transcript that is already attached — never a second ASR run, and transcribing each mic separately is measured and dead: half of each mic's own transcript is the other person, at every isolation tried. Transcribe once, from the mix or either mic, then call this.

streams are ffmpeg audio ordinals into the registered container (0, 1), and labels names them in the same order — one label per stream, defaulting to speaker1, speaker2. The speaker lands on the word: it is a label and never an address, so every cue, description, mark, music anchor and caption still resolves through (clip_id, word_index) and nothing else moves.

It reports; it does not decide below the floor. apply is off by default. The rule is ~99% correct per word on clear speech and at chance on words spoken over each other, and margin_db is what half-knows the difference — anything under it comes back in ambiguous_spans to go and listen to, with the three words either side. Read unmeasurable separately from ambiguous: it means the mics ran out before the transcript did, which is a different recording problem. Applying keeps any label already on a word this refuses to call.

ParametersJSON 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.
applyNoWrite the labels onto the words. Off by default — it reports first, and applying keeps any label already on a word this refuses to call.
limitNoHow many ambiguous spans to return; the reply also says how many there are in total.
labelsNoWhat to call each stream, in the same order — one per stream. Unset, `speaker1`, `speaker2`.
clip_idYesThe co-hosted clip: one container, one mic per speaker, one transcript already attached.
streamsNoWhich audio streams the speakers are on, as ffmpeg audio ordinals (`[0, 1]`). Unset, the container's readable audio streams in order.
margin_dbNoHow much louder one mic has to be to be believed, in dB. It reports a default and is not a threshold to trust: on words spoken over each other the rule is at chance, and anything under this margin comes back in `ambiguous_spans` to go and listen to.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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

Beyond annotations (readOnlyHint false, idempotentHint true), the description discloses behavior richly: it reports without applying by default, keeps existing labels on words it refuses to call, distinguishes 'unmeasurable' from 'ambiguous', and states accuracy figures (~99% on clear speech, chance on overlap). It also explains that margin_db is not a threshold to trust, which is a nuanced behavioral caveat.

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 long, but it is well-structured with bold headings and logical flow: purpose first, then how it differs from alternatives, then parameter explanations, then behavioral caveats. Each sentence earns its place; nothing is redundant. It is appropriately detailed for a complex tool with many edge cases, though it could be tightened slightly.

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 tool's complexity (7 parameters, output schema present, multiple edge cases), the description covers everything an agent needs: the core operation, when to use it, how parameters interact, the difference between ambiguous and unmeasurable, and the apply behavior. The presence of an output schema further reduces the burden of explaining return values. Nothing critical is missing.

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?

The input schema already provides descriptions for all 7 parameters (100% coverage), so the baseline is 3. The description adds significant meaning beyond the schema: it explains streams as ffmpeg audio ordinals in order, labels as names in the same order, margin_db as a reporting floor rather than a decision threshold, and the interplay between apply and existing labels. This extra context lifts the score to 4.

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 crisp, specific verb-resource statement: 'Label each word with the mic that was loudest while it was spoken.' This clearly distinguishes it from transcription tools (transcribe, hear) and from tools that manipulate transcript structure. It also frames the tool as a post-transcription step, which separates it from ASR workflows.

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 and when-not-to-use guidance: it is a single pass over an attached transcript, never a second ASR run, and it warns that transcribing each mic separately is 'measured and dead' with concrete evidence. It also tells the user to transcribe once first, then call this tool. This is actionable and leaves no ambiguity about prerequisites.

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

broll_briefA
Read-onlyIdempotent

The whole b-roll question as data: what there is, and what it goes under.

Returns the footage catalogue with each clip's synopsis and duration, then every shot position on the timeline with the narration that plays over it, how long it is held, and what is currently there. card: true positions are shown for rhythm and are not choices.

This is the half proofcut can do. Choosing is the other half, and it belongs to you: read the brief, decide which clip goes under which sentence, and write the answers back with cue_add, where the picture plan checks each one. Ranking the catalogue by text similarity was measured and does not work — the sentence that earns a clip routinely shares no word with any description of it.

missing_synopsis is the thing to fix first. A clip with no synopsis is invisible to any reasoning about the catalogue, so it will simply never be chosen.

ParametersJSON Schema
NameRequiredDescriptionDefault
fpsNoThe frame grid the shot positions are projected on. Defaults to the rate `export` would use.
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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is known. The description adds substantial behavioral context beyond those: it explains that `card: true` positions are shown for rhythm and are not choices, that ranking by text similarity was measured and does not work, and that `missing_synopsis` clips will never be chosen. These are non-obvious traits an agent needs to interpret the output correctly, and they do not contradict any annotation.

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 long but well-structured: it front-loads the purpose, then explains the workflow, and closes with a priority instruction. Every sentence contributes useful guidance, though the opening line ('The whole b-roll question as data...') is somewhat poetic and less concrete than the rest. It is appropriately sized for the tool's complexity, but slightly verbose.

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?

The tool has an output schema (not shown but flagged as present), and the description explains exactly what the output contains: clip synopsis, duration, shot positions, narration, hold length, current content, and card positions. It also explains how to act on that output via `cue_add`, and what to fix first. For a read-only briefing tool, this is complete enough for an agent to call it correctly and interpret the result.

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 baseline is 3. The description does not add any parameter-specific meaning beyond what the schema already provides for `fps` and `path`. It focuses on the output and usage context, not the parameters, so it neither enhances nor detracts from the schema's documentation.

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 clear statement of what the tool returns: the footage catalogue with clip synopsis and duration, plus shot positions with narration, hold duration, and current content. It explicitly notes that `card: true` positions are shown for rhythm and are not choices, which distinguishes this read-only briefing tool from the write-oriented `cue_add` sibling. The verb 'Returns' and the specific resource make the purpose unmistakable.

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 usage direction: it states this is the half that reads the brief, and that choosing belongs to the user via `cue_add`. It also warns that ranking by text similarity does not work, guiding the agent away from a common but flawed heuristic, and instructs to fix `missing_synopsis` first because such clips are invisible to reasoning. This is clear when-to-use and when-not-to-use guidance.

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

build_shotsA
Read-onlyIdempotent

Project the cue table into contiguous shots over the current edit.

Maps each cue's word through the edit's surviving ranges to a timeline frame, resolves its asset to a checked path (card:name under assets/cards/, else a registered video clip_id), and runs each shot to the next cue — the last to the edit's own frame total. Refuses if a cue's word was cut from the edit; fix it with cue_rm/cue_add first.

fps picks the frame grid; it defaults to the project's timebase, which for an audio-only project is milliseconds rather than frames. Pass the rate export will use to see the frames the export actually cuts at.

ParametersJSON Schema
NameRequiredDescriptionDefault
fpsNoThe frame grid to project onto. Unset, the project's timebase — which on an audio-only project is milliseconds rather than frames. Pass the rate `export` will use to see the frames the export actually cuts at.
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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior5/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, and the description adds meaningful behavioral detail beyond that: the exact mapping algorithm, asset resolution rules, shot extension to the next cue and final frame, refusal on cut cues, and the subtle fps/timebase default behavior. This is rich, non-contradictory 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 well-structured and front-loaded with a one-line summary, followed by concise technical detail and a parameter note. Each sentence adds value; there is no padding or repetition of obvious annotation facts.

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 annotations, full schema descriptions, and presence of an output schema, the description covers the critical behavior, failure mode, how shots are ended, asset resolution, and fps selection. An agent has everything needed to select and invoke this tool correctly without additional inference.

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?

The input schema has 100% description coverage for both fps and path, so the baseline is 3. The description reinforces the fps behavior and timebase nuance, but that information already appears in the schema description; no new semantic detail is added for path or beyond what the schema provides.

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

Purpose4/5

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

The description clearly states a specific verb and resource: 'Project the cue table into contiguous shots over the current edit.' It explains the core operation in detail and differentiates itself from generic edit operations, though it does not explicitly name or contrast sibling tools such as shot_sheet or cut_by_transcript.

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?

Clear context is provided: the tool projects cues into shots, and it will refuse if a cue's word was cut, with a directive to fix it via cue_rm/cue_add first. It also gives practical guidance on the fps parameter for export alignment, but it does not explicitly state when to prefer this tool over alternatives or list exclusions.

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

canvasA
DestructiveIdempotent

Read or change the shape this project renders at.

The canvas is project state and every frame size derives from it — the MLT profile and the captions' reference canvas both read it, so a project cannot quote caption sizes against one shape and render another. Call it with no size to read what is in force plus the footage-derived shape it would fall back to; reset drops the override and returns to that shape.

size is "WIDTHxHEIGHT", e.g. "1080x1920" for a vertical reel. Both edges must be even.

Setting one has a routing consequence, reported as routes_through: an overridden project renders through the MLT writer whatever its source count, because auto-editor cannot be handed a canvas it will honour. An override that changes the aspect crops to fill rather than pillarboxing, so cropped names every clip that loses footage to it — use reframe to see or change which part of each one is kept.

ParametersJSON 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.
sizeNo`WIDTHxHEIGHT`, e.g. `1080x1920` for a vertical reel. Both edges must be even. Omit it to read what is in force plus the footage-derived shape it would fall back to.
resetNoDrop the override and return to the footage-derived shape.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

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

Annotations flag `destructiveHint` and `idempotentHint`; the description goes beyond by detailing the routing consequence (override forces MLT writer), the cropping behavior (aspect change crops to fill, not pillarbox), and the side‑effect on caption quoting. It even mentions the `plan` flag as a safer alternative, which is exactly the kind of operational detail an agent needs. No contradiction with annotations.

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 moderately long but every sentence is packed with unique, actionable information. It is front‑loaded with the core purpose, then flows naturally into call patterns, behavioral consequences, and parameter details. There is no fluff or redundancy.

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 state‑changing tool with subtle rendering implications, the description covers everything: what it does, when to call it, what happens on override (routing, cropping), how to preview safely, and which sibling to use for fine‑grained adjustments. The presence of an output schema and rich parameter descriptions further reduces any missing context. Nothing essential is left out.

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?

The input schema already covers all four parameters with detailed descriptions (100% coverage). The main description adds extra meaning for `size` (even edges, vertical example) and `reset` (drops override), and explains the consequences of setting a size (routing, cropping). This goes beyond the schema, so a 4 is warranted; it stops short of a 5 because the schema already does much of the heavy lifting.

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-resource pairing ('Read or change the shape this project renders at') and goes on to explain exactly what the canvas is, how it relates to project state and rendering, and why it matters (caption quoting consistency). It also names a related tool (reframe) for a specific sub‑task, which distinguishes it from siblings without needing to list them.

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 call patterns: reading with no `size`, resetting with `reset`, and using `plan` to preview. It also tells the agent when to delegate to `reframe` for changing which part of a crop is kept, effectively stating when not to use this tool. This is model guidance.

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

caption_styleA
DestructiveIdempotent

Read or change the caption look this project keeps.

The style is project state and the captions are derived from it, so a restyle survives every later cut: regenerating re-reads this. Call it with no arguments to read the current look and learn the field names; any argument sets that field and leaves the others alone. reset drops every override first — reset plus preset starts clean from a preset.

preset is the base look ("clean", "karaoke" for per-word highlight, or "boxed"); everything else overrides one of its fields, and only the overrides are stored.

Colours take "#rrggbb", "#rrggbbaa", a name ("yellow", "white", "red", …) or an ASS "&H…" value. text is the word's colour and highlight what it turns as it is spoken, which only shows with karaoke on. position is named: "bottom", "top", "top-right", and so on. Both come back resolved, because ASS quotes colours backwards and alpha-inverted.

plan validates and resolves without writing. Use caption_view to see the result on the actual timeline.

ParametersJSON Schema
NameRequiredDescriptionDefault
boxNoDraw an opaque box behind the words. It buys legibility over light footage — white captions over the film's own light cards measure 1.10:1 without one — and costs clean edges, since libass draws one box per override block.
boldNoDraw bold.
fontNoFamily name to draw with. Whether it actually draws is a different question from whether it is installed — `fonts` measures a render, and libass substitutes silently at exit 0.
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.
planNoResolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it.
sizeNoType size, against the project's canvas as the reference frame.
textNoThe word's own colour: `#rrggbb`, `#rrggbbaa`, a name, or an ASS `&H…` value. It comes back resolved, because ASS quotes colours backwards and alpha-inverted.
resetNoDrop every override first. `reset` together with `preset` starts clean from that preset.
marginNoDistance from the frame edge, in canvas pixels.
presetNoThe base look: `clean`, `karaoke` (per-word highlight) or `boxed`. Everything else overrides one of its fields, and only the overrides are stored.
shadowNoDrop-shadow distance.
karaokeNoFill each word as it is spoken. The fill is left-to-right within a line rather than a per-word step, which is what the grouping fields below shape.
max_gapNoStart a new cue when the silence between two words exceeds this many seconds.
positionNoWhere captions sit, named: `bottom`, `top`, `top-right` and so on.
highlightNoWhat a word turns as it is spoken. It only shows with `karaoke` on.
max_wordsNoMost words in one caption cue. Grouping is part of the look, which is why it is stored with it.
box_colourNoColour of the box behind the type, when `box` is on.
max_durationNoLongest a single cue stays on screen, in seconds.
outline_widthNoOutline thickness. With no box this is what holds the words apart from the picture.
outline_colourNoColour of the outline around the type.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already mark this as destructive and idempotent, and the description aligns: it says changes persist ('restyle survives every later cut') and that `reset` drops overrides. It adds context beyond annotations by explaining how colour values are resolved (ASS quoting) and that only overrides are stored, giving an agent a clear mental model of the state mutation. Slight gap: it doesn't explicitly state that the call is idempotent, but the description implies it.

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 long (roughly 300 words) but well-structured with clear paragraphs. It front-loads the purpose and usage, then details colour formats, then plan/view. Every sentence contributes to the agent's decision-making. It could arguably be tighter, but for a tool with 21 parameters and a destructive mutation, the length is justified.

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 tool's complexity—21 parameters, destructive behavior, and interaction with sibling tools—the description is remarkably complete. It covers read vs write semantics, persistence, colour handling, preset/override relationships, and points to `caption_view` for verification. An agent has all the information needed to call it correctly without additional assumptions. The output schema exists, so return-value details are not required in the description.

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?

The input schema has 100% parameter coverage with per-field descriptions, but the tool description goes far beyond: it explains the preset options ('clean', 'karaoke', 'boxed'), how overrides work, colour format options, the relationship between `text` and `highlight` with karaoke, and the meaning of `plan` and `reset`. This adds substantial semantic value that the schema alone does not provide, especially for the 21 parameters.

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 'Read or change the caption look this project keeps,' a specific verb pair and resource. It distinguishes itself from the sibling caption_view ('Use caption_view to see the result on the actual timeline') and explains that captions are derived from this style, so an agent immediately knows this tool is the source of truth for caption appearance, not a renderer.

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?

Explicit usage rules are given: 'Call it with no arguments to read the current look and learn the field names; any argument sets that field and leaves the others alone.' It also explains the `reset` and `preset` interaction, and directs to `plan` for dry-run validation and `caption_view` for visual confirmation. No ambiguity about when to use it.

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

caption_viewA
Read-onlyIdempotent

The captions this timeline would produce, and the style in force.

add_captions without writing a file: the same cues, in timeline seconds, already grouped by the project's own break rules — so this is how to check a restyle, or read back what a caption actually says at some moment, before committing a file to it.

Reports rather than refuses: a project with no transcript, or one whose every word has been cut, comes back with an empty cues and a cues_error saying which. Read-only.

cues is a window of limit from first; cues_total is how many the film has and cues_next, when present, where to continue. Use locate to find the cue at a moment rather than paging to it.

ParametersJSON 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.
firstNoIndex of the first cue to return. 0 by default.
limitNoMost cues to return; `cues_next` says where to continue.
clip_idNoShow one transcript's captions rather than every clip's.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true. The description adds beyond this by explaining that it reports rather than refuses (empty `cues` and a `cues_error` for missing transcripts) and describes the pagination fields (`cues_total`, `cues_next`). It also notes that cues are grouped by the project's break rules. This is useful behavioral context not covered by annotations.

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 compact and each sentence serves a purpose. It front-loads the core purpose, then usage, then error behavior, then pagination. No fluff; every line contributes to accurate tool selection and invocation.

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 that an output schema exists, the description still explains the important return fields (cues, cues_error, cues_total, cues_next) and how to navigate them. It addresses edge cases (missing transcript) and recommends an alternative for time-based lookup. For a read-only tool, this is complete.

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 description coverage is 100%, so the baseline is 3. The description adds meaning by explaining the relationship between `first`, `limit`, and `cues_next` (a window of `limit` from `first`), and suggests using `locate` instead of paging. It also clarifies that `cues` is a window, which goes beyond the individual parameter 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?

The description states a specific purpose: it returns the captions a timeline would produce along with the active style, and explicitly contrasts itself with add_captions (which writes a file). This clearly distinguishes it from siblings like caption_style or cue_ls. The phrase 'The captions this timeline would produce, and the style in force' is a precise verb-resource pairing.

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?

It explicitly states when to use this tool: 'this is how to check a restyle, or read back what a caption actually says at some moment, before committing a file to it.' It also names the alternative (add_captions) that writes, and recommends using `locate` for finding a cue at a moment rather than paging. This gives clear when-to and when-not-to guidance.

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

card_newA
DestructiveIdempotent

Make a card from a template: fill its slots, write the SVG, render it.

name is the <name> in card:<name> — the key a cue points at. Both the SVG source and the PNG are written under the project's assets/cards/, so the card can be re-edited later and re-rendered with card_render rather than redrawn.

A slot value is text. A newline inside one is a line break wherever the template accepts multiple lines; nothing wraps automatically, because a guessed wrap overflows the frame without saying so. Ratings are numbers out of five, to the nearest half.

Leave width/height unset unless you mean something other than this film. They default to the project's own canvas, which is what stops a card from pillarboxing inside the frame it was made for; naming a size that is not the project's is how a card loses a quarter of its width to black bar. Given at all, both must be.

Refused if a card of this name exists, unless overwrite — a cue may already point at it. Read font_warnings in the result: a template naming a face this machine lacks still renders, in a substitute, with nothing else to say so.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesThe `<name>` in `card:<name>` — the key a cue points at. The SVG and the PNG are both written under `assets/cards/`.
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.
slotsYesThe template's slots filled in, as text. A newline is a line break where the template takes several lines; ratings are numbers out of five, to the nearest half.
widthNoRender width. **Leave it unset unless you mean something other than this film** — it defaults to the project's canvas, which is what stops a card pillarboxing inside the frame it was made for. Given at all, `height` must be too.
heightNoRender height, given together with `width` or not at all.
templateYesWhich template to fill; `card_templates` lists them with their slots. A per-aspect variant file is resolved from the canvas, never named here.
overwriteNoRedraw a card of this name that already exists. Refused without it, since a cue may already point at that card.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already carry readOnlyHint=false, destructiveHint=true, idempotentHint=true. The description adds meaningful behavioral context: the overwrite refusal guard, the side effect of writing SVG+PNG to assets/cards, the non-wrapping newline behavior, and the font-substitution fallback. No contradiction with annotations.

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?

Front-loaded with a one-line summary, then structured paragraphs for storage, slots, size, and error/fallback behavior. Bold warning for width/height. Every sentence earns its place; 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?

Covers purpose, storage, parameter semantics, destructive-guard behavior, and result-reading (font_warnings). Good cross-references to card_render and card_templates. Given the output schema exists, nothing an agent needs to call it correctly is missing.

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 coverage is 100%, so the schema already documents all parameters. The description adds marginal nuance (e.g., 'nothing wraps automatically' and the pillarboxing warning for width/height), but these largely duplicate the schema text. 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?

States a specific verb+resource: 'Make a card from a template: fill its slots, write the SVG, render it.' Distinguishes from card_render and card_reauthor by naming the rendering pipeline and the storage location, so an agent can tell it apart from siblings.

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?

Explicitly names alternatives: 're-rendered with card_render rather than redrawn' and 'card_templates lists them with their slots.' Gives concrete conditions: leave width/height unset unless you need a different size, and read font_warnings in the result. This is clear when-to-use and when-not-to-use guidance.

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

card_reauthorA
DestructiveIdempotent

Draw recorded cards again at the shape this project renders at now.

Reach for this after canvas — a card is the only thing in a project whose shape a canvas change cannot fix on its own, because the aspect is baked into the SVG it was drawn from. Re-rendering the old SVG at the new size would pillarbox the card inside the frame; this fills the template again at the new canvas, from what card_new recorded.

With no name it sweeps every recorded card the canvas has left behind, plus any whose files have gone missing. Named, it redraws that one whatever its canvas.

Read unrecorded in the result. Those are cards with files on disk and no record of what made them — nothing can re-author one, and the way to fix it is card_new with overwrite, which records it on the way past. plan reports what would change and writes nothing.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoOne card to redraw, whatever its canvas. Omit it to sweep every recorded card the canvas has left behind, plus any whose files have gone missing.
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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already mark this as destructive and idempotent; the description adds substantial behavioral detail: it sweeps all recorded cards or missing files, redraws a named card, leaves unrecorded cards untouched, and writes nothing in `plan` mode. No contradiction with the annotations.

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 organized into tight paragraphs: purpose, usage context, and result interpretation. Every sentence contributes either a behavioral fact, a routing rule, or an edge case, 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 full schema coverage, an output schema, and safety annotations, the description covers the trigger context, the sibling distinction, the unrecorded-card failure mode, and the safe planning path. Nothing needed to call the tool correctly is missing.

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?

The input schema already describes all three parameters at 100% coverage, including the sweep-vs-named behavior and the `plan` write-nothing behavior. The description mostly restates this rather than adding new parameter-level meaning, so the baseline 3 applies.

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: 'Draw recorded cards again at the shape this project renders at now.' It clearly distinguishes this from siblings like canvas and card_new by explaining exactly what makes card_reauthor necessary.

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?

It explicitly says to reach for this after `canvas`, explains why a canvas change cannot fix cards, and names `card_new` with `overwrite` as the alternative for unrecorded cards. It also recommends `plan` for dry-run behavior, giving an agent clear decision rules.

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

card_renderA
DestructiveIdempotent

Rasterise assets/cards/<name>.svg into the PNG card:<name> shows.

Author the SVG under the project's assets/cards/, then render it here; both files are kept, so a card can be re-edited rather than redrawn. The PNG is what a card: cue resolves to, so a card is not usable until this has run.

width/height are given together or not at all and set the render size — the document is drawn at that scale rather than rasterised and resampled — and they fit rather than distort, so a size at a different aspect from the document's comes back smaller on one axis. Omitted, the document renders at its own declared size.

Every call reports the fonts the document names and what fontconfig will actually draw. Read font_warnings: a card naming a face this machine lacks renders pixel-identically to one naming a face it has, so nothing downstream can catch the substitution.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesThe card to rasterise: `assets/cards/<name>.svg` becomes the PNG that `card:<name>` resolves to.
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.
widthNoRender width. The document is *drawn* at this scale rather than resampled, so text stays sharp, and it fits rather than distorts. Given together with `height` or not at all; omitted, the document renders at its own declared size.
heightNoRender height, given together with `width` or not at all.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

Annotations only state idempotent and destructive hints, but the description goes far beyond them: it explains that both source and output are kept, that rendering at a different scale draws rather than resamples, that fit behavior shrinks one axis on aspect mismatch, and critically warns about font substitution producing pixel-identical renders that cannot be caught downstream. This is exactly the kind of behavioral context an agent needs and that annotations do not provide.

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 longer than a couple of sentences, but every paragraph earns its place: purpose, workflow, size semantics, and font warnings are each distinct and necessary. It is front-loaded with the core purpose and organized by concern, with no filler or redundancy beyond a minor overlap with schema descriptions.

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 tool's moderate complexity, a full output schema, and strong annotations, the description is remarkably complete. It covers the entire lifecycle (author → render → use), explains the size constraints with real behavioral detail, and preempts the hardest-to-detect failure mode (font substitution). An agent can call this tool correctly with no additional knowledge.

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% and the schema already documents width/height pairing and omission behavior. The description adds genuine value by explaining the non-resampling render behavior, the fit-not-distort constraint, and the consequence of aspect ratio mismatch. That extra semantic depth moves it above the baseline of 3.

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: 'Rasterise `assets/cards/<name>.svg` into the PNG `card:<name>` shows.' This clearly differentiates it from sibling tools like card_new or card_templates, which create or edit card definitions rather than render them. The purpose is unambiguous and immediately front-loaded.

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?

The description gives clear workflow context: author the SVG under assets/cards, then render it to make it usable; it also explains that the PNG is what a card: cue resolves to. It does not explicitly name alternatives or provide when-not-to-use guidance, but the implied usage is strong and sufficient for an agent to decide when this tool is the right one.

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

card_safe_zonesA
Read-onlyIdempotent

Measure a rendered card's ink in and around a platform's reserved band.

Report only — nothing here blocks a render, and there is no default floor: SCENE_THRESHOLD's own history is that a threshold gets pinned by looking at real output, not picked cold, and this check has had exactly one look so far. platform is one of proofcut's own zones (tiktok-organic, tiktok-ads, reels, shorts, worst-case) or one an applied pack's active variant declares — pack_show lists both.

Reads card from its already-rendered PNG, never from the manifest's recorded slots alone, so the ink it measures is the ink actually on disk. Refuses a card with no PNG yet (card_new/card_render it first) or a platform neither source declares.

ParametersJSON Schema
NameRequiredDescriptionDefault
cardYesThe card to measure, read from its already-rendered PNG rather than from the recorded slots — so the ink measured is the ink on disk.
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.
platformYesWhose reserved band to measure against: one of proofcut's own zones (`tiktok-organic`, `tiktok-ads`, `reels`, `shorts`, `worst-case`) or one an applied pack's active variant declares. `pack_show` lists both.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false. The description adds significant behavioral context: it reads from the actual rendered PNG on disk (not manifest slots), it is report-only and does not block renders, it has no default floor for thresholds (with historical justification), and it refuses cards without a PNG. This goes well beyond the annotations and clearly sets expectations for an agent.

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 front-loaded with the core purpose in the first sentence. The SCENE_THRESHOLD digression in the second sentence adds context but is tangential to immediate usage. The rest is concise and relevant. Overall it is efficient, though slightly verbose with the historical note.

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 read-only, idempotent measurement tool with an output schema (not shown), the description covers all necessary operational details: prerequisites (PNG must exist), valid platform sources, the read-from-disk behavior, and refusal conditions. Nothing essential is missing for an agent to call this 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 coverage is 100%, so the baseline is 3. The main description largely repeats what the schema property descriptions already say for 'card' and 'platform' (e.g., reading from PNG, enumerating zones). It adds a minor nuance about SCENE_THRESHOLD history, but that is behavioral, not parameter-specific. No new parameter meaning is introduced beyond the schema, so a 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?

The description opens with a clear, specific verb-resource pair: 'Measure a rendered card's ink in and around a platform's reserved band.' It distinguishes itself from siblings by being a pure measurement/report operation, and it names related tools (card_new, card_render, pack_show) that support its prerequisites. This leaves no ambiguity about what the tool does.

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?

The description explains when the tool refuses to run (no PNG yet, unknown platform) and implies the workflow: render first via card_new/card_render. It also references pack_show to discover valid platforms. However, it does not explicitly contrast itself with alternative measurement tools (e.g., reframe_coverage), so the 'when to use this vs. alternatives' guidance is implicit rather than explicit.

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

card_templatesA
Read-onlyIdempotent

The card templates proofcut ships, and the slots each one takes.

Read this before card_new: each slot says what it is for, whether it is required, and what it defaults to. The palette and font stacks are slots too, so a card can be restyled without authoring an SVG by hand.

Call it with no name to choose one, then with name to read only that template's slots — the whole table is long.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoOne template to return in full. The others come back as name and description only. Unset, every template in full.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, and non-destructive behavior, so the description only needs to add context beyond that. It explains the returned structure (slots with purpose, required, defaults) and hints at response size ('the whole table is long'). This adds value without contradicting annotations.

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 moderately sized, front-loads the core purpose, and uses separate sentences for distinct points. It avoids redundancy with the schema, though it could be tightened by merging some sentences. Overall, it's efficient and well-ordered.

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?

The tool has a single optional parameter, a clear schema, rich annotations, and an output schema. The description explains what the tool returns, how to use it, and its relationship to card_new. Nothing an agent needs to invoke it correctly is missing, even without seeing the output schema.

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?

The schema already describes the `name` parameter with 100% coverage, including the default and effect. The description adds a usage pattern—'call it with no name to choose one, then with name to read only that template's slots'—which clarifies the intended sequence and helps the agent decide how to use the parameter.

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 first sentence explicitly states the tool's purpose: it returns the card templates and the slots each takes. It differentiates from siblings by positioning itself as a prerequisite to card_new ('Read this before card_new'). This is a specific verb+resource with clear scope.

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?

It gives explicit usage instructions: call with no `name` to choose one, then with `name` to read a specific template's slots. It also tells the agent when to use it relative to card_new ('Read this before card_new'), making the selection obvious.

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

changesA
Read-onlyIdempotent

What the last steps mutations did — what undo that many times would roll back.

Read-only. Compares the snapshot every mutation already leaves against the live project. timeline.removed and timeline.added are source spans per clip with the words they carry and where they played, so a cut reads as the words it took out rather than as every later segment moving; a pure reorder is reordered; spans under 50 ms (a frame's edge moving) are only counted, in removed_slivers/added_slivers. manifest.keys lists each changed manifest key: records added/removed, and changed field by field where a record has a name (a cue by its word, a framing window by its in-point, a clip by its id); a word-addressed record echoes its word in brackets with three either side. Lists past 40 entries are cut, with exact _counts beside them. unchanged: true means the snapshot and the project agree. Words come from the transcripts as they stand now.

ParametersJSON 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.
stepsNoHow many mutations back to compare against, from 1 (the last one — what a single undo would roll back) up to the undo depth. The reply covers everything since that point, not only the oldest step.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, and the description reinforces this with 'Read-only.' It goes well beyond the annotations by explaining precisely how the comparison is computed, what fields appear ('timeline.removed', 'timeline.added', 'manifest.keys'), how edge cases like reorders and sub-50 ms slivers are represented, and that lists past 40 entries are truncated with `_count`s. This gives an agent a clear model of the tool's behavior and output semantics.

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 sentence contributes meaningful behavioral or output-semantic detail. It is front-loaded with the core purpose and read-only guarantee, then systematically explains output structure with concrete examples. Its length is justified by the complexity of the output, though it could be slightly more scannable with explicit field lists.

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 tool's complexity, the detailed input schemas, the annotations, and the presence of an output schema, the description is remarkably complete. It covers what the tool does, how it behaves on edge cases, what the output fields mean, truncation behavior, and the meaning of `unchanged: true`. An agent has enough context to invoke it correctly and interpret its results.

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%, with both `path` and `steps` already documented in detail. The tool description references `steps` in the opening sentence but adds no parameter semantics beyond what the schema provides naturally, so the baseline of 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?

The description opens with a precise statement of what the tool computes: 'What the last `steps` mutations did — what `undo` that many times would roll back.' It then states the concrete mechanism, 'Compares the snapshot every mutation already leaves against the live project,' which clearly identifies the verb and resource. The 'Read-only' tag and the contrast with `undo` distinguish it from the sibling tool that actually performs the rollback.

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?

The description gives clear context for when to use the tool: to inspect what recent mutations changed and to preview what an undo would revert, without actually undoing. It does not explicitly name alternative tools or state exclusion conditions, but the 'what undo would roll back' phrasing and 'Read-only' marker make the use case reasonably unambiguous.

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

check_blackA
Read-onlyIdempotent

Scan a render for black stretches, and say whether each is the known kdenlive-export tail frame (picture.KNOWN_TAIL_FRAME) or a genuine defect.

target is required — unlike check_frames, there is no cheap no-target mode; there is nothing to detect black in without a render. A run is only ever explained when it sits at the tail and the frame delta against the timeline matches the known defect exactly; a black run inside the declared picture is always reported as a real defect.

ParametersJSON Schema
NameRequiredDescriptionDefault
fpsNoThe rate the timeline's own frame arithmetic is counted on.
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.
pix_thNoHow dark a pixel counts as black, 0–1.
targetYesThe render to scan. Required — unlike `check_frames` there is no cheap no-target mode, since there is nothing to detect black in without a render.
min_durationNoShortest black run to report, in seconds.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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

Even though annotations already declare readOnly/idempotent/non-destructive, the description adds important behavioral detail: a run is only 'explained' as the known tail defect when it is at the tail AND the frame delta matches exactly; any black run inside the picture is always a real defect. This is substantive decision logic beyond what annotations reveal.

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 compact and front-loaded: the core purpose appears in the first sentence, followed by the key usage constraint and the classification rule. Every sentence adds value and none are wasted.

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?

With annotations covering safety, an output schema present, and the input schema fully documented, the description supplies the remaining essential context: required target, the invariant classification logic, and the reference to check_frames. An agent has everything needed to decide when and how to call 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 every parameter. The description repeats the target-required rationale that already appears in the schema's target property, adding no meaning beyond that. Other parameters are left entirely to the schema, which is acceptable but not enhanced.

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: 'Scan a render for black stretches' and states the two possible verdicts (known kdenlive-export tail frame vs genuine defect). It distinguishes itself from sibling check_frames by name and by the absent no-target mode, so an agent can tell them apart without inspecting schemas.

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 says `target` is required and contrasts with check_frames' cheap no-target mode, giving a clear condition for using this tool. It does not enumerate broader when-to-use vs when-not-to-use scenarios, but the target requirement and the classification rule provide solid contextual guidance.

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

check_framesA
Read-onlyIdempotent

Check an export's frame count against what the timeline says it should be.

The picture-side counterpart to verify, which covers only the audio. Run this on the exported NLE project before rendering — that is where it is worth the most, because the count settles whether the cut positions are right for the price of reading a document rather than encoding one.

target is an NLE project (.kdenlive/.mlt/.xml, put to melt -consumer xml) or a finished render (counted with ffprobe). Omit it to just report expected_frames, the total the timeline lays down.

Read agrees first, then delta — how many frames the target has that the timeline does not. A non-zero delta on an NLE project means the render will not be the length the edit is, and notes says so when the cause is one proofcut already knows about. agrees is null, not false, for an audio-only render: it has no frames, so nothing was checked.

fps must match the rate the export ran at or the two sides are counting on different grids; it defaults to the rate export would have picked.

ParametersJSON Schema
NameRequiredDescriptionDefault
fpsNoThe rate the export ran at. It has to match, or the two sides are counting on different grids; it defaults to the rate `export` would have picked.
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.
targetNoAn NLE project (`.kdenlive`/`.mlt`/`.xml`) or a finished render. Omit it to just report `expected_frames`, the total the timeline lays down. Run it on the **exported project before rendering** — that is where it is worth the most.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

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

Even though annotations already declare the tool read-only and idempotent, the description adds substantial behavioral context: how to read the output (`agrees` first, then `delta`), what a non-zero delta implies, that `agrees` is null rather than false for audio-only renders, and when `notes` will explain a mismatch. This goes beyond what the annotations provide and significantly helps the agent interpret results.

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, positioning relative to `verify`, best timing, target forms, output-field reading order, edge case, and fps caveat. The main purpose is front-loaded, and the length is appropriate for the tool's complexity.

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 annotations, full schema coverage, and the presence of an output schema, the description is complete. It covers the key behavioral edge cases an agent needs to call and interpret the tool correctly, and it names the relevant sibling alternative. Nothing essential appears missing.

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 schema already documents all three parameters well. The description adds extra value by explaining the tooling for targets ('put to `melt -consumer xml`', 'counted with ffprobe') and reinforcing the `fps` matching constraint. It does not add much about `path`, but the schema's own description for `path` is already exhaustive.

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: 'Check an export's frame count against what the timeline says it should be.' It also distinguishes itself from the sibling `verify` by explicitly positioning itself as the picture-side counterpart. An agent can immediately tell what this tool does and how it differs from nearby tools.

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 clear when-to-use guidance: run it before rendering, and explains the target alternatives (NLE project vs finished render) and what omitting `target` does. It names the sibling `verify` as the audio-side alternative and says this tool covers the picture side. These explicit conditions leave little to inference.

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

clip_rmA
Destructive

Un-register a clip import_media added, when nothing depends on it yet.

Refused, naming every reason, if the clip is on the timeline, cued, held, the music bed's own clip, marked unspoken, transcribed or described — clear those first (cue_rm/hold_rm/unspoken_rm/music reset=True, or proofcut undo) or use undo back to before the import instead. The media on disk is never touched either way.

ParametersJSON 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.
clip_idYesThe clip to un-register. Its media on disk is never touched.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

The description explains the refusal behavior in detail: it will refuse when any dependency exists and will 'name every reason'. It also adds an important safety boundary not implied by the raw destructive annotation: 'The media on disk is never touched either way'. This materially improves an agent's understanding of the tool's side effects beyond the annotations.

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 front-loaded with the core purpose, then compacts all refusal conditions and alternative tools into a second dense but scannable block. Every clause earns its place: no filler words, no repeated schema information. The code formatting and named alternatives make the long conditional list easy to parse.

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 destructive, dependency-sensitive unregistration tool, the description covers the intended use window, every known blocking state, how to clear those blocks, the alternative undo route, and the disk-safety guarantee. Since an output schema exists, return-value documentation is not required from the description. An agent has enough operational information to decide when and how to call 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 coverage is 100%, so `clip_id` and `path` are already fully described in the input schema. The description contributes the operational context that clip_id refers to an import_media-registered clip and that media on disk is never touched, but it does not need to re-document parameter formats. A baseline of 3 is appropriate because the schema carries the parameter documentation burden.

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: 'Un-register a clip `import_media` added', which clearly identifies the tool as the inverse of import_media. The scope is narrowed with 'when nothing depends on it yet' and the disk-safety line prevents confusion with media-deleting operations. This distinguishes it from the many sibling removal tools such as cue_rm and hold_rm.

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 an explicit when-to-use condition: only when nothing depends on the clip yet. It then lists the dependency states that cause refusal and names the exact alternatives (`cue_rm`, `hold_rm`, `unspoken_rm`, `music reset=True`, `proofcut undo`, or `undo`) to use instead. This is unusually clear routing between the tool and its fallbacks.

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

clip_roleA
DestructiveIdempotent

Read or set a clip's import role — voiceover vs footage.

Called with no role and no reset it just reports what is stored; role must be "voiceover" or "footage" (ops.CLIP_ROLES); reset clears it back to undeclared.

This changes nothing about how transcribe/attach_transcript or describe treat the clip. Both already gate on their own evidence — a transcript file, has_video — and neither reads this field, so an undeclared clip is exactly as eligible for both as it always was. It is the assets pane's grouping, purely, and setting one is not a schema bump for that reason: an additive optional field on an existing clip record.

ParametersJSON 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.
roleNo`voiceover` or `footage`. Omit it and `reset` to read what is stored. It is the assets pane's grouping and nothing else: neither transcribe/describe nor any render path reads it.
resetNoClear the role back to undeclared.
clip_idYesThe clip to read or set.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the annotations, the description discloses exactly what reset destroys (the role, back to undeclared), that setting the role is additive and not a schema bump, and that downstream tools are unaffected. This is substantial behavioral context that prevents an agent from mispredicting side effects.

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 front-loaded with the core purpose and then organizes modes and side-effect clarifications clearly. It is somewhat repetitive with the role parameter description (e.g., 'assets pane's grouping' appears in both), so it is not maximally concise, but every paragraph earns its place.

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 tool with 4 parameters angled semantics, the description covers all invocation modes, the allowed values, the reset behavior, and the key non-effects on sibling tools. The output schema is present, so the lack of explicit return-value detail is acceptable.

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% and the schema already documents each parameter richlyging. The description adds interaction semantics between role and reset, clarifies the read mode, and names the allowed values with the ops.CLIP_ROLES constant, which goes slightly beyond the schema's individual property 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?

The description opens with a specific verb-resource pair ('Read or set a clip's import role') and precisely defines the two possible values, voiceover vs footage. It also distinguishes this tool from likely siblings by explicitly stating it has no effect on transcribe/attach_transcript or describe.

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?

Call modes are explicit: no role and no reset reads, role sets, reset clears. The description also gives clear when-not guidance by explaining that transcribe/describe do not read this field and that its purpose is purely the assets pane's grouping.

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

contact_sheetA
Read-onlyIdempotent

Look at a clip's own head — the first look, as an image.

The sheet to call before cueing anything to a clip you have not seen. Two shots of the film were cued to a clip's own head and got 4.5s of "BASED ON THE NOVEL BY THOMAS HARRIS" over black, because nobody had looked at its first seconds. Ten seconds at 1.5s spacing by default, each tile labelled with the source second it is.

The frames come from thumbnail()'s cache — no new cache location, no new manifest key, no new web route — and the montage of them comes back here as bytes, since an agent confined to proofcut's tools (the agent panel's --tools ToolSearch) cannot open a path. import_media makes the frames for every clip it registers, so this is usually a cache hit; call it to see them, to look further than ten seconds, or to redraw after a re-import.

An audio-only clip returns frames: [] and no sheet, not a refusal — the same "nothing to look at is not a failure" as check_frames. A box without magick returns the frames and a sheet_error.

ParametersJSON 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.
clip_idYesThe clip whose head to look at.
secondsNoHow much of the head to cover, in seconds. Ten by default — long enough to catch credits, black or a slate before anything is cued to the clip.
intervalNoSeconds between tiles.

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already cover read-only/idempotent safety, but the description adds valuable edge-case behavior: returns bytes rather than a path, audio-only clips yield frames:[] without refusal, and boxes without magick return a sheet_error. It also discloses the cache origin (thumbnail()) and that no new cache/manifest/route is created.

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 longer than average but front-loaded with a bolded purpose, and all parts serve a function: the anecdote illustrates the failure mode, and the middle paragraphs explain cache/bytes and edge cases. It could be tightened, but it's structured and not bloated.

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?

Without an output schema, the description must explain return behavior, and it does: montage as bytes, audio-only returns empty frames, and missing magick yields sheet_error. It also covers integration with import_media and thumbnail cache, which is enough for an agent to invoke it 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?

Input schema covers all four parameters with detailed descriptions, so baseline is 3. The tool description restates defaults ('Ten seconds at 1.5s spacing by default') but adds little meaning beyond that; no parameter is explained more deeply than the schema already does.

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: 'Look at a clip's own head — the first look, as an image.' It also brands it as 'The sheet to call before cueing anything to a clip you have not seen,' which clearly differentiates it from sibling tools like thumbnail or check_frames by its role in the workflow.

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?

The description gives explicit when-to-use guidance: 'The sheet to call before cueing anything to a clip you have not seen' and 'call it to see them, to look further than ten seconds, or to redraw after a re-import.' It does not explicitly name alternatives or list when-not-to-use, but the context is clear enough for an agent to decide.

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

continuity_acceptA
Idempotent

Acknowledge one continuity finding once — a deliberate rhyme, never re-reported every run.

Addressed the way a cue is (clip_id, word_index), plus kind, since one shot can carry more than one finding. Stores a fingerprint of the finding's own numbers; a later run whose recomputed fingerprint disagrees means the shot moved under the mark, and the finding is reported again rather than trusted blindly. Refuses when no finding of kind currently sits at that cue — continuity_check first, then accept what it found.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindYesWhich finding to acknowledge: `rewind`, `replay`, `short_shot` or `stub`.
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.
clip_idYesThe cue's own addressing transcript, as `continuity_check` reports it.
word_indexYesThe cue's word. With `clip_id` and `kind` it is the finding's address — one shot can carry more than one finding.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

The description goes beyond the annotations. It explains the idempotency behavior in detail: 'a deliberate rhyme, never re-reported every run' and the fingerprint mechanism: 'Stores a fingerprint of the finding's own numbers; a later run whose recomputed fingerprint disagrees means the shot moved under the mark, and the finding is reported again rather than trusted blindly.' This discloses a complex behavioral trait that the idempotentHint annotation only hints at, providing crucial context for the agent to understand side effects and constraints.

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 well-structured: it opens with the core purpose in a clear, memorable line, then explains the addressing mechanism and the fingerprint behavior, and ends with usage guidance. It is concise, with no fluff, and each sentence adds value. The key constraint is front-loaded (acknowledge once), which is helpful for the agent's quick understanding.

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?

The description is complete for a tool of this complexity. It has an output schema (not shown but indicated) which likely explains the return value, so that's covered. It addresses the main edge cases: the fingerprint mismatch scenario and the refusal when no finding exists. It also provides the prerequisite of running continuity_check. Given the availability of annotations (idempotentHint, destructiveHint=false) and a rich schema, the description provides all necessary behavioral and usage context an agent needs to invoke it 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?

The input schema already has 100% coverage with detailed descriptions for each parameter, including what values are valid (e.g., kind enum values). The description adds some context about how these parameters combine to form the finding's address: 'Addressed the way a cue is (`clip_id`, `word_index`), plus `kind`, since one shot can carry more than one finding.' This reinforces the relationship but doesn't add substantial new semantics beyond the schema. So it's a baseline 3, as the schema does the heavy lifting.

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 clearly states the tool's purpose: to acknowledge one continuity finding exactly once, preventing re-reporting. It specifies the resource (a continuity finding identified by clip_id, word_index, and kind) and the action (acknowledge). This distinguishes it from siblings like continuity_check (which reports findings) and continuity_reject (likely a different disposition), making it clear that this tool is for accepting/handling a specific finding.

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 provides explicit guidance on when to use this tool: 'Refuses when no finding of `kind` currently sits at that cue — `continuity_check` first, then accept what it found.' This tells the agent to run continuity_check before accepting, and implies it should not be used if no matching finding exists. It also implies that this is the tool for accepting a finding, as opposed to rejecting (continuity_reject) or listing (continuity_ls). This is clear and actionable.

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

continuity_checkA
Read-onlyIdempotent

Rewinds, replays, short shots, and film-internal-cut stubs — reports, never decides.

Rewind: a shot lands behind where its own asset last left off, with under gap seconds of timeline since. Replay: an earlier shot's source range is re-shown, gap seconds or more later — reported, never refused, because a deliberate narrative rhyme and a mistake look identical from the cue table alone. short_shot: under min_shot seconds (stills excluded). stub: a shot ends or begins right where its own footage has a real internal cut — likely a fragment rather than the shot itself.

The stored cold open (head) is walked as a pseudo-shot before the first real one, so a body shot that rewinds into the head's own footage is caught the same way a body-to-body rewind is. Overrun is never a finding: mlt.plan_picture already refuses it structurally, so nothing reaches this walk having overrun its asset.

stubs=True costs a scene-cut decode per distinct asset placed — stubs=False skips it. scene_threshold defaults to the pinned 0.15 but is caller-settable: darker footage from a different film has needed 0.12.

Findings already acknowledged by continuity_accept are dropped unless the shot moved under the mark, in which case they are kept and marked accepted_stale: True rather than silently re-suppressed.

ParametersJSON Schema
NameRequiredDescriptionDefault
gapNoHow much timeline may pass before re-showing an asset reads as a replay rather than a rewind, 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.
stubsNoLook for stubs. On by default, and it costs a scene-cut decode per distinct asset placed — `false` skips that.
min_shotNoShortest a shot may run before it is reported as a short shot, in seconds. Stills are excluded.
stub_toleranceNoHow close a shot edge has to sit to its footage's own internal cut to be called a stub, in seconds.
scene_thresholdNoThe scene-cut threshold for the stub scan. It defaults to the pinned 0.15, but darker footage from a different film has needed 0.12.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Beyond annotations that already declare readOnly/idempotent/non-destructive, the description discloses important behaviors: accepted findings can be marked accepted_stale, the cold open is walked as a pseudo-shot, overruns are structurally impossible, stubs=True has a decode cost, and scene_threshold tuning is sensitive to footage. This is rich, non-obvious behavioral information with no contradiction of the annotations.

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 longer than average, but every sentence carries distinct information: definitions, edge cases, cost implications, and acknowledgement-staleness behavior. It is front-loaded with a one-line summary and uses bold labels effectively, making dense content scannable without fluff.

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 six-parameter, multi-finding analysis tool, the description covers the full decision surface: findings, parameter effects, edge cases, cost, and interaction with continuity_accept. With an output schema present, the absence of return-value discussion is acceptable; the description answers essentially any question an agent would need before calling.

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, but the description adds semantic value by wiring parameters to finding definitions: gap separates rewind from replay, min_shot defines short_shot, stubs controls the expensive decode, and scene_threshold is given a real-world tuning example. It does not add new meaning to stub_tolerance, but the schema already covers it.

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 opening line names the tool's exact role: detecting rewinds, replays, short shots, and stubs, and 'reports, never decides.' Each finding type is defined in enough detail to distinguish for checking from sibling continuity_accept/continuity_reject/continuity_ls, which handle decisions and listing after the fact.

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?

The description conveys strong context for when this tool is appropriate: it is a non-deciding reporter, and it explains how acknowledged findings from continuity_accept are handled, implying the accept/reject workflow. It does not explicitly name alternatives or say 'use this instead of X,' but the never-decides framing and the continuity_accept reference make the usage context clear.

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

continuity_lsA
Read-onlyIdempotent

Every accepted continuity finding, with whether it is still live and whether it still matches what was accepted (stale).

A finding that has disappeared entirely — the shot was re-cued away, or the issue was fixed — reports still_found: False rather than stale, since there is nothing live left to disagree with the mark.

ParametersJSON 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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds behavioral context about how findings are reported: it explains the difference between stale (still exists but disagrees with the mark) and still_found=False (disappeared entirely). This clarifies the output semantics beyond what annotations convey, though it doesn't discuss edge cases like empty results or sorting.

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 compact and front-loaded: the first sentence states the core purpose, and the second paragraph clarifies a nuanced behavioral distinction. Every sentence earns its place, with no redundancy or filler. The structure efficiently conveys the tool's scope and output semantics.

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?

Given the output schema exists and the path parameter is fully documented, the description covers the essential semantics of what findings are returned and the status fields. It explains the key distinction between stale and still_found, which is critical for correct interpretation. Minor details like ordering or pagination are not mentioned, but these are likely covered by the output schema. Overall, the description is complete enough for an agent to call it 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?

The single parameter `path` is 100% covered by the schema, including a detailed description of how it resolves when bound or unbound. The tool description does not repeat parameter details, but with full schema coverage, the baseline is 3. No additional semantic value is needed from the description.

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 clearly states the tool lists accepted continuity findings and defines the status semantics (live vs stale vs still_found). It specifies the resource (accepted continuity findings) and the verb (list), distinguishing it from continuity_accept, continuity_reject, and continuity_check. The distinction between stale and still_found adds precision, making the purpose unambiguous.

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

Usage Guidelines3/5

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

The description does not explicitly state when to use this tool versus alternatives. It is implicitly the listing counterpart to continuity_accept and continuity_reject, and it contrasts with continuity_check, but no explicit when-to-use or when-not-to-use guidance is given. The semantics are clear, but the tool does not proactively route the agent away from sibling tools.

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

continuity_rejectA
Destructive

Unmark a continuity finding, putting it back into continuity_check.

The inverse of continuity_accept: the acknowledgement is dropped from the manifest, so every later run reports that finding again instead of passing over it. Addressed exactly as it was accepted (clip_id, word_index, kind), and refused when no accepted finding of that kind sits there — so a second call says so rather than quietly doing nothing. Nothing on the timeline moves either way; an acknowledgement is a manifest entry, and undo puts it back.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindYesWhich finding to un-acknowledge: `rewind`, `replay`, `short_shot` or `stub`.
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.
clip_idYesThe cue's own addressing transcript.
word_indexYesThe cue's word, with `clip_id` and `kind` the address the acknowledgement was stored under.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior5/5

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

Beyond the destructiveHint annotation, the description discloses the full behavioral profile: the acknowledgement is dropped from the manifest, later runs report the finding again, a second call is refused rather than silently no-oping, nothing on the timeline moves, and undo reverses it. This is rich, non-redundant context that is fully consistent with the annotations (destructive=true, idempotent=false).

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 dense sentences, each earning its place: core purpose first, then inverse/refusal behavior, then timeline and undo semantics. It is front-loaded and efficiently structured, though the second sentence is heavy with parentheticals and could be split for readability.

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 destructive 4-parameter tool with an output schema present, the description covers the essential ground: what it does, when it is refused, what side effects occur, and how to reverse it. The output schema relieves it of explaining return values. Minor gaps like naming the list alternative are acceptable given the existing coverage.

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 coverage is 100%, so the baseline is 3. The description adds that clip_id/word_index/kind form the address 'exactly as it was accepted,' reinforcing that they must match the prior accept call. It adds modest value over the schema but does not elaborate on the path parameter or the kind values, which the schema already documents.

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?

Opens with a specific verb+resource ('Unmark a continuity finding, putting it back into continuity_check') and immediately frames itself as the inverse of continuity_accept. This clearly distinguishes it from the accept/check/ls sibling cluster without ambiguity.

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?

Explicitly names continuity_accept as the counterpart and describes the exact precondition (an accepted finding of that kind must sit there, else it is refused). It also notes that undo re-applies the acknowledgement. It does not explicitly name a sibling for viewing accepted findings (continuity_ls) or state 'use this only after an accept,' but the inverse framing carries the guidance.

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

cue_addA
Idempotent

Add a picture cue: from word_index of clip_id onward, show asset.

Source-addressed like a word range — asset is an opaque key or path, not checked against disk here; build_shots resolves it, the same way assemble_scream.py's CUES table did by hand. Refused if a cue already sits at that exact word; cue_rm it first to replace it. Echoes the resolved word plus three either side, the same convention every word-indexed tool follows.

Addressed by word_index or phrase (exactly one) — a phrase binds to its first word ("from this word onward"). after/occurrence disambiguate a phrase matching more than once; a resolved phrase is stored alongside the word index, additive metadata cue_reresolve can re-derive after a re-record.

src_start pins where inside asset the shot reads from: seconds in that asset's own source time, which is exactly the number describe_ls reports for a window. This is how a moment you found with describe gets placed — without it the shot reads from wherever the per-asset cursor had got to, which is right for re-using a clip and wrong for showing the thing you searched for.

It is an in-point and never a range: the out-point stays derived from the next cue through the edit, so a later cut still renumbers the shot correctly. The cost is a refusal instead of a rewind — if the shot's length runs past the end of the asset from that in-point, build_shots and the picture lane report it rather than quietly showing the asset's opening seconds instead. Shorten the shot with another cue, or pin earlier. A card takes no src_start; a held frame has no playhead.

ParametersJSON 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.
afterNoA forward cursor over a phrase's matches: any match at or before this word index is skipped. -1, the default, means from the start.
assetNoWhat to show from that word onward: a registered clip id, or `card:<name>` for a card. An opaque key here, resolved by `build_shots` rather than checked against disk now.
phraseNoAddress the cue by what is said instead of by index. It binds to the phrase's **first** word — "from this word onward".
clip_idYesThe transcript the cue is addressed against — the VO on a voiceover project, not the footage being shown. `asset` is what gets seen.
src_startNoWhere inside `asset` the shot reads from, in that asset's own source seconds — the number `describe_ls` reports for a window. An in-point and never a range: unpinned, the shot reads from wherever the per-asset cursor had got to, which is right for re-using a clip and wrong for showing the thing you searched for. A card takes none.
occurrenceNoDisambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — rather than guessed at.
word_indexNoThe word the picture starts on, in `clip_id`'s transcript. Give this or `phrase`, not both.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the annotations, the description discloses that `asset` is not checked against disk, duplicate cues are refused, the tool echoes the resolved word plus three neighbors, the out-point is derived from the next cue, and over-long shots cause a reported refusal rather than silent rewind. This is rich behavioral context with no contradiction against readOnlyHint=false, idempotentHint=true, and destructiveHint=false.

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 long but front-loaded with a one-sentence definition and organized into focused paragraphs. It is dense rather than padded, though some historical context and convention references could be trimmed without losing operational value.

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 an 8-parameter mutation tool, the description covers addressing modes, duplicate and ambiguity failures, `src_start` placement, in-point behavior, card special cases, and the echo response. With annotations and an output schema present, nothing an agent needs to invoke this tool correctly is missing.

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?

The schema already documents all 8 parameters at 100% coverage, so the baseline is 3. The tool description adds genuine cross-parameter meaning: exactly one of `word_index`/`phrase` must be given, `after`/`occurrence` disambiguate phrase matches, and `src_start` is an in-point measured in the asset's own source seconds. This goes beyond the individual parameter descriptions without duplicating all of them.

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 opening sentence states a specific action and resource: 'Add a picture cue: from `word_index` of `clip_id` onward, show `asset`.' It is unambiguous about creating cues and clearly distinguishable from sibling cue tools that list, remove, or re-resolve cues.

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 concrete when-to-use guidance: replace an existing cue by 'cue_rm it first', include `src_start` when placing a found moment versus omit it when re-using a clip, and choose `word_index` or `phrase` with disambiguation rules. It also explains when the tool refuses, so an agent can predict and correct failed calls.

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

cue_lsA
Read-onlyIdempotent

List the picture cue table, each entry echoed with its resolved word.

Read-only. Omit clip_id to see every clip's cues. Ordered by (clip_id, word_index), not by resolved timeline position — that needs the edit's surviving ranges, which is build_shots's job.

ParametersJSON 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.
clip_idNoList one clip's cues. Omit it for the whole table.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already carry readOnlyHint, idempotentHint, and destructiveHint, so the description's 'Read-only' adds no new safety info. However, it adds genuinely new behavioral context: the result is ordered by (clip_id, word_index) rather than timeline position, which is a non-obvious trait an agent needs to interpret results. No contradiction with annotations.

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?

Three terse sentences with no filler: purpose first, then scope, then the ordering caveat and pointer to build_shots. Every sentence earns its place and the most decision-relevant fact (what it lists) is front-loaded.

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 simple read-only listing tool with a rich output schema and full parameter coverage, the description is complete. It covers what is returned, scope control, ordering behavior, and where to go for timeline ordering. Nothing an agent needs to call or interpret this tool is missing.

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 coverage is 100%, so both parameters are already fully documented, including path resolution semantics and the clip_id filter. The description adds a small behavioral note about omitting clip_id for the whole table, which slightly extends the schema, but the heavy lifting is done by the schema itself. 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?

The description opens with a specific verb+resource ('List the picture cue table') and clarifies that each entry is echoed with its resolved word. It implicitly distinguishes itself from the mutation siblings (cue_add, cue_rm, cue_reresolve) by declaring itself read-only, and explicitly separates itself from build_shots over the ordering question.

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 gives clear operational guidance on scope ('Omit clip_id to see every clip's cues') and explicitly routes the timeline-ordering need to build_shots, naming the alternative. It stops short of stating explicit when-not-to-use conditions versus the cue_* mutation siblings, but the read-only framing and ordering caveat give the agent enough to choose correctly.

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

cue_reresolveA
DestructiveIdempotent

Re-resolve every phrase-addressed cue, unspoken mark and music-bed boundary against the current transcript, and report what moved.

A re-record replaces a clip's transcript wholesale, and every stored word_index on that clip potentially now addresses the wrong word — already true today of a plain word-index entry, and this does not close that gap for one. What it closes it for is an entry that also carries the phrase it was placed with: re-resolving says where that same wording landed now, without hand re-indexing a whole cue table.

apply=False (default): report only, nothing is written — the same posture as reframe_detect/unspoken_detect. apply=True rewrites word_index in place for every entry whose phrase still resolves to exactly one match; anything ambiguous or unresolved is reported and left untouched, never guessed. An entry with no stored phrase is reported as "action": "unchanged (no phrase to re-resolve)", not silently skipped.

ParametersJSON 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.
applyNoRewrite `word_index` wherever the stored phrase still resolves to exactly one match. Off by default: it reports first, and anything ambiguous or unresolved is reported and left untouched either way.
clip_idNoRe-resolve one clip's entries. Omit it for every clip.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

Annotations carry destructiveHint=true, idempotentHint=true, and readOnlyHint=false, and the description fully complements them: it discloses exactly what gets destroyed (word_index rewritten in place), the never-guess policy for ambiguous/unresolved entries, the special 'action': 'unchanged (no phrase to re-resolve)' report, and the apply=False default safety posture. No contradiction with annotations; substantial added context.

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?

Front-loaded with the core purpose and outcome before the 'why', and the paragraphs are organized by concern (motivation, then apply semantics). It is somewhat long, but every sentence carries load — the re-record/word_index background and the no-phrase edge case earn their place. No fluff.

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 destructive, state-mutating tool with three parameters and an output schema, the description is complete: it covers apply semantics, ambiguity/unresolved handling, the no-phrase case, and the path-binding behavior is already fully documented in the schema. Nothing an agent needs 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.

Parameters4/5

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

Schema coverage is 100% and each parameter is well-documented, so baseline is 3. The description adds genuine value beyond the schema by explaining the semantic requirement that an entry must carry a stored phrase to be re-resolvable, and how apply interacts with ambiguity — detail not derivable from the schema alone.

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 names a specific verb ('re-resolve') and precise resource ('phrase-addressed cues, unspoken marks, music-bed boundaries') and states the outcome ('report what moved'). It is immediately distinguishable from siblings like resolve_phrase (single phrase lookup) and the unspoken_*/reframe_detect report tools because it targets the re-record/word_index-invalidation scenario explicitly.

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?

The description gives a concrete trigger condition (a re-record replacing a clip's transcript, invalidating stored word_index entries) and explains the apply=False vs apply=True decision, explicitly aligning the report-only posture with reframe_detect/unspoken_detect. It does not explicitly name resolve_phrase as the alternative for single-entry lookup, but the scenario framing makes routing reasonably clear.

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

cue_rmA
Destructive

Remove one picture cue, addressed the way cue_add placed it.

Give word_index, or phrase to resolve against clip_id's transcript (its first word, cue_add's own binding). Refuses, listing every cue, when none sits at that word — cue_ls shows the table first. Shots re-project from the cues that remain; no other cue moves. Replacing a cue's asset is cue_rm then cue_add, since cue_add refuses an occupied word. undo puts it back.

ParametersJSON 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.
afterNoA forward cursor over a phrase's matches: any match at or before this word index is skipped. -1, the default, means from the start.
phraseNoAddress it by wording instead; it resolves to its first word, the way `cue_add` placed it.
clip_idYesThe transcript the cue was addressed against.
occurrenceNoDisambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — rather than guessed at.
word_indexNoThe word the cue sits on. Give this or `phrase`.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the destructiveHint=true annotation, the description discloses concrete behavioral effects: refusal with a full cue listing when the address is empty, re-projection of shots from remaining cues, and that no other cue moves. It also explains why replacement must be rm-then-add, and that `undo` reverses it. This is exactly the extra behavioral context annotations cannot provide.

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 compact and front-loaded: action first, then addressing rules, then refusal behavior, then side effects, then workflow guidance. Every sentence contributes behavioral or usage value; there is no fluff or repetition of structured schema content.

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 rich input schema and the presence of an output schema, the description supplies all the missing contextual glue: how to address a cue, what happens on failure, side effects on shots, the replacement pattern, and undo behavior. The agent has everything needed to decide when and how to call 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%, with each parameter already richly documented, so the description carries little additional per-parameter burden. It does reinforce the central `word_index`/`phrase` addressing relationship and ties it to `cue_add`'s binding, but largely restates what the schema already says. Baseline 3 is appropriate here.

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 — 'Remove one picture cue' — and immediately anchors addressing to `cue_add`'s placement semantics. This cleanly distinguishes it from siblings like `cue_add`, `cue_reresolve`, `unspoken_rm`, and `hold_rm`. An agent can tell exactly what the tool does at a glance.

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 explicitly tells the agent to provide `word_index` or `phrase`, and explains what to do when no cue sits at the word (`cue_ls` shows the table first). It also names the replacement workflow (`cue_rm` then `cue_add`) and notes that `undo` restores it, giving clear when-to-use and alternative context. This is strong practical guidance beyond mere tool naming.

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

cut_by_timeA
Destructive

Cut spans of RENDER/TIMELINE time — what a human reports watching an export.

Each span is [start, end) in the seconds the current export plays at (what timeline_status/verify describe), not source time and not word indices. proofcut converts each span to the source interval(s) it plays — the inverse of the mapping captions and playback use — and cuts those through the same Edit.remove path cut_by_transcript uses. The render timestamp is never stored: the conversion happens once, here, at call time.

All spans resolve against the CURRENT timeline before any is applied, so a list of notes from one watch stays valid together even though a real cut would shift every later timestamp. Overlapping spans are refused rather than silently double-applied.

Every piece echoes the source interval it produced (more than one when the span crosses an earlier cut or a clip boundary) and the words it overlaps there, plus three neighbours either side — the human check that the timestamp actually hit the intended flub. pad widens only the OUTER edges of each requested span. plan=True resolves and reports without writing, identically to cut_by_transcript.

Refused the same way cut_by_transcript is if a span overlaps a word with a suspect duration; confirm_suspect=True or plan=True behave the same.

A second call is not the same call. These are render timestamps, and this cut moves everything after it, so the same numbers name different material next time — take them off a fresh watch rather than reusing a list across two calls. That is also why one call takes every span at once.

ParametersJSON Schema
NameRequiredDescriptionDefault
padNoWiden only the outer edges of each requested span, 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.
planNoResolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it.
spansYesHalf-open `[start, end)` spans in the seconds **an export plays at** — what a person reports off a watch, not source time and not word indices. Every span resolves against the current timeline before any is applied, so a list of notes from one watch stays valid together; overlapping spans are refused rather than double-applied.
confirm_suspectNoGo ahead even though a boundary word claims a suspect duration. Read the echoed words first — a suspect duration usually means whisper hid a retake inside that word, so the edge is not where it reads.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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

Even with the destructiveHint annotation already true, the description adds substantial behavioral detail: render timestamps are never stored, conversion happens once at call time, all spans resolve before any are applied, overlapping spans are refused, and a second call is not equivalent to the first. This is exactly the contextual disclosure an agent needs for a destructive operation.

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 long but dense and front-loaded with the core concept before diving into details. Some content repeats what the input schema already states, but the extra length is justified by the destructive nature and the non-obvious render-time mapping.

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 complex, destructive tool with one required parameter and several interdependent behaviors, the description covers the conversion semantics, resolution order, overlap refusal, output echoes, pad behavior, plan mode, suspect-word refusal, and the critical 'second call is not the same call' warning. Nothing an agent needs to call it correctly appears to be missing.

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%, and the schema already explains spans, pad, plan, path, and confirm_suspect in detail. The tool description adds some cross-cutting context about plan/confirm behaving like cut_by_transcript, but it does not substantially extend the parameter-level meaning already present in the schema.

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 names a specific verb ('Cut'), a precise resource ('spans of RENDER/TIMELINE time'), and immediately distinguishes it from source time and word indices. It also references cut_by_transcript by name, helping an agent separate the two tools.

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?

The description gives strong usage context: use it for what a human reports watching in an export, resolve all spans against the current timeline, and take spans from a fresh watch rather than reusing them across calls. It names cut_by_transcript as the analogous path and says this tool is not for source time or word indices, though it stops short of explicitly stating 'use cut_by_transcript instead in those cases.'

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

cut_by_transcriptA
Destructive

Cut or keep inclusive word ranges, e.g. cut=[[30, 45], [120, 131]].

Pass exactly one of cut or keep. pad widens each range on both sides in seconds, to land the cut in the silence between words. The timeline is snapshotted first, so this is undoable.

Every range echoes back the words it resolved to, plus the few words either side of it — an index one past the intended phrase reads fine on its own and is only visibly wrong next to its neighbours. pad_reach names any neighbour the padding eats, since padding is in seconds and the echoed text is not.

through_pause=True (cut only) extends each range's trailing edge through the pause after its last word, whenever that gap is wide enough to have drawn a [N.Ns] marker in the transcript pane — so cutting a phrase also removes the dead air after it instead of leaving it playing. A no-op when the trailing gap is too short to have drawn a marker.

plan=True returns that whole payload — including what the timeline would become — without writing anything. Prefer it over cutting and undoing.

Refused if a range's first or last word claims a suspect duration (see attach_transcript/transcribe's suspect_durations) — that word's end/start is what the cut boundary resolves to, and it is usually hiding a retake rather than ending where it claims. Check the word, then retry with confirm_suspect=True if the boundary is actually fine. Under plan=True these are reported as suspect_boundaries instead of refused.

ParametersJSON Schema
NameRequiredDescriptionDefault
cutNoInclusive word ranges to remove, e.g. `[[30, 45], [120, 131]]`. Pass exactly one of `cut` or `keep`.
padNoWiden each range on both sides, in seconds, so the cut lands in the silence between words rather than on them. `pad_reach` names any neighbour the padding eats.
keepNoInclusive word ranges to keep, everything else going. Pass exactly one of `cut` or `keep`.
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.
clip_idYesThe transcript the word ranges address.
through_pauseNoExtend each cut's trailing edge through the pause after its last word, wherever that gap was wide enough to draw a `[N.Ns]` marker — so cutting a phrase also takes the dead air after it. A no-op when the gap is short.
confirm_suspectNoGo ahead even though a boundary word claims a suspect duration. Read the echoed words first — a suspect duration usually means whisper hid a retake inside that word, so the edge is not where it reads.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A5/5.0
Behavior5/5

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

Beyond the annotations' destructiveHint, the description discloses crucial behavioral traits: the timeline is snapshotted so the operation is undoable, `plan=True` writes nothing, `pad_reach` and echoed-word feedback explain boundary effects, and suspect durations trigger refusal or `suspect_boundaries` reporting. This is rich, non-obvious behavioral disclosure.

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 long but every sentence carries distinct value: main operation first, then mutually exclusive parameters, then side effects, then safety/refusal behavior. The structure is logical and front-loaded; the length is justified by the tool's complexity.

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 destructive nature, eight parameters, and existing output schema, the description is complete: it covers what happens, what not to do, how to preview safely, how to handle suspect boundaries, and how padding interacts with echoes. An agent has enough context to invoke this correctly.

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 substantially enriches the parameters: it explains what `pad` does in seconds, what `through_pause` means semantically, how `plan` differs from execution, and what `confirm_suspect` is for. This goes well beyond the baseline schema 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?

The opening sentence states a specific verb and resource: 'Cut or keep inclusive word ranges', with a concrete example showing the exact input shape. This clearly distinguishes it from the sibling `cut_by_time`, which operates on time rather than transcript word ranges.

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 constraints ('Pass exactly one of `cut` or `keep`'), mode-specific guidance (`through_pause=True` is cut-only, `plan=True` is preferred over acting and undoing), and a detailed refusal-and-retry workflow for suspect boundaries. These are actionable instructions an agent can follow without inferring.

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

describeA
DestructiveIdempotent

Describe footage in fixed windows, so b-roll can be found by what is in it.

A description is (clip_id, src_start, src_end, text) in source seconds, which is why cutting the edit can never invalidate one. Omit clip_id to describe every video clip that has not been described yet; name one to do just that clip. Audio-only clips are refused — their words are what transcribe indexes.

This is a job, not a request. Cost is about three seconds per window regardless of how much footage the window spans, so a project's footage is minutes of GPU time. Run it with plan=True first: that resolves the whole work list and the estimate, and reports whether this machine can run the model at all, without loading anything.

Already-described clips are skipped unless force. Do not widen window to save time without a reason — a single pass over a whole clip describes six frames as six people, fluently and with nothing saying it is wrong.

Read errors and truncated in the result. A truncated description stops mid-fact and reads exactly like a complete one, and a window is never evidence of a continuous shot: the model narrates across a cut inside one as though it were a single take.

The descriptions are written into the project, and force replaces the ones a clip already has; without it an already-described clip is skipped, so a repeat costs nothing and changes nothing.

ParametersJSON 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.
forceNoDescribe clips that already have descriptions, replacing them. Without it they are skipped.
windowNoSeconds of footage per description. Do not widen it to save time: a single pass over a whole clip describes six frames as six people, fluently, with nothing saying it is wrong.
clip_idNoOne clip to describe. Omit it for every video clip not described yet; audio-only clips are refused, since their words are what `transcribe` indexes.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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

Annotations declare destructiveHint=true and idempotentHint=true, and the description enriches both: the GPU cost model (~3s per window, minutes of project footage), that plan=True runs without loading the model and reports machine capability, that force replaces while a plain repeat costs nothing, and the two serious pitfalls — truncated descriptions read exactly like complete ones, and a window is never evidence of a continuous shot. No contradiction with annotations.

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?

Front-loaded with the core purpose and data model before the cost and pitfall discussion, and every sentence earns its place. Mild redundancy: the final paragraph restates the force/skip behavior already covered by 'Already-described clips are skipped unless force' earlier, which is the only trimming opportunity in an otherwise tight definition.

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 complex, cost-bearing, GPU-running tool with an output schema present (so return values need not be explained), the description is remarkably complete. It covers cost, machine-capability preflight, idempotency, destructive replacement semantics, and the two failure modes an agent could not guess (truncation that looks complete, narration across cuts). Nothing an agent needs to call it correctly is missing.

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% and the schema descriptions are already rich, so baseline is 3. The tool description adds genuine value on top: the omitting-clip_id semantics (describe all undescribed video clips), the reframe-proof rationale for source seconds, and the concrete 'six frames as six people' example that motivates not widening window. This elevates it above the baseline.

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?

Opens with a specific verb+resource+purpose ('Describe footage in fixed windows, so b-roll can be found by what is in it'), then pins down the data model (clip_id, src_start, src_end, text). It actively distinguishes itself from transcribe ('their words are what transcribe indexes') and describes_ls is implied by the read-the-result guidance, so an agent can tell it apart from its close siblings without opening 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?

Explicit when-to-use and when-not: audio-only clips go to transcribe, already-described clips are skipped unless force, and it names plan=True as the preferred first invocation for a cost-bearing job. It even warns against widening window to save time. No alternative or condition is left to inference.

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

describe_lsA
Read-onlyIdempotent

Read the footage descriptions, to find b-roll by what is in it.

This is the search. There is no ranking and no similarity score to ask for — you read the descriptions and pick, which is why the prompt behind them asks for concrete nouns. Each entry is (clip_id, src_start, src_end, text) in source seconds, so what you pick stays valid however the edit is cut.

contains filters: whitespace-separated terms, case-insensitive, and every term must appear — "kitchen knife" matches "a knife on the kitchen counter". Reach for it before reading everything on a large project; words says how much text came back.

Two things not to over-read. A window is evidence of what is visible in a span, never of a continuous shot — the model narrates across a cut inside one as though it were a single take. And an entry with truncated true stopped mid-fact and reads exactly like a complete description.

A clip listed under clips with windows: 0 has not been described yet; describe is what indexes it.

ParametersJSON 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.
clip_idNoList only this clip's windows.
containsNoKeep only windows whose text holds every whitespace-separated term, case-insensitively — so `"kitchen knife"` matches "a knife on the kitchen counter".

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already carry readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so safety is covered. The description adds genuinely valuable behavioral nuance beyond that: there is no ranking/similarity score (the agent must read and choose), entries are returned in source seconds so they stay valid across edits, a window is evidence of what is visible in a span and never a continuous shot (the model narrates across cuts), and a `truncated` entry reads like a complete description but stopped mid-fact. These are exactly the kind of pitfalls an agent would otherwise misjudge.

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 long (several paragraphs), but every section earns its place: purpose, the no-ranking philosophy, output format in source seconds, `contains` semantics, two critical interpretive caveats (window vs. shot, truncated), and the `windows: 0`/`describe` indexing note. It is front-loaded with the purpose and structured with bold lead-ins that make it skimmable. Slightly longer than strictly necessary, but nothing is 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?

For a read-only search tool with an output schema present and 3 optional params, this is complete. The output schema relieves the description of explaining return structure, yet the description still supplies the interpretive keys an agent needs: how to read entries, what `truncated` and `windows: 0` mean, and the source-seconds guarantee. No critical calling information is missing.

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 coverage is 100% — `path`, `clip_id`, and `contains` all carry detailed schema descriptions, so the baseline is 3. The tool description adds only marginal parameter value beyond the schema: it reinforces the `contains` semantics (already well documented in the schema) and adds the strategic advice to reach for it on large projects. It mentions the `words` output field, but that is output-related rather than parameter meaning. The schema does the heavy lifting here.

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 opening line states a specific verb and resource ('Read the footage descriptions, to find b-roll by what is in it') and then boldly declares '**This is the search.**', which sharply distinguishes it from the sibling `describe` (the indexing tool) and other media tools like `transcribe`/`hear`. An agent immediately knows what this does and what it does not do — it does not rank or score, it lists descriptions to pick from.

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?

The description gives clear strategic guidance: 'Reach for it before reading everything on a large project' (use `contains` to filter early) and explicitly notes that a clip with `windows: 0` has not been described yet and that '`describe` is what indexes it' — routing the agent to the correct sibling. It stops short of enumerating explicit when-not-to-use conditions against other search-adjacent tools, but the context is strong enough to be actionable.

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

doctorA
Read-onlyIdempotent

Probe every external binary proofcut depends on, and name each one's trap.

Takes no project — it answers the question asked before there is one. Report-only: nothing is installed and nothing is written. ok reads the required section alone; the four optional entries each gate one feature (cards, describe, reframe_detect, vo_synth) and everything else works without them.

Every failing entry carries the fix, not just the ✗ — where melt actually lives, why PyPI's auto-editor is the wrong program, what to set on a box with no display.

server says which project this server is bound to and how (ping's own answer), since that decides which path a call may name.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already mark readOnly, idempotent, and non-destructive, and the description adds meaningful detail: 'nothing is installed and nothing is written,' feature-gated optional sections, and failures that include fixes. This goes well beyond the structured hints without contradicting them.

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 longer than strictly necessary, but each sentence contributes a distinct fact: scope, side-effect-free behavior, optional feature gates, failure messaging, and server binding. The structure is coherent and front-loads the main purpose.

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 zero-parameter diagnostic with an output schema present, the description is complete. It covers what is probed, what is not touched, how output is organized, and how failing entries are reported. Nothing needed for correct invocation is missing.

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?

The tool has zero parameters)Skip and the schema is trivially covered. The description reinforces the only semantic point: it 'takes no project,' which is the key thing a caller needs to know.

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 states a specific diagnostic action: 'Probe every external binary proofcut depends on, and name each one's trap.' It also clarifies the tool takes no project, clearly distinguishing it from project-scoped sibling tools.

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?

The description gives strong context for when to use it: before a project exists ('answers the question asked before there is one') and as a report-only check. It does not explicitly name an alternative tool to prefer instead, but the no-project framing is enough to route an agent correctly.

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

exportA
DestructiveIdempotent

Export the timeline as an NLE project, or render it.

The default writes an MLT project Kdenlive opens; export_format=null renders media. The writer is chosen from the project, never from an argument: a single-source timeline goes through auto-editor, and a multi-source one — a cue table, a second clip, a canvas, a bed, a tail — is written as MLT by proofcut and rendered by melt, because auto-editor renders a second source at 720x576 while exiting 0. The reply names the writer, and a melt render reports resolution and frame count measured off the finished file.

preset bundles quality for a render; tiktok-reels checks 9:16 and never sets the shape — use canvas first. loudness masters to a LUFS target and refuses, leaving the render as it was, if it misses by more than 1 LU.

Captions are not burned by this — add_captions is its own step. Then check the file against the timeline with check_frames and verify; a render that exists is not a render that is right.

ParametersJSON Schema
NameRequiredDescriptionDefault
fpsNoThe NLE timeline's frame rate, defaulting to the picture's own (30 for an audio-only project). It sets the render's rate too wherever proofcut owns the profile, and is ignored when auto-editor renders a single-source timeline.
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 project file or the render. A file argument, not a project selector: it writes where you say.
presetNoA named quality bundle — `youtube`, `web`, `tiktok-reels`, or `custom` (which needs `resolution`) — meaningful only with `export_format=null`, since an NLE project file has no bitrate. `tiktok-reels` also **checks** that the project renders 9:16 and refuses otherwise; it never sets the shape. Use `canvas` for that.
loudnessNoMaster the render to this many LUFS integrated: one gain and a true-peak limiter, measured before and after, and refused — leaving the render as it was — if the result misses by more than 1 LU. Render only.
true_peakNoThe dBTP ceiling the loudness pass limits under. -1.0 by default.
resolutionNo`[width, height]`. It **letterboxes** the existing frame on the single-source render path rather than cropping or reframing it, and is refused outright on a melt (multi-source) project.
export_formatNo`kdenlive` (the default) writes an MLT project Kdenlive opens and melt renders. Pass null to render media instead. Other auto-editor targets — shotcut, premiere, resolve, final-cut-pro — pass straight through.kdenlive

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A5/5.0
Behavior5/5

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

Annotations mark this as destructive and non-read-only, but the description goes far beyond: it explains that the writer is chosen from the project (never from an argument), details the single-source vs multi-source behavior, the resolution letterboxing vs refusal, the loudness refusal condition, and the safety rule about paths outside the bound project. It also notes that a render that exists is not necessarily correct, implying the need for verification. No contradiction with annotations.

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. It is front-loaded with the core purpose, then progresses through writer selection, presets, loudness, and post-export verification. No fluff or repetition. The length is justified by the complexity of the tool (8 parameters, multiple modes, and interactions).

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 tool's complexity, the description is complete. It covers the main modes, writer selection, parameter interactions, destructive behavior, and directs the user to complementary tools. The output schema exists, so return-value details are not required. An agent can correctly invoke this tool without additional documentation.

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?

Schema coverage is 100%, so the baseline is 3, but the description adds substantial semantic value. It explains parameter interactions: preset is meaningful only with export_format=null, tiktok-reels checks 9:16 and never sets shape, resolution letterboxes on single-source and is refused on multi-source, loudness is render-only, fps is ignored when auto-editor renders single-source, and path resolution rules. These are critical operational details not present in the schema.

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-resource pair ('Export the timeline as an NLE project, or render it') and immediately clarifies the two modes. It distinguishes from siblings by explicitly stating captions are not burned (add_captions) and mentions verification tools. The writer-selection logic based on project composition further sharpens the tool's unique role.

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 and when-not-to-use guidance. It says captions require add_captions as a separate step, and recommends check_frames and verify after export. It also warns that tiktok-reels preset never sets the shape and directs to use canvas first. This routes the agent to the correct tools for each sub-task.

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

film_checkA
DestructiveIdempotent

Compare this project against the export it is supposed to be.

check_frames answers whether an export agrees with this project's own arithmetic; it cannot catch this project being the wrong film to begin with — a project can pass every check it has and still be seeded from a stale stage of an outside edit (HISTORY.md § The VO the project was holding: 73 segments/410.963s sat in a project whose shipped film was 63 segments/336.269s, with the render, verify, the cue table and the shot plan all agreeing with the wrong one). This checks the project's timeline_duration against a reference file's own ffprobe duration — cheap, no frame counting, no melt. Segment count has nothing on the reference side to compare against once a film is encoded, so segments is reported alone and the notes say why.

reference is remembered: passing it stores it on the project (additive, no schema bump), so a later call with no argument re-asks the same question against the same file. reset drops the stored reference; plan resolves without writing. With no reference given or stored, this reports the project's own numbers and says there is nothing to compare them against, rather than raising.

ParametersJSON 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.
resetNoDrop the stored reference.
referenceNoThe delivered file this project is supposed to be. It is remembered, so a later call with no argument re-asks the same question against the same file.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the annotations, the description discloses important stateful behavior: 'reference is remembered: passing it stores it on the project', 'reset drops the stored reference', and 'plan resolves without writing.' It even specifies that the check is 'cheap, no frame counting, no melt' and explains what happens when no reference is present, which adds valuable context the annotations do not provide.

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

Conciseness3/5

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

The description is front-loaded with purpose but becomes overly long, including an extended HISTORY.md anecdote that is not necessary for selecting or invoking the tool correctly. The paragraph on segment counts and the detailed example add noise, though the structure is logical and organized.

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 output schema exists, return values need no explanation, and the description covers all essential behavioral edge cases: no reference, stored reference, reset, plan, and what exactly is compared. Nothing an agent needs to call this tool correctly is missing.

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?

All parameters already have rich descriptions in the input schema, so baseline is 3. The description primarily repeats what the schema says (e.g., reference is remembered, reset drops it, plan resolves without writing). It adds no new parameter-level meaning beyond the schema.

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 states a specific verb and resource: 'Compare this project against the export it is supposed to be.' It also explicitly distinguishes itself from the sibling check_frames by explaining what each tool can and cannot catch, so an agent can tell them apart without opening 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?

The description explicitly contrasts film_check with check_frames, identifying the key difference: check_frames validates against the project's own arithmetic, while film_check compares against an external reference file. It also describes behavior in the no-reference case ('reports the project's own numbers and says there is nothing to compare them against') and names the plan and reset alternatives for safe operation.

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

finish_checkA
Read-onlyIdempotent

Check a delivered file against this project's timeline — verify/check_frames/check_black/film_check for a file an external mix pass produced, not one of proofcut's own renders.

final carries a cold open and/or holds concatenated on outside proofcut, so every position this reports is in final's own absolute seconds. prepend_seconds defaults to this project's stored head length; holds defaults to its stored holds, resolved live and offset the same way — pass either explicitly (an empty holds list included) to check a file against a different set than what is currently stored.

Eight checks, none individually fatal to the others: stream/chapter/ duration agreement against the timeline's own arithmetic; loudness (report only); blackdetect, with a run explained only when it falls inside the prepend or a hold's own span; each hold's own span transcribed and its seam levels measured; a windowed transcription of final diffed against the timeline's expected words, with every heard word inside the prepend or a hold filtered out first; every dropped run re-cut and re-transcribed on its own to catch a windowed-pass false miss at a window stitch (boundary_misses, recovered — a run that still cannot be found stays in missing, a real fault); and a self-repeat scan over the same filtered transcript. faults/ok aggregate all of it, and every run is logged (finishlog) so proofcut review serve can show a WARN badge keyed to the file's own sha256.

ParametersJSON Schema
NameRequiredDescriptionDefault
fpsNoThe frame grid the timeline's arithmetic is counted on. Defaults to the rate `export` would have picked.
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.
finalYesThe delivered file to check — one an external mix pass produced, not a proofcut render. Every position reported is in this file's own absolute seconds.
holdsNoThe holds to expect in `final`, resolved and offset the same way the stored ones are. Defaults to the project's own; pass a list (an empty one included) to check against a different set.
pix_thNoblackdetect's pixel threshold: how dark a pixel counts as black.
windowNoLength of each transcription window, in seconds.
clip_idNoDiff against one transcript's expected words rather than all of them.
overlapNoHow far each window overlaps the one before, in seconds.
languageNoForce a language code for the transcription.
recheck_padNoHow much to pad a dropped run when re-cutting it for its own transcription — the pass that separates a real miss from a false one at a window stitch.
windowed_modelNoThe whisper model for the windowed transcription of `final`. A deliberately small one is the default, since the windowed pass runs over twice the audio.
prepend_secondsNoHow much runs before the timeline's first frame in `final` — a cold open concatenated on outside proofcut. Defaults to the project's stored head length.
transcript_pathNoAn existing transcription of `final`, to diff again without re-transcribing.
black_min_durationNoShortest black run to report, in seconds.
duration_toleranceNoHow far `final`'s duration may sit from the timeline's own arithmetic before it is a fault, in seconds.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already establish readOnly/idempotent/non-destructive, and the description adds substantial non-redundant behavioral context: the full inventory of eight checks with their semantics (loudness is 'report only', blackdetect runs are 'explained only when it falls inside the prepend or a hold's own span'), the window-stitch false-miss recovery behavior (`boundary_misses`, recovered), the aggregation into `faults`/`ok`, and the `finishlog` side effect enabling `proofcut review serve` WARN badges keyed to sha256. No contradiction with annotations.

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

Conciseness3/5

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

The core purpose is front-loaded in the opening sentence and nearly every sentence earns its place given the tool's eight-check complexity. However, the body is one dense ~170-word paragraph built from slash-chains and semicolons that is genuinely hard to scan; the eight checks could be enumerated or broken into digestible chunks. The information is justified, but the structure is not.

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 15-parameter tool with an output schema, the description is unusually complete: it covers the coordinate/time-base semantics, the default resolution of `prepend_seconds` and `holds`, the per-check behavior including what is report-only versus fatal-adjacent, recovery mechanics, and the logging/observability contract. The output schema covers return values and the 100%-coverage schema covers parameter mechanics; the only residual gap is that the density of the checks paragraph still demands careful reading, but nothing operationally necessary is missing.

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, but the description clearly exceeds it: it explains the coordinate system binding `final`, `prepend_seconds`, and `holds` together ('every position this reports is in `final`'s own absolute seconds'), clarifies that `prepend_seconds`/`holds` default to stored project values with live offset resolution, and gives purpose to `recheck_pad` ('the pass that separates a real miss from a false one at a window stitch') and `windowed_model` ('runs over twice the audio'). This is genuine semantic value beyond the schema's field-level 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?

The description opens with a specific verb+resource pair ('Check a delivered file against this project's timeline') and immediately differentiates from siblings: it is the `verify`/`check_frames`/`check_black`/`film_check` equivalent 'for a file an external mix pass produced, not one of proofcut's own renders.' An agent can unambiguously distinguish this from its four named sibling tools without opening schemas.

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?

The first sentence establishes the selecting condition — external mix pass deliverables versus proofcut's own renders — which implicitly routes proofcut renders to verify/check_frames/film_check. It also gives explicit guidance on when to override defaults: 'pass either explicitly (an empty `holds` list included) to check a file against a different set than what is currently stored.' It stops short of an explicit when-not statement naming the alternative for proofcut renders, so it is clear but not fully explicit.

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

finish_reportA
Read-onlyIdempotent

Duration/canvas/caption/picture/marks/seams report for Finish mode, composed only — the truth strip's own numbers.

duration: edit seconds, tail seconds, and their sum. canvas: the stored or footage-fallback canvas, plus each export preset's own ok/refusal-message. captions: whether a style is configured, its resolved font, and whether the last render actually burned it in ("yes"/"no"/"unknown" — unknown when no render log exists). picture: cue count, pinned count, and the picture plan's own refusal message when it has one. marks: unspoken marks applied vs. still stale. seams: the transcript's own overlap count. unused_clips: registered clips on no lane, cued nowhere, held nowhere, not the music bed — a clip imported and forgotten (TRIAL.md § Registered-and-not-on-the-timeline has no report of its own), clearable with clip_rm or by cueing it. flags: the rolled-up warnings behind all of the above, each one naming the mode that fixes it.

framing adds reframe_coverage's stale-framing numbers and their two flags, and is off by default because it decodes placed footage for a scene-cut scan — 5.7s wall and 46s of CPU on the film, uncached, every call. Off, framing is None, which means "not measured" rather than "nothing stale".

holds adds hold_check's own per-hold seam/transcription report against the last render — off by default for the same reason framing is: it decodes and transcribes render spans. None when not asked for, and also None when asked for but nothing has rendered here yet.

continuity adds continuity_check's finding count by kind (rewind, replay, short_shot, stub) and how many are currently accepted — also off by default, its stubs=True half paying the identical scene-cut decode framing does. None when not asked for.

ParametersJSON 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.
holdsNoAdd the per-hold seam and transcription report against the last render. Off by default for the same reason: it decodes and transcribes render spans. Null when not asked for, and also null when nothing has rendered here yet.
framingNoAdd stale-framing numbers. Off by default because it decodes placed footage for a scene-cut scan (5.7s wall, 46s of CPU on the film, uncached, every call). Off, `framing` is null, which means *not measured* rather than nothing stale.
continuityNoAdd the continuity finding counts by kind and how many are accepted. Off by default — its stub half pays the same scene-cut decode `framing` does.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so safety is known. The description adds substantial behavioral context beyond that: it explains the cost of optional sections (5.7s wall, 46s CPU for framing), the meaning of None (not measured vs. nothing stale), and the special semantics of unused_clips and its clearable methods. No contradiction with annotations; instead, it enriches the behavioral model.

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 long but exceptionally well-organized: it opens with a one-line summary, then uses a bulleted list for the core sections, and separately details the optional flags with their costs. Every sentence earns its place; nothing is redundant. The front-loading of the main purpose and the structured breakdown make it easy to scan despite its length.

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?

The description thoroughly covers all sections and optional flags, including return semantics (None cases), performance trade-offs, and even how to clear unused clips. Since an output schema exists, the description need not spell out the return structure, and indeed it doesn't. Nothing an agent needs to decide whether to call this tool or how to set its flags is missing.

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?

The input schema covers all four parameters with descriptions (100% coverage), so the baseline is 3. The description adds extra nuance, especially for 'holds' and 'framing', explaining when they return None and reiterating the cost rationale. This goes slightly beyond the schema's one-liners, providing the agent with better context for deciding when to pass true.

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 states a specific verb and resource: it produces a comprehensive report for Finish mode, listing the exact components (duration, canvas, captions, picture, marks, seams, unused clips, flags). It also differentiates from siblings by emphasizing 'the truth strip's own numbers' and by referencing optional sections that mirror dedicated check tools (framing, holds, continuity), making its aggregating role clear.

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?

The description explains when to enable each optional section (framing, holds, continuity) and notes the computational cost for each, giving clear context for choosing to include them. It implies this tool is the go-to Finish report rather than calling the individual check tools, but it does not explicitly state 'use this instead of X' or list alternative tools for specific scenarios. Still, the cost warnings effectively guide usage.

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

fontsA
DestructiveIdempotent

Will the caption font actually draw on this machine?

Reports two answers side by side and does not merge them: fontconfig says whether the family is present, render burns the family and an impossible family and compares the pixels. Identical pixels mean the name is substituting whatever fontconfig claims — the only way to settle which face drew is to measure a render.

path is optional: with a project, this checks the font that project's caption style would burn; without one, proofcut's default. install copies the vendored face where this OS's font system looks (fontconfig, CoreText or DirectWrite) and is off by default, because it writes into the home directory.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoA project directory, or nothing. Omitting it means *no project* here — never the bound one — and reports proofcut's own default caption face; with a project, it reports the face that project's caption style would burn.
installNoCopy the vendored face where this OS's font system looks (fontconfig, CoreText or DirectWrite). Off by default, because it writes into the home directory.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the annotations, the description discloses important behavioral traits: the tool reports two answers side by side without merging them, uses an impossible-family render comparison to detect substitution, and has an install flag that writes into the home directory. This adds real context about side effects and output semantics that annotations alone do not provide.

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?

Despite its length, every sentence earns its place: the opening question sets intent, the next two explain the core mechanism and non-merging behavior, and the final paragraph covers the two parameters. The structure front-loads the most important behavioral facts.

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?

The description fully covers what the tool does, how it does it, the optional behaviors, and the side-effect risk of install. The output schema is present, so return-value details do not need to be spelled out. Nothing an agent needs to correctly select and invoke this tool is missing.

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 coverage is 100%, so the baseline is 3. The description restates the path and install semantics already present in the schema and adds some rationale about why the impossible-family comparison matters, but it does not meaningfully extend the schema's parameter documentation.

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 concrete diagnostic question and then specifies exactly what the tool reports: fontconfig presence versus an actual render comparison. It clearly identifies the resource (caption font, default or project-specific) and the unique two-answer behavior that distinguishes it from sibling tools.

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?

The description gives clear context for when to use the tool: when you need to know whether a caption font will actually draw on this machine, rather than just whether the family is present. It explains the path semantics and the default behavior, though it does not explicitly name alternatives or say when not to use it.

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

footage_sheetA
DestructiveIdempotent

Look at a clip's own footage — one labelled tile per moment, as an image.

The tool to see what is in some footage, as opposed to shot_sheet, which shows an existing edit's picture track. It needs no edit, cues or transcript, so it is the first look at b-roll, recordings and gameplay — material describe can search by text but cannot show. The bytes come back in the reply.

mode picks the instants: auto (described windows if the clip has any, else the interval), interval, describe (each tile beside its window's sentence), or scenes (one per detected cut — opt-in, since a continuous take has none and a scan decodes the whole clip). page walks a long recording. A tile with nothing in it is marked [blank] on the picture, so a black square is never mistaken for a frame that failed to extract.

What you see is a hypothesis, not a check — and this sheet is read to choose footage. synopsis is where a person says what a clip is; a tile shows what the camera saw, which is a different fact.

ParametersJSON Schema
NameRequiredDescriptionDefault
outNoWrite the image to this path as well, replacing whatever file is there. Unset, it goes to the project's own sheet cache and only the bytes come back.
modeNoWhich instants to draw: `auto` (the default) uses the clip's described windows if it has any and the interval otherwise, and never scans; `interval` draws every `interval` seconds; `describe` draws one tile per described window, beside its text; `scenes` draws one per detected cut. Scenes is opt-in because its yield is uncorrelated with anything the caller knows — 0 cuts on a 29s b-roll loop, 17 in 60s of gameplay — and it decodes the whole clip.auto
pageNoWhich page of rows to draw, from 1. Unset, the first.
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.
clip_idYesThe registered clip to browse. This sheet reads the clip's **own source**, so it needs no edit, no cues and no transcript.
intervalNoSeconds between tiles when drawing by interval (`interval`, or `auto` on a clip with no descriptions). It is `describe`'s own window length, so a tile lines up with a description.
per_pageNoRows per page. `null` draws the whole project in one montage, which returns a path rather than readable bytes — for a person to open, not for an agent to read.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations declare destructiveHint=true and idempotentHint=true, but the description adds meaningful behavioral context: it returns bytes in the reply, marks blank tiles as '[blank]' to avoid confusion with failed extraction, and warns that the sheet is 'a hypothesis, not a check' and is read to choose footage. It also discloses that scenes mode decodes the whole clip. This goes beyond the annotations without contradicting them.

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 well-organized: a one-sentence summary, a paragraph on positioning, a paragraph on modes, and a paragraph on interpretation. Every sentence earns its place, though the mode paragraph is long and could be tightened. The key contrast with shot_sheet is front-loaded.

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 7-parameter tool with no output schema, the description covers the main behavioral concerns: what the output looks like (image tiles, bytes in reply), how modes interact, and the caveat that it's a hypothesis. It doesn't explicitly describe the full return structure, but the description's emphasis on 'bytes come back' and 'path rather than readable bytes' covers the essential return distinction. The blank-tile behavior and scenes opt-in warning are valuable completeness additions.

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 value by explaining the relationship between interval and describe windows ('It is describe's own window length, so a tile lines up with a description'), clarifying that per_page=null returns a path rather than bytes, and explaining the path resolution behavior for bound vs unbound servers. These are semantic details beyond the schema.

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: 'Look at a clip's own footage — one labelled tile per moment, as an image.' It immediately distinguishes itself from shot_sheet ('shows an existing edit's picture track') and describe ('can search by text but cannot show'). The purpose is unmistakable and differentiated from siblings.

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 explicitly states when to use this tool: 'the first look at b-roll, recordings and gameplay' and contrasts it with shot_sheet and describe. It also explains mode selection semantics (auto, interval, describe, scenes) and when scenes is appropriate ('opt-in, since a continuous take has none'). This is explicit when/when-not guidance.

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

get_transcriptA
Read-onlyIdempotent

Read a clip's transcript.

With search, returns each match as a word range ready to hand to cut_by_transcript — prefer this to reading the whole transcript. With first/last, returns that window of words. Indices are inclusive.

At most limit words come back per call. total_words is the whole transcript, last_word where this reply stopped, and next_first — only present when words were left out — is the first to ask for next.

ParametersJSON Schema
NameRequiredDescriptionDefault
lastNoLast word index to return, inclusive.
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.
firstNoFirst word index to return, inclusive.
limitNoMost words to return in one call, counted from `first`. The reply's `next_first` says where to continue. Bounded by default because a whole transcript can be past what a client will put in context.
searchNoReturn each match as a word range ready to hand to `cut_by_transcript`, instead of the whole transcript. Prefer it: a transcript is a lot of words to read to find two.
clip_idYesThe clip to read.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the tool is safe and idempotent. The description adds pagination details (total_words, last_word, next_first) and notes that next_first is only present when words are left out, which is useful behavioral context beyond annotations.

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 concise and well-structured. It front-loads the primary use case (search) and then explains pagination in a few clear sentences. 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?

With an output schema present and complete schema coverage, the description sufficiently covers the key aspects: modes, pagination, and continuation. It could be a bit more explicit about the output schema fields, but overall it's complete for an agent to use effectively.

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 coverage is 100%, so the schema already describes all parameters. The description clarifies the interplay between first, last, limit, and search, and explains how next_first is used for continuation, but this is largely redundant with schema descriptions. It doesn't add major new semantics.

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 clearly states the tool reads a clip's transcript and explains the different modes (search, first/last). It distinguishes itself from siblings like cut_by_transcript by showing how search results are meant to feed into it.

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?

It explicitly says to prefer search over reading the whole transcript, and explains first/last semantics. It also mentions pagination with limit and next_first, providing complete guidance on when and how to use the tool.

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

hearA
Read-onlyIdempotent

What does clip_id's source audio actually say between start and end?

Use this when the transcript and the audio might disagree — a word with a suspect duration, a hole with no words in it, a stretch that reads clean but sounds wrong. It runs the same short-overlapping-window pass verify(windowed=True) runs, over the clip's own media across the span (source seconds), and comes back with heard_words/heard_text beside the attached transcript's own words over that span (transcript_words). No need to seed, export and verify to hear your source material.

Reports, never attaches — nothing is written and no word index moves. Where the two disagree, cut_by_time addresses what the transcript has no word for. heard_words can be empty: silence is a real answer. One whisper run over the span; end past the clip is refused.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYesWhere to stop, in the same source seconds. Past the end of the clip it is refused rather than clamped.
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.
modelNoThe whisper model for this windowed pass.small
startYesWhere to start listening, in that clip's own **source** seconds — never timeline seconds and never a word index.
windowNoLength of each window, in seconds.
clip_idYesThe clip whose source audio to listen to.
overlapNoHow far each window overlaps the one before it, in seconds. The overlap is what stops a word straddling a boundary from being lost between two windows.
languageNoForce a language code, e.g. `en`. Unset, whisper detects it.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the read-only/idempotent annotations, it discloses that the call reports and never attaches, writes nothing, moves no word index, may return empty `heard_words` as a valid silence answer, performs one whisper run over the span, and refuses `end` past the clip. This is substantive behavioral context the annotations do not provide.

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, trigger conditions, method, return fields, side effects, alternatives, and edge cases. The opening question front-loads the core purpose, and the bold 'Reports, never attaches' makes the side-effect statement highly scannable.

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 read-only listening/verification tool with an output schema and well-documented parameters, this description covers everything an agent needs to call it correctly: when to use it, what it returns, what it does not do, cost/run characteristics, and refusal behavior. Nothing important is missing.

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%, and the schema already explains source seconds, refusal behavior, defaults, and language handling in detail. The description reinforces the source-seconds framing and mentions windowed passes, but it does not need to compensate because the schema already carries the parameter semantics.

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 precise question: what does a clip's source audio actually say over a span, and immediately ties it to comparing audio against the attached transcript. It also distinguishes itself from siblings by explicitly referencing `verify(windowed=True)` and `cut_by_time`, so an agent can disambiguate without opening 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?

It gives explicit trigger conditions: suspect word durations, holes with no words, or passages that read clean but sound wrong. It also names the relevant alternatives, saying there is no need to seed/export/verify and pointing to `cut_by_time` for disagreements, which is strong when-vs-alternative guidance.

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

hold_addA
Destructive

Splice a hold into clip_id after gap_word_index: a real gap opens in the VO (vo_extend's own mechanism, reused) and a picture cue pins asset's own in-point, snapped to whole words with margin and refused, never clamped, when it cannot fit.

Addressed by (clip_id, gap_word_index), unique — a second hold_add at the same address is refused. gap_word_index/cue_word_index/ word_index_first+word_index_last each also accept a phrase alternative: gap_phrase binds its last word (the gap opens right after it), cue_phrase binds its first, and asset_phrase resolves against asset's own transcript and binds its first and last words to word_index_first/word_index_last together.

Everything else is resolved live: elapsed (how long the VO plays between the cue and the gap), src_start (deterministically — phrase_start - elapsed - head_margin), and hold_length (the phrase's own span plus both margins). Refused, with the measured numbers, when there is no room or the asset runs out.

Mix-only fields (head_margin/tail_margin/under/fade_in/ fade_out) are re-settable on an already-spliced hold by calling again with the same address and no change to word_index_first/ word_index_last — those two are one-way once spliced (hold_rm then hold_add again, or proofcut undo, are the only ways to resize one).

plan=True resolves and reports without writing anything.

ParametersJSON 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 `gap_phrase`/`cue_phrase`/`asset_phrase`: any match at or before this word index is skipped. -1, the default, means from the start.
assetNoThe film clip whose own audio plays in the gap, and whose picture the cue pins.
underNoHow far below the VO the held audio sits, in LU. Re-settable.
clip_idYesThe VO track the gap opens in.
fade_inNoSeconds of fade as the held audio comes in. Re-settable.
fade_outNoSeconds of fade as it goes out. Re-settable.
cue_phraseNoAddress the cue by wording; it binds its **first** word.
gap_phraseNoAddress the gap by wording; it binds its **last** word, since the gap opens right after it.
occurrenceNoDisambiguate `gap_phrase`/`cue_phrase`/`asset_phrase` by count, **1-based**. Unset, an ambiguous phrase is refused rather than guessed at.
head_marginNoSeconds kept before the line, so it does not start on the word. Re-settable on an already-spliced hold.
tail_marginNoSeconds kept after the line. Re-settable.
asset_phraseNoThe line to play, resolved against `asset`'s **own** transcript, binding its first and last words together. One phrase is the source of truth for both ends; hand-typed indices drift the moment a transcript changes under them.
cue_word_indexNoThe word the picture cue for `asset` is placed on.
gap_word_indexNoThe word the gap opens right after. With `clip_id` it is the hold's address, and a second `hold_add` at the same address is refused.
word_index_lastNoLast word of that line. With `word_index_first` it is one-way once spliced: resizing means `hold_rm` then `hold_add`, or `undo`.
word_index_firstNoFirst word of the line to play, in **`asset`'s own** transcript — not the VO's.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the destructiveHint annotation, it discloses exact behavioral edge cases: refusal rather than clamping when there is no room, deterministic live resolution of elapsed/src_start/hold_length, one-way word indices once spliced, and plan=True writing nothing. This is substantial context beyond the structured hints.

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 first sentence is an excellent front-loaded summary and the dense paragraphs earn their place for an 18-parameter tool. It is longer than ideal, with some information already present in the schema, but still well organized.

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 tool's complexity, a rich output schema, and per-parameter schema descriptions, the description covers mutation constraints, refusal modes, live computation, re-set semantics, and plan mode. An agent has enough to call it correctly without missing core 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?

With 100% schema coverage the baseline is 3, but the description adds cross-parameter meaning: (clip_id, gap_word_index) is the unique address, phrase alternatives bind first/last words, and asset_phrase ties word_index_first and word_index_last together. It stops short of describing every optional combination, so not a 5.

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?

Opens with a specific operation: 'Splice a hold into `clip_id` after `gap_word_index`' and details the two effects (opening a real gap in the VO and pinning a picture cue). The address uniqueness and refusal behavior further distinguish it from siblings like hold_rm/hold_ls.

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?

Explicitly says when a second hold_add is refused, when re-calling is allowed (re-settable mix-only fields), and states that resizing requires hold_rm + hold_add or proofcut undo. plan=True also offers a no-write alternative, so an agent knows to preview before mutating.

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

hold_checkA
Read-onlyIdempotent

Transcribe each hold's own span off render and check its seams.

For each stored hold: the required phrase, transcribed off the render at the hold's live-resolved span, plus the level right at each edge against the quiet floor just after it — "still loud" (a word cut off) or a "noise-floor cliff" (a hard drop with nowhere graceful to land). Report, never refuse — a post-hoc listening check on a render that already exists, verify's and film_check's own stance.

ParametersJSON 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.
renderYesThe rendered file to listen to. Each hold's span is resolved live against the current edit and transcribed off this file.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already mark this read-only, idempotent, and non-destructive. The description goes further by explaining the actual check mechanism: comparing level at each edge against the quiet floor just after it, and classifying results as 'still loud' or 'noise-floor cliff.' This adds meaningful behavioral detail beyond the annotations.

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 well-structured: a front-loaded headline, a compact explanation of the seam-check logic, and a bolded behavioral stance. Every sentence contributes meaning without redundancy or 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?

For a specialized auditing tool, the description explains the domain concepts, the exact input source, what is examined, and the reporting philosophy. An output schema exists, so lack of return-value detail is acceptable, and the schema covers path/resolution behavior.

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 itself already documents `render` and `path` thoroughly. The description reinforces `render`'s role by mentioning live-resolved spans, but it does not add substantial new parameter meaning beyond the schema.

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?

Opens with a specific verb and resource: 'Transcribe each hold's own span off render and check its seams.' It clearly identifies this as a checking/verification action for stored holds, distinguishing it from sibling hold_* mutation tools and aligning it with verify/film_check's report stance.

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?

Gives clear context: this is a 'post-hoc listening check on a render that already exists' and should 'report, never refuse.' It does not explicitly list when-not-to-use or name alternative tools as replacements, but the context is strong enough to guide selection.

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

hold_lsA
Read-onlyIdempotent

Every stored hold plus its live-resolved plan.

A hold that cannot currently resolve is reported inline (hold_error), never raised. Each item also carries cue_drift — a check between the hold's own owned cue and what it would compute fresh right now, since nothing stops a plain cue_rm/cue_add on that exact word from an unrelated caller.

ParametersJSON 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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior4/5

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

The annotations already cover read-only, idempotent, and non-destructive behavior. The description adds meaningful behavioral detail beyond that: unresolved holds are surfaced via an inline hold_error field rather than raised exceptions, and cue_drift exposes live recomputation differences caused by unrelated cue mutations. This is valuable context an agent would not otherwise know.

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 compact, front-loaded with the core purpose, and every sentence adds meaningful detail about error behavior or cue_drift. No filler or repetition is present.

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?

With annotations covering safety, an output schema present, and the path parameter fully documented in the schema, the description supplies the important behavioral nuances that structured fields cannot. It is complete enough for an agent to invoke and interpret the tool correctly, though it could strengthen the case by mentioning when to prefer this over related hold/cue inspection tools.

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 single path parameter is already fully documented in the schema. The tool description adds no additional parameter semantics, which matches the baseline expectation when the schema carries the full burden.

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

Purpose4/5

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

The description identifies the resource clearly: every stored hold plus its live-resolved plan and related diagnostics. It implies listing behavior through the tool name and content description, but lacks an explicit verb and does not directly distinguish itself from sibling tools such as hold_check or cue_ls.

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

Usage Guidelines2/5

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

No explicit guidance is given about when to use hold_ls versus alternatives like hold_check, cue_ls, or cue_reresolve. The description provides useful context about inline errors and cue_drift, but leaves the selection criteria to the agent's inference.

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

hold_rmA
Destructive

Drop a hold's record and its owned cue — the spliced silence stays.

vo_extend's own irreversibility, inherited: there is no clean "un-splice", only proofcut undo. After this the gap reverts to being an ordinary manufactured silence, a coherent pre-existing state rather than a broken one.

ParametersJSON 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.
clip_idYesThe VO track the hold was spliced into.
gap_word_indexYesThe hold's address, with `clip_id`. The record and its owned cue go; the spliced silence stays, since there is no clean un-splice — only `undo`.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior4/5

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

Beyond the destructiveHint annotation, the description adds critical nuance: the operation is irreversible in the sense that there is no clean un-splice, and the gap reverts to a 'coherent pre-existing state' rather than a broken one. It also states what persists (the spliced silence) and what disappears (the record and cue). This is meaningful behavioral disclosure that the annotation alone does not convey.

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 concise—two short paragraphs—and front-loads the primary action in the first sentence. The additional explanation about irreversibility and the resulting state is valuable but delivered in slightly poetic language ('spliced silence stays', 'coherent pre-existing state') that, while not verbose, could be more direct. Overall it is well-structured and avoids redundancy.

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 destructive tool, the description covers the key operational aspect (what is removed and what remains) and the irreversibility condition. It does not explain domain concepts like 'record' or 'owned cue', but these are likely defined elsewhere or in the sibling tools' context. Given that an output schema exists (not shown here but flagged), the tool's return information is presumably documented there. The description is complete enough for an agent familiar with the domain.

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 parameter descriptions already explain each field adequately. The description itself adds minimal parameter semantics, only clarifying that gap_word_index plus clip_id forms the hold's address and that 'the record and its owned cue go'—which slightly enriches the parameter meaning. However, this is marginal beyond what the schema already provides, so the baseline 3 is appropriate.

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

Purpose4/5

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

The description clearly states the tool drops a hold's record and its owned cue, with the explicit note that the spliced silence remains. This distinguishes it from sibling tools like hold_under_rm (which likely removes a 'hold under' region) and cue_rm (which would remove a cue without necessarily the hold record). However, the verb 'Drop' is informal and the exact scope of 'record' and 'owned cue' is implicit, requiring domain familiarity.

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

Usage Guidelines2/5

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

The description does not provide explicit when-to-use guidance relative to alternative hold-removal tools. It mentions that undo is the only way to revert, but never states 'use this when you want to completely remove a hold and its cue, versus hold_under_rm for partial removal' or similar. The context about irreversibility is behavioral, not usage-directional, so an agent is left to infer when this is the right choice among several hold-related sibling tools.

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

hold_underA
DestructiveIdempotent

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.

ParametersJSON 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

ParametersJSON Schema
NameRequiredDescription

No output parameters

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.

hold_under_rmA
Destructive

Drop the film audio under the VO addressed by (clip_id, word_index_start).

The inverse of hold_under: that span plays the VO alone again, and the music bed — which a hold gates out — comes back across it. Refused when no entry sits at that address, so a second call says so rather than doing nothing quietly. The audio was a manifest entry, not a splice, so no word moves and undo restores it.

ParametersJSON 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.
clip_idYesThe VO track the entry was addressed against.
word_index_startYesThe span's first VO word — the entry's address, with `clip_id`.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true, readOnlyHint=false, and idempotentHint=false, covering the basic mutation safety profile. The description adds context beyond that: it explains the effect on the music bed, the refusal on missing entries, and the undo/restore behavior. No contradiction with annotations.

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 roughly four sentences, each carrying distinct information: the primary action, the inverse relationship, the error behavior, and the undo effect. It is front-loaded with the core action and avoids fluff, though a slightly tighter phrasing could be imagined.

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 destructive operation with a clear output schema (present), the description covers the main effect, the inverse counterpart, the failure mode, and the reversibility. It omits only generic prerequisites like permissions, which are likely project-wide. No material information an agent needs to call it correctly is missing.

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 coverage is 100%, so all parameters (path, clip_id, word_index_start) are already described in the schema. The description references the address pair but doesn't add new semantic meaning beyond reinforcing that they form the address. This meets the baseline for high schema coverage.

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: 'Drop the film audio under the VO addressed by (clip_id, word_index_start)'. It clearly identifies the tool as the inverse of hold_under, distinguishing it from the sibling tool without ambiguity. The purpose is unambiguous and not a tautology.

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 explicitly names the inverse relationship to hold_under, telling the agent exactly when to use this tool instead of that one. It also states the refusal behavior when no entry exists, which is a key precondition. This is strong guidance for selection among siblings.

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

import_editA
DestructiveIdempotent

Lay a cut made in Kdenlive down as this project's timeline.

The supported way to bring an outside edit in. seed_timeline lays a clip down and lets auto-editor find the cuts; this takes a .kdenlive (or .mlt) playlist somebody already trimmed by hand and reads its surviving ranges into the timeline. It replaces the whole timeline, and the previous one is snapshotted first, so it is undoable like any other mutation — which is the part the hand-rolled version of this never had (HISTORY.md § The VO the project was holding: 63 ranges were parsed out of a .kdenlive and written straight to Edit, bypassing cut and its history).

Every clip the document references has to be registered already — the resources are matched against registered clips by resolved path, and any that do not match are named rather than imported behind your back. Pass clip_id for a single-source document whose media sits at a path this project does not know.

Ranges that overrun a clip's registered duration are clamped and reported in overshot, never silently dropped: auto-editor's own exports overshoot the tail by one frame, so a clean overshot is worth reading rather than assuming. plan resolves and checks without writing.

Refused by name rather than half-read: a <blank> in the playlist (real runtime an Edit has nowhere to put), and two playlists carrying different cuts (a multi-track picture edit, which proofcut's one linked A/V track has no shape for).

ParametersJSON 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.
clip_idNoThe registered clip to attribute a single-source document to, when its media sits at a path this project does not know.
documentYesThe `.kdenlive` or `.mlt` playlist somebody already trimmed by hand. Every clip it references has to be registered already; ones that do not match a registered clip by resolved path are named rather than imported behind your back.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare destructiveHint=true and idempotentHint=true, and the description adds substantial behavioral context: it replaces the whole timeline, snapshots the previous one so it is undoable, clamps and reports overshot ranges rather than silently dropping them, refuses by name rather than half-reading, and requires clips to be registered already. This goes well beyond the annotations and gives the agent a clear model of side effects and failure modes.

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 sentence earns its place: it covers purpose, alternatives, side effects, error behavior, and parameter guidance. It is front-loaded with the core purpose and the key distinction from seed_timeline. It is longer than the typical description, but the complexity of the tool (destructive, with registration requirements and edge cases) justifies the length. A small amount of trimming could improve it, but it is well organized.

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 tool's complexity (destructive timeline replacement, registered-clip requirements, clamping behavior, refusal cases, plan mode), the description covers everything an agent needs to call it correctly. The output schema exists, so return values need not be explained. The description even includes a historical note that explains why the undoable behavior matters, which helps the agent understand the tool's guarantees.

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 description coverage is 100%, so the baseline is 3. The description adds extra meaning beyond the schema: it explains the path resolution rules (bound project vs unbound, relative paths, refusal of outside paths), the purpose of plan ('Prefer it over doing the thing and undoing it'), and the exact role of clip_id. The document parameter's description is also enriched by the main description's explanation of registered-clip matching and named refusals. This is more than the schema alone provides, though the schema already covers the basics.

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: 'Lay a cut made in Kdenlive down as this project's timeline.' It then distinguishes itself from seed_timeline by explaining that this tool imports a hand-trimmed .kdenlive/.mlt playlist, while seed_timeline lays a clip down and lets auto-editor find cuts. This clearly differentiates it from the closest sibling.

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 explicitly states when to use this tool ('The supported way to bring an outside edit in'), contrasts it with seed_timeline, and gives concrete conditions: use clip_id for a single-source document whose media sits at an unknown path, and use plan to resolve and check without writing. It also names refusal cases (blank in playlist, two playlists with different cuts), which tells the agent when the tool will not work.

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

import_mediaA
Idempotent

Register a media file with the project, probing it with ffprobe.

Links the media by default rather than copying it. Returns the clip record, including the clip_id every other tool takes, and audio_streams — how many the container holds, since every other audio field on the record describes only the first.

A container with more than one audio stream is refused rather than registered as if the first were the recording: whisper picks a stream of its own and MLT picks again at render, so the others would be missing from the film with every check clean. mix=True sums them into one track (two mics of one performance); audio_stream=k keeps one, numbered from 0 in ffmpeg's own audio ordering. Either writes a derived copy under cache/mixed/ that every later op reads without knowing it.

A chapter list or the data/text track it rides on — a movie rip's own inherited from its parent film — is stripped unconditionally, with no flag to opt out: there is no legitimate choice to offer, unlike the audio-stream one. strip/stripped on the record say so when it happened; duration is corrected from the real video/audio streams either way it was detected.

sheet=True by default: a contact_sheet of the clip's first ten seconds rides along on the returned record — cached frames from thumbnail(), so the clip's own opening (credits, black, a slate) is seen before it is cued to a shot rather than discovered after. Pass sheet=False to skip it. --no-sheet on the CLI.

ParametersJSON Schema
NameRequiredDescriptionDefault
mixNoSum a container's audio streams into one track, for two mics on one performance. It writes a derived copy every later op reads without knowing it.
copyNoCopy the media into the project instead of referencing it where it sits. Off by default — a reference costs no disk, and it is also the fallback where symlinks are rejected.
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.
sheetNoDraw a contact sheet of the clip's first ten seconds onto the returned record. On by default, because a first look that has to be asked for is one nobody takes.
sourceYesThe media file to register. A file argument rather than a project selector, so it is deliberately left unconfined — footage usually lives outside the project.
clip_idNoThe id every later tool addresses this clip by. Unset, one is derived from the filename. Keep it short: it becomes part of cache paths, and a stock Windows measures those against 248 characters.
audio_streamNoKeep one of a container's audio streams and drop the rest, numbered from 0 in ffmpeg's own audio ordering — not the container's absolute stream index, which is a different number once there is video.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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

Annotations indicate idempotentHint=true, but description explains that it refuses multi-audio-stream containers unless mix or audio_stream is set, which is a critical behavioral detail. It also discloses that it strips chapter lists and data/text tracks unconditionally, with no opt-out flag, which is a significant side effect beyond the schema. While readOnlyHint=false and destructiveHint=false are consistent, the description elaborates on the derived copy creation and the contact sheet behavior, adding valuable context. It does not contradict annotations, and it goes beyond them in explaining refusal conditions and side effects.

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 long but well-structured, with each paragraph covering a distinct topic: basic registration, audio stream handling, stripping, and contact sheet. It front-loads the core purpose and clip_id return, which is the most frequently needed information. However, some redundancy exists with the schema descriptions (e.g., mix, sheet), and it could be slightly more concise without losing essential context. It is not verbose to the point of obscuring key points.

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 tool's complexity (7 parameters, multiple edge cases like multi-audio streams and stripping), the description is remarkably complete. It explains the rationale behind default behaviors, refusal conditions, and derived copies. The output schema exists, so it doesn't need to describe return values, but it does mention the clip_id and contact_sheet. The description covers all necessary operational details an agent would need to correctly invoke this tool, including caveats about file paths and cache limits.

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 all parameters. The description adds some value by explaining the default linking vs copying behavior and the audio stream handling rationale, which goes beyond the schema. However, it doesn't significantly extend the meaning of parameters like 'path' or 'source' that are already well-described in the schema. It does clarify 'mix' and 'audio_stream' usage in context, but overall it's a moderate addition over the schema.

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 clearly states the tool's verb ('Register'), resource ('a media file with the project'), and method ('probing it with ffprobe'). It distinguishes itself from sibling tools like 'import_edit' and 'list_media' by specifying it creates a clip record and returns a clip_id. The purpose is unambiguous and specific, not a tautology.

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 explicitly states when to use this tool versus alternatives: it mentions 'every other tool takes' the clip_id, and it explains the default linking behavior. It also provides clear conditions for using optional parameters like 'mix=True' for multiple audio streams and 'audio_stream=k' for keeping one. It implies this is the entry point for adding media, unlike 'list_media' which likely just lists. There is explicit guidance on when to use the tool and when not to (e.g., refusing multi-audio-stream containers unless mix or audio_stream is specified).

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

initA
Idempotent

Create a proofcut project directory at path.

Writes proofcut.json and the empty assets/, cache/, media/ and renders/ directories, and nothing else — no media, no timeline. Refuses a directory that already holds a project rather than resetting it, so it is safe to call when unsure. Next is import_media, then a transcript, then seed_timeline.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoA name for the project, recorded in the manifest. Unset, the directory's own name is used.
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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already mark it as idempotent and non-destructive, but the description adds crucial context: it writes only specific files and refuses to overwrite an existing project. This directly explains the idempotent behavior and gives the agent confidence about side effects. It also states what it does not do (no media, no timeline), which is valuable for setting expectations.

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 well-structured: the first sentence states the core action, the second details outputs and safety behavior, and the third gives the workflow sequence. It is concise with no redundant phrases, and the most important information is front-loaded.

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 tool's simplicity, the description covers the essential aspects: what it does, what it writes, what it refuses, and how to proceed next. The output schema exists to define the return value, so that is not a gap. The description also handles edge cases (bound vs unbound) clearly. Nothing an agent needs to call it correctly is missing.

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 both parameters are described in the schema. However, the description adds substantial meaning for the path parameter: how it resolves when bound to a project, relative path behavior, and refusal of external paths. This goes beyond the schema's basic description. The name parameter is not addressed in the description, but its schema description is adequate, so the added value is focused on the critical parameter.

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 clearly states the tool creates a proofcut project directory at a given path, specifies exactly what it writes (proofcut.json and four empty directories), and what it does not (media, timeline). It also positions itself as the first step before import_media and seed_timeline, differentiating it from sibling tools like migrate_project.

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 explicitly states when it is safe to call ('safe to call when unsure') because it refuses to reset an existing project, and provides a clear sequence of next steps: import_media, transcript, seed_timeline. It also gives detailed guidance on the path parameter, including bound-project behavior and refusal of paths outside the project, which helps an agent decide when and how to invoke it.

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

list_mediaA
Read-onlyIdempotent

List media files under source_dir that import_media could register.

What hands an unattended agent source paths on a real job, since an agent confined to proofcut's tools (the agent panel's --tools ToolSearch) has no directory listing of its own (HISTORY.md § The seventh queue item, decided and built). A filename filter, not a probe — import_media is still what decides a file is actually usable. Each entry's already_imported is checked against this project's own registered clips, so a repeated call does not keep re-suggesting footage already on the asset list. source_dir names wherever the footage lives and is not confined to the project.

ParametersJSON 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.
recursiveNoWalk subdirectories too. On by default.
source_dirYesThe directory to list. It names where footage lives rather than which project, so it is deliberately not confined to the bound project.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

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

Annotations already establish read-only, idempotent, non-destructive behavior. The description adds useful context beyond that: `already_imported` is checked against the project's registered clips, repeated calls avoid re-suggesting existing footage, and `source_dir` is not confined to the bound project. No contradiction with annotations.

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

Conciseness3/5

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

The first sentence is strong and front-loaded, but the second paragraph is verbose and includes tangential references to HISTORY.md and panel flags that do not help an agent call the tool. The content is relevant overall, but it could be trimmed without losing usefulness.

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?

Given the output schema and full parameter documentation, the description provides enough context for correct invocation: what the tool lists, how `already_imported` is determined, and that `source_dir` is intentionally not project-constrained. Nothing critical for selecting or using the tool is missing, though the phrasing could be more direct.

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 baseline of 3 applies. The description's note about `source_dir` largely restates what the schema already says; it adds behavioral context but no new per-parameter semantic details beyond the schema.

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 first sentence states the exact verb, resource, and scope: "List media files under `source_dir` that `import_media` could register." It also distinguishes this from being a probe, clarifying that it is a filename filter and not the tool that decides usability.

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?

The description explains the main use case: handing source paths to an unattended agent that has no directory listing of its own. It also gives an important exclusion: this is not a probe, and `import_media` remains the authority on whether a file is usable. It could be tighter by naming sibling alternatives explicitly, but the guidance is clear.

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

locateA
Read-onlyIdempotent

Where does a SOURCE word or SOURCE time play in the current render?

cut_by_time's read-only mirror, and the tool to reach for before quoting any timestamp to a human: word indices and transcript times address the original recording, so they are NOT render times and every accumulated cut moves them further apart.

Two clocks, and this reports the Edit's. timeline_start/ timeline_end are 0 = the Edit's own first frame, unchanged whether or not a head (a cold open) is configured. head_seconds rides along (0.0 with none) so a caller that needs the actual render time — this tool's own stated purpose — can add it: render time = Edit time + head_seconds.

Address it one way per call — first/last are inclusive word indices (last defaults to first), source_start/source_end are seconds into the recording (omit source_end to locate an instant), or phrase — a phrase naturally is a range, so it resolves straight to first/last with no edge to pick (after/occurrence disambiguate a phrase matching more than once).

Read present first. False means the material is not in the render, and beyond_source distinguishes "you cut it" from "the recording never went that far". A partially-cut range is normal: placements lists each surviving piece in playback order with the source coordinates saying which part of the phrase it is, covered how much survives, and contiguous whether the survivors still play back-to-back. Word mode (and phrase mode, which resolves into it) echoes the resolved words plus three either side; time mode echoes the words the interval overlaps, or its nearest neighbours if it landed in silence. Read-only: nothing is written.

ParametersJSON Schema
NameRequiredDescriptionDefault
lastNoLast word index, inclusive. Defaults to `first`.
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.
afterNoA forward cursor over a phrase's matches: any match at or before this word index is skipped. -1, the default, means from the start.
firstNoFirst word index, inclusive. Address it one way per call: `first`/`last`, `source_start`/`source_end`, or `phrase`.
phraseNoLocate by wording. A phrase is naturally a range, so it resolves straight to first and last with no edge to pick.
clip_idYesThe transcript, or the recording, the address belongs to.
occurrenceNoDisambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — rather than guessed at.
source_endNoEnd of the source interval, in the recording's own seconds.
source_startNoSeconds into the original recording. Omit `source_end` to locate an instant.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, and openWorldHint=false. The description goes well beyond these by explaining the two-clock semantics, how `present`/`beyond_source` distinguish outcomes, how partial cuts surface via `placements`/`covered`/`contiguous`, and explicitly stating 'Read-only: nothing is written.' It also explains what happens in edge cases like silence and ambiguous phrases. No contradiction with annotations.

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 long but every paragraph earns its place: core purpose first, then the clock explanation, addressing modes, output semantics, and the read-only note. It is dense without redundancy. A small deduction because the path parameter's behavior is only explained in the schema, not reinforced here, though that is arguably fine given 100% schema coverage.

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 9-parameter tool with an output schema and rich annotations, the description is remarkably complete. It covers the core purpose, the clock distinction, all three addressing modes, the output fields and their meanings, edge cases (partial cuts, silence, ambiguity), and the read-only nature. An agent could confidently invoke this tool correctly on the basis of this description alone.

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 schema already documents every parameter. The description adds genuine value beyond the schema by stating the 'one way per call' constraint (first/last XOR source_start/source_end XOR phrase), the default relationship between first/last, and how phrase mode resolves to a range with after/occurrence disambiguation. It also explains that time mode returns overlapping words or nearest neighbors in silence, which the schema doesn't convey.

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 states a specific verb-resource pair ('Where does a SOURCE word or SOURCE time play in the current render?') and immediately differentiates itself from its read-only mirror, cut_by_time. It also clarifies the critical two-clock distinction (Edit time vs render time) that would otherwise confuse an agent.

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?

The description gives an explicit usage directive ('the tool to reach for before quoting any timestamp to a human') and names cut_by_time as its mirror, implying the read/write split. It explains why word indices and transcript times are not render times, which tells the agent when this tool is needed. It doesn't explicitly state when NOT to use it beyond the mirror relationship, but the context is clear.

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

migrate_projectA
DestructiveIdempotent

Bring an older project manifest forward to the current schema version.

Every other tool refuses a project written by an older proofcut rather than guessing at a layout it does not recognise; this is what clears that. It is forward-only, and it copies the manifest into cache/history/ before writing. plan=True reports the version and the steps without writing, which is how to ask what a project is before deciding to change it. A project whose manifest is still lucid.json (written before the rename) is renamed to proofcut.json first, reported as the first step.

ParametersJSON 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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations (delete/rebuild, idempotent, read-write), the description discloses that it copies the manifest into cache/history before writing, is forward-only, and handles the pre-rename lucid.json case. No contradiction with the annotations exists.

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 information-dense with no filler. It front-loads the core purpose, then adds justification, safety behavior, plan usage, and an edge case in logical order. Every sentence contributes useful guidance.

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 migration tool with an output schema and rich parameter descriptions, the description covers the what, when, why, safety mechanism, dry-run alternative, and an important edge case. An agent has everything needed to invoke it 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%, and both path and plan already carry detailed descriptions in the schema. The tool description adds minor reinforcement about plan=True reporting version and steps, but it does not fundamentally extend what the schema already states.

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: 'Bring an older project manifest forward to the current schema version.' It also distinguishes this tool from everything else by noting that 'every other tool refuses' such projects, so the agent can identify exactly when migrate_project applies.

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?

It gives explicit context for use: older project manifests that other tools refuse. It also explains the plan=True mode as the safe way to inspect before changing, which is a clear usage directive. The 'forward-only' statement further sets expectations about directionality.

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

musicA
DestructiveIdempotent

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.

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, duck dips it while the voice speaks, keyed off the edit's own audio at export. export's music field says what the render carried. clear_* and reset undo each; plan validates without writing.

ParametersJSON 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.
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.
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 transcript the bed's word indices address — 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.
passagesNoReplace the list of passages after the bed's own asset: each `{asset, word_index_start | phrase_start, 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.
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.
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.
word_index_endNoWhere the bed goes out. Unset means *to the end of the edit*, so a tail holds over silence.
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

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

The annotations already carry destructiveHint and idempotentHint, and the description substantially adds behavioral details: the bed stores word indices rather than a length, duration is derived at build time, phrase-based entries store the phrase while index-based ones clear it, and `plan` validates without writing. It also discloses that `clear_*` and `reset` undo each respective action, giving the agent a reliable mental model of side effects.

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 long, but it is front-loaded with the core read/change distinction and organized into clear thematic sections covering boundaries, phrase storage, and auxiliary features. Each sentence contributes a model fact or usage constraint, leaving little waste. It is denser than strictly necessary, but for a 22-parameter tool this level of detail is reasonable and well-structured.

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 a 22-parameter schema with 100% coverage, annotations, and an output schema, the description completes the picture by explaining how the bed span is derived, the initial-bundle requirement, and the interaction mechanics of phrase resolution, ducking, under, and plan. It covers all major branches—read, set, clear, reset, plan, passages, and rotate—so an agent is unlikely to need external context before calling.

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?

The schema has 100% coverage and many parameter descriptions already contain rich detail (e.g., `asset` never takes `card:name`, `clip_id` must be the VO transcript). The description adds cross-parameter semantics that are not in the schema: the first set must bundle `asset`, `clip_id`, and one start, and boundaries can mix phrase and index forms independently. These interactions materially clarify how to call the tool correctly.

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 precise verb pair—'Read or change'—and a concrete resource, 'the A2 music bed this project mixes under its edit,' so the tool's function is immediately unambiguous. It also exposes two fundamental modes (no-arg read vs. arg mutation), which helps distinguish it from related audio tools like `hear` or `vo_extend`.

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?

The description gives explicit usage guidance for the read mode ('Call with no arguments to read what is in force') and states the key first-set requirement for writes: `asset`, `clip_id`, and one start together, after which fields update independently. It does not name any sibling tool as an explicit alternative, so there is no when-not-to-use contrast, but the context is otherwise clear.

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

pack_activateA
DestructiveIdempotent

Switch the active pack variant to one already snapshotted by pack_apply.

No file re-read — refuses an unknown variant by name, naming the ones that are actually available, rather than trying to load it here.

ParametersJSON 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.
variantYesWhich already-snapshotted variant to switch to. No file is re-read, and an unknown name is refused by listing the ones that are available.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already signal destructiveness and idempotency; the description adds concrete behavior beyond that: it refuses unknown variant names by listing available ones, and it never re-reads files. This meaningfully supplements the structured hints without contradicting them.

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?

Two short sentences with the primary action front-loaded and the refusal/no-re-read behavior placed second. No filler or redundant restatement of the schema.

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 mutation tool with strong annotations, an output schema, and fully described parameters, the description covers the essential precondition, the no-re-read guarantee, and the error behavior. It leaves the relationship to pack_status/pack_show implicit, but nothing critical is missing for correct invocation.

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 coverage is 100%, and the schema already documents path, plan, and variant in detail. The tool description mainly restates variant's 'already snapshotted' constraint, so it adds little over the parameter schema.

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 states a specific action and resource: 'Switch the active pack variant to one already snapshotted by pack_apply.' It also names the relevant sibling, making it easy to distinguish from pack_apply, pack_show, and pack_status.

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?

The description clarifies the key precondition: the variant must already be snapshotted by pack_apply, and no file re-read is involved. It gives clear context for when the tool applies, though it does not explicitly exclude alternative tools or state when not to use it.

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

pack_applyA
DestructiveIdempotent

Load a channel preset pack, resolve and snapshot every variant, activate one.

pack_path is an external file — never confined to the project, the same way import_media's source is not — because a pack typically lives in a separate branding repo. Every declared variant is resolved and hashed, not only the one variant activates, so pack_activate can switch between them later with no file re-read; nothing after this call ever depends on pack_path staying reachable.

For every font role, fonts.probe asks whether the declared family actually draws on this machine — a family that does not refuses the whole call unless allow_fallback (then its declared CSS fallback is used and recorded, never silent); one that draws but is vendored nowhere proofcut knows about is recorded font_provenance: "unvendored" rather than refused, since the render here is genuinely correct today. install_fonts vendors the pack's own fonts/ directory if it ships one — off by default, since it writes into $HOME.

Writes nothing to caption styling or to any card already on disk; a card picks up the new style only when card_new/card_reauthor next draws it, and captions only via pack_apply_captions. plan resolves and probes without writing.

ParametersJSON 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.
variantNoWhich resolved variant to activate. Every declared variant is snapshotted regardless, so `pack_activate` can switch later with no file re-read.default
pack_pathYesThe pack file to load. An external file, never confined to the project — a pack usually lives in a separate branding repo — and nothing after this call depends on it staying reachable.
install_fontsNoVendor the pack's own `fonts/` directory, if it ships one. Off by default, since it writes into `$HOME`.
allow_fallbackNoAccept a declared CSS fallback for a font family that does not actually draw on this machine, recording which was used. Without it, a family that does not draw refuses the whole call.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

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

Despite the annotations already declaring readOnlyHint=false, idempotentHint=true, and destructiveHint=true, the description adds substantial behavioral detail: it resolves and hashes every variant (not just the activated one), describes font probing with fallback and 'unvendored' provenance, explains that install_fonts writes to $HOME, and clarifies that it writes nothing to existing cards or caption styling. It also mentions the plan mode as non-writing. This goes far beyond the annotations without contradicting them.

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 comprehensive yet efficiently structured. It starts with the core purpose, then explains the external file nature, variant snapshotting, font probing behavior, install_fonts caveat, writing limitations, and plan mode—all in a logical flow. Every sentence earns its place; there is no fluff or redundancy. The use of bold for key points (e.g., 'Every declared variant is resolved and hashed') aids scanning.

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 tool with 6 parameters, complex side effects, and a destructiveHint=true annotation, the description covers all critical aspects: what it does, what it does not write to, font handling nuances, plan mode, and how it relates to pack_activate and pack_apply_captions. It also addresses error conditions (refusal for non-drawing fonts) and environmental context (path binding). An agent has everything needed to invoke it correctly and safely.

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 each parameter already has a thorough description. The tool description reinforces and adds cross-parameter context, such as the interaction between allow_fallback and font probing, and the relationship between variant and pack_activate. While it does not add new per-parameter syntax, it enriches the meaning of the parameters as a whole, making it more than a simple restatement.

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, action-packed sentence: 'Load a channel preset pack, resolve and snapshot every variant, activate one.' This clearly names the resource (pack), the core actions (load, resolve, snapshot, activate), and distinguishes it from siblings like pack_activate (switching later) and pack_apply_captions (captions only). The purpose is unmistakable and differentiated.

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 explicitly states when to use this tool versus alternatives: it notes that pack_activate can switch variants later, that captions are applied via pack_apply_captions, and that cards only pick up the style on next card_new/card_reauthor. It also mentions plan as a dry-run alternative. These clear usage boundaries and conditional guidance make it easy for an agent to select the right tool.

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

pack_apply_captionsA
DestructiveIdempotent

Apply the active pack variant's caption preset, through caption_style.

Concrete resolved fields, never a live pointer: this reads the preset's already-resolved dict off the snapshot and hands it to the ordinary caption_style call, so a later pack swap can never silently overwrite a project's caption look out from under it. Separate from pack_apply on purpose — applying a pack never restyles captions on its own, only this does.

ParametersJSON 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.
presetYesWhich caption preset of the active variant to apply, through the ordinary `caption_style` call. This is the only thing that restyles captions from a pack; `pack_apply` never does it on its own.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already indicate destructive and idempotent behavior, and the description adds meaningful behavioral context: it reads already-resolved fields from a snapshot rather than a live pointer, so a later pack swap cannot silently overwrite the project's caption look. This is the kind of implementation-level guarantee that an agent cannot infer from the 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 compact and front-loaded: the first sentence states the action, and the second paragraph earns its place by clarifying the snapshot behavior and the relationship to pack_apply. Every sentence adds distinct value.

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 rich input schema, output schema, and annotations, the description covers the key contextual facts an agent needs: what gets applied, how it is resolved, why it is separate from pack_apply, and what makes it safe against later pack swaps. Nothing necessary for correct invocation is missing.

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%, and the tool description does not add parameter-specific meaning beyond what the schema already provides. The description mentions 'caption preset' and 'caption_style', but the preset parameter already says the same thing; the baseline of 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?

The description uses a specific verb ('Apply'), names the exact resource ('the active pack variant's caption preset'), and clarifies the mechanism ('through caption_style'). It explicitly separates itself from pack_apply, so an agent can immediately distinguish this tool from its siblings.

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-not guidance: 'Separate from pack_apply on purpose — applying a pack never restyles captions on its own, only this does.' This directly tells the agent that pack_apply is not the way to restyle captions and that this tool is the intended route.

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

pack_showA
Read-onlyIdempotent

What a pack declares — from its file, a project's snapshot, or both.

pack_path alone reads and resolves the file fresh, needing no project (card_templates's own shape). path alone reports what a project actually has applied, from its stored snapshot — never the file again. Both together compares "what the file says now" against "what the project is still running."

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoA project directory, or nothing. Omitting it means *no project* here — never the bound one — so `pack_path` alone reads the file fresh; given, it reports what that project has applied.
variantNoReport one variant rather than all of them.
pack_pathNoRead and resolve this pack file fresh, needing no project. With `path` as well, it compares what the file says now against what the project is still running.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds behavioral context beyond annotations: it explains that path alone reads from the stored snapshot and never the file again, and that pack_path alone reads and resolves the file fresh. This clarifies the data source behavior, which is valuable. It doesn't describe output format, but an output schema exists, so that's not required.

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 compact and front-loaded: the first sentence states the core purpose, and the following sentences explain the three modes without redundancy. Every sentence earns its place, and the structure makes the mode distinction immediately clear.

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 read-only inspection tool with three optional parameters, an output schema, and full schema description coverage, the description is complete. It explains all three usage modes, the data sources involved, and the comparison semantics. Nothing an agent needs to select and invoke the tool correctly is missing.

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 description coverage is 100%, so the schema already documents all three parameters. The description adds meaning by explaining the interaction between path and pack_path: how they combine to compare file state vs. project state, and that omitting path means no project. This goes beyond the individual parameter descriptions and clarifies the semantic relationship between parameters.

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 clearly states the tool's purpose: reporting what a pack declares from its file, a project's snapshot, or both. It distinguishes three modes (pack_path alone, path alone, both together) with specific verbs and resources. This differentiates it from siblings like pack_apply, pack_activate, and pack_status.

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 explicitly explains when to use each mode: pack_path alone for reading a file fresh without a project, path alone for reporting what a project has applied, and both together for comparing file state vs. project state. It also clarifies that omitting path means no project, never the bound one, which prevents a common misuse.

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

pack_statusA
Read-onlyIdempotent

Active pack variant, and which cards/captions have drifted from it.

A card is stale when its own recorded pack_hash no longer matches the active variant's current hash — not wrong, since card_new only pre-merges a pack's style and a per-call slot still wins, but worth a card_reauthor to catch up. caption_preset_stale is the same question for whatever pack_apply_captions last wrote.

ParametersJSON 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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior5/5

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

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds valuable interpretation beyond those flags: 'stale' does not mean wrong, a per-call slot still wins, and caption_preset_stale tracks the last pack_apply_captions write. This gives the agent accurate expectations about what the status values mean and what action they imply.

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 three sentences with the core statement front-loaded and two dense but purposeful sentences explaining the stale semantics. Nothing is redundant, and the technical nuance earns its place.

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 read-only status tool with a full output schema and safety annotations, the description is complete: it defines the two drift statuses, explains why stale is not wrong, and points to the relevant follow-up tool. The only implicit notion, 'active pack variant,' is a consistent domain term supported by sibling tools like pack_activate.

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?

The only parameter, path, is fully documented in the input schema with 100% coverage, including its optional behavior when bound to a project. The description contains no parameter-level detail, which is acceptable because the schema already carries that burden.

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

Purpose4/5

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

The description names the resource ('active pack variant') and the specific output (which cards/captions have drifted), so an agent can tell what the tool reports. It lacks an explicit verb, but the status framing and concrete drift/stale terminology make the purpose clear and distinguishable from pack_show.

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

Usage Guidelines3/5

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

The description implies usage context: when a card's recorded pack_hash no longer matches the active variant, a card_reauthor may be worth doing, and caption_preset_stale refers to what pack_apply_captions last wrote. However, it never explicitly states when to call pack_status versus a sibling like pack_show or pack_apply, so the guidance is implied rather than explicit.

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

pingA
Read-onlyIdempotent

Check that the proofcut MCP server is alive, and report its version.

project is the project every tool addresses when path is omitted, and bound_by says how it was chosen: -C at startup, or cwd because the server was started inside a project. Both are null when it is unbound.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds meaningful context beyond annotations by explaining the project and bound_by fields, which inform the agent about the server's configuration. It does not contradict any annotation and enriches the agent's understanding of the environment.

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 split into two concise sentences. The first sentence states the core purpose, and the second adds necessary context about project binding. There is no fluff; every clause earns its place. It is front-loaded with the primary action, making it easy for an agent to scan quickly.

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 simple health-check tool with no parameters, an output schema, and annotations covering safety, the description is complete. It explains the server's liveness check, version reporting, and the meaning of project/bound_by, which is all an agent needs to correctly invoke and interpret the tool. Nothing is missing.

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?

There are zero parameters, so the input schema is trivially fully covered. The description doesn't need to explain parameters, and the baseline for 0 params is 4. It correctly notes that project and bound_by are both null when unbound, which clarifies the server state without being parameter-related.

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 states a specific verb ('Check') and resource ('proofcut MCP server'), and clearly distinguishes this health-check tool from all sibling tools, none of which perform a liveness check. It also adds the useful detail that it reports the server version, making the purpose unambiguous.

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?

While it doesn't explicitly say 'use when you need to verify server connectivity', the purpose is self-evident and no sibling tool overlaps. It does provide valuable context about the project binding and how it was chosen, which helps an agent understand the server's current state and when this info is relevant. No exclusions or alternatives are needed.

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

propertiesA
Read-onlyIdempotent

Project/clip/cue detail for a properties inspector, composed only.

No arguments: status, canvas and caption_style's own reports. clip_id: adds that clip's assets entry, its reframe window table, and its whole cue_ls. Both clip_id and word_index: adds cue (the matching entry from that cue_ls, or null if the word carries none) and, only when cue is null, context — the word plus three either side, the same echo every word-indexed tool gives (a cue's own entry already carries this, so it is not duplicated). word_index needs clip_id.

ParametersJSON 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.
clip_idNoAdd this clip's assets entry, framing windows and cue table to the report.
word_indexNoWith `clip_id`, add the cue at that word — or, when there is none, the word plus three either side. It needs `clip_id`.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already establish readOnlyHint, idempotentHint, and non-destructive behavior, so the bar is lower. The description adds genuinely useful behavioral context beyond annotations: conditional composition of reports, the null-cue fallback to a context window, and the dedup guarantee that a cue's own entry already carries context so it is not repeated.

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

Conciseness3/5

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

The description is compact and parameter detail is logically organized, but the opening 'composed only' phrasing and shorthand like 'the same echo every word-indexed tool gives' are jargon-heavy and hinder immediate comprehension. It is appropriately sized but not as clear as it could be given the density.

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 read-only composition tool with an output schema present, the description covers the key agent-facing concerns: the no-argument report set, each parameter's incremental contribution, the word_index-to-clip_id dependency, null-cue behavior, and deduplication. The main gap is the absence of explicit sibling routing, but the conditional behavior an agent needs to invoke it correctly is well specified.

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%, setting a baseline of 3, but the description materially enriches all three parameters: it spells out exactly what clip_id contributes (assets entry, reframe window table, cue_ls) and what word_index yields (the matching cue or the word±3 context fallback). The path parameter's semantics are already well-covered by the schema, so the description's added value is distributed where it matters.

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

Purpose4/5

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

The description identifies the resource ('Project/clip/cue detail for a properties inspector') and the composition behavior, which distinguishes it from dedicated sibling tools like cue_ls or assets. However, the phrase 'composed only' is cryptic and does not crisply convey that this aggregates existing reports rather than computing new data, leaving some ambiguity on first read.

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

Usage Guidelines3/5

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

The description clearly explains the within-tool parameter combinations (no args vs clip_id vs clip_id+word_index) and the dependency that word_index needs clip_id. It does not, however, explicitly guide when to choose this tool over siblings like describe_ls, cue_ls, or assets, leaving alternative routing to inference.

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

proxy_transcodeA
Idempotent

Make footage the preview cannot decode playable in the window.

The other half of what the viewer already reports: an unplayable clip names its reason (hev1, 10-bit, an unopenable container, an undecodable audio track) and shows black. This transcodes a downscaled h264/aac/mp4 stand-in into the project's cache so it plays. One ffmpeg pass; a long clip is minutes.

The result is a preview artefact and cannot reach a render: nothing records it in the manifest, so media_path() — what export, verify and check_frames all resolve through — has no way to see it. That containment is structural, not a convention to be careful about.

Skips the work when a current proxy already exists (keyed by the source's size and mtime), so calling it on every unplayable clip in a project is cheap after the first pass. Refuses a clip that already plays, and refuses a file with no decodable streams — that is a broken file, not a codec problem, and it is the one refusal a transcode cannot close. force rebuilds a current proxy but does not override either refusal.

ParametersJSON 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.
forceNoRebuild a proxy that is already current. It touches nothing authored: a proxy is a preview artefact the manifest never records, so no render can reach one. It overrides neither refusal.
clip_idYesThe clip the preview cannot decode. A clip that already plays is refused, and so is one with no decodable streams — that is a broken file, not a codec problem.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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

The description is unusually transparent: it discloses the side effect (writing a cache proxy), the performance profile (one ffmpeg pass; long clips take minutes), the structural containment from renders, the idempotent caching behavior, both refusal conditions, and what `force` does and does not override. These go well beyond the annotations, which already mark the tool as non-read-only, non-destructive, and idempotent. No contradiction exists between the description and annotations.

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 front-loaded with a one-sentence purpose and then expands into distinct, clearly separated concerns: mechanics, render containment, idempotency, and refusals. Every paragraph earns its place given the tool's nuanced non-obvious behavior; there is no filler or redundant repetition.

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 tool with this complexity and with rich annotations and schema, the description covers everything needed to invoke it correctly: what it produces, where it writes, how long it takes, when it skips, when it refuses, what `force` does, and why the proxy cannot leak into renders. An output schema exists, so not describing return values is acceptable.

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?

Input schema coverage is 100%, and the schema already explains `path` binding rules, `force` behavior, and `clip_id` refusals in detail. The free-text description adds useful operational context, such as the ffmpeg pass and proxy-cache behavior, but it does not add new per-parameter semantics beyond what the schema already provides. Baseline 3 is appropriate for full schema coverage.

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 names the precise verb ('transcodes'), the resource (a downscaled h264/aac/mp4 stand-in in the project cache), and the triggering condition (footage the preview cannot decode). It clearly separates this preview-only proxy behavior from render/export behavior, so it distinguishes itself from siblings.

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?

The description clearly says when to call the tool — on unplayable clips — and gives strong exclusions: refuse clips that already play, refuse files with no decodable streams, and skip work when a current proxy exists. It also clarifies that the result cannot reach a render, which sets expectations versus export/verify/check_frames. It does not name a specific sibling alternative, but no obvious sibling competes for this action.

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

reelA
Destructive

Derive a new project at dest holding [start, end) of this timeline.

start/end are render seconds naming the span to keep — the opposite direction from every other tool; the head and tail are cut through cut_by_time. Reach for this before setting a vertical canvas on a film: the canvas is project state, so pass the reel's shape here and it lands on the copy only.

Media is linked, not copied. Descriptions and reframes carry over. Cues carry over only where the reel keeps their word — read cues_dropped head-first, since one pruned just outside the kept span opens the reel on no picture. Survivors are pinned to the film's in-points (cues_pinned, or pins_error). Cards are re-authored at the new canvas (cards_unrecorded names any that cannot be); over_platform_cap says if it still runs long for a vertical feed.

Nothing after the film is inherited: tail_dropped and music_dropped name what the film had. An edge on a suspect-duration word — likely a hidden retake — refuses unless confirm_suspect; read suspect_edges. plan=True creates nothing.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYesWhere it ends, in those same render seconds. `start`/`end` name the span to **keep**, the opposite direction from every other tool here.
destYesWhere the derived project is created. It is a project selector too, not a file, so a bound server confines it to the same tree as `path` rather than letting a reel be written anywhere on disk.
nameNoA name for the derived project. Unset, it is derived from `dest`.
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.
startYesWhere the reel begins, in the seconds **an export plays at** — the same numbers `cut_by_time` takes, read off a watch.
canvasNoThe shape to set on the derived project only, e.g. `1080x1920`. Setting it on the film instead is what deriving exists to avoid — a canvas is project state and would stay.
confirm_suspectNoGo ahead even though a boundary word claims a suspect duration. Read the echoed words first — a suspect duration usually means whisper hid a retake inside that word, so the edge is not where it reads.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only say destructiveHint=true and readOnlyHint=false; the description carries the full side-effect burden and exceeds it: media is linked not copied, carry-over rules for cues/cards, dropped items (`tail_dropped`, `music_dropped`, `cards_unrecorded`), refusal on suspect-duration edges unless `confirm_suspect`, and `plan=True` dry-run. This is exactly the disclosure a destructive derivation tool needs, with no contradiction to annotations.

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?

Effectively front-loaded with the core operation in the first sentence, then organized into focused paragraphs: parameter semantics, carry-over behavior, non-inherited tail items, edge-case refusal, and dry-run. Despite length, the tool is genuinely complex (8 params, destructive, many carry-over rules), and every sentence carries load-bearing information rather than padding.

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 destructive 8-parameter tool with an output schema, the description is complete: it covers what the operation does, when to reach for it, parameter rationale, what carries over, what is dropped, failure/safety behaviors, and the plan dry-run. With an output schema present, it need not explain return values, and it still references all relevant output fields (e.g., `cues_dropped`, `suspect_edges`, `over_platform_cap`) as behavioral context.

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% with rich per-parameter text, so the baseline is 3. The description adds meaning beyond that baseline: it explains the `start`/`end` 'span to keep' semantics in relation to `cut_by_time`, ties `confirm_suspect` to the suspect-edge refusal flow, and frames `canvas` as the reason to derive rather than set state on the film. Some repetition of schema text exists, but genuine workflow-level meaning is added.

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?

Opens with a specific verb+resource: 'Derive a new project at `dest` holding `[start, end)` of this timeline.' It distinguishes itself from siblings by contrasting its parameter direction with 'every other tool' and by relating its cut mechanics to `cut_by_time`, and from `canvas` by explaining the copy-only landing. An agent can tell what this does and what it is not.

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?

Gives explicit when-to-use guidance: 'Reach for this before setting a vertical `canvas` on a film' with the rationale that canvas is project state. It also names `cut_by_time` as the mechanism that cuts head/tail, which orients the agent toward the sibling. It stops short of an explicit when-not-to-use/alternative selection rule (e.g., 'use cut_by_time instead when cutting in place'), hence not a 5.

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

reframeA
DestructiveIdempotent

Read or set which part of each clip survives into the frame.

What makes a swapped canvas fill the frame instead of pillarboxing it. The default is a centre crop, which is wrong whenever the subject is not centred. Call with no clip_id to read the crops in force for every clip; clips[].windows is each clip's whole series.

A rect is a floor rather than a frame: grown to the canvas's shape, never shrunk into it, stored as asked and refit whenever the canvas moves; the reply gives both asked and the crop it became. src_start makes it a per-shot window, addressed on the source's own clock, so every placement of the clip picks it up. pane makes that window a stacked split for a shot one crop cannot hold; interp slides into it rather than stepping; fill="blur" draws it whole over a blurred copy of itself instead of cropping, for a shot every crop loses something from.

reset drops overrides (one clip, one window, or all); plan resolves without writing. Nothing here analyses the picture — reframe_detect proposes crops and writes through this tool. Judge a window on reframe_sheet, never on a watch: a wrong one reads as framing in motion.

ParametersJSON Schema
NameRequiredDescriptionDefault
fillNo`blur` draws this window **blur-filled**: the whole source contained in the frame, over a blurred, darkened copy of the same moment covering the canvas. For a shot every crop loses something from and no split divides. Takes no `rect`, `pane` or `interp`; set `src_start` for one shot.
paneNoA second rect making this window a **stacked split**: `rect` on top, `pane` below, each about twice the width one 9:16 window gets. For the shot one window cannot frame. Both are grown to the full source height — nothing masks a pane, so a shorter crop scales into the other half at exit 0.
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.
rectNo`X,Y,W,H` in that clip's **own source pixels** — the region kept. An override is a floor rather than a frame: a rect that is not the canvas's shape is grown to it, so nothing named is pushed off screen, and the reply gives both `asked` and the `crop` it became.
resetNoWith `clip_id`, drop that clip's overrides; with `src_start` as well, only the window there. Alone, drop every override.
interpNoSlide into this window from whatever governed before it instead of stepping to it. It needs `src_start` past 0 — there is nothing before the head of the source to slide from — and cannot be combined with `pane`.
clip_idNoThe clip to read or frame. Omit it to read the crops in force for every clip, including how much of each is kept.
src_startNoFrame a **shot** rather than a clip: seconds into that clip's own source, the rect holding from there until the next window. Because the address is the source's own clock, a clip used seven times picks up the right window at each placement. Omitted, it is the window from the head of the file.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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

Annotations declare destructiveHint=true and idempotentHint=true, and the description is fully consistent with these (no contradiction). It adds rich behavioral context beyond annotations: the rect is 'a floor rather than a frame' that is grown to the canvas and never shrunk, the reply gives both 'asked' and the 'crop' it became, src_start addresses on the source's own clock so repeated clips pick up the right window, and pane details like 'nothing masks a pane'. This substantially exceeds what annotations alone convey.

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 long but information-dense — every sentence carries distinct semantic weight, from the core purpose to the key conceptual warning (centre crop is wrong for off-centre subjects) to per-parameter behaviors. It is front-loaded with the purpose and the most critical concept. It loses one point only because its density demands careful reading; it is thorough rather than concise.

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 9-parameter, 0-required, complex tool with an output schema, the description covers all operational modes (read, set, reset, plan), explains response format ('the reply gives both asked and the crop it became'), explains the clip-vs-shot distinction, addresses the path binding behavior, and names its complementary siblings. An agent has everything needed to invoke this tool correctly.

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, and the description clearly exceeds it. It adds meaning the schema cannot: the floor-vs-frame growth semantics for rect, why src_start matters for clips used multiple times, the stacking behavior for pane, and the interp constraint of needing src_start past 0. The description genuinely enriches parameter understanding rather than restating the schema.

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 precise verb+resource statement ('Read or set which part of each clip survives into the frame') and then explicitly differentiates itself from siblings: 'Nothing here analyses the picture — reframe_detect proposes crops and writes through this tool' and 'Judge a window on reframe_sheet'. This is unambiguous sibling differentiation.

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 for every mode: call with no clip_id to read all crops, use src_start for per-shot windows, use pane for stacked splits, use fill='blur' when every crop loses something. It explicitly names the analysis sibling (reframe_detect) and the judging tool (reframe_sheet), with the instruction 'never on a watch'. Nothing is left to inference.

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

reframe_coverageA
Read-onlyIdempotent

Which placed seconds are framed by a window chosen for an earlier shot.

The question reframe_detect cannot answer: that one is about a proposal, this is about the project on disk. A refused proposal writes nothing, so a stretch can sit under a rect chosen for a shot that ended long before — 13.6s of one clip across four camera setups on the film, with the manifest, status and reframe_sheet all clean.

Every placement is walked against its source's scene cuts. A cut with no window boundary within a frame of it opens a stale stretch. Read stale_seconds — an override held across a cut, which looks deliberate — not default_seconds (the centre crop, only the default doing what it always did). Each stretch carries timeline_start; the fix is reframe_sheet to look, then reframe_detect on the clip.

steps is the mirror, and the one a viewer notices: a window boundary with no cut, where the frame slides sideways mid-take and reads as an edit that is not there. Each carries shift and nearest_cut.

Needs no face detector, reads and never writes — but it decodes placed footage, so it is seconds, not free.

ParametersJSON 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.
clip_idNoWalk one clip's placements. Omit it for the whole project.
thresholdNoHow strong a scene change has to be to **demand** a window. Boundaries are scored against every detected cut rather than only these, since a cut too weak to demand a window still explains one.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false; the description reinforces 'reads and never writes' and adds valuable context: 'Needs no face detector, reads and never writes — but it decodes placed footage, so it is seconds, not free' (discloses compute cost). It also discloses output fields ('Each stretch carries `timeline_start`', 'Each carries `shift` and `nearest_cut`'), which goes beyond annotations.

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

Conciseness2/5

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

The description is verbose and narrative, including an extended anecdote ('13.6s of one clip across four camera setups...') and metaphor ('the mirror, and the one a viewer notices'). While rich, it is not front-loaded and each sentence does not earn its place; an agent must parse a lot of prose to extract the core operational details. The structure could be tightened significantly without losing meaning.

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?

The description covers the tool's purpose, its distinction from `reframe_detect`, the concepts of 'stale stretch' and 'steps', output fields, cost, and the follow-up workflow (`reframe_sheet` then `reframe_detect`). Given the tool's complexity and the presence of an output schema, this is quite complete. It could be more systematic, but it does not leave major gaps.

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?

The input schema has 100% description coverage for all three parameters (path, clip_id, threshold). The description does not add any extra parameter-specific meaning beyond what the schema already provides. Since the schema fully documents the parameters, the baseline of 3 is appropriate; there is no additional value from the description.

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 opening sentence states exactly what the tool does: 'Which placed seconds are framed by a window chosen for an earlier shot.' It uses a specific verb ('framed') and names the resource ('placed seconds'), and it immediately differentiates from sibling `reframe_detect` by contrasting proposal vs. on-disk state. The purpose is unambiguous and distinct.

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 explicitly explains when NOT to use it: 'The question `reframe_detect` cannot answer: that one is about a proposal, this is about the project on disk.' It also prescribes the workflow: 'the fix is `reframe_sheet` to look, then `reframe_detect` on the clip.' This gives clear usage guidance and directs the agent to the right alternative.

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

reframe_detectA
Idempotent

Propose a framing window per camera shot, from where the faces are.

Every placement is split at its camera cuts, each window sampled at a few moments and centred on the faces found. Against fifteen hand-framed, approved windows it beats the centre crop on every measure (0.755 mean overlap against 0.568).

It proposes; it does not frame. apply is off by default: the pass is still about a quarter of a window's width out on average, and a wrong window reads as framing in motion. Look at reframe_sheet before applying. Applying writes through reframe and never over an existing override.

A window with no face is refused, never guessed at — expect about one in seven — and nothing is written for it, so read falls_back_to: at a clip's head that is the centre crop, anywhere else the previous shot's framing. Nothing here chooses the subject either.

A window one crop cannot hold comes back as a stacked split (rect and pane). Read subjects (per frame), not faces, which sums detections across samples and calls one face three. Needs PROOFCUT_FACE.

ParametersJSON 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.
applyNoWrite the proposals through `reframe`. Off by default — the opposite of `cut --plan` — because the pass runs 24% of a window's width out on average. Call `reframe_sheet` and look first. It never writes over a window that is already an override.
splitNoOffer a stacked split where every sampled frame holds two or three faces one window cannot hold. On by default; `false` turns the offer off.
framesNoHow many moments to sample inside each window before centring it on the faces found there.
clip_idNoPropose windows for one clip. Omit it for every placed clip.
thresholdNoHow strong a scene change has to be to count as a camera cut, 0–1. 0.15 is pinned by judging detections on real footage: every candidate from 0.141 to 0.244 was a real cut, and the first non-cut is 0.137.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already mark this as non-read-only, idempotent, and non-destructive, and the description adds substantial behavioral detail beyond those: apply is off by default, refused windows produce no output, falls_back_to behavior at clip heads vs elsewhere, stacked splits, and the PROOFCUT_FACE dependency. It also clarifies the non-destructive 'never over an existing override' behavior, which is consistent with destructiveHint=false.

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 long but front-loaded with the core purpose and then organized into behavioral warnings, edge cases, and dependencies. Some benchmark statistics and repeated accuracy caveats are arguably extra, but they earn their place by justifying why apply is off by default and why review is needed.

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 complex proposal tool with six optional parameters, an output schema, and several edge cases, this description covers the essential invocation context: what gets proposed, what is refused, what fallback behavior to expect, how splits work, and the required environment variable. The presence of an output schema means return-value documentation is not needed in the description.

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 all six parameters thoroughly. The description adds useful behavioral context for apply and split, and warns about reading subjects rather than faces, but it does not need to compensate for missing parameter docs. 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?

The first sentence states a specific action and resource: 'Propose a framing window per camera shot, from where the faces are.' It further distinguishes itself from the apply step with the explicit contrast 'It proposes; it does not frame,' making its role among siblings like reframe and reframe_sheet clear.

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?

The description makes the workflow obvious: proposals are not applied by default, one should 'Look at reframe_sheet before applying,' and applying writes through reframe. It does not explicitly enumerate all sibling alternatives or say 'use reframe_detect when...', but the propose-vs-apply framing and the reference to reframe_sheet give strong contextual guidance.

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

reframe_sheetA
DestructiveIdempotent

Draw every placement's framing window on its own source frames.

A framing decision is unreviewable without this. The hand-framed teaser had 2 of its 15 windows wrong and neither was visible in motion — a badly-placed window reads as framing. Drawn on the whole source frame, what the window leaves out sits right beside it.

Every placement the render shows is walked window by window, the window in force drawn in red and labelled with its rect. A row is a window shown, not a placement: each placement is split at the boundaries it crosses, so a window covering a small slice of a long placement still gets a row. window on a row is the source address reframe --src-start takes; windows is how many the whole placement crosses. Stills come back under skipped — a card is re-authored, never cropped.

A tile is evidence about an instant, not an approval of the span. A static rect over a moving subject has a best moment and a sample can land on it; extremes draws where the subject is leftmost, median and rightmost instead, worst first, with worst_offset on the row to sort by.

A page of rows comes back as an image, six windows by default, at a width vision reads verbatim; row keeps its project-wide number on every page. per_page: null is the whole project as a PNG path, for a person.

ParametersJSON Schema
NameRequiredDescriptionDefault
outNoWrite the image to this path as well, replacing whatever file is there. Unset, it goes to the project's own sheet cache and only the bytes come back.
pageNoWhich page of rows to draw, from 1. Unset, the first.
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.
momentsNoFractions of each window to draw tiles at, e.g. `[0.1, 0.5, 0.9]`. A tile is evidence about one instant while a rect is a claim about a stretch, so where the subject moves these decide what the sheet can see. Refused alongside `extremes`.
extremesNoDraw the subject's own leftmost and rightmost moments, worst first, instead of fixed fractions — the rect does not move inside a stretch, so that is where a static window is worst. Off by default: it costs the face detector and about half a second a probe. Read `worst_offset` beside `multi_face`, never after it.
per_pageNoRows per page. `null` draws the whole project in one montage, which returns a path rather than readable bytes — for a person to open, not for an agent to read.

TDQS

A3.6/5.0
Behavior4/5

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

The description adds significant behavioral detail beyond the annotations: the `out` parameter replaces any existing file (destructive), `extremes` costs face-detection time (~half a second a probe), and `per_page: null` returns a path for a person rather than readable bytes. It also clarifies row semantics and skipped stills. This matches the idempotent/destructive annotations and provides operational insights without contradiction.

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

Conciseness2/5

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

The description is much longer than necessary and uses metaphorical language ('A tile is evidence about an instant, not an approval of the span') that adds literary style but not operational clarity. It is front-loaded with the purpose, but subsequent paragraphs contain rationale and tangential details (e.g., 'A badly-placed window reads as framing.') that do not directly help an agent invoke the tool. It could be condensed and structured more clearly.

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 tool with 6 parameters and no output schema, the description covers the key behavioral aspects: how windows are drawn, row splitting across placement boundaries, skipped stills, extremes selection, pagination, and the difference between returning bytes vs. a path. It is thorough enough for an AI agent to understand the tool's behavior, though it omits edge cases like empty projects or error conditions.

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?

With 100% schema description coverage, the baseline is 3, but the tool description enriches several parameters: `moments` are explained as 'evidence about one instant,' `extremes` draws leftmost/median/rightmost worst-first with `worst_offset`, and `per_page: null` is explicitly for human consumption. These additions go beyond the schema's own descriptions and aid correct parameter selection.

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

Purpose4/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: 'Draw every placement's framing window on its own source frames.' This clearly distinguishes the tool from likely siblings like `reframe` or `reframe_detect`, which probably perform the actual reframe, though it does not explicitly name alternatives. The heavy use of domain jargon ('placement', 'framing window') may require background knowledge but does not obscure the core purpose.

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

Usage Guidelines3/5

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

The description gives a strong contextual reason to use the tool ('A framing decision is unreviewable without this') and explains the informational value of the drawn windows. However, it does not explicitly contrast the tool with sibling visualization tools (e.g., `footage_sheet`, `contact_sheet`) or provide conditions for when not to use it. The guidance is contextual but lacks explicit alternatives or exclusions.

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

resolve_phraseA
Read-onlyIdempotent

Resolve a phrase to a word range against clip_id's transcript.

What phrase= on cue_add/cue_rm/unspoken_add/unspoken_rm/vo_extend/music/ locate calls internally, exposed on its own so a resolution — including its full ambiguity list — can be inspected without attempting a write. Companion to get_transcript with search=, which lists every match with no cursor/occurrence/fuzzy; this picks exactly one, or explains why it can't.

after skips matches at or before that word index (forward cursor, -1 means from the start). More than one exact match with no occurrence given fails with every candidate's word range and text — pass occurrence (1-based) to pick one, or narrow the phrase. Zero exact matches falls back to a fuzzy match (fuzzy=False to refuse instead) — ratio is set only on a fuzzy hit, never disguised as exact. Read-only.

ParametersJSON 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.
afterNoA forward cursor over a phrase's matches: any match at or before this word index is skipped. -1, the default, means from the start.
fuzzyNoFall back to a fuzzy match when nothing matches exactly. A fuzzy hit sets `ratio` and is never reported as an exact one; `false` refuses instead.
phraseYesThe words to find, as they were spoken.
clip_idYesThe transcript to resolve against.
occurrenceNoDisambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — rather than guessed at.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

Beyond the readOnlyHint/idempotentHint/destructiveHint annotations, the description discloses important edge-case behavior: ambiguous matches fail and list candidates, fuzzy fallback sets ratio and is never disguised as exact, and the after cursor skips matches at or before a word index. The explicit 'Read-only' statement is consistent with the annotations.

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 front-loaded with the core purpose and is dense with useful information, but it runs to four paragraphs and slightly repeats details already present in the input schema. Still, each paragraph contributes real behavioral or usage context, so it remains tight for the tool's complexity.

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 6-parameter resolver with ambiguity handling, fuzzy fallback, cursor semantics, and a read-only inspection role, the description covers all critical behavior an agent needs to invoke it correctly. An output schema exists, so not detailing return values is acceptable.

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%, and the parameter descriptions already explain after, occurrence, fuzzy, clip_id, phrase, and path in detail. The tool description mostly restates key semantics rather than adding new parameter-level meaning, so the baseline of 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?

The opening sentence states a specific verb, resource, and result: 'Resolve a phrase to a word range against clip_id's transcript.' It further distinguishes itself from get_transcript and explains its role as the internal resolver behind phrase= on several mutation tools, so an agent can tell exactly what it does.

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 explicitly contrasts this tool with get_transcript's search= mode: that tool lists every match, while this one picks exactly one or explains why it cannot. It also says it is exposed for inspecting a resolution without attempting a write, giving a clear when-to-use signal versus the mutation tools that call phrase= internally.

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

restoreA
DestructiveIdempotent

Un-cut whichever part of these inclusive word ranges is not currently in the timeline.

Same range shape as cut_by_transcript's cut=/keep=. Each range resolves to source time exactly like a cut does; only the part Edit.gaps says is actually absent comes back — material still present in the request is left alone, a request spanning two separate cuts restores both as separate pieces, a request only touching part of one cut restores only that part. Restoring only ever brings back material the source recording already has (bounded by the clip's own registered duration), so the timeline stays a subset of the source throughout — this is not vo_extend (PLAN.md parks that separately), which would add material the source never had.

pad matches cut_by_transcript's own pad: pass the same value used on the original cut to bring back its padding sliver, not just the words.

Unlike a cut, there is no suspect-duration refusal — a boundary that looks like it swallowed a retake is exactly the kind of thing restore exists to bring back, not a mistake to guard against.

Refused if clip_id has no surviving segment anywhere in the edit (nothing left of it to splice the range next to — undo or re-seed instead), or if its segments are not contiguous in the edit (an interleaved multi-source timeline, which restore does not support yet).

plan=True resolves and reports without writing, identically to cut_by_transcript.

ParametersJSON Schema
NameRequiredDescriptionDefault
padNoPass the same `pad` the original cut used to bring its padding sliver back, not only the words.
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.
rangesYesInclusive word ranges, the shape `cut_by_transcript` takes. Only the part the edit says is actually absent comes back; material still present is left alone.
clip_idYesThe clip whose cut material to bring back.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare destructiveHint=true and readOnlyHint=false, but the description adds substantial behavioral detail: it explains partial restoration, multiple-cut handling, padding sliver recovery, the subset-of-source constraint, and the refusal conditions. It explicitly contrasts with vo_extend and notes the plan mode writes nothing. No contradiction with annotations; idempotentHint=true aligns with 'material still present is left alone.'

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 long but well-structured and front-loaded with the core purpose. It flows logically from the primary function to range behavior, pad handling, differences from cuts, refusal conditions, and plan mode. Every sentence adds meaningful context; it is not bloated with fluff, though it could be tightened slightly for brevity.

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 tool of this complexity, the description covers all necessary aspects: what it does, how ranges behave, pad semantics, differences from cut, refusal conditions, and plan mode. It references the output schema exists, and the description does not need to explain return values since an output schema is present. It is complete for an agent to call 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?

The input schema already provides 100% coverage with detailed descriptions for every parameter, including pad, ranges, and clip_id. The tool description reiterates some of these (e.g., 'pad matches cut_by_transcript's own pad') but adds little beyond what the schema states. It offers helpful context on range resolution, but since the schema already does the heavy lifting, a baseline of 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?

The description opens with a clear verb-resource pair: 'Un-cut whichever part of these inclusive word ranges is not currently in the timeline.' It explicitly states the tool's purpose (restoring removed material) and distinguishes it from siblings like cut_by_transcript and vo_extend, leaving no ambiguity about what it does.

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 and when-not-to-use guidance. It names vo_extend as the alternative for adding material the source never had, notes the absence of suspect-duration refusal that a cut would have, and lists two refusal conditions (no surviving segment or non-contiguous segments) with the fallback actions (undo or re-seed). It also recommends plan=True for preview.

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

review_addA
Destructive

Register a rendered file, sheet or A/B member for proofcut review serve.

Never copies source — a render already lives in renders/, a sheet in reframe_sheet's own directory — this just points name at it, so a served round has something to stream and a verdict has something to attach to.

Registering a name that already exists replaces that entry, and the verdict recorded against it stays — so re-pointing a name at a different file leaves yesterday's answer attached to today's bytes. Register the new file under a new name unless replacing it is what you mean.

kind is one of render, sheet, ab, control. A control requires baseline, the name of an already-registered item, and the two files' sha256 must match — a mismatch refuses the call. This is the rule the round that went wrong exists to enforce (HISTORY.md § The bumper the teaser never had): a page once served three cuts, one mislabelled "control" when it was a different, later render. Nothing is labelled a control here unless it is byte-identical to what it claims.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindYesOne of `render`, `sheet`, `ab`, `control`.
nameYesWhat to call this item in the served round. Re-using a name replaces that entry while its verdict stays attached.
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.
sourceYesThe file to point at — never copied. A render already lives in `renders/`, a sheet in the sheet directory.
baselineNoRequired for `kind="control"`: the name of the already-registered item this one claims to be identical to. Both files' sha256 must match or the call is refused — nothing is labelled a control here unless it is byte-identical to what it claims.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

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 the annotations (destructiveHint=true) by detailing that registering an existing name replaces that entry while keeping its verdict, and that a control requires byte-identical sha256 or the call is refused. It also explains the non-copying behavior and the historical rationale. This is rich, specific behavioral disclosure that matches the destructive hint.

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 well-structured: it states the core purpose in the first sentence, then clarifies non-copying, then explains replacement semantics, and finally details the control rule with a historical note. Every sentence earns its place; nothing is redundant. It is appropriately sized for the complexity.

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 presence of an output schema and rich annotations, the description covers all essential operational aspects: behavior, side effects, constraints, and usage context. It even includes a rationale for the control rule. An agent has everything needed to invoke this tool correctly without further lookup.

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?

With 100% schema coverage, the baseline is 3, but the description adds substantial meaning: it explains that `source` is never copied, that re-using `name` replaces the entry with verdict retention, that `baseline` is required for controls with sha256 enforcement, and that `path` resolves against the bound project or refuses outside it. This enriches every parameter beyond the schema.

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 clear verb+resource statement: 'Register a rendered file, sheet or A/B member for `proofcut review serve`.' It explicitly states what the tool does and its domain. It distinguishes from sibling review tools (review_verdict, review_list) by focusing on registration and clarifying that it never copies source files.

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?

The description gives clear context on when to use it: when a render already exists and needs to be pointed at for review. It explains that it never copies and that a control requires a baseline with sha256 match. It implicitly distinguishes from alternatives like review_list (to view) and review_verdict (to judge) but doesn't explicitly name them. Still, the guidance is sufficient for an agent to decide when to call this tool.

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

review_listA
Read-onlyIdempotent

List every item registered for this project's review round, and its verdict.

Read-only. Returns items (each review_add registration: name, kind, project-relative path, sha256 and any control baseline) and verdicts (keyed by item name: the verdict, its note and when it was recorded). Items are registered with review_add, judged with review_verdict, and served to a phone by proofcut review serve.

ParametersJSON 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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description confirms read-only and adds detail on the return structure (items and verdicts). It does not disclose additional behavioral traits beyond the annotations, so a baseline 3 is appropriate.

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 two sentences, front-loaded with the core purpose, then the return shape, then workflow context. Every sentence adds value without redundancy. No fluff or unnecessary detail.

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?

The tool is a simple list operation with one well-documented parameter, safety covered by annotations, and an output schema. The description explains the return structure and how it relates to sibling tools, which is complete for an agent to invoke it correctly. Nothing essential is missing.

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?

Only one optional parameter (path) exists, and its schema description covers 100% of its semantics, including default behavior and binding rules. The tool description adds no additional parameter guidance, so it relies on the schema. Baseline 3 is correct given the high schema coverage.

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?

States a specific verb ('List') and resource ('every item registered for this project's review round, and its verdict'). The description distinguishes it from siblings like review_add (registration) and review_verdict (judging) by clearly scoping its function. It leaves no ambiguity about what the tool does.

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?

Provides context on how it fits into the review workflow by mentioning review_add and review_verdict. It implies when to use it (to inspect registrations and verdicts) but does not explicitly state exclusions or alternative conditions. The related-tools note gives enough situational awareness for an agent to select it appropriately.

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

review_verdictA
DestructiveIdempotent

Record a verdict against a review item registered by review_add.

verdict is a free string, not an enum — past review rounds answered yes/no, "loop"/"hold", or a specific choice by name, and a fixed vocabulary would misfit whichever question the next round is actually asking.

Refuses a name review_add has not registered. Calling it again for the same item replaces that item's answer rather than appending one, so a round holds one verdict per item, with the time it was recorded.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesThe registered item being answered. An unregistered name is refused.
noteNoAnything to record beside the verdict.
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.
verdictYesThe answer, as free text rather than an enum — past rounds answered yes/no, loop/hold, or a specific choice by name, and a fixed vocabulary would misfit whichever question the next round asks.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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

Beyond annotations, the description discloses refusal of unregistered names, replacement rather than appending, one-verdict-per-item semantics, and that the recorded time is part of the state. This gives the agent a clear picture of side effects without relying on inference.

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 purpose is front-loaded in the first sentence, and the rest provides important behavioral context. The free-text rationale is slightly repetitive with the verdict parameter description, but all sentences earn their place.

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 output schema and complete input schema, the description covers the registration prerequisite, free-text semantics, replacement behavior, refusal case, and timestamp side effect. An agent has enough information to select and invoke the 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 coverage is 100%, and each parameter already has a detailed description, including nuanced path behavior. The description mostly reiterates the verdict free-text rationale from the schema rather than adding new parameter-level meaning, so the baseline 3 applies.

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 states a specific action ('Record a verdict') against a specific resource ('a review item registered by review_add'). This clearly distinguishes it from sibling tools like review_add (registration) and review_list (listing).

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?

The description makes the prerequisite explicit: the verdict must be against an item already registered by review_add. It gives clear context for when this tool is appropriate, though it does not explicitly name alternatives or 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.

seed_timelineA
DestructiveIdempotent

Lay a clip down as the timeline, silence-cut by auto-editor by default.

edit_expr passes auto-editor's edit language straight through, e.g. "(or audio:0.03 motion:0.06)".

Writes project.otio and replaces any timeline already there — every cut made since the last seed included. It seeds a project rather than re-cutting one, and a re-seed with the same arguments lands the same timeline. The old one is snapshotted first, so undo puts it back.

ParametersJSON 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.
marginNoHow much to leave either side of kept audio, in auto-editor's own notation (e.g. `0.2s`), so an edge lands in the silence rather than on the breath.
clip_idYesThe clip to lay down as the timeline.
edit_exprNoauto-editor's edit language, passed straight through — e.g. `(or audio:0.03 motion:0.06)`. It replaces the threshold-based rule.
thresholdNoauto-editor's audio loudness threshold, 0–1. Lower keeps quieter material.
remove_silencesNoSilence-cut the clip on the way in, through auto-editor. On by default; false lays the whole clip down untouched.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and idempotentHint=true; the description builds on these by explaining exactly what gets destroyed ('replaces any timeline already there, every cut made since the last seed included') and how recovery works ('snapshotted first, so undo puts it back'). It also confirms idempotence ('a re-seed with the same arguments lands the same timeline'). This adds genuine context beyond the structured hints, though it doesn't contradict them.

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?

Four sentences with the core action front-loaded in the first line, followed by the edit_expr usage, then side effects. No filler or redundant restatement of the name; every sentence earns its place and the most important behavioral warnings appear early.

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?

Given an output schema exists, return values need no description. With 100% schema coverage on six parameters and rich behavioral notes on the destructive/idempotent nature, the description is complete for an agent deciding whether and how to call it. Only minor omissions, such as explicit permission requirements, keep it from a 5.

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 baseline is 3. The description reinforces edit_expr ('passes auto-editor's edit language straight through') with an example and clarifies margin's purpose, but it largely echoes what the schema already documents. It adds modest value rather than compensating for gaps, so 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?

Opens with a specific verb-plus-resource statement: 'Lay a clip down as the timeline, silence-cut by auto-editor by default.' It also distinguishes itself from the cut_by_* and timeline_* siblings by framing the action as seeding a project rather than re-cutting one, so an agent can tell it apart without opening 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?

Gives an explicit when-not: 'It seeds a project rather than re-cutting one,' which separates it from cut_by_transcript/cut_by_time. It also warns it replaces any existing timeline, which sets expectations about when a call is appropriate. It does not name specific sibling alternatives, but the exclusion is concrete enough.

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

shot_sheetA
DestructiveIdempotent

Look at the picture track — one labelled tile per shot, as an image.

This is the tool to call to see what the film looks like — the picture track of the edit as it stands. Its neighbours answer different questions with the same kind of picture: footage_sheet browses one registered clip's own material, contact_sheet looks at a clip's first ten seconds, and reframe_sheet reviews framing windows a page at a time. All four hand the bytes back, because an agent confined to proofcut's tools (the agent panel's --tools ToolSearch) can open no path at all.

One tile per shot, at the exact source second that shot reads from, four across and about two dozen a page — the measured ceiling before vision downscales the sheet and takes the labels with it. Each tile is labelled asset t=<timeline second>s src=<source second>s, and page walks a longer film.

asset on a row is the footage; clip_id is the transcript the cue is addressed against, which on a voiceover project is the VO and not anything you can see. Read asset.

Drawn from the same projection export renders, so a plan that refuses comes back as shots_error with no sheet rather than a picture of a film that will not render.

What you see here is a hypothesis, not a check. Nothing downstream reads a verdict formed off this sheet — confirm one with an op that measures (check_frames, verify, black, reframe_coverage).

out is the one thing here that writes where you say: the montage lands at that path, replacing whatever file is there. Without it a page is written into the project's own sheet cache, which nothing reads back as authored state.

ParametersJSON Schema
NameRequiredDescriptionDefault
outNoWrite the image to this path as well, replacing whatever file is there. Unset, it goes to the project's own sheet cache and only the bytes come back.
pageNoWhich page of rows to draw, from 1. Unset, the first.
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.
per_pageNoRows per page. `null` draws the whole project in one montage, which returns a path rather than readable bytes — for a person to open, not for an agent to read.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations indicate `destructiveHint: true` and `readOnlyHint: false`. The description goes beyond these flags by detailing the destructive case: 'the montage lands at that path, replacing whatever file is there.' It also discloses that all four sibling tools 'hand the bytes back' and that the sheet is a hypothesis ('What you see here is a hypothesis, not a check'), plus explains rendering failure behavior (`shots_error`). No contradiction with annotations.

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 long but well-organized, opening with the core purpose, then differentiating siblings, then diving into tile mechanics, labels, rendering pitfalls, and parameter notes. Every section adds necessary context; it is not padded. It could be slightly tightened (e.g., merging some repeated mentions of 'four' and 'two dozen'), but the structure supports comprehension.

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 tool with four parameters, no output schema, and complex behavioral nuances (destructive write, rendering failure, hypothesis status, page navigation, asset-vs-clip distinction), the description covers all critical aspects. It explains what the agent will receive (bytes, or a path if `per_page` is null), how to handle the output, and warns against using it as a verdict. Nothing an agent needs to call 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?

Schema coverage is 100%, but the description adds substantial meaning. For `out`, it clarifies it writes and replaces a file; for `page`, it says 'walks a longer film'; for `per_page`, it explains that `null` returns a path for a person, not an agent; for `path`, it covers project binding behavior and refusal cases. This extra context makes the parameters safer and clearer to use.

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 clear statement: 'Look at the picture track — one labelled tile per shot, as an image.' It names the resource (picture track of the edit) and the action (look at). It then explicitly differentiates from siblings (`footage_sheet`, `contact_sheet`, `reframe_sheet`) by describing what each neighbor does instead, leaving no ambiguity about this tool's unique role.

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?

It states 'This is the tool to call to see what the film looks like' and contrasts with siblings: 'footage_sheet browses one registered clip's own material, contact_sheet looks at a clip's first ten seconds, and reframe_sheet reviews framing windows a page at a time.' It also warns this is a hypothesis, not a verification, and points to measurement tools (`check_frames`, `verify`, `black`, `reframe_coverage`) for confirmation. This gives explicit when/when-not guidance.

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

speech_overlapA
Read-onlyIdempotent

Does a proposed placement of clip_id overlap the VO's speech?

The prerequisite check behind "can this clip speak here?" — answer it before designing any ducking. at/clip_in/clip_out describe where clip_id would sit on the timeline (defaults: unplaced at 0, its whole duration) — the clip need not be on the timeline yet, and usually isn't, since the current model is single-track. VO's own words map through the existing edit (Edit.timeline_span); clip_id's map by offsetting into the proposed window instead. Both sides are trimmed with energy.believable first — an inflated word duration can hide a real seam — then merged into speech runs with max_gap tolerance, since a 0.05s gap is not a usable seam.

Read overlaps first: any entry means placing clip_id there would step on VO speech, not empty air — this caught exactly that on Billy/Stu, where the clip's speech nearly fully covered a VO thesis line with no clean seam to duck into. clean_seams (>= min_seam wide) are the windows where clip_id could speak without touching the VO. Read-only — nothing is written, and there is no plan=.

clip_id need not have a transcript. Without one the clip side is its energy envelope — runs of sound, reported as sound rather than speech (a sting or a swell counts too) — and clip_evidence in the result says "energy" so the reading is not mistaken for a word-level one. Pass clip_evidence="transcript" to refuse instead, or "energy" to force the envelope on a clip that has a transcript. The VO always needs its transcript.

ParametersJSON Schema
NameRequiredDescriptionDefault
atNoWhere the clip would sit on the timeline, in seconds.
capNoHow far a word's claimed duration is trusted, as a multiple of the median. Whisper inflates the word after a collapsed retake until it covers the second take, so believing the claim masks exactly the hole being looked for — 3x is the same multiple a suspect duration is flagged at.
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.
clip_idYesThe clip whose placement is being proposed. It need not be on the timeline yet, and usually is not.
clip_inNoWhere inside the clip the proposed placement starts, in its own source seconds. Unset, its head.
max_gapNoHow short a silence may be and still be swallowed into one speech run, in seconds — a 0.05s gap is not a usable seam.
clip_outNoWhere it ends, in the clip's own source seconds. Unset, its end.
min_seamNoHow wide a gap has to be to be reported as a `clean_seam`, in seconds.
vo_clip_idNoWhich transcript is the VO. Unset, the project's own. The VO always needs a transcript; the placed clip does not.
clip_evidenceNo`auto` (the default) uses the clip's transcript if it has one and its energy envelope otherwise, saying which in the result. `transcript` refuses a clip with none; `energy` forces the envelope even on a clip that has one — sound rather than speech, which counts a sting or a swell too.auto

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond that: it explains the trimming with `energy.believable`, the merging into speech runs with `max_gap` tolerance, and the read-only nature ('nothing is written, and there is no `plan=`'). It also discloses the fallback behavior when `clip_id` lacks a transcript, which is a meaningful behavioral trait not visible in the schema. Minor gap: it doesn't describe the exact result shape beyond `overlaps`, `clean_seams`, and `clip_evidence`, but the output schema exists.

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 long but every paragraph earns its place: the first paragraph states the core question and the mapping logic, the second explains the output semantics and the real-world catch, the third covers the transcript/energy fallback. It is front-loaded with the purpose and read-only note. It loses one point for density—some sentences are packed with domain jargon ('energy.believable', 'speech runs', 'seam') that could be tightened—but it is not bloated or repetitive.

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 complex 10-parameter tool with an output schema, the description is remarkably complete. It explains the default placement semantics, the single-track model assumption, the trimming and merging pipeline, the meaning of `overlaps` and `clean_seams`, the transcript/energy fallback, and the read-only guarantee. The output schema covers return values, so the description doesn't need to enumerate them. An agent has everything needed to decide when to call this tool and how to interpret its result.

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 description coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by explaining the conceptual role of `at`/`clip_in`/`clip_out` as describing where `clip_id` would sit on the timeline, and how the clip's words map by offsetting into the proposed window. It also explains the rationale behind `max_gap` ('a 0.05s gap is not a usable seam') and `cap` (Whisper inflation), which the schema descriptions only hint at. It doesn't restate every parameter, but it adds interpretive context that helps an agent choose values correctly.

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 direct question—'Does a proposed placement of `clip_id` overlap the VO's speech?'—which precisely states the tool's verb, resource, and purpose. It distinguishes itself from siblings by framing it as the prerequisite check behind 'can this clip speak here?' and explicitly notes it is read-only with no `plan=`, separating it from planning or editing tools.

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: 'answer it before designing any ducking.' It also explains the clip need not be on the timeline yet and usually isn't, since the current model is single-track. It clarifies when to pass `clip_evidence` values ('Pass `clip_evidence="transcript"` to refuse instead, or `"energy"` to force the envelope'), and notes the VO always needs a transcript. This is strong routing and exclusion guidance.

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

spot_framesA
Read-onlyIdempotent

Pull count evenly-spaced frames (plus any explicit times) from a render as PNGs with signalstats luma, ranked darkest-first.

When target's own probed duration still matches the current timeline within a frame (mapping_trusted), each frame also reports which clip/word it lands near via Edit.source_at — refused, not guessed, when the render looks stale.

Like shot_sheet/footage_sheet/contact_sheet, the reply also carries a montage of the sampled frames as an image — frames[].png is a path, and an agent confined to proofcut's tools (the agent panel's --tools ToolSearch) has no Read to open one (TRIAL.md § spot_frames hands back paths the agent cannot open).

ParametersJSON Schema
NameRequiredDescriptionDefault
fpsNoThe rate used to map a frame back to the clip and word it lands near — refused rather than guessed when the render's duration no longer matches the timeline.
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.
countNoHow many evenly-spaced frames to pull. They come back ranked darkest-first, with a montage of them as an image.
timesNoExplicit seconds to sample as well as the evenly-spaced ones.
targetYesThe render to pull frames from.

TDQS

A4.2/5.0
Behavior5/5

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

Beyond the readOnly/idempotent/non-destructive annotations, the description adds crucial behavioral detail: mapping is refused rather than guessed when the render is stale, and the returned PNG paths cannot be opened by an agent limited to proofcut tools. This significantly improves an agent's ability to predict tool behavior.

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 each sentence earns its place: core operation, trust/mapping behavior, and output/agent-access limitation. It is longer than minimal, but that length is justified by genuinely useful caveats; the first sentence front-loads the primary action.

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?

With no output schema, the description compensates by explaining the key return aspects: PNG frames, montage, darkest-first ranking, and per-frame source mapping. It also warns about the agent's inability to open returned paths, which is critical context for a proofcut-bound agent. Inputs, outputs, and edge-case behavior are all covered.

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 coverage is 100%, so the schema already documents all five parameters thoroughly. The description reuses `count`, `times`, and `target` but does not add much meaning beyond what the parameter descriptions already provide; the baseline of 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?

The description opens with a specific, concrete operation: pull `count` evenly-spaced frames (plus `times`) from a render as PNGs with signalstats luma, ranked darkest-first. This clearly identifies the tool's resource and behavior, and the sibling references (shot_sheet/footage_sheet/contact_sheet) place it in a family without obscuring its distinct purpose.

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

Usage Guidelines3/5

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

The description signals that it belongs with sheet-like tools by naming shot_sheet/footage_sheet/contact_sheet, but it never states when an agent should choose spot_frames over those siblings. The mapping_trusted caveat describes behavior, not selection criteria, so usage guidance is implied rather than explicit.

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

synopsisA
DestructiveIdempotent

Read, set or clear what a clip is — the corpus b-roll gets chosen from.

No clip_id lists every clip's synopsis and which are missing one; clip_id alone reads one; text writes; clear removes.

A synopsis is a different fact from a describe window. A description says what is in front of the camera — rooms, clothing, lighting. A synopsis says what the footage is: the work, the scene, the people, and whatever else decides whether it belongs under a sentence. It is meant to carry what no camera can see, because that is where the signal turned out to be — measured on real footage, the vision index chose the same clip a human did 2 times in 25, and this catalogue read by something that knows the material chose it 13.

Write these yourself. Nothing generates them: a model looking at the pixels cannot, and guessing a title from a filename would produce confident wrong placements rather than an obviously empty catalogue.

ParametersJSON 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.
textNoWhat this footage **is** — the work, the scene, the people. A different fact from a `describe` window, which says what is in front of the camera. Write it yourself: nothing generates one, because a model reading the pixels measurably cannot.
clearNoRemove this clip's synopsis.
clip_idNoThe clip to read or write. Omit it to list every clip's synopsis and which are missing one.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already provide idempotentHint=true and destructiveHint=true (with readOnlyHint=false), and the description adds genuine value on top: omitting clip_id lists all clips' synopses, clip_id alone reads, text writes, clear removes. It also discloses the destructive nature of `clear` in plain terms and explains the expected agent behavior (write synopses, don't guess from filenames). No contradiction with annotations.

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 front-loaded: purpose and operational modes come in the first two short paragraphs, followed by the describe distinction and the write-it-yourself directive. The statistical anecdote (2 in 25 vs 13) is slightly tangential but earns partial keep by motivating why careful synopsis writing matters. A bit longer than strictly necessary, but every section serves the agent's decision to invoke and write well.

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 four-optional-parameter multi-mode tool, the description covers all operation modes, the key sibling distinction, and the expected authoring behavior. An output schema exists so return values need not be spelled out, and annotations carry the safety profile. Minor omissions like error behavior for unknown clip_ids are acceptable given the annotation and schema richness.

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, but the description adds the mode semantics that the schema does not: how to combine the four optional parameters to get list, read, write, or clear behavior (no clip_id → list; clip_id alone → read; text → write; clear → removes). It also reinforces the meaning of `text` as carrying what no camera can see, beyond the schema's wording.

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 first line states a specific set of verbs (read, set, clear) on a specific resource (a clip's synopsis), defined as 'what a clip *is* — the corpus b-roll gets chosen from.' It explicitly differentiates itself from the sibling `describe` tool, telling the agent that a synopsis is a different fact from a describe window. An agent can immediately distinguish this from describe_ls and clip_role.

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?

The description clearly draws the when-to-use line against `describe`: descriptions say what is in front of the camera, synopses say what the footage is and whether it belongs under a sentence. It also gives the operational rule 'write these yourself,' warning that nothing generates them. It does not enumerate other sibling alternatives, but the key exclusion (describe) is explicit and central.

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

tailA
DestructiveIdempotent

Read or change the finishing pass this project plays after its last frame.

An end card or a bumper, applied by export itself rather than glued on afterward with ffmpeg — the fix for a defect that has already shipped: a finishing pass applied downstream of export is dropped by every derivation at exit 0, silently, because nothing in the project ever knew it existed (HISTORY.md § The bumper the teaser never had, § The end card). Call it with no arguments to read what is in force.

asset must be card:name, never a clip_id — verify diffs a render's own transcription against the timeline's words, and silence adds none of its own, which is exactly what a card behind it guarantees and a media clip would not. seconds is the tail's whole length, card included, not a hold with fade added on top of it (the known trap: xfade finishes exactly at the length it is given). fade is recorded and echoed but not yet drawn — this build cuts to the card hard, at seconds.

Setting asset or seconds for the first time needs both together; either alone after that updates just that field, the same partial-update shape caption_style has. reset drops the tail entirely.

Needs an existing picture cue lane covering the whole film — add cues first (cue_add) if the project does not have one; export names why otherwise. plan resolves and validates without writing.

ParametersJSON Schema
NameRequiredDescriptionDefault
fadeNoRecorded and echoed, not yet drawn: this build cuts to the card hard, at `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.
planNoResolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it.
assetNoThe end card or bumper, as `card:name` — never a clip id. `verify` diffs the render's own transcription against the timeline's words, and a card behind silence adds none of its own, which a media clip would.
resetNoDrop the tail entirely. Note a derivation inherits none of it anyway and reports `tail_dropped`.
secondsNoThe tail's **whole** length, card included — not a hold with `fade` added on top of it.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A5/5.0
Behavior5/5

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

Annotations already indicate mutability, idempotency, and destructiveness, but the description adds substantial behavioral context: the finishing pass is applied by `export` itself, the fix for a shipped defect, that `fade` is recorded but not drawn (cuts hard at `seconds`), that first-time setting of `asset`/`seconds` requires both together, and that `reset` drops the tail. This goes well beyond the annotation flags.

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. It front-loads the core purpose, then layers parameter semantics, edge cases, and prerequisites in a logical flow. Bold emphasis on the cue-lane requirement and use of inline code for parameters aid scanning. No fluff or redundancy.

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 tool with six parameters, non-trivial interactions, and integration with `export` and `verify`, the description covers all necessary angles: read/write behavior, partial-update rules, reset semantics, `plan` safety, and prerequisites. It even references HISTORY.md for deeper context. With an output schema present, nothing an agent needs to call 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?

Although schema descriptions cover all six parameters at 100%, the tool description adds deep meaning beyond them: for `asset`, it explains why it must be `card:name` and the verify rationale; for `seconds`, it clarifies the whole-length semantics and the `xfade` trap; for `fade`, it discloses it's not yet drawn; for `plan`, it says it resolves and validates without writing. These enrich the schema with critical domain logic.

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 precise verb and resource: 'Read or change the finishing pass this project plays after its last frame.' It immediately distinguishes itself from siblings like `export` (which applies the pass) and `finish_report` (which likely reports on it). The phrase 'end card or bumper' and 'applied by export itself rather than glued on afterward' clearly define the tool's unique scope.

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 provides explicit guidance on when to use the tool: to read or set the finishing pass. It warns about the `xfade` trap, explains the prerequisite of an existing picture cue lane and directs to `cue_add` if missing, and recommends `plan` to validate without writing. It also clarifies the partial-update semantics and that `reset` drops the tail entirely, leaving no ambiguity about usage.

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

thumbnailA
Read-onlyIdempotent

One filmstrip frame for clip_id, at the source time nearest at.

at snaps to a multiple of interval before anything is extracted, and the frame is cached under cache/thumbs/ keyed by the clip's media size and mtime — a repeated ask for a nearby instant is a cache hit. The result is a path, not the image bytes; proofcut web serves those over /api/thumb/<clip_id>?at=. It never enters the manifest, so nothing that renders can reach it (the same wall the preview proxy has).

ParametersJSON Schema
NameRequiredDescriptionDefault
atYesSource seconds to pull the frame at. It snaps to a multiple of `interval` first, so a repeated ask for a nearby instant is a cache hit.
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.
clip_idYesThe clip to pull a frame from.
intervalNoThe grid `at` snaps to, in seconds.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already mark the tool read-only and idempotent. The description adds substantial behavior beyond that: `at` snapping, cache keys based on media size and mtime, cache-hit semantics, path output, and isolation from the manifest. There is no contradiction with the annotations.

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?

Purpose is front-loaded and the cache/output caveats are tightly written. The closing simile about the preview proxy is useful context but is the least essential sentence.

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 read-only retrieval tool with a rich output schema and fully documented parameters, the description covers the return contract (a path, not bytes), caching behavior, and render isolation. Nothing an agent needs 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.

Parameters3/5

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

The input schema already has 100% description coverage for all four parameters, including the `at` snapping and `path` binding behavior. The description repeats the snapping behavior but adds little new parameter-level meaning beyond what the schema already documents.

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 opening sentence identifies the exact resource and operation: a filmstrip frame for `clip_id` at source time `at`. It is clearly distinguished from render/manifest tools by stating the result is a path and that it never enters the manifest.

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?

The description gives clear operational context: it returns a cached path, and the actual bytes are served by `proofcut web` via a specific endpoint. It doesn't explicitly name alternative sibling tools, but the manifest exclusion and web-serving note provide a useful boundary for when this tool is appropriate.

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

timeline_statusA
Read-onlyIdempotent

Report the current timeline: duration, segment count, undo depth.

head/tail echo the cold open / finishing pass set with the head/ tail tools, or null for either with none. expected_frames/ expected_duration are what export would lay down — timeline_duration alone stays the Edit's own length even with a head or a tail configured, since the Edit never grows to describe either bookend.

This is the tool to call first, to see what state a project is in — a fresh or un-seeded project answers seeded: false with the clip list rather than refusing (TRIAL.md § timeline_status is the first call an agent makes and it refuses on a fresh project).

ParametersJSON 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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare read-only, idempotent, and non-destructive behavior. The description adds valuable context: head/tail echo semantics, expected_frames/expected_duration versus timeline_duration, and seeded:false behavior. However, the parenthetical 'it refuses on a fresh project' contradicts the earlier 'rather than refusing', creating ambiguity.

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 core purpose is front-loaded in the first sentence, and the head/tail and expected_duration details are substantive. The final TRIAL.md parenthetical is tangential and internally confusing, which prevents full marks for conciseness.

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?

An output schema exists and the description explains subtle return-value semantics and edge cases around head/tail, export, and seeded projects. The contradictory sentence about refusing on a fresh project leaves one behavioral area ambiguous, so completeness is slightly diminished.

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?

The single path parameter is fully documented in the input schema with 100% coverage, including default and binding behavior, so the description does not need to add parameter detail. It also does not repeat parameter semantics, matching the baseline expectation.

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?

States a specific verb 'Report' and resource 'current timeline', and enumerates concrete outputs: duration, segment count, undo depth. The scope is unambiguous and clearly differentiates this from state-mutating siblings like seed_timeline or cut tools.

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?

Explicitly identifies this as 'the tool to call first, to see what state a project is in' and explains the fresh/unseeded project behavior. It does not explicitly compare against alternatives like timeline_view or properties, so exclusions are absent, but the primary usage context is clear.

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

timeline_viewA
Read-onlyIdempotent

The whole edit at once: segments, cut seams, and every word's fate.

timeline_status counts things; this says what they are. Each segment carries both coordinate systems (source in, timeline out), each seam is named by the surviving words either side of it rather than by the second it currently sits at, and each word reports whether it survived, how much of it did, and where it now plays.

Survival is an overlap test, so a word a cut split reports present with partial set — that is normal on whisper timings, not a defect. Words with a suspect duration carry the same flag attach_transcript reported.

This is locate asked once for the whole clip instead of once per range, and it is what the proofcut web view draws. Read-only.

shots is the picture lane the cue table projects — null when there are no cues, and null with a shots_error message when the plan refuses (a cue that was cut, or a shot longer than the asset it points at). The refusal is reported here rather than raised, because this is the view a person uses to find the cue to fix. shots_rate is the frame grid it was quantised on, which is export's rate and not timebase.

segments/shots/seams stay Edit-relative even with a head configured — see head's own docstring for the two-clock rule. head_seconds is the offset a render-time reader needs (0.0 with none); head is the stored config plus its resolved frame count.

words is a window of limit from first (words_total, words_next); the lanes are always whole. get_transcript with search= finds a word faster than paging here.

ParametersJSON 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.
firstNoIndex into the `words` list to start the window at. 0 by default.
limitNoMost entries of `words` to return; `words_next` says where to continue. The segments, seams and shots are always whole.
clip_idNoThe transcript whose words' fate to report. A clip that is registered but not on the edit still answers — read `off_timeline`, or every word reads `present: false` and looks cut.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent, and the description adds substantial non-obvious behavior: partial survival is normal on whisper timings, shots refusals are reported not raised, segments/shots/seams stay edit-relative under head, and the shots_rate grid is export's rate not timebase. This goes well beyond the annotation baseline.

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 long and dense but front-loaded with a one-sentence summary and organized into clear thematic paragraphs. Some phrasing is poetic ('every word's fate', 'the picture lane the cue table projects') but generally every paragraph earns its place given the tool's complexity.

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?

The description covers edge cases thoroughly: partial survival, suspect durations, shots null/refusal behavior, head clock relativity, pagination windowing, and the search alternative. With an output schema present and detailed input schema, an agent has everything needed to call and interpret the 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 baseline is 3 even without parameter details in the description. The description adds only modest param-level value — noting words is a window while lanes stay whole and recommending get_transcript for faster single-word search — but does not meaningfully override what the schema already provides.

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 opening line — 'The whole edit at once: segments, cut seams, and every word's fate' — states a specific resource and scope. It explicitly contrasts with timeline_status ('counts things; this says what they are') and frames itself as 'locate asked once for the whole clip instead of once per range,' making differentiation from siblings immediate.

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 names alternatives explicitly and gives selection conditions: use this instead of timeline_status when item-level detail is needed, use get_transcript with search= for faster single-word lookup, and use locate for per-range queries. This satisfies both 'when' and 'when-not' guidance.

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

transcribeA
Destructive

Transcribe a clip's own media with whisper, and attach the result.

attach_transcript's ASR-driven sibling: use that when the recording already has a transcript, this when it needs one made. Takes minutes on a long recording — there is no timeout, so let it run. Reports near_duplicates, suspect_durations, overlaps and repeats the same way attach_transcript does.

It replaces whatever transcript the clip already had, and it is the one mutation undo cannot reach: a transcript is its own file, so this writes neither the manifest nor the timeline and nothing is snapshotted. There is no cache either — a second call spends the same minutes again. get_transcript first if a transcript might already be there.

ParametersJSON 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.
modelNoThe whisper model to run, e.g. `small.en`. Larger is slower, and there is no timeout.turbo
clip_idYesThe clip whose own media whisper transcribes.
languageNoForce a language code, e.g. `en`. Unset, whisper detects it, which it gets wrong on short or noisy clips.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

The description goes well beyond the annotations by disclosing that the tool replaces any existing transcript, is unreachable by undo, writes neither manifest nor timeline, has no cache, takes minutes, and has no timeout. These are critical behavioral facts that annotations alone would not convey.

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 front-loaded with the core purpose, then cleanly covers sibling selection, runtime expectations, destructive behavior, and undo/cache caveats. Every sentence adds distinct value, and the density is appropriate for a tool with this many behavioral implications.

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 annotations, output schema, and fully documented parameters, the description covers everything an agent needs to invoke this tool correctly: what it does, when to use it, what it destroys, how long it can take, and what to check beforehand. The mention of diagnostics like near_duplicates and overlaps compensates for not detailing the output, which the output schema already provides.

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?

Input schema description coverage is 100%, and each parameter already has a meaningful description. The tool description adds useful context around behavior and alternatives but does not add new parameter-level semantics, so the baseline of 3 applies.

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: 'Transcribe a clip's own media with whisper, and attach the result.' It also distinguishes itself from attach_transcript by naming the sibling and its purpose, so an agent can tell them apart immediately.

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?

It explicitly states when to use this tool versus attach_transcript: 'use that when the recording already has a transcript, this when it needs one made.' It also advises calling get_transcript first if a transcript might already exist, which is concrete pre-use guidance.

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

transcript_checksA
Read-onlyIdempotent

Re-check an already-attached transcript against itself.

Returns the same four findings attach_transcript does — near_duplicates, suspect_durations, overlaps, repeats — for a transcript attached earlier, whose findings were reported once and are otherwise gone. Omit clip_id for every clip that has a transcript.

Read overlaps before anything derived from this transcript is drawn on screen. A seam there is whisper reading across a retake splice and interleaving both takes, which invents words nobody said — and they read as ordinary English, so a human proofread finds some and is blind to the rest. repeats catches the other shape a retake takes: one that survived transcription as distinct, cleanly-timed duplicated words rather than as an interleaved seam. Reads only; it never writes.

ParametersJSON 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.
clip_idNoOne clip to re-check. Omit it for every clip that has a transcript.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already carry readOnlyHint=true and destructiveHint=false, and the description reinforces with 'Reads only; it never writes' — consistent. Beyond that, it adds genuinely valuable behavioral context: the warning that an overlaps seam means whisper is inventing words nobody said, and that a human proofread is blind to some of them, plus the ordering directive to read overlaps before drawing on screen. This is substantial context beyond what annotations provide.

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 purpose and return findings are front-loaded in the first sentence. The description is long (~130 words), and the deep-dive into overlaps/retakes is verbose, but every sentence carries actionable weight — the invented-words danger and the read-overlaps-first directive justify the length. Slightly over-detailed but not wasteful.

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 read-only, idempotent tool with two optional parameters, full schema coverage, and an output schema, the description is complete. It explains the four findings, their significance, the clip_id omission case, and the safety-critical ordering. Nothing an agent needs to call it correctly is missing.

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 coverage is 100%, so both parameters are fully documented in the schema. The description's clip_id guidance ('Omit clip_id for every clip that has a transcript') is verbatim identical to the schema's own clip_id description, adding no new meaning. With full coverage, the baseline of 3 applies.

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+resource ('Re-check an already-attached transcript against itself') and lists the exact four findings returned, tying itself to sibling attach_transcript ('Returns the same four findings attach_transcript does'). This clearly distinguishes it from the sibling that performs the original attachment.

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?

The phrase 'already-attached' and 'attached earlier, whose findings were reported once and are otherwise gone' clearly scopes the use case to re-checking prior transcripts. The clip_id omission rule ('Omit clip_id for every clip that has a transcript') gives practical invocation guidance. It does not explicitly name an alternative to prefer for first-time checks, but the relationship to attach_transcript is strongly implied.

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

undoA
Destructive

Roll the project back one mutation — the timeline, the manifest, or both.

Mutating tools snapshot first (migrate_project keeps its own backup instead), so this undoes cuts, cues, framing, the music bed, caption style and the rest alike; call it again to go back further. The reply says what came back: timeline_restored, manifest_restored, and timeline_removed when undoing a seed_timeline leaves no timeline at all. Undoing an import un-registers the clip but leaves its media on disk. There is no redo, so read undo_depth first when stepping back more than once.

ParametersJSON 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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior5/5

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

Beyond the `destructiveHint: true` annotation, the description discloses important side effects: undo snapshots are taken first, imports unregister clips but leave media on disk, there is no redo, and return flags like `timeline_restored` and `timeline_removed` are explained. This is rich behavioral 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: scope, examples, return values, edge cases, and redo limitation. The first sentence front-loads the core behavior, and the rest expands without fluff.

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?

The description covers behavior, side effects, return values, and the main path semantics from the schema. It loses a point because it instructs the agent to read `undo_depth` first, but no `undo_depth` tool appears in the provided sibling list, making that guidance unactionable.

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?

The schema already provides 100% coverage for `path`, including binding behavior and refusal rules. The description adds no parameter-specific meaning beyond the schema, so the baseline 3 applies.

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

Purpose4/5

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

The description clearly states a specific action ('Roll the project back one mutation') and the resources affected ('the timeline, the manifest, or both'), with concrete examples. However, it does not explicitly differentiate itself from the sibling tool `restore`, leaving the distinction to inference.

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?

The description provides clear context for when to use the tool: after a mutation, repeatedly to go further back, and with the caution to read `undo_depth` first for multi-step undos. It does not name alternatives or exclusions, so it stops short of a 5.

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

unspoken_addA
Idempotent

Mark a word the transcript holds and the recording never said.

Whisper transcribes straight across a retake splice and emits words from both takes interleaved, so words appear in the index that nobody said. They are in the transcript and nowhere else — not the audio, not the render — so captions draw them and verify expects them.

This writes a mark beside the transcript and never touches the transcript itself: word indices must not renumber, or every cue pointing at one would move. Captions, caption_view and verify all stop expecting the word; no audio, timing or shot changes, because the seconds around it are the take that was kept. Echoes the word it resolved to, plus three either side.

Addressed by word_index or phrase — but unlike cue_add, a phrase resolving to more than one word is refused rather than bound to an edge: unspoken addresses exactly one word, and picking a side of a wider match would silently mark the wrong one half the time. Narrow the phrase, or pass occurrence= if it is disambiguation rather than width.

Prefer unspoken_detect to find them: it is evidence rather than reading, and reading for sense provably misses the grammatical ones.

ParametersJSON 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.
afterNoA forward cursor over a phrase's matches: any match at or before this word index is skipped. -1, the default, means from the start.
phraseNoAddress it by wording instead — but unlike `cue_add`, a phrase matching more than one word is refused rather than bound to an edge: a mark addresses exactly one word.
clip_idYesThe transcript holding the word.
occurrenceNoDisambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — rather than guessed at.
word_indexNoThe word to mark. Give this or `phrase`.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

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

The description details side effects beyond the annotations: it 'writes a mark beside the transcript and never touches the transcript itself,' ensuring word indices don't renumber, and that captions, caption_view, and verify stop expecting the word. It also clarifies no audio/timing/shot changes occur. Since annotations only state readOnlyHint=false and idempotentHint=true, this adds substantial behavioral context without contradicting any structured hint.

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?

Every sentence earns its place: purpose, cause, side effects, addressing semantics, and guidance are organized logically. It is front-loaded with the core action, then expands into rationale and constraints. Despite its length, there is zero filler—each paragraph serves a distinct purpose.

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 tool with six parameters and an output schema, the description covers all essential aspects: how to address a word (index or phrase), disambiguation rules, side effects on downstream systems, and the recommended sibling tool. It also mentions the refusal behavior for ambiguous phrases, which is critical for correct usage. Nothing an agent needs 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.

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 value by explaining the behavioral difference between word_index and phrase (refusal on multi-word matches), the meaning of occurrence as 1-based disambiguation, and the interaction with `after`. While not strictly necessary given the schema, these clarifications improve selection and invocation confidence.

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 precise verb and resource: 'Mark a word the transcript holds and the recording never said.' It immediately explains the root cause (Whisper splicing artifacts) and contrasts with siblings like cue_add and unspoken_detect, making the tool's unique role unmistakable. An agent can instantly distinguish it from similar editing tools.

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 explicitly directs users to 'Prefer `unspoken_detect` to find them' and explains why reading is insufficient. It also contrasts with cue_add, stating that ambiguous phrases are refused rather than bound to an edge, and clarifies when to narrow or use occurrence. This gives clear when-to-use and when-not-to-use guidance with concrete alternatives.

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

unspoken_detectA
Destructive

Propose the words a render's own transcription says were never spoken.

Candidates come from two mechanisms and one witness decides both. A seam is where whisper read across a splice and invented a word; a fragment is where a cut left a sliver of a real one, which draws as a whole word on screen and is inaudible. The witness is the render: the candidate's word is counted in the timeline over a short window and in the render's own transcription over the same seconds, and it is proposed only where the timeline has more of them than the render heard. Counted rather than looked up because the inventions are function words — asking whether the render says "the" near here answers yes off the real one beside it.

apply=False by default, like reframe_detect: this changes what a caption says, and a wrong mark deletes a real word from every check proofcut has. Read the echoes first.

transcript_path takes an existing transcription of the render, which is what verify leaves in cache/verify/. Pass it explicitly — it is never found automatically, because a re-render under the same filename would otherwise be judged against the previous render's audio.

ParametersJSON Schema
NameRequiredDescriptionDefault
padNoWiden the window each candidate is counted in, 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.
applyNoMark the proposals. Off by default, like `reframe_detect`: a wrong mark deletes a real word from every check proofcut has, so read the echoes first.
modelNoThe whisper model to transcribe the render with, when no `transcript_path` is given.
renderYesThe rendered file to judge against — the witness. A word is proposed only where the timeline holds more of it over a span than the render's own transcription heard.
clip_idNoLimit the scan to one transcript.
languageNoForce a language code for that transcription.
transcript_pathNoAn existing transcription of `render`, which is what `verify` leaves in `cache/verify/`. It is never found automatically: a re-render under the same filename would otherwise be judged against the previous render's audio.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already flag `destructiveHint: true`, and the description adds critical context beyond that: a wrong mark "deletes a real word from every check proofcut has" and therefore the agent should read echoes first. It also discloses that `transcript_path` is never found automatically to avoid judging a re-render by previous audio, which is exactly the kind of behavioral nuance annotations cannot convey.

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 long but well structured: purpose first, then mechanism, safety, and the key parameter caution. Every paragraph adds useful context, though the algorithm explanation (seams, fragments, counting rationale) is more elaborate than strictly necessary for invocation. It is not bloated, but it earns a 4 rather than a 5 because of that extra explanatory weight.

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 complex 8-parameter tool with an output schema, the description covers purpose, algorithm, safety, prerequisites, and the one parameter behavior that would otherwise cause subtle errors. The output schema handles return-value details, and the schema covers the remaining parameters. Nothing essential is missing for an agent to call this 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 coverage is 100%, so the baseline is 3 even without parameter details in the description. The description does reinforce the meaning of `apply`, `transcript_path`, and the counting window, but it mostly restates what the schema already says rather than adding new parameter-level semantics.

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: "Propose the words a render's own transcription says were never spoken." It then explains the two detection mechanisms (seam and fragment) and clearly separates proposing from applying by noting `apply=False` by default. This distinguishes it from manual siblings like `unspoken_add`/`unspoken_rm` without needing to inspect them.

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?

The description gives strong operational guidance: pass `transcript_path` explicitly from `verify`'s cache, read the echoes first, and keep `apply=False` unless sure. It names `reframe_detect` as a sibling with the same safety default. It does not explicitly say when to prefer `unspoken_detect` over manual unspoken tools, but the propose-vs-apply distinction implies it.

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

unspoken_lsA
Read-onlyIdempotent

Every word marked never-spoken, with what the transcript says now.

Read-only. stale is a mark whose recorded text and current text disagree — the transcript was re-attached under it. A stale mark is never applied, so re-transcribing surfaces as a list to re-check rather than as words disappearing from a caption file.

ParametersJSON 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.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already establish read-only/idempotent/non-destructive behavior, so the description adds meaningful value by defining the 'stale' state and its consequence: stale marks are never applied, and re-transcriptions appear as a list to re-check. This goes beyond the structured hints without contradicting them.

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 compact and front-loaded: a one-line purpose, followed by a pithy, high-value explanation of stale marks. No filler or repetition of schema content.

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 read-only listing tool with an output schema, complete parameter documentation, and annotations covering safety, the description provides the one missing piece of domain behavior — the stale-mark distinction — and is therefore sufficient for correct invocation.

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?

Only one parameter, path, is fully documented in the schema (100% coverage), including bound/unbound server behavior. The description adds no path-specific information, which is fine because the schema carries the full burden.

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 opening sentence 'Every word marked never-spoken, with what the transcript says now' states the operation as a listing of a specific resource (unspoken marks) and the key data returned. It is clearly distinct from sibling unspoken_add/rm/detect, which manage or detect marks.

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

Usage Guidelines3/5

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

Usage is implied rather than explicitly stated. The stale-mark explanation gives one concrete scenario — after re-transcribing, use this to re-check marks — but the description never says when to prefer it over unspoken_detect or a general transcript tool.

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

unspoken_rmA
Destructive

Unmark a word unspoken_add marked, putting it back into captions and verify.

Address it by word_index, or by a phrase resolving to exactly one word. Refuses a word that is not marked. The transcript file is never edited either way — a mark is a manifest entry — so no cue or caption renumbers. unspoken_ls lists the marks; undo restores one.

ParametersJSON 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.
afterNoA forward cursor over a phrase's matches: any match at or before this word index is skipped. -1, the default, means from the start.
phraseNoAddress it by wording instead; it has to resolve to exactly one word.
clip_idYesThe transcript holding the marked word.
occurrenceNoDisambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — rather than guessed at.
word_indexNoThe marked word. Give this or `phrase`.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

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

Annotations mark this as destructive (destructiveHint=true) and not read-only. The description adds key nuance: the transcript file is never edited, only a manifest entry changes, so no renumbering occurs. It also discloses the refusal behavior for unmarked words. This adds value beyond the annotations and clarifies the actual side effects.

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 composed of three sentences, each carrying distinct information: the core action, the addressing method and refusal, and the side-effect transparency plus sibling pointers. It is front-loaded with the primary purpose and avoids fluff. Slightly longer than minimal but well-organized.

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 tool with six parameters and an output schema, the description covers the essential behavioral aspects: what it does, how to address, refusal, side effects, and related tools. It doesn't repeat parameter details already in the schema, and the output format is presumably covered by the output schema. It is complete enough for an agent to invoke 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?

The input schema already describes all six parameters in detail (100% coverage), including word_index, phrase, clip_id, after, occurrence, and path. The description reiterates that addressing is by word_index or a phrase resolving to exactly one word, but this is already in the schema. It does not add new parameter-specific semantics, so the baseline of 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?

The description states a specific action ('Unmark a word'), names the resource type (word marked by unspoken_add), and gives the effect (putting it back into captions and verify). It explicitly references the sibling unspoken_add, which differentiates it clearly from other tools like unspoken_ls and undo.

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?

The description gives clear addressing options (word_index or phrase) and notes the refusal of unmarked words. It mentions alternatives: unspoken_ls lists marks and undo restores one, which helps an agent choose between them. However, it doesn't explicitly state conditions like 'use when you want to remove a mark' vs 'use undo to revert a removal', but the context is sufficient.

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

verifyA
Read-onlyIdempotent

Transcribe a finished render and diff it against what the timeline says.

Run this after rendering, before calling an edit done. It transcribes the render with whisper and compares that word sequence to the one the timeline should play, which is the only check that catches a retake still in the picture: whisper collapses an immediate repeat into a single utterance, so a doubled phrase can be invisible in the source transcript and still be in the render.

Read repeated first — an entry there is a phrase the render plays more times than the timeline expects, i.e. a surviving retake, with the heard word index to look at. dropped is the opposite: words the timeline expects that the render never says, usually a cut that reached too far.

A clean single-pass result is not proof. This check has a known blind spot: the render's transcript is itself one whisper pass, which collapses a repeat the same way the source transcript did — three retakes survived a correct run of it on a real video. Set windowed=True to transcribe in short overlapping windows instead, which is what found them. It costs one whisper run over 2x the audio and uses a deliberately smaller model, so run the default first and escalate to it before calling an edit finished.

loud_gaps comes back either way and trusts no transcript: it measures the render's own energy and reports holes in the heard word map that hold sound anyway. An entry is a place to listen, not a verdict — a music bed or an attenuated noise can produce one. Read speech_db/threshold_db beside it.

similarity around 0.97 is normal on a clean render — whisper spells its own output differently on a second pass ("whodunit" / "who done it", "4" / "four"). Treat it as triage; diff is the artifact. Transcription takes minutes on a long render, and the result is cached under cache/verify/ and reported as heard_transcript — pass it back as transcript_path to re-diff without re-transcribing.

ParametersJSON 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.
modelNoThe whisper model for the single-pass transcription.
renderYesThe finished render to transcribe and diff against the timeline.
windowNoLength of each window in the windowed pass, in seconds.
clip_idNoDiff against one transcript's expected words rather than all of them.
overlapNoHow far each window overlaps the one before, in seconds.
languageNoForce a language code for it.
windowedNoTranscribe in short overlapping windows instead of one pass. **A clean single-pass result is not proof** — one pass collapses an immediate repeat the same way the source transcript did, and three surviving retakes passed a correct single-pass run on a real video. It costs a run over twice the audio and a smaller model.
transcript_pathNoAn existing transcription of `render` — what a previous run cached and reported as `heard_transcript`. Pass it back to re-diff without spending the minutes again.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already mark it read-only and non-destructive, but the description adds crucial behavioral caveats: the single-pass transcript can collapse immediate repeats (a real documented blind spot), windowed mode uses a smaller model over 2x audio, `loud_gaps` entries are places to listen rather than verdicts, and `similarity` is triage not proof. It also discloses caching under cache/verify/.

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 long but information-dense; the core action is front-loaded and subsequent paragraphs each address a discrete component (windowed, loud_gaps, similarity, caching). No filler – every sentence adds operational guidance, though the length is ambitious for a casual skim.

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 tool's complexity – 9 parameters, a real blind spot, output interpretation, and caching – the description covers its operation end-to-end. It explains how to read the results (`repeated`, `dropped`, `loud_gaps`, `similarity`), how to escalate to windowed mode, and how to recycle a cache. The existing output schema covers the return structure, so nothing essential is missing.

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 description coverage is 100%, so the baseline is 3. The description goes further by explaining the behavioral consequences of `windowed=True` (cost, smaller model) and `transcript_path` (re-diff without re-transcribing), and clarifies that `render` is the finished artifact to diff. It does not add original meaning for path/model/window/overlap, but the critical params get useful context.

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 concrete action – 'Transcribe a finished render and diff it against what the timeline says' – and reinforces its unique role as the only check that catches a surviving retake. It also provides invocation context ('after rendering, before calling an edit done'), which distinguishes it from sibling transcript/check tools.

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?

It explicitly instructs when to run: after rendering, before calling an edit done, and stipulates a two-step escalation – run the default single pass first, then escalate to `windowed=True` if necessary. It also tells the agent when to reuse a cached transcript via `transcript_path`, giving a clear operational flow.

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

vo_extendA
Destructive

Open a gap in clip_id's track for material the recording never had.

The one tool allowed to grow the edit rather than cut it: a real hold in the VO, e.g. to let a line the footage carries play under it. Not the end card (tail), and not restore, which only brings back cut source.

Addressed by word_index or phrase — the last word before the gap, which must be on the timeline — for seconds. The stretch is a real silent WAV, registered like any clip; a second call at the same seconds reuses it.

Read covered_by. build_shots runs each shot to the next cue, so whatever picture was playing freezes across the hold by default, with shots_error, verify and check_frames all staying clean. It names every shot the gap now overlaps ([] with no cue table at all).

Two consequences are permanent once a hold lands: restore refuses across the seam, and export always goes through the MLT writer. plan=True reports covered_by without writing; its hold_clip_id is a placeholder.

ParametersJSON 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 a phrase's matches: any match at or before this word index is skipped. -1, the default, means from the start.
phraseNoAddress it by wording instead. A phrase binds to its **last** word here, which is this tool's own meaning: the last word before the gap.
clip_idYesThe track the gap opens in — the VO.
secondsNoHow long the hold runs. An editorial call this makes no attempt to derive.
occurrenceNoDisambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — rather than guessed at.
word_indexNoThe last word **before** the gap; the hold opens immediately after that word's own end. It has to be on the timeline: an index naming cut material is refused rather than guessed at.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already mark destructiveHint=true, but the description adds crucial consequences: `restore` refuses across the seam, export always goes through the MLT writer, a second call at the same `seconds` reuses the WAV, and `build_shots` interaction is explained. This far exceeds what annotations alone provide.

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 long but every sentence carries essential information. It front-loads the tool's purpose and exclusions, then uses bolded headings for parameters and consequences, making it scannable despite density.

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 tool's complexity and destructive nature, the description covers addressing modes (word_index/phrase), duration, plan mode, permanent effects, and interaction with `build_shots`. An output schema exists, so return values need not be detailed; nothing critical for correct invocation 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?

Despite 100% schema coverage, the description enriches parameter meaning: `word_index` is 'the last word before the gap' and must be on the timeline, `phrase` binds to its last word, `occurrence` is 1-based and ambiguous phrases are refused, and `plan=True` reports without writing. This is substantial added value beyond the schema.

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?

Opens with a specific verb and resource: 'Open a gap in `clip_id`'s track' for material the recording never had. It also explicitly differentiates itself from `tail` and `restore`, making the tool's unique role clear.

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?

The description states clear exclusions ('Not the end card (`tail`), and not `restore`') and gives context ('real hold' in the VO to let footage play under). It doesn't explicitly list every alternative among the `hold_*` siblings, but it provides enough direction for an agent to distinguish this tool.

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

vo_synthA
Destructive

Say text in a cloned voice — render several seeds, rank them, read the winner back.

Zero-shot Qwen3-TTS from a ≈19s reference clip (voice); there is no built-in voice. Seeds seed .. seed+candidates-1 render in one process, each with sim (speaker-embedding likeness to the reference — a real take ≈0.99, a 3-semitone shift ≈0.96) and spread (voiced pitch movement). chosen is the best sim less a flatness penalty, since likeness alone keeps the flattest read. A render that hit max_seconds is capped and never wins while an uncapped one exists.

The winner is read back through whisper and heard/wer reported — a clone that sounds right and says the wrong words is the failure nothing else sees. A report, never a gate.

Renders are cached under cache/synth/, so a repeat spends no GPU. The splice is not cached: with clip_id + word_index the winner is registered and spliced in after that word through vo_extend's mechanism (melt routing, restore refusing across the seam, a covered_by report), and calling again splices a second time — check the timeline or undo rather than re-calling. plan=True reports the ranking and splice preview from cached renders only, and says rendered: False rather than spending the GPU.

ParametersJSON 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.
seedNoFirst seed of the range; seeds `seed .. seed+candidates-1` render in one process. A new range renders only what the cache lacks.
textYesWhat the voice says. It is respelled first through the project's `lexicon.json` `say` folds, if one exists — the fix for a mispronounced name.
voiceNoA directory holding `ref.wav` + `ref.txt`, the ≈19s reference the clone is zero-shot from. Unset, `$PROOFCUT_TTS_VOICE`. There is no built-in voice, and none ships in the repo: a voice is somebody's recorded speech.
clip_idNoWith `word_index`, the track to splice the winner into. Omitted, nothing is spliced and the renders are just ranked.
lexiconNoA `{"say": {…}, "hear": {…}}` file: `say` respells what the model is given, `hear` folds whisper's spelling back to the script's before the WER is scored. Defaults to the project's own `lexicon.json` if it has one.
readbackNoTranscribe the winner with whisper and report `heard`/`wer`. On by default: a clone that sounds right and says the wrong words is the failure nothing else sees. The numbers are a report, never a gate.
candidatesNoHow many seeds to render and rank. Seed moves a render more than the reference does, which is why this ranks rather than renders once.
flat_floorNoBelow this much voiced pitch movement (semitones) a render starts paying the flatness penalty. Likeness alone keeps the flattest read, because sims in one pool differ by thousandths while spread differs by semitones.
word_indexNoThe word to splice the winner in right after, through `vo_extend`'s own mechanism — so the same one-way consequences follow (melt routing, `restore` refusing across the seam).
flat_weightNoHow much likeness to subtract per semitone of flatness under the floor. 0 restores likeness-only ranking.
max_secondsNoLength cap per render. One that hits it is reported `capped` and never wins while an uncapped one exists — a 21s reference once ran every render to 655s.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare destructiveHint=true, and the description richly confirms and extends this: it discloses the non-cached splice with double-splice risk, the caching under `cache/synth/` that avoids GPU on repeat, the ranking rule ('best `sim` less a flatness penalty'), the `capped`-never-wins rule, and the readback as 'a report, never a gate.' It even explains the failure mode a clone that sounds right but says the wrong words. This is far beyond what annotations provide and contradicts nothing.

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

Conciseness3/5

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

The description is front-loaded with the core purpose in the first sentence and organized into logical paragraphs (ranking logic, readback, caching/splice warning, plan behavior). However, it is quite long and dense for a description, requiring sustained reading. For a 13-parameter tool much of the length is earned, but it could be tightened without losing essential behavioral disclosure.

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?

An output schema exists, so return values need not be explained. For a destructive, 13-parameter tool with splicing side effects, the description covers everything an agent needs: caching, splice non-idempotency, ranking rules, capped renders, readback semantics, and the `plan` path. The one reliance on `vo_extend`'s documented mechanism is a reasonable pointer rather than a gap. Complete for the tool's complexity.

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 goes well beyond the schema by explaining the meaning of core outputs and ranking terms (`sim`, `spread`, `chosen`, `capped`) and the rationale behind `flat_floor`/`flat_weight` ('likeness alone keeps the flattest read, because sims in one pool differ by thousandths while spread differs by semitones'). It also clarifies `max_seconds` with a concrete anecdote. This adds real value over the schema's per-parameter 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?

The first sentence is a specific verb+resource: 'Say `text` in a cloned voice — render several seeds, rank them, read the winner back.' This states exactly what the tool does and clearly separates it from its sibling `vo_extend` (splicing/extension) and `transcribe`/`hear` (readback-only). An agent can tell what this tool is for immediately.

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?

The description gives strong workflow guidance: it explains when to use `plan=True` (report from cached renders, spend no GPU), and explicitly warns against re-calling the splice ('calling again splices a second time — check the timeline or `undo` rather than re-calling'). It references `vo_extend`'s mechanism as an alternative pathway for splicing. It lacks an explicit when-not-to-use statement versus a specific sibling, but the workflow context is clear.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 93 tool updatesv0.25.0
    • Changedadd_captions39 fields changed
      • 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"
    • Changedassets5 fields changed
      • 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 / title
        Removed value: -"assetsArguments"
    • Changedattach_transcript9 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip this transcript belongs to. Its words become `(clip_id, word_index)`, which is how every cue, mark and caption addresses them afterwards."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • 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"
        +]
      • addedInput schema / properties / transcript_path / description
        Added value: +"The whisper JSON to ingest. It has to carry word-level timings — proofcut addresses words, not segments."
      • removedInput schema / properties / transcript_path / title
        Removed value: -"Transcript Path"
      • removedInput schema / title
        Removed value: -"attach_transcriptArguments"
    • Changedattenuate_noises19 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip to scan. It always reads that clip's **original** media, never a previous attenuated copy, so repeated calls never compound gain."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / confirm_suspect / description
        Added value: +"Go ahead even though a boundary word claims a suspect duration. Read the echoed words first — a suspect duration usually means whisper hid a retake inside that word, so the edge is not where it reads."
      • removedInput schema / properties / confirm_suspect / title
        Removed value: -"Confirm Suspect"
      • addedInput schema / properties / db / description
        Added value: +"How far to pull each qualifying event down, in dB. Negative is quieter."
      • removedInput schema / properties / db / title
        Removed value: -"Db"
      • addedInput schema / properties / max_event_seconds / description
        Added value: +"Longest an event may run and still qualify automatically. Anything longer is reported as `disqualified` and never written."
      • removedInput schema / properties / max_event_seconds / title
        Removed value: -"Max Event Seconds"
      • addedInput schema / properties / max_gap_seconds / description
        Added value: +"How wide the word-map gap around an event may be. A wide gap disqualifies even a very short event — that is the false-positive class this exists to prevent, speech sitting in a hole the transcript never wrote down."
      • removedInput schema / properties / max_gap_seconds / title
        Removed value: -"Max Gap Seconds"
      • addedInput schema / properties / pad / description
        Added value: +"Seconds added either side of each event before it is pulled down."
      • removedInput schema / properties / pad / title
        Removed value: -"Pad"
      • 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"
        +]
      • 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 / title
        Removed value: -"attenuate_noisesArguments"
    • Changedattribute_speakers23 fields changed
      • addedInput schema / properties / apply / description
        Added value: +"Write the labels onto the words. Off by default — it reports first, and applying keeps any label already on a word this refuses to call."
      • removedInput schema / properties / apply / title
        Removed value: -"Apply"
      • addedInput schema / properties / clip_id / description
        Added value: +"The co-hosted clip: one container, one mic per speaker, one transcript already attached."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • removedInput schema / properties / labels / anyOf
        Removed value: -[
        -  {
        -    "items": {
        -      "type": "string"
        -    },
        -    "type": "array"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / labels / description
        Added value: +"What to call each stream, in the same order — one per stream. Unset, `speaker1`, `speaker2`."
      • addedInput schema / properties / labels / items
        Added value: +{
        +  "type": "string"
        +}
      • removedInput schema / properties / labels / title
        Removed value: -"Labels"
      • addedInput schema / properties / labels / type
        Added value: +[
        +  "array",
        +  "null"
        +]
      • addedInput schema / properties / limit / description
        Added value: +"How many ambiguous spans to return; the reply also says how many there are in total."
      • removedInput schema / properties / limit / title
        Removed value: -"Limit"
      • addedInput schema / properties / margin_db / description
        Added value: +"How much louder one mic has to be to be believed, in dB. It reports a default and is not a threshold to trust: on words spoken over each other the rule is at chance, and anything under this margin comes back in `ambiguous_spans` to go and listen to."
      • removedInput schema / properties / margin_db / title
        Removed value: -"Margin Db"
      • 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 / streams / anyOf
        Removed value: -[
        -  {
        -    "items": {
        -      "type": "integer"
        -    },
        -    "type": "array"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / streams / description
        Added value: +"Which audio streams the speakers are on, as ffmpeg audio ordinals (`[0, 1]`). Unset, the container's readable audio streams in order."
      • addedInput schema / properties / streams / items
        Added value: +{
        +  "type": "integer"
        +}
      • removedInput schema / properties / streams / title
        Removed value: -"Streams"
      • addedInput schema / properties / streams / type
        Added value: +[
        +  "array",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"attribute_speakersArguments"
    • Changedbroll_brief9 fields changed
      • removedInput schema / properties / fps / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / fps / description
        Added value: +"The frame grid the shot positions are projected on. Defaults to the rate `export` would use."
      • removedInput schema / properties / fps / title
        Removed value: -"Fps"
      • addedInput schema / properties / fps / type
        Added value: +[
        +  "number",
        +  "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 / title
        Removed value: -"broll_briefArguments"
    • Changedbuild_shots9 fields changed
      • removedInput schema / properties / fps / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / fps / description
        Added value: +"The frame grid to project onto. Unset, the project's timebase — which on an audio-only project is milliseconds rather than frames. Pass the rate `export` will use to see the frames the export actually cuts at."
      • removedInput schema / properties / fps / title
        Removed value: -"Fps"
      • addedInput schema / properties / fps / type
        Added value: +[
        +  "number",
        +  "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 / title
        Removed value: -"build_shotsArguments"
    • Changedcanvas13 fields changed
      • 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"
        +]
      • 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 override and return to the footage-derived shape."
      • removedInput schema / properties / reset / title
        Removed value: -"Reset"
      • removedInput schema / properties / size / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / size / description
        Added value: +"`WIDTHxHEIGHT`, e.g. `1080x1920` for a vertical reel. Both edges must be even. Omit it to read what is in force plus the footage-derived shape it would fall back to."
      • removedInput schema / properties / size / title
        Removed value: -"Size"
      • addedInput schema / properties / size / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"canvasArguments"
    • Changedcaption_style81 fields changed
      • removedInput schema / properties / bold / anyOf
        Removed value: -[
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / bold / description
        Added value: +"Draw bold."
      • removedInput schema / properties / bold / title
        Removed value: -"Bold"
      • addedInput schema / properties / bold / type
        Added value: +[
        +  "boolean",
        +  "null"
        +]
      • removedInput schema / properties / box / anyOf
        Removed value: -[
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / box / description
        Added value: +"Draw an opaque box behind the words. It buys legibility over light footage — white captions over the film's own light cards measure 1.10:1 without one — and costs clean edges, since libass draws one box per override block."
      • removedInput schema / properties / box / title
        Removed value: -"Box"
      • addedInput schema / properties / box / type
        Added value: +[
        +  "boolean",
        +  "null"
        +]
      • removedInput schema / properties / box_colour / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / box_colour / description
        Added value: +"Colour of the box behind the type, when `box` is on."
      • removedInput schema / properties / box_colour / title
        Removed value: -"Box Colour"
      • addedInput schema / properties / box_colour / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / font / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / font / description
        Added value: +"Family name to draw with. Whether it actually draws is a different question from whether it is installed — `fonts` measures a render, and libass substitutes silently at exit 0."
      • removedInput schema / properties / font / title
        Removed value: -"Font"
      • addedInput schema / properties / font / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / highlight / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / highlight / description
        Added value: +"What a word turns as it is spoken. It only shows with `karaoke` on."
      • removedInput schema / properties / highlight / title
        Removed value: -"Highlight"
      • addedInput schema / properties / highlight / 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 / karaoke / anyOf
        Removed value: -[
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / karaoke / description
        Added value: +"Fill each word as it is spoken. The fill is left-to-right within a line rather than a per-word step, which is what the grouping fields below shape."
      • removedInput schema / properties / karaoke / title
        Removed value: -"Karaoke"
      • addedInput schema / properties / karaoke / type
        Added value: +[
        +  "boolean",
        +  "null"
        +]
      • removedInput schema / properties / margin / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / margin / description
        Added value: +"Distance from the frame edge, in canvas pixels."
      • removedInput schema / properties / margin / title
        Removed value: -"Margin"
      • addedInput schema / properties / margin / type
        Added value: +[
        +  "integer",
        +  "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. Grouping is part of the look, which is why it is stored with it."
      • removedInput schema / properties / max_words / title
        Removed value: -"Max Words"
      • addedInput schema / properties / max_words / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / properties / outline_colour / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / outline_colour / description
        Added value: +"Colour of the outline around the type."
      • removedInput schema / properties / outline_colour / title
        Removed value: -"Outline Colour"
      • addedInput schema / properties / outline_colour / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / outline_width / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / outline_width / description
        Added value: +"Outline thickness. With no box this is what holds the words apart from the picture."
      • removedInput schema / properties / outline_width / title
        Removed value: -"Outline Width"
      • addedInput schema / properties / outline_width / type
        Added value: +[
        +  "number",
        +  "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"
        +]
      • 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 / position / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / position / description
        Added value: +"Where captions sit, named: `bottom`, `top`, `top-right` and so on."
      • removedInput schema / properties / position / title
        Removed value: -"Position"
      • addedInput schema / properties / position / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / preset / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / preset / description
        Added value: +"The base look: `clean`, `karaoke` (per-word highlight) or `boxed`. Everything else overrides one of its fields, and only the overrides are stored."
      • removedInput schema / properties / preset / title
        Removed value: -"Preset"
      • addedInput schema / properties / preset / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / reset / description
        Added value: +"Drop every override first. `reset` together with `preset` starts clean from that preset."
      • removedInput schema / properties / reset / title
        Removed value: -"Reset"
      • removedInput schema / properties / shadow / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / shadow / description
        Added value: +"Drop-shadow distance."
      • removedInput schema / properties / shadow / title
        Removed value: -"Shadow"
      • addedInput schema / properties / shadow / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / size / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / size / description
        Added value: +"Type size, against the project's canvas as the reference frame."
      • removedInput schema / properties / size / title
        Removed value: -"Size"
      • addedInput schema / properties / size / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / properties / text / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / text / description
        Added value: +"The word's own colour: `#rrggbb`, `#rrggbbaa`, a name, or an ASS `&H…` value. It comes back resolved, because ASS quotes colours backwards and alpha-inverted."
      • removedInput schema / properties / text / title
        Removed value: -"Text"
      • addedInput schema / properties / text / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"caption_styleArguments"
    • Changedcaption_view11 fields changed
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"Show one transcript's captions 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"
        +]
      • addedInput schema / properties / first
        Added value: +{
        +  "default": 0,
        +  "description": "Index of the first cue to return. 0 by default.",
        +  "type": "integer"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "default": 30,
        +  "description": "Most cues to return; `cues_next` says where to continue.",
        +  "type": "integer"
        +}
      • 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 / title
        Removed value: -"caption_viewArguments"
    • Changedcard_new21 fields changed
      • removedInput schema / properties / height / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / height / description
        Added value: +"Render height, given together with `width` or not at all."
      • removedInput schema / properties / height / title
        Removed value: -"Height"
      • addedInput schema / properties / height / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • addedInput schema / properties / name / description
        Added value: +"The `<name>` in `card:<name>` — the key a cue points at. The SVG and the PNG are both written under `assets/cards/`."
      • removedInput schema / properties / name / title
        Removed value: -"Name"
      • addedInput schema / properties / overwrite / description
        Added value: +"Redraw a card of this name that already exists. Refused without it, since a cue may already point at that card."
      • removedInput schema / properties / overwrite / title
        Removed value: -"Overwrite"
      • 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"
        +]
      • addedInput schema / properties / slots / description
        Added value: +"The template's slots filled in, as text. A newline is a line break where the template takes several lines; ratings are numbers out of five, to the nearest half."
      • removedInput schema / properties / slots / title
        Removed value: -"Slots"
      • addedInput schema / properties / template / description
        Added value: +"Which template to fill; `card_templates` lists them with their slots. A per-aspect variant file is resolved from the canvas, never named here."
      • removedInput schema / properties / template / title
        Removed value: -"Template"
      • removedInput schema / properties / width / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / width / description
        Added value: +"Render width. **Leave it unset unless you mean something other than this film** — it defaults to the project's canvas, which is what stops a card pillarboxing inside the frame it was made for. Given at all, `height` must be too."
      • removedInput schema / properties / width / title
        Removed value: -"Width"
      • addedInput schema / properties / width / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"card_newArguments"
    • Changedcard_reauthor11 fields changed
      • removedInput schema / properties / name / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / name / description
        Added value: +"One card to redraw, whatever its canvas. Omit it to sweep every recorded card the canvas has left behind, plus any whose files have gone missing."
      • removedInput schema / properties / name / title
        Removed value: -"Name"
      • addedInput schema / properties / name / type
        Added value: +[
        +  "string",
        +  "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"
        +]
      • 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 / title
        Removed value: -"card_reauthorArguments"
    • Changedcard_render15 fields changed
      • removedInput schema / properties / height / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / height / description
        Added value: +"Render height, given together with `width` or not at all."
      • removedInput schema / properties / height / title
        Removed value: -"Height"
      • addedInput schema / properties / height / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • addedInput schema / properties / name / description
        Added value: +"The card to rasterise: `assets/cards/<name>.svg` becomes the PNG that `card:<name>` resolves to."
      • removedInput schema / properties / name / title
        Removed value: -"Name"
      • 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 / width / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / width / description
        Added value: +"Render width. The document is *drawn* at this scale rather than resampled, so text stays sharp, and it fits rather than distorts. Given together with `height` or not at all; omitted, the document renders at its own declared size."
      • removedInput schema / properties / width / title
        Removed value: -"Width"
      • addedInput schema / properties / width / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"card_renderArguments"
    • Changedcard_safe_zones9 fields changed
      • addedInput schema / properties / card / description
        Added value: +"The card to measure, read from its already-rendered PNG rather than from the recorded slots — so the ink measured is the ink on disk."
      • removedInput schema / properties / card / title
        Removed value: -"Card"
      • 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"
        +]
      • addedInput schema / properties / platform / description
        Added value: +"Whose reserved band to measure against: one of proofcut's own zones (`tiktok-organic`, `tiktok-ads`, `reels`, `shorts`, `worst-case`) or one an applied pack's active variant declares. `pack_show` lists both."
      • removedInput schema / properties / platform / title
        Removed value: -"Platform"
      • removedInput schema / title
        Removed value: -"card_safe_zonesArguments"
    • Changedcard_templates2 fields changed
      • addedInput schema / properties / name
        Added value: +{
        +  "default": null,
        +  "description": "One template to return in full. The others come back as name and description only. Unset, every template in full.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • removedInput schema / title
        Removed value: -"card_templatesArguments"
    • Addedchanges
    • Changedcheck_black17 fields changed
      • removedInput schema / properties / fps / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / fps / description
        Added value: +"The rate the timeline's own frame arithmetic is counted on."
      • removedInput schema / properties / fps / title
        Removed value: -"Fps"
      • addedInput schema / properties / fps / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / min_duration / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / min_duration / description
        Added value: +"Shortest black run to report, in seconds."
      • removedInput schema / properties / min_duration / title
        Removed value: -"Min Duration"
      • addedInput schema / properties / min_duration / type
        Added value: +[
        +  "number",
        +  "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"
        +]
      • addedInput schema / properties / pix_th / description
        Added value: +"How dark a pixel counts as black, 0–1."
      • removedInput schema / properties / pix_th / title
        Removed value: -"Pix Th"
      • addedInput schema / properties / target / description
        Added value: +"The render to scan. Required — unlike `check_frames` there is no cheap no-target mode, since there is nothing to detect black in without a render."
      • removedInput schema / properties / target / title
        Removed value: -"Target"
      • removedInput schema / title
        Removed value: -"check_blackArguments"
    • Changedcheck_frames13 fields changed
      • removedInput schema / properties / fps / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / fps / description
        Added value: +"The rate the export ran at. It has to match, or the two sides are counting on different grids; it defaults to the rate `export` would have picked."
      • removedInput schema / properties / fps / title
        Removed value: -"Fps"
      • addedInput schema / properties / fps / type
        Added value: +[
        +  "number",
        +  "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 / target / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / target / description
        Added value: +"An NLE project (`.kdenlive`/`.mlt`/`.xml`) or a finished render. Omit it to just report `expected_frames`, the total the timeline lays down. Run it on the **exported project before rendering** — that is where it is worth the most."
      • removedInput schema / properties / target / title
        Removed value: -"Target"
      • addedInput schema / properties / target / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"check_framesArguments"
    • Changedclip_rm7 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip to un-register. Its media on disk is never touched."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • 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 / title
        Removed value: -"clip_rmArguments"
    • Changedclip_role13 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip to read or set."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • 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"
        +]
      • addedInput schema / properties / reset / description
        Added value: +"Clear the role back to undeclared."
      • removedInput schema / properties / reset / title
        Removed value: -"Reset"
      • removedInput schema / properties / role / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / role / description
        Added value: +"`voiceover` or `footage`. Omit it and `reset` to read what is stored. It is the assets pane's grouping and nothing else: neither transcribe/describe nor any render path reads it."
      • removedInput schema / properties / role / title
        Removed value: -"Role"
      • addedInput schema / properties / role / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"clip_roleArguments"
    • Changedcontact_sheet11 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip whose head to look at."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / interval / description
        Added value: +"Seconds between tiles."
      • removedInput schema / properties / interval / title
        Removed value: -"Interval"
      • 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"
        +]
      • addedInput schema / properties / seconds / description
        Added value: +"How much of the head to cover, in seconds. Ten by default — long enough to catch credits, black or a slate before anything is cued to the clip."
      • removedInput schema / properties / seconds / title
        Removed value: -"Seconds"
      • removedInput schema / title
        Removed value: -"contact_sheetArguments"
    • Changedcontinuity_accept11 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The cue's own addressing transcript, as `continuity_check` reports it."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / kind / description
        Added value: +"Which finding to acknowledge: `rewind`, `replay`, `short_shot` or `stub`."
      • removedInput schema / properties / kind / title
        Removed value: -"Kind"
      • 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"
        +]
      • addedInput schema / properties / word_index / description
        Added value: +"The cue's word. With `clip_id` and `kind` it is the finding's address — one shot can carry more than one finding."
      • removedInput schema / properties / word_index / title
        Removed value: -"Word Index"
      • removedInput schema / title
        Removed value: -"continuity_acceptArguments"
    • Changedcontinuity_check15 fields changed
      • addedInput schema / properties / gap / description
        Added value: +"How much timeline may pass before re-showing an asset reads as a replay rather than a rewind, in seconds."
      • removedInput schema / properties / gap / title
        Removed value: -"Gap"
      • addedInput schema / properties / min_shot / description
        Added value: +"Shortest a shot may run before it is reported as a short shot, in seconds. Stills are excluded."
      • removedInput schema / properties / min_shot / title
        Removed value: -"Min Shot"
      • 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"
        +]
      • addedInput schema / properties / scene_threshold / description
        Added value: +"The scene-cut threshold for the stub scan. It defaults to the pinned 0.15, but darker footage from a different film has needed 0.12."
      • removedInput schema / properties / scene_threshold / title
        Removed value: -"Scene Threshold"
      • addedInput schema / properties / stub_tolerance / description
        Added value: +"How close a shot edge has to sit to its footage's own internal cut to be called a stub, in seconds."
      • removedInput schema / properties / stub_tolerance / title
        Removed value: -"Stub Tolerance"
      • addedInput schema / properties / stubs / description
        Added value: +"Look for stubs. On by default, and it costs a scene-cut decode per distinct asset placed — `false` skips that."
      • removedInput schema / properties / stubs / title
        Removed value: -"Stubs"
      • removedInput schema / title
        Removed value: -"continuity_checkArguments"
    • Changedcontinuity_ls5 fields changed
      • 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 / title
        Removed value: -"continuity_lsArguments"
    • Changedcontinuity_reject11 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The cue's own addressing transcript."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / kind / description
        Added value: +"Which finding to un-acknowledge: `rewind`, `replay`, `short_shot` or `stub`."
      • removedInput schema / properties / kind / title
        Removed value: -"Kind"
      • 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"
        +]
      • addedInput schema / properties / word_index / description
        Added value: +"The cue's word, with `clip_id` and `kind` the address the acknowledgement was stored under."
      • removedInput schema / properties / word_index / title
        Removed value: -"Word Index"
      • removedInput schema / title
        Removed value: -"continuity_rejectArguments"
    • Changedcue_add29 fields changed
      • addedInput schema / properties / after / description
        Added value: +"A forward cursor over a phrase's matches: 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: +"What to show from that word onward: a registered clip id, or `card:<name>` for a card. An opaque key here, resolved by `build_shots` rather than checked against disk now."
      • removedInput schema / properties / asset / title
        Removed value: -"Asset"
      • addedInput schema / properties / asset / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / clip_id / description
        Added value: +"The transcript the cue is addressed against — the VO on a voiceover project, not the footage being shown. `asset` is what gets seen."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • removedInput schema / properties / occurrence / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / occurrence / description
        Added value: +"Disambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — 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 / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / phrase / description
        Added value: +"Address the cue by what is said instead of by index. It binds to the phrase's **first** word — \"from this word onward\"."
      • removedInput schema / properties / phrase / title
        Removed value: -"Phrase"
      • addedInput schema / properties / phrase / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / src_start / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / src_start / description
        Added value: +"Where inside `asset` the shot reads from, in that asset's own source seconds — the number `describe_ls` reports for a window. An in-point and never a range: unpinned, the shot reads from wherever the per-asset cursor had got to, which is right for re-using a clip and wrong for showing the thing you searched for. A card takes none."
      • removedInput schema / properties / src_start / title
        Removed value: -"Src Start"
      • addedInput schema / properties / src_start / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / word_index / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / word_index / description
        Added value: +"The word the picture starts on, in `clip_id`'s transcript. Give this or `phrase`, not both."
      • removedInput schema / properties / word_index / title
        Removed value: -"Word Index"
      • addedInput schema / properties / word_index / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"cue_addArguments"
    • Changedcue_ls9 fields changed
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"List one clip's cues. Omit it for the whole table."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "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 / title
        Removed value: -"cue_lsArguments"
    • Changedcue_reresolve11 fields changed
      • addedInput schema / properties / apply / description
        Added value: +"Rewrite `word_index` wherever the stored phrase still resolves to exactly one match. Off by default: it reports first, and anything ambiguous or unresolved is reported and left untouched either way."
      • removedInput schema / properties / apply / title
        Removed value: -"Apply"
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"Re-resolve one clip's entries. Omit it for every clip."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "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 / title
        Removed value: -"cue_reresolveArguments"
    • Changedcue_rm21 fields changed
      • addedInput schema / properties / after / description
        Added value: +"A forward cursor over a phrase's matches: 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 / clip_id / description
        Added value: +"The transcript the cue was addressed against."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • removedInput schema / properties / occurrence / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / occurrence / description
        Added value: +"Disambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — 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 / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / phrase / description
        Added value: +"Address it by wording instead; it resolves to its first word, the way `cue_add` placed it."
      • removedInput schema / properties / phrase / title
        Removed value: -"Phrase"
      • addedInput schema / properties / phrase / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / word_index / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / word_index / description
        Added value: +"The word the cue sits on. Give this or `phrase`."
      • removedInput schema / properties / word_index / title
        Removed value: -"Word Index"
      • addedInput schema / properties / word_index / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"cue_rmArguments"
    • Changedcut_by_time13 fields changed
      • addedInput schema / properties / confirm_suspect / description
        Added value: +"Go ahead even though a boundary word claims a suspect duration. Read the echoed words first — a suspect duration usually means whisper hid a retake inside that word, so the edge is not where it reads."
      • removedInput schema / properties / confirm_suspect / title
        Removed value: -"Confirm Suspect"
      • addedInput schema / properties / pad / description
        Added value: +"Widen only the outer edges of each requested span, in seconds."
      • removedInput schema / properties / pad / title
        Removed value: -"Pad"
      • 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"
        +]
      • 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 / spans / description
        Added value: +"Half-open `[start, end)` spans in the seconds **an export plays at** — what a person reports off a watch, not source time and not word indices. Every span resolves against the current timeline before any is applied, so a list of notes from one watch stays valid together; overlapping spans are refused rather than double-applied."
      • removedInput schema / properties / spans / title
        Removed value: -"Spans"
      • removedInput schema / title
        Removed value: -"cut_by_timeArguments"
    • Changedcut_by_transcript25 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The transcript the word ranges address."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / confirm_suspect / description
        Added value: +"Go ahead even though a boundary word claims a suspect duration. Read the echoed words first — a suspect duration usually means whisper hid a retake inside that word, so the edge is not where it reads."
      • removedInput schema / properties / confirm_suspect / title
        Removed value: -"Confirm Suspect"
      • removedInput schema / properties / cut / anyOf
        Removed value: -[
        -  {
        -    "items": {
        -      "items": {
        -        "type": "integer"
        -      },
        -      "type": "array"
        -    },
        -    "type": "array"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / cut / description
        Added value: +"Inclusive word ranges to remove, e.g. `[[30, 45], [120, 131]]`. Pass exactly one of `cut` or `keep`."
      • addedInput schema / properties / cut / items
        Added value: +{
        +  "items": {
        +    "type": "integer"
        +  },
        +  "type": "array"
        +}
      • removedInput schema / properties / cut / title
        Removed value: -"Cut"
      • addedInput schema / properties / cut / type
        Added value: +[
        +  "array",
        +  "null"
        +]
      • removedInput schema / properties / keep / anyOf
        Removed value: -[
        -  {
        -    "items": {
        -      "items": {
        -        "type": "integer"
        -      },
        -      "type": "array"
        -    },
        -    "type": "array"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / keep / description
        Added value: +"Inclusive word ranges to keep, everything else going. Pass exactly one of `cut` or `keep`."
      • addedInput schema / properties / keep / items
        Added value: +{
        +  "items": {
        +    "type": "integer"
        +  },
        +  "type": "array"
        +}
      • removedInput schema / properties / keep / title
        Removed value: -"Keep"
      • addedInput schema / properties / keep / type
        Added value: +[
        +  "array",
        +  "null"
        +]
      • addedInput schema / properties / pad / description
        Added value: +"Widen each range on both sides, in seconds, so the cut lands in the silence between words rather than on them. `pad_reach` names any neighbour the padding eats."
      • removedInput schema / properties / pad / title
        Removed value: -"Pad"
      • 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"
        +]
      • 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 / through_pause / description
        Added value: +"Extend each cut's trailing edge through the pause after its last word, wherever that gap was wide enough to draw a `[N.Ns]` marker — so cutting a phrase also takes the dead air after it. A no-op when the gap is short."
      • removedInput schema / properties / through_pause / title
        Removed value: -"Through Pause"
      • removedInput schema / title
        Removed value: -"cut_by_transcriptArguments"
    • Changeddescribe15 fields changed
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"One clip to describe. Omit it for every video clip not described yet; audio-only clips are refused, since their words are what `transcribe` indexes."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / force / description
        Added value: +"Describe clips that already have descriptions, replacing them. Without it they are skipped."
      • removedInput schema / properties / force / title
        Removed value: -"Force"
      • 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"
        +]
      • 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 / window / description
        Added value: +"Seconds of footage per description. Do not widen it to save time: a single pass over a whole clip describes six frames as six people, fluently, with nothing saying it is wrong."
      • removedInput schema / properties / window / title
        Removed value: -"Window"
      • removedInput schema / title
        Removed value: -"describeArguments"
    • Changeddescribe_ls13 fields changed
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"List only this clip's windows."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / contains / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / contains / description
        Added value: +"Keep only windows whose text holds every whitespace-separated term, case-insensitively — so `\"kitchen knife\"` matches \"a knife on the kitchen counter\"."
      • removedInput schema / properties / contains / title
        Removed value: -"Contains"
      • addedInput schema / properties / contains / type
        Added value: +[
        +  "string",
        +  "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 / title
        Removed value: -"describe_lsArguments"
    • Changeddoctor1 field changed
      • removedInput schema / title
        Removed value: -"doctorArguments"
    • Changedexport30 fields changed
      • removedInput schema / properties / export_format / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / export_format / description
        Added value: +"`kdenlive` (the default) writes an MLT project Kdenlive opens and melt renders. Pass null to render media instead. Other auto-editor targets — shotcut, premiere, resolve, final-cut-pro — pass straight through."
      • removedInput schema / properties / export_format / title
        Removed value: -"Export Format"
      • addedInput schema / properties / export_format / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / fps / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / fps / description
        Added value: +"The NLE timeline's frame rate, defaulting to the picture's own (30 for an audio-only project). It sets the render's rate too wherever proofcut owns the profile, and is ignored when auto-editor renders a single-source timeline."
      • removedInput schema / properties / fps / title
        Removed value: -"Fps"
      • addedInput schema / properties / fps / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / loudness / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / loudness / description
        Added value: +"Master the render to this many LUFS integrated: one gain and a true-peak limiter, measured before and after, and refused — leaving the render as it was — if the result misses by more than 1 LU. Render only."
      • removedInput schema / properties / loudness / title
        Removed value: -"Loudness"
      • addedInput schema / properties / loudness / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • addedInput schema / properties / output / description
        Added value: +"Where to write the project file or the render. A file argument, not a project selector: it writes where you say."
      • 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: +"A named quality bundle — `youtube`, `web`, `tiktok-reels`, or `custom` (which needs `resolution`) — meaningful only with `export_format=null`, since an NLE project file has no bitrate. `tiktok-reels` also **checks** that the project renders 9:16 and refuses otherwise; it never sets the shape. Use `canvas` for that."
      • removedInput schema / properties / preset / title
        Removed value: -"Preset"
      • addedInput schema / properties / preset / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / resolution / anyOf
        Removed value: -[
        -  {
        -    "items": {
        -      "type": "integer"
        -    },
        -    "type": "array"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / resolution / description
        Added value: +"`[width, height]`. It **letterboxes** the existing frame on the single-source render path rather than cropping or reframing it, and is refused outright on a melt (multi-source) project."
      • addedInput schema / properties / resolution / items
        Added value: +{
        +  "type": "integer"
        +}
      • removedInput schema / properties / resolution / title
        Removed value: -"Resolution"
      • addedInput schema / properties / resolution / type
        Added value: +[
        +  "array",
        +  "null"
        +]
      • addedInput schema / properties / true_peak / description
        Added value: +"The dBTP ceiling the loudness pass limits under. -1.0 by default."
      • removedInput schema / properties / true_peak / title
        Removed value: -"True Peak"
      • removedInput schema / title
        Removed value: -"exportArguments"
    • Changedfilm_check13 fields changed
      • 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"
        +]
      • 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 / reference / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / reference / description
        Added value: +"The delivered file this project is supposed to be. It is remembered, so a later call with no argument re-asks the same question against the same file."
      • removedInput schema / properties / reference / title
        Removed value: -"Reference"
      • addedInput schema / properties / reference / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / reset / description
        Added value: +"Drop the stored reference."
      • removedInput schema / properties / reset / title
        Removed value: -"Reset"
      • removedInput schema / title
        Removed value: -"film_checkArguments"
    • Changedfinish_check48 fields changed
      • addedInput schema / properties / black_min_duration / description
        Added value: +"Shortest black run to report, in seconds."
      • removedInput schema / properties / black_min_duration / title
        Removed value: -"Black Min Duration"
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"Diff against one transcript's expected words rather than all of them."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / duration_tolerance / description
        Added value: +"How far `final`'s duration may sit from the timeline's own arithmetic before it is a fault, in seconds."
      • removedInput schema / properties / duration_tolerance / title
        Removed value: -"Duration Tolerance"
      • addedInput schema / properties / final / description
        Added value: +"The delivered file to check — one an external mix pass produced, not a proofcut render. Every position reported is in this file's own absolute seconds."
      • removedInput schema / properties / final / title
        Removed value: -"Final"
      • removedInput schema / properties / fps / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / fps / description
        Added value: +"The frame grid the timeline's arithmetic is counted on. Defaults to the rate `export` would have picked."
      • removedInput schema / properties / fps / title
        Removed value: -"Fps"
      • addedInput schema / properties / fps / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / holds / anyOf
        Removed value: -[
        -  {
        -    "items": {
        -      "additionalProperties": true,
        -      "type": "object"
        -    },
        -    "type": "array"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / holds / description
        Added value: +"The holds to expect in `final`, resolved and offset the same way the stored ones are. Defaults to the project's own; pass a list (an empty one included) to check against a different set."
      • addedInput schema / properties / holds / items
        Added value: +{
        +  "additionalProperties": true,
        +  "type": "object"
        +}
      • removedInput schema / properties / holds / title
        Removed value: -"Holds"
      • addedInput schema / properties / holds / type
        Added value: +[
        +  "array",
        +  "null"
        +]
      • removedInput schema / properties / language / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / language / description
        Added value: +"Force a language code for the transcription."
      • removedInput schema / properties / language / title
        Removed value: -"Language"
      • addedInput schema / properties / language / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / overlap / description
        Added value: +"How far each window overlaps the one before, in seconds."
      • removedInput schema / properties / overlap / title
        Removed value: -"Overlap"
      • 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"
        +]
      • addedInput schema / properties / pix_th / description
        Added value: +"blackdetect's pixel threshold: how dark a pixel counts as black."
      • removedInput schema / properties / pix_th / title
        Removed value: -"Pix Th"
      • removedInput schema / properties / prepend_seconds / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / prepend_seconds / description
        Added value: +"How much runs before the timeline's first frame in `final` — a cold open concatenated on outside proofcut. Defaults to the project's stored head length."
      • removedInput schema / properties / prepend_seconds / title
        Removed value: -"Prepend Seconds"
      • addedInput schema / properties / prepend_seconds / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • addedInput schema / properties / recheck_pad / description
        Added value: +"How much to pad a dropped run when re-cutting it for its own transcription — the pass that separates a real miss from a false one at a window stitch."
      • removedInput schema / properties / recheck_pad / title
        Removed value: -"Recheck Pad"
      • removedInput schema / properties / transcript_path / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / transcript_path / description
        Added value: +"An existing transcription of `final`, to diff again without re-transcribing."
      • removedInput schema / properties / transcript_path / title
        Removed value: -"Transcript Path"
      • addedInput schema / properties / transcript_path / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / window / description
        Added value: +"Length of each transcription window, in seconds."
      • removedInput schema / properties / window / title
        Removed value: -"Window"
      • removedInput schema / properties / windowed_model / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / windowed_model / description
        Added value: +"The whisper model for the windowed transcription of `final`. A deliberately small one is the default, since the windowed pass runs over twice the audio."
      • removedInput schema / properties / windowed_model / title
        Removed value: -"Windowed Model"
      • addedInput schema / properties / windowed_model / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"finish_checkArguments"
    • Changedfinish_report11 fields changed
      • addedInput schema / properties / continuity / description
        Added value: +"Add the continuity finding counts by kind and how many are accepted. Off by default — its stub half pays the same scene-cut decode `framing` does."
      • removedInput schema / properties / continuity / title
        Removed value: -"Continuity"
      • addedInput schema / properties / framing / description
        Added value: +"Add stale-framing numbers. Off by default because it decodes placed footage for a scene-cut scan (5.7s wall, 46s of CPU on the film, uncached, every call). Off, `framing` is null, which means *not measured* rather than nothing stale."
      • removedInput schema / properties / framing / title
        Removed value: -"Framing"
      • addedInput schema / properties / holds / description
        Added value: +"Add the per-hold seam and transcription report against the last render. Off by default for the same reason: it decodes and transcribes render spans. Null when not asked for, and also null when nothing has rendered here yet."
      • removedInput schema / properties / holds / title
        Removed value: -"Holds"
      • 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 / title
        Removed value: -"finish_reportArguments"
    • Changedfonts7 fields changed
      • addedInput schema / properties / install / description
        Added value: +"Copy the vendored face where this OS's font system looks (fontconfig, CoreText or DirectWrite). Off by default, because it writes into the home directory."
      • removedInput schema / properties / install / title
        Removed value: -"Install"
      • removedInput schema / properties / path / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / path / description
        Added value: +"A project directory, or nothing. Omitting it means *no project* here — never the bound one — and reports proofcut's own default caption face; with a project, it reports the face that project's caption style would burn."
      • removedInput schema / properties / path / title
        Removed value: -"Path"
      • addedInput schema / properties / path / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"fontsArguments"
    • Changedfootage_sheet19 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The registered clip to browse. This sheet reads the clip's **own source**, so it needs no edit, no cues and no transcript."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / interval / description
        Added value: +"Seconds between tiles when drawing by interval (`interval`, or `auto` on a clip with no descriptions). It is `describe`'s own window length, so a tile lines up with a description."
      • removedInput schema / properties / interval / title
        Removed value: -"Interval"
      • addedInput schema / properties / mode / description
        Added value: +"Which instants to draw: `auto` (the default) uses the clip's described windows if it has any and the interval otherwise, and never scans; `interval` draws every `interval` seconds; `describe` draws one tile per described window, beside its text; `scenes` draws one per detected cut. Scenes is opt-in because its yield is uncorrelated with anything the caller knows — 0 cuts on a 29s b-roll loop, 17 in 60s of gameplay — and it decodes the whole clip."
      • removedInput schema / properties / mode / title
        Removed value: -"Mode"
      • removedInput schema / properties / out / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / out / description
        Added value: +"Write the image to this path as well, replacing whatever file is there. Unset, it goes to the project's own sheet cache and only the bytes come back."
      • removedInput schema / properties / out / title
        Removed value: -"Out"
      • addedInput schema / properties / out / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / page / description
        Added value: +"Which page of rows to draw, from 1. Unset, the first."
      • removedInput schema / properties / page / title
        Removed value: -"Page"
      • 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"
        +]
      • addedInput schema / properties / per_page / description
        Added value: +"Rows per page. `null` draws the whole project in one montage, which returns a path rather than readable bytes — for a person to open, not for an agent to read."
      • removedInput schema / properties / per_page / title
        Removed value: -"Per Page"
      • removedInput schema / title
        Removed value: -"footage_sheetArguments"
    • Changedget_transcript20 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip to read."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • removedInput schema / properties / first / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / first / description
        Added value: +"First word index to return, inclusive."
      • removedInput schema / properties / first / title
        Removed value: -"First"
      • addedInput schema / properties / first / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / properties / last / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / last / description
        Added value: +"Last word index to return, inclusive."
      • removedInput schema / properties / last / title
        Removed value: -"Last"
      • addedInput schema / properties / last / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • addedInput schema / properties / limit
        Added value: +{
        +  "default": 300,
        +  "description": "Most words to return in one call, counted from `first`. The reply's `next_first` says where to continue. Bounded by default because a whole transcript can be past what a client will put in context.",
        +  "type": "integer"
        +}
      • 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 / search / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / search / description
        Added value: +"Return each match as a word range ready to hand to `cut_by_transcript`, instead of the whole transcript. Prefer it: a transcript is a lot of words to read to find two."
      • removedInput schema / properties / search / title
        Removed value: -"Search"
      • addedInput schema / properties / search / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"get_transcriptArguments"
    • Changedhead33 fields changed
      • removedInput schema / properties / asset / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / asset / description
        Added value: +"The footage the cold open plays, as a registered clip id — never `card:name`. A cold open is real footage with real dialogue by definition, and `verify` accounts for its words rather than forbidding them."
      • removedInput schema / properties / asset / title
        Removed value: -"Asset"
      • addedInput schema / properties / asset / type
        Added value: +[
        +  "string",
        +  "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 head. Unlike `tail`'s fade this is drawn, and it is the whole reason the feature exists — a hard butt-join between room tone and digital silence is exactly the seam a missing fade produces."
      • 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 where the cold open hands over to the film."
      • removedInput schema / properties / fade_out / title
        Removed value: -"Fade Out"
      • addedInput schema / properties / fade_out / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / gain_db / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / gain_db / description
        Added value: +"A flat level shift for the cold open, in dB, distinct from the fades. 0.0 is unity."
      • removedInput schema / properties / gain_db / title
        Removed value: -"Gain Db"
      • addedInput schema / properties / gain_db / type
        Added value: +[
        +  "number",
        +  "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"
        +]
      • 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 cold open entirely."
      • removedInput schema / properties / reset / title
        Removed value: -"Reset"
      • removedInput schema / properties / seconds / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / seconds / description
        Added value: +"How long the cold open runs. Setting `asset` or `seconds` for the first time needs both together; either alone afterwards updates just that field."
      • removedInput schema / properties / seconds / title
        Removed value: -"Seconds"
      • addedInput schema / properties / seconds / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / src_start / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / src_start / description
        Added value: +"Where inside that asset the cold open reads from, in source seconds. 0.0 on a first set."
      • removedInput schema / properties / src_start / title
        Removed value: -"Src Start"
      • addedInput schema / properties / src_start / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"headArguments"
    • Changedhear21 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip whose source audio to listen to."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / end / description
        Added value: +"Where to stop, in the same source seconds. Past the end of the clip it is refused rather than clamped."
      • removedInput schema / properties / end / title
        Removed value: -"End"
      • removedInput schema / properties / language / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / language / description
        Added value: +"Force a language code, e.g. `en`. Unset, whisper detects it."
      • removedInput schema / properties / language / title
        Removed value: -"Language"
      • addedInput schema / properties / language / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / model / description
        Added value: +"The whisper model for this windowed pass."
      • removedInput schema / properties / model / title
        Removed value: -"Model"
      • addedInput schema / properties / overlap / description
        Added value: +"How far each window overlaps the one before it, in seconds. The overlap is what stops a word straddling a boundary from being lost between two windows."
      • removedInput schema / properties / overlap / title
        Removed value: -"Overlap"
      • 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"
        +]
      • addedInput schema / properties / start / description
        Added value: +"Where to start listening, in that clip's own **source** seconds — never timeline seconds and never a word index."
      • removedInput schema / properties / start / title
        Removed value: -"Start"
      • addedInput schema / properties / window / description
        Added value: +"Length of each window, in seconds."
      • removedInput schema / properties / window / title
        Removed value: -"Window"
      • removedInput schema / title
        Removed value: -"hearArguments"
    • Changedhold_add67 fields changed
      • addedInput schema / properties / after / description
        Added value: +"A forward cursor over the matches of `gap_phrase`/`cue_phrase`/`asset_phrase`: 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 film clip whose own audio plays in the gap, and whose picture the cue pins."
      • removedInput schema / properties / asset / title
        Removed value: -"Asset"
      • addedInput schema / properties / asset / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / asset_phrase / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / asset_phrase / description
        Added value: +"The line to play, resolved against `asset`'s **own** transcript, binding its first and last words together. One phrase is the source of truth for both ends; hand-typed indices drift the moment a transcript changes under them."
      • removedInput schema / properties / asset_phrase / title
        Removed value: -"Asset Phrase"
      • addedInput schema / properties / asset_phrase / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / clip_id / description
        Added value: +"The VO track the gap opens in."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • removedInput schema / properties / cue_phrase / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / cue_phrase / description
        Added value: +"Address the cue by wording; it binds its **first** word."
      • removedInput schema / properties / cue_phrase / title
        Removed value: -"Cue Phrase"
      • addedInput schema / properties / cue_phrase / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / cue_word_index / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / cue_word_index / description
        Added value: +"The word the picture cue for `asset` is placed on."
      • removedInput schema / properties / cue_word_index / title
        Removed value: -"Cue Word Index"
      • addedInput schema / properties / cue_word_index / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • 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 held audio comes in. Re-settable."
      • 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. Re-settable."
      • removedInput schema / properties / fade_out / title
        Removed value: -"Fade Out"
      • addedInput schema / properties / fade_out / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / gap_phrase / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / gap_phrase / description
        Added value: +"Address the gap by wording; it binds its **last** word, since the gap opens right after it."
      • removedInput schema / properties / gap_phrase / title
        Removed value: -"Gap Phrase"
      • addedInput schema / properties / gap_phrase / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / gap_word_index / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / gap_word_index / description
        Added value: +"The word the gap opens right after. With `clip_id` it is the hold's address, and a second `hold_add` at the same address is refused."
      • removedInput schema / properties / gap_word_index / title
        Removed value: -"Gap Word Index"
      • addedInput schema / properties / gap_word_index / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / properties / head_margin / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / head_margin / description
        Added value: +"Seconds kept before the line, so it does not start on the word. Re-settable on an already-spliced hold."
      • removedInput schema / properties / head_margin / title
        Removed value: -"Head Margin"
      • addedInput schema / properties / head_margin / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / occurrence / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / occurrence / description
        Added value: +"Disambiguate `gap_phrase`/`cue_phrase`/`asset_phrase` 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"
        +]
      • 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 / tail_margin / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / tail_margin / description
        Added value: +"Seconds kept after the line. Re-settable."
      • removedInput schema / properties / tail_margin / title
        Removed value: -"Tail Margin"
      • addedInput schema / properties / tail_margin / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / under / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / under / description
        Added value: +"How far below the VO the held audio sits, in LU. Re-settable."
      • removedInput schema / properties / under / title
        Removed value: -"Under"
      • addedInput schema / properties / under / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / word_index_first / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / word_index_first / description
        Added value: +"First word of the line to play, in **`asset`'s own** transcript — not the VO's."
      • removedInput schema / properties / word_index_first / title
        Removed value: -"Word Index First"
      • addedInput schema / properties / word_index_first / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / properties / word_index_last / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / word_index_last / description
        Added value: +"Last word of that line. With `word_index_first` it is one-way once spliced: resizing means `hold_rm` then `hold_add`, or `undo`."
      • removedInput schema / properties / word_index_last / title
        Removed value: -"Word Index Last"
      • addedInput schema / properties / word_index_last / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"hold_addArguments"
    • Changedhold_check7 fields changed
      • 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"
        +]
      • addedInput schema / properties / render / description
        Added value: +"The rendered file to listen to. Each hold's span is resolved live against the current edit and transcribed off this file."
      • removedInput schema / properties / render / title
        Removed value: -"Render"
      • removedInput schema / title
        Removed value: -"hold_checkArguments"
    • Changedhold_ls5 fields changed
      • 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 / title
        Removed value: -"hold_lsArguments"
    • Changedhold_rm9 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The VO track the hold was spliced into."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / gap_word_index / description
        Added value: +"The hold's address, with `clip_id`. The record and its owned cue go; the spliced silence stays, since there is no clean un-splice — only `undo`."
      • removedInput schema / properties / gap_word_index / title
        Removed value: -"Gap Word Index"
      • 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 / title
        Removed value: -"hold_rmArguments"
    • Changedhold_under45 fields changed
      • 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"
    • Changedhold_under_rm9 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The VO track the entry was addressed against."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • 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"
        +]
      • addedInput schema / properties / word_index_start / description
        Added value: +"The span's first VO word — the entry's address, with `clip_id`."
      • removedInput schema / properties / word_index_start / title
        Removed value: -"Word Index Start"
      • removedInput schema / title
        Removed value: -"hold_under_rmArguments"
    • Changedimport_edit13 fields changed
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"The registered clip to attribute a single-source document to, when its media sits at a path this project does not know."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / document / description
        Added value: +"The `.kdenlive` or `.mlt` playlist somebody already trimmed by hand. Every clip it references has to be registered already; ones that do not match a registered clip by resolved path are named rather than imported behind your back."
      • removedInput schema / properties / document / title
        Removed value: -"Document"
      • 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"
        +]
      • 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 / title
        Removed value: -"import_editArguments"
    • Changedimport_media21 fields changed
      • removedInput schema / properties / audio_stream / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / audio_stream / description
        Added value: +"Keep one of a container's audio streams and drop the rest, numbered from 0 in ffmpeg's own audio ordering — not the container's absolute stream index, which is a different number once there is video."
      • removedInput schema / properties / audio_stream / title
        Removed value: -"Audio Stream"
      • addedInput schema / properties / audio_stream / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"The id every later tool addresses this clip by. Unset, one is derived from the filename. Keep it short: it becomes part of cache paths, and a stock Windows measures those against 248 characters."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / copy / description
        Added value: +"Copy the media into the project instead of referencing it where it sits. Off by default — a reference costs no disk, and it is also the fallback where symlinks are rejected."
      • removedInput schema / properties / copy / title
        Removed value: -"Copy"
      • addedInput schema / properties / mix / description
        Added value: +"Sum a container's audio streams into one track, for two mics on one performance. It writes a derived copy every later op reads without knowing it."
      • removedInput schema / properties / mix / title
        Removed value: -"Mix"
      • 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"
        +]
      • addedInput schema / properties / sheet / description
        Added value: +"Draw a contact sheet of the clip's first ten seconds onto the returned record. On by default, because a first look that has to be asked for is one nobody takes."
      • removedInput schema / properties / sheet / title
        Removed value: -"Sheet"
      • addedInput schema / properties / source / description
        Added value: +"The media file to register. A file argument rather than a project selector, so it is deliberately left unconfined — footage usually lives outside the project."
      • removedInput schema / properties / source / title
        Removed value: -"Source"
      • removedInput schema / title
        Removed value: -"import_mediaArguments"
    • Changedinit9 fields changed
      • removedInput schema / properties / name / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / name / description
        Added value: +"A name for the project, recorded in the manifest. Unset, the directory's own name is used."
      • removedInput schema / properties / name / title
        Removed value: -"Name"
      • addedInput schema / properties / name / type
        Added value: +[
        +  "string",
        +  "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 / title
        Removed value: -"initArguments"
    • Changedlist_media9 fields changed
      • 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"
        +]
      • addedInput schema / properties / recursive / description
        Added value: +"Walk subdirectories too. On by default."
      • removedInput schema / properties / recursive / title
        Removed value: -"Recursive"
      • addedInput schema / properties / source_dir / description
        Added value: +"The directory to list. It names where footage lives rather than which project, so it is deliberately not confined to the bound project."
      • removedInput schema / properties / source_dir / title
        Removed value: -"Source Dir"
      • removedInput schema / title
        Removed value: -"list_mediaArguments"
    • Changedlocate33 fields changed
      • addedInput schema / properties / after / description
        Added value: +"A forward cursor over a phrase's matches: 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 / clip_id / description
        Added value: +"The transcript, or the recording, the address belongs to."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • removedInput schema / properties / first / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / first / description
        Added value: +"First word index, inclusive. Address it one way per call: `first`/`last`, `source_start`/`source_end`, or `phrase`."
      • removedInput schema / properties / first / title
        Removed value: -"First"
      • addedInput schema / properties / first / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / properties / last / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / last / description
        Added value: +"Last word index, inclusive. Defaults to `first`."
      • removedInput schema / properties / last / title
        Removed value: -"Last"
      • addedInput schema / properties / last / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / properties / occurrence / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / occurrence / description
        Added value: +"Disambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — 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 / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / phrase / description
        Added value: +"Locate by wording. A phrase is naturally a range, so it resolves straight to first and last with no edge to pick."
      • removedInput schema / properties / phrase / title
        Removed value: -"Phrase"
      • addedInput schema / properties / phrase / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / source_end / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / source_end / description
        Added value: +"End of the source interval, in the recording's own seconds."
      • removedInput schema / properties / source_end / title
        Removed value: -"Source End"
      • addedInput schema / properties / source_end / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / source_start / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / source_start / description
        Added value: +"Seconds into the original recording. Omit `source_end` to locate an instant."
      • removedInput schema / properties / source_start / title
        Removed value: -"Source Start"
      • addedInput schema / properties / source_start / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"locateArguments"
    • Changedmigrate_project7 fields changed
      • 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"
        +]
      • 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 / title
        Removed value: -"migrate_projectArguments"
    • Changedmusic75 fields changed
      • 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"
    • Changedpack_activate9 fields changed
      • 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"
        +]
      • 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 / variant / description
        Added value: +"Which already-snapshotted variant to switch to. No file is re-read, and an unknown name is refused by listing the ones that are available."
      • removedInput schema / properties / variant / title
        Removed value: -"Variant"
      • removedInput schema / title
        Removed value: -"pack_activateArguments"
    • Changedpack_apply15 fields changed
      • addedInput schema / properties / allow_fallback / description
        Added value: +"Accept a declared CSS fallback for a font family that does not actually draw on this machine, recording which was used. Without it, a family that does not draw refuses the whole call."
      • removedInput schema / properties / allow_fallback / title
        Removed value: -"Allow Fallback"
      • addedInput schema / properties / install_fonts / description
        Added value: +"Vendor the pack's own `fonts/` directory, if it ships one. Off by default, since it writes into `$HOME`."
      • removedInput schema / properties / install_fonts / title
        Removed value: -"Install Fonts"
      • addedInput schema / properties / pack_path / description
        Added value: +"The pack file to load. An external file, never confined to the project — a pack usually lives in a separate branding repo — and nothing after this call depends on it staying reachable."
      • removedInput schema / properties / pack_path / title
        Removed value: -"Pack Path"
      • 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"
        +]
      • 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 / variant / description
        Added value: +"Which resolved variant to activate. Every declared variant is snapshotted regardless, so `pack_activate` can switch later with no file re-read."
      • removedInput schema / properties / variant / title
        Removed value: -"Variant"
      • removedInput schema / title
        Removed value: -"pack_applyArguments"
    • Changedpack_apply_captions9 fields changed
      • 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"
        +]
      • 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 / preset / description
        Added value: +"Which caption preset of the active variant to apply, through the ordinary `caption_style` call. This is the only thing that restyles captions from a pack; `pack_apply` never does it on its own."
      • removedInput schema / properties / preset / title
        Removed value: -"Preset"
      • removedInput schema / title
        Removed value: -"pack_apply_captionsArguments"
    • Changedpack_show13 fields changed
      • removedInput schema / properties / pack_path / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / pack_path / description
        Added value: +"Read and resolve this pack file fresh, needing no project. With `path` as well, it compares what the file says now against what the project is still running."
      • removedInput schema / properties / pack_path / title
        Removed value: -"Pack Path"
      • addedInput schema / properties / pack_path / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / path / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / path / description
        Added value: +"A project directory, or nothing. Omitting it means *no project* here — never the bound one — so `pack_path` alone reads the file fresh; given, it reports what that project has applied."
      • removedInput schema / properties / path / title
        Removed value: -"Path"
      • addedInput schema / properties / path / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / variant / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / variant / description
        Added value: +"Report one variant rather than all of them."
      • removedInput schema / properties / variant / title
        Removed value: -"Variant"
      • addedInput schema / properties / variant / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"pack_showArguments"
    • Changedpack_status5 fields changed
      • 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 / title
        Removed value: -"pack_statusArguments"
    • Changedping2 fields changed
      • removedInput schema / title
        Removed value: -"pingArguments"
      • changedOutput schema / additionalProperties
        Previous value: -{
        -  "type": "string"
        -}New value: +true
    • Changedproperties13 fields changed
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"Add this clip's assets entry, framing windows and cue table to the report."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "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 / word_index / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / word_index / description
        Added value: +"With `clip_id`, add the cue at that word — or, when there is none, the word plus three either side. It needs `clip_id`."
      • removedInput schema / properties / word_index / title
        Removed value: -"Word Index"
      • addedInput schema / properties / word_index / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"propertiesArguments"
    • Changedproxy_transcode9 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip the preview cannot decode. A clip that already plays is refused, and so is one with no decodable streams — that is a broken file, not a codec problem."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / force / description
        Added value: +"Rebuild a proxy that is already current. It touches nothing authored: a proxy is a preview artefact the manifest never records, so no render can reach one. It overrides neither refusal."
      • removedInput schema / properties / force / title
        Removed value: -"Force"
      • 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 / title
        Removed value: -"proxy_transcodeArguments"
    • Changedreel23 fields changed
      • removedInput schema / properties / canvas / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / canvas / description
        Added value: +"The shape to set on the derived project only, e.g. `1080x1920`. Setting it on the film instead is what deriving exists to avoid — a canvas is project state and would stay."
      • removedInput schema / properties / canvas / title
        Removed value: -"Canvas"
      • addedInput schema / properties / canvas / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / confirm_suspect / description
        Added value: +"Go ahead even though a boundary word claims a suspect duration. Read the echoed words first — a suspect duration usually means whisper hid a retake inside that word, so the edge is not where it reads."
      • removedInput schema / properties / confirm_suspect / title
        Removed value: -"Confirm Suspect"
      • addedInput schema / properties / dest / description
        Added value: +"Where the derived project is created. It is a project selector too, not a file, so a bound server confines it to the same tree as `path` rather than letting a reel be written anywhere on disk."
      • removedInput schema / properties / dest / title
        Removed value: -"Dest"
      • addedInput schema / properties / end / description
        Added value: +"Where it ends, in those same render seconds. `start`/`end` name the span to **keep**, the opposite direction from every other tool here."
      • removedInput schema / properties / end / title
        Removed value: -"End"
      • removedInput schema / properties / name / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / name / description
        Added value: +"A name for the derived project. Unset, it is derived from `dest`."
      • removedInput schema / properties / name / title
        Removed value: -"Name"
      • addedInput schema / properties / name / type
        Added value: +[
        +  "string",
        +  "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"
        +]
      • 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 / start / description
        Added value: +"Where the reel begins, in the seconds **an export plays at** — the same numbers `cut_by_time` takes, read off a watch."
      • removedInput schema / properties / start / title
        Removed value: -"Start"
      • removedInput schema / title
        Removed value: -"reelArguments"
    • Changedreframe28 fields changed
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip to read or frame. Omit it to read the crops in force for every clip, including how much of each is kept."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / fill
        Added value: +{
        +  "default": null,
        +  "description": "`blur` draws this window **blur-filled**: the whole source contained in the frame, over a blurred, darkened copy of the same moment covering the canvas. For a shot every crop loses something from and no split divides. Takes no `rect`, `pane` or `interp`; set `src_start` for one shot.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedInput schema / properties / interp / description
        Added value: +"Slide into this window from whatever governed before it instead of stepping to it. It needs `src_start` past 0 — there is nothing before the head of the source to slide from — and cannot be combined with `pane`."
      • removedInput schema / properties / interp / title
        Removed value: -"Interp"
      • removedInput schema / properties / pane / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / pane / description
        Added value: +"A second rect making this window a **stacked split**: `rect` on top, `pane` below, each about twice the width one 9:16 window gets. For the shot one window cannot frame. Both are grown to the full source height — nothing masks a pane, so a shorter crop scales into the other half at exit 0."
      • removedInput schema / properties / pane / title
        Removed value: -"Pane"
      • addedInput schema / properties / pane / type
        Added value: +[
        +  "string",
        +  "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"
        +]
      • 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 / rect / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / rect / description
        Added value: +"`X,Y,W,H` in that clip's **own source pixels** — the region kept. An override is a floor rather than a frame: a rect that is not the canvas's shape is grown to it, so nothing named is pushed off screen, and the reply gives both `asked` and the `crop` it became."
      • removedInput schema / properties / rect / title
        Removed value: -"Rect"
      • addedInput schema / properties / rect / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / reset / description
        Added value: +"With `clip_id`, drop that clip's overrides; with `src_start` as well, only the window there. Alone, drop every override."
      • removedInput schema / properties / reset / title
        Removed value: -"Reset"
      • removedInput schema / properties / src_start / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / src_start / description
        Added value: +"Frame a **shot** rather than a clip: seconds into that clip's own source, the rect holding from there until the next window. Because the address is the source's own clock, a clip used seven times picks up the right window at each placement. Omitted, it is the window from the head of the file."
      • removedInput schema / properties / src_start / title
        Removed value: -"Src Start"
      • addedInput schema / properties / src_start / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"reframeArguments"
    • Changedreframe_coverage11 fields changed
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"Walk one clip's placements. Omit it for the whole project."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "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"
        +]
      • addedInput schema / properties / threshold / description
        Added value: +"How strong a scene change has to be to **demand** a window. Boundaries are scored against every detected cut rather than only these, since a cut too weak to demand a window still explains one."
      • removedInput schema / properties / threshold / title
        Removed value: -"Threshold"
      • removedInput schema / title
        Removed value: -"reframe_coverageArguments"
    • Changedreframe_detect17 fields changed
      • addedInput schema / properties / apply / description
        Added value: +"Write the proposals through `reframe`. Off by default — the opposite of `cut --plan` — because the pass runs 24% of a window's width out on average. Call `reframe_sheet` and look first. It never writes over a window that is already an override."
      • removedInput schema / properties / apply / title
        Removed value: -"Apply"
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"Propose windows for one clip. Omit it for every placed clip."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / frames / description
        Added value: +"How many moments to sample inside each window before centring it on the faces found there."
      • removedInput schema / properties / frames / title
        Removed value: -"Frames"
      • 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"
        +]
      • addedInput schema / properties / split / description
        Added value: +"Offer a stacked split where every sampled frame holds two or three faces one window cannot hold. On by default; `false` turns the offer off."
      • removedInput schema / properties / split / title
        Removed value: -"Split"
      • addedInput schema / properties / threshold / description
        Added value: +"How strong a scene change has to be to count as a camera cut, 0–1. 0.15 is pinned by judging detections on real footage: every candidate from 0.141 to 0.244 was a real cut, and the first non-cut is 0.137."
      • removedInput schema / properties / threshold / title
        Removed value: -"Threshold"
      • removedInput schema / title
        Removed value: -"reframe_detectArguments"
    • Changedreframe_sheet22 fields changed
      • addedInput schema / properties / extremes / description
        Added value: +"Draw the subject's own leftmost and rightmost moments, worst first, instead of fixed fractions — the rect does not move inside a stretch, so that is where a static window is worst. Off by default: it costs the face detector and about half a second a probe. Read `worst_offset` beside `multi_face`, never after it."
      • removedInput schema / properties / extremes / title
        Removed value: -"Extremes"
      • removedInput schema / properties / moments / anyOf
        Removed value: -[
        -  {
        -    "items": {
        -      "type": "number"
        -    },
        -    "type": "array"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / moments / description
        Added value: +"Fractions of each window to draw tiles at, e.g. `[0.1, 0.5, 0.9]`. A tile is evidence about one instant while a rect is a claim about a stretch, so where the subject moves these decide what the sheet can see. Refused alongside `extremes`."
      • addedInput schema / properties / moments / items
        Added value: +{
        +  "type": "number"
        +}
      • removedInput schema / properties / moments / title
        Removed value: -"Moments"
      • addedInput schema / properties / moments / type
        Added value: +[
        +  "array",
        +  "null"
        +]
      • removedInput schema / properties / out / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / out / description
        Added value: +"Write the image to this path as well, replacing whatever file is there. Unset, it goes to the project's own sheet cache and only the bytes come back."
      • removedInput schema / properties / out / title
        Removed value: -"Out"
      • addedInput schema / properties / out / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / page / description
        Added value: +"Which page of rows to draw, from 1. Unset, the first."
      • removedInput schema / properties / page / title
        Removed value: -"Page"
      • 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 / per_page / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / per_page / description
        Added value: +"Rows per page. `null` draws the whole project in one montage, which returns a path rather than readable bytes — for a person to open, not for an agent to read."
      • removedInput schema / properties / per_page / title
        Removed value: -"Per Page"
      • addedInput schema / properties / per_page / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"reframe_sheetArguments"
    • Changedresolve_phrase17 fields changed
      • addedInput schema / properties / after / description
        Added value: +"A forward cursor over a phrase's matches: 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 / clip_id / description
        Added value: +"The transcript to resolve against."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / fuzzy / description
        Added value: +"Fall back to a fuzzy match when nothing matches exactly. A fuzzy hit sets `ratio` and is never reported as an exact one; `false` refuses instead."
      • removedInput schema / properties / fuzzy / title
        Removed value: -"Fuzzy"
      • removedInput schema / properties / occurrence / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / occurrence / description
        Added value: +"Disambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — 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"
        +]
      • addedInput schema / properties / phrase / description
        Added value: +"The words to find, as they were spoken."
      • removedInput schema / properties / phrase / title
        Removed value: -"Phrase"
      • removedInput schema / title
        Removed value: -"resolve_phraseArguments"
    • Changedrestore13 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip whose cut material to bring back."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / pad / description
        Added value: +"Pass the same `pad` the original cut used to bring its padding sliver back, not only the words."
      • removedInput schema / properties / pad / title
        Removed value: -"Pad"
      • 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"
        +]
      • 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 / ranges / description
        Added value: +"Inclusive word ranges, the shape `cut_by_transcript` takes. Only the part the edit says is actually absent comes back; material still present is left alone."
      • removedInput schema / properties / ranges / title
        Removed value: -"Ranges"
      • removedInput schema / title
        Removed value: -"restoreArguments"
    • Changedreview_add15 fields changed
      • removedInput schema / properties / baseline / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / baseline / description
        Added value: +"Required for `kind=\"control\"`: the name of the already-registered item this one claims to be identical to. Both files' sha256 must match or the call is refused — nothing is labelled a control here unless it is byte-identical to what it claims."
      • removedInput schema / properties / baseline / title
        Removed value: -"Baseline"
      • addedInput schema / properties / baseline / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / kind / description
        Added value: +"One of `render`, `sheet`, `ab`, `control`."
      • removedInput schema / properties / kind / title
        Removed value: -"Kind"
      • addedInput schema / properties / name / description
        Added value: +"What to call this item in the served round. Re-using a name replaces that entry while its verdict stays attached."
      • removedInput schema / properties / name / title
        Removed value: -"Name"
      • 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"
        +]
      • addedInput schema / properties / source / description
        Added value: +"The file to point at — never copied. A render already lives in `renders/`, a sheet in the sheet directory."
      • removedInput schema / properties / source / title
        Removed value: -"Source"
      • removedInput schema / title
        Removed value: -"review_addArguments"
    • Changedreview_list5 fields changed
      • 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 / title
        Removed value: -"review_listArguments"
    • Changedreview_verdict13 fields changed
      • addedInput schema / properties / name / description
        Added value: +"The registered item being answered. An unregistered name is refused."
      • removedInput schema / properties / name / title
        Removed value: -"Name"
      • removedInput schema / properties / note / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / note / description
        Added value: +"Anything to record beside the verdict."
      • removedInput schema / properties / note / title
        Removed value: -"Note"
      • addedInput schema / properties / note / type
        Added value: +[
        +  "string",
        +  "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"
        +]
      • addedInput schema / properties / verdict / description
        Added value: +"The answer, as free text rather than an enum — past rounds answered yes/no, loop/hold, or a specific choice by name, and a fixed vocabulary would misfit whichever question the next round asks."
      • removedInput schema / properties / verdict / title
        Removed value: -"Verdict"
      • removedInput schema / title
        Removed value: -"review_verdictArguments"
    • Changedseed_timeline19 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip to lay down as the timeline."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • removedInput schema / properties / edit_expr / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / edit_expr / description
        Added value: +"auto-editor's edit language, passed straight through — e.g. `(or audio:0.03 motion:0.06)`. It replaces the threshold-based rule."
      • removedInput schema / properties / edit_expr / title
        Removed value: -"Edit Expr"
      • addedInput schema / properties / edit_expr / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / margin / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / margin / description
        Added value: +"How much to leave either side of kept audio, in auto-editor's own notation (e.g. `0.2s`), so an edge lands in the silence rather than on the breath."
      • removedInput schema / properties / margin / title
        Removed value: -"Margin"
      • addedInput schema / properties / margin / type
        Added value: +[
        +  "string",
        +  "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"
        +]
      • addedInput schema / properties / remove_silences / description
        Added value: +"Silence-cut the clip on the way in, through auto-editor. On by default; false lays the whole clip down untouched."
      • removedInput schema / properties / remove_silences / title
        Removed value: -"Remove Silences"
      • addedInput schema / properties / threshold / description
        Added value: +"auto-editor's audio loudness threshold, 0–1. Lower keeps quieter material."
      • removedInput schema / properties / threshold / title
        Removed value: -"Threshold"
      • removedInput schema / title
        Removed value: -"seed_timelineArguments"
    • Changedshot_sheet13 fields changed
      • removedInput schema / properties / out / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / out / description
        Added value: +"Write the image to this path as well, replacing whatever file is there. Unset, it goes to the project's own sheet cache and only the bytes come back."
      • removedInput schema / properties / out / title
        Removed value: -"Out"
      • addedInput schema / properties / out / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / page / description
        Added value: +"Which page of rows to draw, from 1. Unset, the first."
      • removedInput schema / properties / page / title
        Removed value: -"Page"
      • 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"
        +]
      • addedInput schema / properties / per_page / description
        Added value: +"Rows per page. `null` draws the whole project in one montage, which returns a path rather than readable bytes — for a person to open, not for an agent to read."
      • removedInput schema / properties / per_page / title
        Removed value: -"Per Page"
      • removedInput schema / title
        Removed value: -"shot_sheetArguments"
    • Changedspeech_overlap29 fields changed
      • addedInput schema / properties / at / description
        Added value: +"Where the clip would sit on the timeline, in seconds."
      • removedInput schema / properties / at / title
        Removed value: -"At"
      • addedInput schema / properties / cap / description
        Added value: +"How far a word's claimed duration is trusted, as a multiple of the median. Whisper inflates the word after a collapsed retake until it covers the second take, so believing the claim masks exactly the hole being looked for — 3x is the same multiple a suspect duration is flagged at."
      • removedInput schema / properties / cap / title
        Removed value: -"Cap"
      • addedInput schema / properties / clip_evidence / description
        Added value: +"`auto` (the default) uses the clip's transcript if it has one and its energy envelope otherwise, saying which in the result. `transcript` refuses a clip with none; `energy` forces the envelope even on a clip that has one — sound rather than speech, which counts a sting or a swell too."
      • removedInput schema / properties / clip_evidence / title
        Removed value: -"Clip Evidence"
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip whose placement is being proposed. It need not be on the timeline yet, and usually is not."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • removedInput schema / properties / clip_in / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_in / description
        Added value: +"Where inside the clip the proposed placement starts, in its own source seconds. Unset, its head."
      • removedInput schema / properties / clip_in / title
        Removed value: -"Clip In"
      • addedInput schema / properties / clip_in / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / clip_out / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_out / description
        Added value: +"Where it ends, in the clip's own source seconds. Unset, its end."
      • removedInput schema / properties / clip_out / title
        Removed value: -"Clip Out"
      • addedInput schema / properties / clip_out / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • addedInput schema / properties / max_gap / description
        Added value: +"How short a silence may be and still be swallowed into one speech run, in seconds — a 0.05s gap is not a usable seam."
      • removedInput schema / properties / max_gap / title
        Removed value: -"Max Gap"
      • addedInput schema / properties / min_seam / description
        Added value: +"How wide a gap has to be to be reported as a `clean_seam`, in seconds."
      • removedInput schema / properties / min_seam / title
        Removed value: -"Min Seam"
      • 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 / vo_clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / vo_clip_id / description
        Added value: +"Which transcript is the VO. Unset, the project's own. The VO always needs a transcript; the placed clip does not."
      • removedInput schema / properties / vo_clip_id / title
        Removed value: -"Vo Clip Id"
      • addedInput schema / properties / vo_clip_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"speech_overlapArguments"
    • Changedspot_frames18 fields changed
      • addedInput schema / properties / count / description
        Added value: +"How many evenly-spaced frames to pull. They come back ranked darkest-first, with a montage of them as an image."
      • removedInput schema / properties / count / title
        Removed value: -"Count"
      • removedInput schema / properties / fps / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / fps / description
        Added value: +"The rate used to map a frame back to the clip and word it lands near — refused rather than guessed when the render's duration no longer matches the timeline."
      • removedInput schema / properties / fps / title
        Removed value: -"Fps"
      • addedInput schema / properties / fps / type
        Added value: +[
        +  "number",
        +  "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"
        +]
      • addedInput schema / properties / target / description
        Added value: +"The render to pull frames from."
      • removedInput schema / properties / target / title
        Removed value: -"Target"
      • removedInput schema / properties / times / anyOf
        Removed value: -[
        -  {
        -    "items": {
        -      "type": "number"
        -    },
        -    "type": "array"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / times / description
        Added value: +"Explicit seconds to sample as well as the evenly-spaced ones."
      • addedInput schema / properties / times / items
        Added value: +{
        +  "type": "number"
        +}
      • removedInput schema / properties / times / title
        Removed value: -"Times"
      • addedInput schema / properties / times / type
        Added value: +[
        +  "array",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"spot_framesArguments"
    • Changedsynopsis15 fields changed
      • addedInput schema / properties / clear / description
        Added value: +"Remove this clip's synopsis."
      • removedInput schema / properties / clear / title
        Removed value: -"Clear"
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip to read or write. Omit it to list every clip's synopsis and which are missing one."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "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 / text / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / text / description
        Added value: +"What this footage **is** — the work, the scene, the people. A different fact from a `describe` window, which says what is in front of the camera. Write it yourself: nothing generates one, because a model reading the pixels measurably cannot."
      • removedInput schema / properties / text / title
        Removed value: -"Text"
      • addedInput schema / properties / text / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"synopsisArguments"
    • Changedtail21 fields changed
      • removedInput schema / properties / asset / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / asset / description
        Added value: +"The end card or bumper, as `card:name` — never a clip id. `verify` diffs the render's own transcription against the timeline's words, and a card behind silence adds none of its own, which a media clip would."
      • removedInput schema / properties / asset / title
        Removed value: -"Asset"
      • addedInput schema / properties / asset / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / fade / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / fade / description
        Added value: +"Recorded and echoed, not yet drawn: this build cuts to the card hard, at `seconds`."
      • removedInput schema / properties / fade / title
        Removed value: -"Fade"
      • addedInput schema / properties / fade / type
        Added value: +[
        +  "number",
        +  "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"
        +]
      • 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 tail entirely. Note a derivation inherits none of it anyway and reports `tail_dropped`."
      • removedInput schema / properties / reset / title
        Removed value: -"Reset"
      • removedInput schema / properties / seconds / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / seconds / description
        Added value: +"The tail's **whole** length, card included — not a hold with `fade` added on top of it."
      • removedInput schema / properties / seconds / title
        Removed value: -"Seconds"
      • addedInput schema / properties / seconds / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"tailArguments"
    • Changedthumbnail11 fields changed
      • addedInput schema / properties / at / description
        Added value: +"Source seconds to pull the frame at. It snaps to a multiple of `interval` first, so a repeated ask for a nearby instant is a cache hit."
      • removedInput schema / properties / at / title
        Removed value: -"At"
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip to pull a frame from."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / interval / description
        Added value: +"The grid `at` snaps to, in seconds."
      • removedInput schema / properties / interval / title
        Removed value: -"Interval"
      • 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 / title
        Removed value: -"thumbnailArguments"
    • Changedtimeline_status5 fields changed
      • 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 / title
        Removed value: -"timeline_statusArguments"
    • Changedtimeline_view11 fields changed
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"The transcript whose words' fate to report. A clip that is registered but not on the edit still answers — read `off_timeline`, or every word reads `present: false` and looks cut."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / first
        Added value: +{
        +  "default": 0,
        +  "description": "Index into the `words` list to start the window at. 0 by default.",
        +  "type": "integer"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "default": 100,
        +  "description": "Most entries of `words` to return; `words_next` says where to continue. The segments, seams and shots are always whole.",
        +  "type": "integer"
        +}
      • 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 / title
        Removed value: -"timeline_viewArguments"
    • Changedtranscribe13 fields changed
      • addedInput schema / properties / clip_id / description
        Added value: +"The clip whose own media whisper transcribes."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • removedInput schema / properties / language / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / language / description
        Added value: +"Force a language code, e.g. `en`. Unset, whisper detects it, which it gets wrong on short or noisy clips."
      • removedInput schema / properties / language / title
        Removed value: -"Language"
      • addedInput schema / properties / language / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / model / description
        Added value: +"The whisper model to run, e.g. `small.en`. Larger is slower, and there is no timeout."
      • removedInput schema / properties / model / title
        Removed value: -"Model"
      • 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 / title
        Removed value: -"transcribeArguments"
    • Changedtranscript_checks9 fields changed
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"One clip to re-check. Omit it for every clip that has a transcript."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "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 / title
        Removed value: -"transcript_checksArguments"
    • Changedundo5 fields changed
      • 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 / title
        Removed value: -"undoArguments"
    • Changedunspoken_add21 fields changed
      • addedInput schema / properties / after / description
        Added value: +"A forward cursor over a phrase's matches: 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 / clip_id / description
        Added value: +"The transcript holding the word."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • removedInput schema / properties / occurrence / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / occurrence / description
        Added value: +"Disambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — 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 / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / phrase / description
        Added value: +"Address it by wording instead — but unlike `cue_add`, a phrase matching more than one word is refused rather than bound to an edge: a mark addresses exactly one word."
      • removedInput schema / properties / phrase / title
        Removed value: -"Phrase"
      • addedInput schema / properties / phrase / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / word_index / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / word_index / description
        Added value: +"The word to mark. Give this or `phrase`."
      • removedInput schema / properties / word_index / title
        Removed value: -"Word Index"
      • addedInput schema / properties / word_index / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"unspoken_addArguments"
    • Changedunspoken_detect27 fields changed
      • addedInput schema / properties / apply / description
        Added value: +"Mark the proposals. Off by default, like `reframe_detect`: a wrong mark deletes a real word from every check proofcut has, so read the echoes first."
      • removedInput schema / properties / apply / title
        Removed value: -"Apply"
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"Limit the scan to one transcript."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / language / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / language / description
        Added value: +"Force a language code for that transcription."
      • removedInput schema / properties / language / title
        Removed value: -"Language"
      • addedInput schema / properties / language / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / model / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / model / description
        Added value: +"The whisper model to transcribe the render with, when no `transcript_path` is given."
      • removedInput schema / properties / model / title
        Removed value: -"Model"
      • addedInput schema / properties / model / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / pad / description
        Added value: +"Widen the window each candidate is counted in, in seconds."
      • removedInput schema / properties / pad / title
        Removed value: -"Pad"
      • 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"
        +]
      • addedInput schema / properties / render / description
        Added value: +"The rendered file to judge against — the witness. A word is proposed only where the timeline holds more of it over a span than the render's own transcription heard."
      • removedInput schema / properties / render / title
        Removed value: -"Render"
      • removedInput schema / properties / transcript_path / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / transcript_path / description
        Added value: +"An existing transcription of `render`, which is what `verify` leaves in `cache/verify/`. It is never found automatically: a re-render under the same filename would otherwise be judged against the previous render's audio."
      • removedInput schema / properties / transcript_path / title
        Removed value: -"Transcript Path"
      • addedInput schema / properties / transcript_path / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"unspoken_detectArguments"
    • Changedunspoken_ls5 fields changed
      • 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 / title
        Removed value: -"unspoken_lsArguments"
    • Changedunspoken_rm21 fields changed
      • addedInput schema / properties / after / description
        Added value: +"A forward cursor over a phrase's matches: 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 / clip_id / description
        Added value: +"The transcript holding the marked word."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • removedInput schema / properties / occurrence / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / occurrence / description
        Added value: +"Disambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — 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 / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / phrase / description
        Added value: +"Address it by wording instead; it has to resolve to exactly one word."
      • removedInput schema / properties / phrase / title
        Removed value: -"Phrase"
      • addedInput schema / properties / phrase / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / word_index / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / word_index / description
        Added value: +"The marked word. Give this or `phrase`."
      • removedInput schema / properties / word_index / title
        Removed value: -"Word Index"
      • addedInput schema / properties / word_index / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"unspoken_rmArguments"
    • Changedverify29 fields changed
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"Diff against one transcript's expected words rather than all of them."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / language / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / language / description
        Added value: +"Force a language code for it."
      • removedInput schema / properties / language / title
        Removed value: -"Language"
      • addedInput schema / properties / language / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / model / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / model / description
        Added value: +"The whisper model for the single-pass transcription."
      • removedInput schema / properties / model / title
        Removed value: -"Model"
      • addedInput schema / properties / model / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / overlap / description
        Added value: +"How far each window overlaps the one before, in seconds."
      • removedInput schema / properties / overlap / title
        Removed value: -"Overlap"
      • 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"
        +]
      • addedInput schema / properties / render / description
        Added value: +"The finished render to transcribe and diff against the timeline."
      • removedInput schema / properties / render / title
        Removed value: -"Render"
      • removedInput schema / properties / transcript_path / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / transcript_path / description
        Added value: +"An existing transcription of `render` — what a previous run cached and reported as `heard_transcript`. Pass it back to re-diff without spending the minutes again."
      • removedInput schema / properties / transcript_path / title
        Removed value: -"Transcript Path"
      • addedInput schema / properties / transcript_path / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / window / description
        Added value: +"Length of each window in the windowed pass, in seconds."
      • removedInput schema / properties / window / title
        Removed value: -"Window"
      • addedInput schema / properties / windowed / description
        Added value: +"Transcribe in short overlapping windows instead of one pass. **A clean single-pass result is not proof** — one pass collapses an immediate repeat the same way the source transcript did, and three surviving retakes passed a correct single-pass run on a real video. It costs a run over twice the audio and a smaller model."
      • removedInput schema / properties / windowed / title
        Removed value: -"Windowed"
      • removedInput schema / title
        Removed value: -"verifyArguments"
    • Changedvo_extend27 fields changed
      • addedInput schema / properties / after / description
        Added value: +"A forward cursor over a phrase's matches: 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 / clip_id / description
        Added value: +"The track the gap opens in — the VO."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • removedInput schema / properties / occurrence / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / occurrence / description
        Added value: +"Disambiguate a phrase by count when it matches more than once, **1-based** in transcript order among the matches after `after`: 1 is the first, 2 the second. Unset, an ambiguous phrase is refused — listing every candidate's range and text — 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 / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / phrase / description
        Added value: +"Address it by wording instead. A phrase binds to its **last** word here, which is this tool's own meaning: the last word before the gap."
      • removedInput schema / properties / phrase / title
        Removed value: -"Phrase"
      • addedInput schema / properties / phrase / 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 / seconds / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / seconds / description
        Added value: +"How long the hold runs. An editorial call this makes no attempt to derive."
      • removedInput schema / properties / seconds / title
        Removed value: -"Seconds"
      • addedInput schema / properties / seconds / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedInput schema / properties / word_index / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / word_index / description
        Added value: +"The last word **before** the gap; the hold opens immediately after that word's own end. It has to be on the timeline: an index naming cut material is refused rather than guessed at."
      • removedInput schema / properties / word_index / title
        Removed value: -"Word Index"
      • addedInput schema / properties / word_index / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"vo_extendArguments"
    • Changedvo_synth37 fields changed
      • addedInput schema / properties / candidates / description
        Added value: +"How many seeds to render and rank. Seed moves a render more than the reference does, which is why this ranks rather than renders once."
      • removedInput schema / properties / candidates / title
        Removed value: -"Candidates"
      • removedInput schema / properties / clip_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / clip_id / description
        Added value: +"With `word_index`, the track to splice the winner into. Omitted, nothing is spliced and the renders are just ranked."
      • removedInput schema / properties / clip_id / title
        Removed value: -"Clip Id"
      • addedInput schema / properties / clip_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / flat_floor / description
        Added value: +"Below this much voiced pitch movement (semitones) a render starts paying the flatness penalty. Likeness alone keeps the flattest read, because sims in one pool differ by thousandths while spread differs by semitones."
      • removedInput schema / properties / flat_floor / title
        Removed value: -"Flat Floor"
      • addedInput schema / properties / flat_weight / description
        Added value: +"How much likeness to subtract per semitone of flatness under the floor. 0 restores likeness-only ranking."
      • removedInput schema / properties / flat_weight / title
        Removed value: -"Flat Weight"
      • removedInput schema / properties / lexicon / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / lexicon / description
        Added value: +"A `{\"say\": {…}, \"hear\": {…}}` file: `say` respells what the model is given, `hear` folds whisper's spelling back to the script's before the WER is scored. Defaults to the project's own `lexicon.json` if it has one."
      • removedInput schema / properties / lexicon / title
        Removed value: -"Lexicon"
      • addedInput schema / properties / lexicon / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • addedInput schema / properties / max_seconds / description
        Added value: +"Length cap per render. One that hits it is reported `capped` and never wins while an uncapped one exists — a 21s reference once ran every render to 655s."
      • removedInput schema / properties / max_seconds / title
        Removed value: -"Max Seconds"
      • 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"
        +]
      • 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 / readback / description
        Added value: +"Transcribe the winner with whisper and report `heard`/`wer`. On by default: a clone that sounds right and says the wrong words is the failure nothing else sees. The numbers are a report, never a gate."
      • removedInput schema / properties / readback / title
        Removed value: -"Readback"
      • addedInput schema / properties / seed / description
        Added value: +"First seed of the range; seeds `seed .. seed+candidates-1` render in one process. A new range renders only what the cache lacks."
      • removedInput schema / properties / seed / title
        Removed value: -"Seed"
      • addedInput schema / properties / text / description
        Added value: +"What the voice says. It is respelled first through the project's `lexicon.json` `say` folds, if one exists — the fix for a mispronounced name."
      • removedInput schema / properties / text / title
        Removed value: -"Text"
      • removedInput schema / properties / voice / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / voice / description
        Added value: +"A directory holding `ref.wav` + `ref.txt`, the ≈19s reference the clone is zero-shot from. Unset, `$PROOFCUT_TTS_VOICE`. There is no built-in voice, and none ships in the repo: a voice is somebody's recorded speech."
      • removedInput schema / properties / voice / title
        Removed value: -"Voice"
      • addedInput schema / properties / voice / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / word_index / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedInput schema / properties / word_index / description
        Added value: +"The word to splice the winner in right after, through `vo_extend`'s own mechanism — so the same one-way consequences follow (melt routing, `restore` refusing across the seam)."
      • removedInput schema / properties / word_index / title
        Removed value: -"Word Index"
      • addedInput schema / properties / word_index / type
        Added value: +[
        +  "integer",
        +  "null"
        +]
      • removedInput schema / title
        Removed value: -"vo_synthArguments"
  2. 92 tool updatesv0.24.0
    • First observedadd_captions
    • First observedassets
    • First observedattach_transcript
    • First observedattenuate_noises
    • First observedattribute_speakers
    • First observedbroll_brief
    • First observedbuild_shots
    • First observedcanvas
    • First observedcaption_style
    • First observedcaption_view
    • First observedcard_new
    • First observedcard_reauthor
    • First observedcard_render
    • First observedcard_safe_zones
    • First observedcard_templates
    • First observedcheck_black
    • First observedcheck_frames
    • First observedclip_rm
    • First observedclip_role
    • First observedcontact_sheet
    • First observedcontinuity_accept
    • First observedcontinuity_check
    • First observedcontinuity_ls
    • First observedcontinuity_reject
    • First observedcue_add
    • First observedcue_ls
    • First observedcue_reresolve
    • First observedcue_rm
    • First observedcut_by_time
    • First observedcut_by_transcript
    • First observeddescribe
    • First observeddescribe_ls
    • First observeddoctor
    • First observedexport
    • First observedfilm_check
    • First observedfinish_check
    • First observedfinish_report
    • First observedfonts
    • First observedfootage_sheet
    • First observedget_transcript
    • First observedhead
    • First observedhear
    • First observedhold_add
    • First observedhold_check
    • First observedhold_ls
    • First observedhold_rm
    • First observedhold_under
    • First observedhold_under_rm
    • First observedimport_edit
    • First observedimport_media
    • First observedinit
    • First observedlist_media
    • First observedlocate
    • First observedmigrate_project
    • First observedmusic
    • First observedpack_activate
    • First observedpack_apply
    • First observedpack_apply_captions
    • First observedpack_show
    • First observedpack_status
    • First observedping
    • First observedproperties
    • First observedproxy_transcode
    • First observedreel
    • First observedreframe
    • First observedreframe_coverage
    • First observedreframe_detect
    • First observedreframe_sheet
    • First observedresolve_phrase
    • First observedrestore
    • First observedreview_add
    • First observedreview_list
    • First observedreview_verdict
    • First observedseed_timeline
    • First observedshot_sheet
    • First observedspeech_overlap
    • First observedspot_frames
    • First observedsynopsis
    • First observedtail
    • First observedthumbnail
    • First observedtimeline_status
    • First observedtimeline_view
    • First observedtranscribe
    • First observedtranscript_checks
    • First observedundo
    • First observedunspoken_add
    • First observedunspoken_detect
    • First observedunspoken_ls
    • First observedunspoken_rm
    • First observedverify
    • First observedvo_extend
    • First observedvo_synth

TDQS

A4/5.0

Scored across 93 tools

Disambiguation4/5

Every tool's purpose is sharply delineated, and the descriptions actively name their sibling tools and state the difference (shot_sheet vs footage_sheet, reframe vs reframe_detect, transcribe vs attach_transcript). However, several sibling clusters — verify/finish_check/hold_check, the four reframe tools, the three sheet tools, and pack_apply/pack_activate — share names and mechanisms closely enough that an agent must read carefully to select correctly, and 93 tools compounds the selection pressure.

Naming Consistency4/5

snake_case throughout with strong family conventions: cue_*/unspoken_*/hold_*/continuity_*/pack_*/review_* prefixes and consistent _add/_rm/_check/_detect/_apply suffixes. Deviations exist: list operations are inconsistently named (list_media vs cue_ls vs review_list vs describe_ls), and several single-noun get/set tools (head, tail, music, canvas, doctor, assets) break the verb_noun pattern.

Tool Count2/5

At 93 tools this is far beyond the 25+ threshold and overwhelms the agent-facing surface, even though the domain is broad. The count forces every tool call through a huge selection space and makes the set impractical to navigate from a plain tool list. Consolidation — e.g., folding hold_*, pack_*, or review_* families together, or merging read-only reports — would be needed to bring it into a usable range.

Completeness5/5

The surface covers the full proofcut pipeline end-to-end: project lifecycle, import, transcription and transcript QA, timeline editing, cues, captions, cards, packs, framing, holds, music, export, render verification, continuity, and human review. CRUD is consistently closed per family (add/rm/ls for cues and unspoken marks, check/accept/reject/ls for continuity, apply/show/status for packs). No obvious dead ends: every mutation is undoable, and deliberately unsupported operations (like manual transcript correction) are explicitly designed around rather than omitted.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers