proofcut
Proofcut is an MCP server that lets an AI agent edit video end-to-end from a transcript, render it locally, and verify the finished film against the edit.
Project setup & media:
init,import_media,list_media,clip_role,clip_rm,migrate_project,assets.Transcription & speech analysis:
transcribe,attach_transcript,get_transcript,resolve_phrase,transcript_checks,hear,attribute_speakers,unspoken_add/rm/ls/detect.Editing the timeline:
seed_timeline,cut_by_transcript,cut_by_time,restore,undo,changes,import_edit,vo_extend,vo_synth.Picture, b-roll & cards:
describe,describe_ls,synopsis,broll_brief,cue_add/rm/ls/reresolve,build_shots,card_templates,card_new/render/reauthor/safe_zones,fonts, pack tools.Canvas, framing & holds:
canvas,reframe,reframe_detect,reframe_coverage,reframe_sheet,head,tail,hold_add/rm/under/under_rm/ls/check.Music & audio:
music,hold_under,attenuate_noises,speech_overlap.Captions:
add_captions,caption_view,caption_style.Render & export:
export,check_frames,check_black,spot_frames,verify,finish_check,film_check.Project inspection & review:
ping,doctor,timeline_status,timeline_view,properties,finish_report,locate,continuity_check/accept/reject/ls,review_add/verdict/list,shot_sheet,footage_sheet,thumbnail,contact_sheet,proxy_transcode,reel.
Allows exporting the project timeline as a Kdenlive project and importing hand-made Kdenlive edits back as the project's timeline.
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 doctorThe 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 setupThe demo and your own recordings run from a checkout:
git clone https://github.com/tydude001/proofcut && cd proofcut
uv syncThe 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-demoIn 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@proofcutThe 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 mcpOn 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 tabRelated 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.
Stage | Command |
| |
| |
| |
| |
Play the footage's own lines in a gap, or under the narration |
|
Score it: placed passages, crossfaded, levelled under the voice |
|
| |
| |
| |
|
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-sheetdraws the whole picture track as one labelled grid, andfootage-sheetbrowses 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
unspokenlets the render itself testify to words nobody said.B-roll by description.
describewrites 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.
reelcuts 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-editthe trim back.

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.
verifytranscribes 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:114names the same words however many cuts came before it.--planprints what a range says before anything changes, andrestoreandundowalk 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-sheetreturn an image of the edit, not a file path the agent can't open.One engine, three ways in. The MCP server, the
proofcutcommand 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
.kdenliveor OTIO file, finish in Resolve, Premiere or Kdenlive, and bring your trim back withimport-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.shIt 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.ps1It 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 |
|
ffmpeg / ffprobe built with | cutting, concatenating, captions, rendering | Fedora's default |
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 |
MLT ( | layered renders (b-roll, cards, music) | Your distribution's MLT package ( |
Optional. Each unlocks one feature, proofcut doctor reports whether it is
available, and everything else works without it:
Optional | Unlocks | Notes |
ImageMagick 7 ( | title and end cards, rendered from SVG templates | ImageMagick 6's |
Claude Code ( | the agent pane in the workspace |
|
|
| The python of a venv with torch, transformers, bitsandbytes and Pillow, on a CUDA GPU. The Qwen2.5-VL model downloads on first use. |
|
| The python of a venv with insightface, onnxruntime and opencv-python. |
|
| 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 |
| Every operation. The MCP tools, the CLI and the web UI all call these. |
| The MCP server. Register tools with |
| The |
| The workspace. It posts to |
| The project manifest ( |
|
|
| The demo maker, the Mac and Windows trial kits, screenshot capture. |
| 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 pytestThe 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:
docs/MANUAL.md: every command, with the reasoning.
docs/DEMO.md: the whole loop in two minutes.
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 toolsadd_captionsADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| burn | No | 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. | |
| hold | No | How long a cue lingers after its last word, in seconds. | |
| path | No | 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. | |
| output | Yes | Where to write the `.ass` sidecar, or the burned video under `burn`. | |
| preset | No | Override the project's base look for this one file — `clean`, `karaoke` or `boxed`. Nothing here is written back to the project. | |
| clip_id | No | Caption one transcript's words rather than every clip's. | |
| max_gap | No | Start a new cue when the silence between two words exceeds this many seconds. | |
| max_words | No | Most words in one caption cue. | |
| burn_output | No | Where the burned video goes. Unset, it is derived from `burn`'s own name. | |
| max_duration | No | Longest a single cue stays on screen, in seconds. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
assetsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_transcriptADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| clip_id | Yes | The clip this transcript belongs to. Its words become `(clip_id, word_index)`, which is how every cue, mark and caption addresses them afterwards. | |
| transcript_path | Yes | The whisper JSON to ingest. It has to carry word-level timings — proofcut addresses words, not segments. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_noisesADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| db | No | How far to pull each qualifying event down, in dB. Negative is quieter. | |
| pad | No | Seconds added either side of each event before it is pulled down. | |
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| clip_id | Yes | The clip to scan. It always reads that clip's **original** media, never a previous attenuated copy, so repeated calls never compound gain. | |
| confirm_suspect | No | 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. | |
| max_gap_seconds | No | 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. | |
| max_event_seconds | No | Longest an event may run and still qualify automatically. Anything longer is reported as `disqualified` and never written. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_speakersAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| apply | No | 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. | |
| limit | No | How many ambiguous spans to return; the reply also says how many there are in total. | |
| labels | No | What to call each stream, in the same order — one per stream. Unset, `speaker1`, `speaker2`. | |
| clip_id | Yes | The co-hosted clip: one container, one mic per speaker, one transcript already attached. | |
| streams | No | Which audio streams the speakers are on, as ffmpeg audio ordinals (`[0, 1]`). Unset, the container's readable audio streams in order. | |
| margin_db | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_briefARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| fps | No | The frame grid the shot positions are projected on. Defaults to the rate `export` would use. | |
| path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_shotsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| fps | No | 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. | |
| path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
canvasADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| size | No | `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. | |
| reset | No | Drop the override and return to the footage-derived shape. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_styleADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| box | No | 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. | |
| bold | No | Draw bold. | |
| font | No | 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. | |
| hold | No | How long a cue lingers after its last word, in seconds. | |
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| size | No | Type size, against the project's canvas as the reference frame. | |
| text | No | 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. | |
| reset | No | Drop every override first. `reset` together with `preset` starts clean from that preset. | |
| margin | No | Distance from the frame edge, in canvas pixels. | |
| preset | No | The base look: `clean`, `karaoke` (per-word highlight) or `boxed`. Everything else overrides one of its fields, and only the overrides are stored. | |
| shadow | No | Drop-shadow distance. | |
| karaoke | No | 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. | |
| max_gap | No | Start a new cue when the silence between two words exceeds this many seconds. | |
| position | No | Where captions sit, named: `bottom`, `top`, `top-right` and so on. | |
| highlight | No | What a word turns as it is spoken. It only shows with `karaoke` on. | |
| max_words | No | Most words in one caption cue. Grouping is part of the look, which is why it is stored with it. | |
| box_colour | No | Colour of the box behind the type, when `box` is on. | |
| max_duration | No | Longest a single cue stays on screen, in seconds. | |
| outline_width | No | Outline thickness. With no box this is what holds the words apart from the picture. | |
| outline_colour | No | Colour of the outline around the type. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_viewARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| first | No | Index of the first cue to return. 0 by default. | |
| limit | No | Most cues to return; `cues_next` says where to continue. | |
| clip_id | No | Show one transcript's captions rather than every clip's. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_newADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The `<name>` in `card:<name>` — the key a cue points at. The SVG and the PNG are both written under `assets/cards/`. | |
| path | No | 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. | |
| slots | Yes | 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. | |
| width | No | 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. | |
| height | No | Render height, given together with `width` or not at all. | |
| template | Yes | Which template to fill; `card_templates` lists them with their slots. A per-aspect variant file is resolved from the canvas, never named here. | |
| overwrite | No | Redraw a card of this name that already exists. Refused without it, since a cue may already point at that card. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_reauthorADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | 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. | |
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_renderADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The card to rasterise: `assets/cards/<name>.svg` becomes the PNG that `card:<name>` resolves to. | |
| path | No | 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. | |
| width | No | 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. | |
| height | No | Render height, given together with `width` or not at all. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_zonesARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| card | Yes | 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. | |
| path | No | 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. | |
| platform | Yes | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_templatesARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | One template to return in full. The others come back as name and description only. Unset, every template in full. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
changesARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| steps | No | How 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
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_blackARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| fps | No | The rate the timeline's own frame arithmetic is counted on. | |
| path | No | 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. | |
| pix_th | No | How dark a pixel counts as black, 0–1. | |
| target | Yes | 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. | |
| min_duration | No | Shortest black run to report, in seconds. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_framesARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| fps | No | 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. | |
| path | No | 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. | |
| target | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_rmADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| clip_id | Yes | The clip to un-register. Its media on disk is never touched. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_roleADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| role | No | `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. | |
| reset | No | Clear the role back to undeclared. | |
| clip_id | Yes | The clip to read or set. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_sheetARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| clip_id | Yes | The clip whose head to look at. | |
| seconds | No | 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. | |
| interval | No | Seconds between tiles. |
TDQS
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.
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.
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.
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.
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.
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_acceptAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | Which finding to acknowledge: `rewind`, `replay`, `short_shot` or `stub`. | |
| path | No | 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. | |
| clip_id | Yes | The cue's own addressing transcript, as `continuity_check` reports it. | |
| word_index | Yes | The cue's word. With `clip_id` and `kind` it is the finding's address — one shot can carry more than one finding. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_checkARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| gap | No | How much timeline may pass before re-showing an asset reads as a replay rather than a rewind, in seconds. | |
| path | No | 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. | |
| stubs | No | Look for stubs. On by default, and it costs a scene-cut decode per distinct asset placed — `false` skips that. | |
| min_shot | No | Shortest a shot may run before it is reported as a short shot, in seconds. Stills are excluded. | |
| stub_tolerance | No | How close a shot edge has to sit to its footage's own internal cut to be called a stub, in seconds. | |
| scene_threshold | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_lsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_rejectADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | Which finding to un-acknowledge: `rewind`, `replay`, `short_shot` or `stub`. | |
| path | No | 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. | |
| clip_id | Yes | The cue's own addressing transcript. | |
| word_index | Yes | The cue's word, with `clip_id` and `kind` the address the acknowledgement was stored under. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_addAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| after | No | 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. | |
| asset | No | 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. | |
| phrase | No | Address the cue by what is said instead of by index. It binds to the phrase's **first** word — "from this word onward". | |
| clip_id | Yes | The transcript the cue is addressed against — the VO on a voiceover project, not the footage being shown. `asset` is what gets seen. | |
| src_start | No | 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. | |
| occurrence | No | 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. | |
| word_index | No | The word the picture starts on, in `clip_id`'s transcript. Give this or `phrase`, not both. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_lsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| clip_id | No | List one clip's cues. Omit it for the whole table. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_reresolveADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| apply | No | 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. | |
| clip_id | No | Re-resolve one clip's entries. Omit it for every clip. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_rmADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| after | No | 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. | |
| phrase | No | Address it by wording instead; it resolves to its first word, the way `cue_add` placed it. | |
| clip_id | Yes | The transcript the cue was addressed against. | |
| occurrence | No | 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. | |
| word_index | No | The word the cue sits on. Give this or `phrase`. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_timeADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| pad | No | Widen only the outer edges of each requested span, in seconds. | |
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| spans | Yes | 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. | |
| confirm_suspect | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_transcriptADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| cut | No | Inclusive word ranges to remove, e.g. `[[30, 45], [120, 131]]`. Pass exactly one of `cut` or `keep`. | |
| pad | No | 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. | |
| keep | No | Inclusive word ranges to keep, everything else going. Pass exactly one of `cut` or `keep`. | |
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| clip_id | Yes | The transcript the word ranges address. | |
| through_pause | No | 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. | |
| confirm_suspect | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
describeADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| force | No | Describe clips that already have descriptions, replacing them. Without it they are skipped. | |
| window | No | 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. | |
| clip_id | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_lsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| clip_id | No | List only this clip's windows. | |
| contains | No | Keep only windows whose text holds every whitespace-separated term, case-insensitively — so `"kitchen knife"` matches "a knife on the kitchen counter". |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
doctorARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
exportADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| fps | No | 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. | |
| path | No | 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. | |
| output | Yes | Where to write the project file or the render. A file argument, not a project selector: it writes where you say. | |
| preset | No | 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. | |
| loudness | No | 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. | |
| true_peak | No | The dBTP ceiling the loudness pass limits under. -1.0 by default. | |
| resolution | No | `[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_format | No | `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
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_checkADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| reset | No | Drop the stored reference. | |
| reference | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_checkARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| fps | No | The frame grid the timeline's arithmetic is counted on. Defaults to the rate `export` would have picked. | |
| path | No | 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. | |
| final | Yes | 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. | |
| holds | No | 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. | |
| pix_th | No | blackdetect's pixel threshold: how dark a pixel counts as black. | |
| window | No | Length of each transcription window, in seconds. | |
| clip_id | No | Diff against one transcript's expected words rather than all of them. | |
| overlap | No | How far each window overlaps the one before, in seconds. | |
| language | No | Force a language code for the transcription. | |
| recheck_pad | No | 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. | |
| windowed_model | No | 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. | |
| prepend_seconds | No | 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. | |
| transcript_path | No | An existing transcription of `final`, to diff again without re-transcribing. | |
| black_min_duration | No | Shortest black run to report, in seconds. | |
| duration_tolerance | No | How far `final`'s duration may sit from the timeline's own arithmetic before it is a fault, in seconds. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_reportARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| holds | No | 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. | |
| framing | No | 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. | |
| continuity | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
fontsADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| install | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_sheetADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| out | No | 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. | |
| mode | No | 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. | auto |
| page | No | Which page of rows to draw, from 1. Unset, the first. | |
| path | No | 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. | |
| clip_id | Yes | The registered clip to browse. This sheet reads the clip's **own source**, so it needs no edit, no cues and no transcript. | |
| interval | No | 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. | |
| per_page | No | 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. |
TDQS
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.
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.
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.
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.
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.
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_transcriptARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| last | No | Last word index to return, inclusive. | |
| path | No | 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. | |
| first | No | First word index to return, inclusive. | |
| limit | No | 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. | |
| search | No | 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. | |
| clip_id | Yes | The clip to read. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
headADestructiveIdempotent
Read or change the cold open this project plays before its first frame.
tail's mirror at the other end of the film — the same read/partial-
update/reset/plan shape — but its asset rule runs the other way:
asset must be a registered clip_id, never card:name. A cold open is
real footage with real dialogue by definition; tail forbids that
because verify would gain a permanent disagreement it can never
resolve, and a head is taught to account for its own words instead
(verify's head_words_trimmed) rather than being restricted to
silence. Call it with no arguments to read what is in force.
Setting asset or seconds for the first time needs both together;
either alone after that updates just that field, tail's partial-update
shape. src_start defaults to 0.0 on a first set. fade_in/fade_out
default to 0.0 and — unlike tail's fade — are drawn from day one,
the whole reason this feature exists (a hard butt-join between room tone
and digital silence is exactly the seam a missing fade produces).
gain_db defaults to 0.0, a flat non-fading level shift distinct from
the fades.
Needs an existing picture cue lane covering the whole film, tail's
own requirement — add cues first (cue_add) if the project does not
have one. reset drops the head entirely. plan resolves and validates
without writing.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| asset | No | 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. | |
| reset | No | Drop the cold open entirely. | |
| fade_in | No | 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. | |
| gain_db | No | A flat level shift for the cold open, in dB, distinct from the fades. 0.0 is unity. | |
| seconds | No | How long the cold open runs. Setting `asset` or `seconds` for the first time needs both together; either alone afterwards updates just that field. | |
| fade_out | No | Seconds of fade where the cold open hands over to the film. | |
| src_start | No | Where inside that asset the cold open reads from, in source seconds. 0.0 on a first set. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Although annotations already mark the tool as destructive and idempotent, the description goes far beyond them: it explains partial-update semantics, `reset` dropping the head entirely, `plan` resolving without writing, the cue-lane prerequisite, and the reason fades are drawn from day one. This is rich behavioral context beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but each paragraph covers a distinct operational rule: reading, partial updates, defaults, prerequisites, reset, and plan. It is front-loaded with the core purpose; the additional rationale is dense but mostly earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the rich parameter schema, and annotations, the description covers all necessary invocation modes, preconditions, defaults, and sibling-tool relationships. The output schema exists, so the lack of return-value detail is not a gap. Nothing essential for calling this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 schema itself already documents each parameter. The description adds real value by explaining interdependencies — `asset` and `seconds` must be set together on first set — and by clarifying defaults like `src_start` at 0.0 and the distinction between `gain_db` and the fades.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: "Read or change the cold open this project plays before its first frame." It clearly distinguishes the tool from `tail` by calling it that tool's mirror at the other end of the film, 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit invocation guidance: call with no arguments to read, set asset and seconds together on first set, update individually afterward, use `plan` to validate without writing, and `cue_add` first if no picture cue lane exists. It also names `tail` and `verify` as related tools, making the when-to-use boundary clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hearARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| end | Yes | Where to stop, in the same source seconds. Past the end of the clip it is refused rather than clamped. | |
| path | No | 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. | |
| model | No | The whisper model for this windowed pass. | small |
| start | Yes | Where to start listening, in that clip's own **source** seconds — never timeline seconds and never a word index. | |
| window | No | Length of each window, in seconds. | |
| clip_id | Yes | The clip whose source audio to listen to. | |
| overlap | No | 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. | |
| language | No | Force a language code, e.g. `en`. Unset, whisper detects it. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_addADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| after | No | 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. | |
| asset | No | The film clip whose own audio plays in the gap, and whose picture the cue pins. | |
| under | No | How far below the VO the held audio sits, in LU. Re-settable. | |
| clip_id | Yes | The VO track the gap opens in. | |
| fade_in | No | Seconds of fade as the held audio comes in. Re-settable. | |
| fade_out | No | Seconds of fade as it goes out. Re-settable. | |
| cue_phrase | No | Address the cue by wording; it binds its **first** word. | |
| gap_phrase | No | Address the gap by wording; it binds its **last** word, since the gap opens right after it. | |
| occurrence | No | Disambiguate `gap_phrase`/`cue_phrase`/`asset_phrase` by count, **1-based**. Unset, an ambiguous phrase is refused rather than guessed at. | |
| head_margin | No | Seconds kept before the line, so it does not start on the word. Re-settable on an already-spliced hold. | |
| tail_margin | No | Seconds kept after the line. Re-settable. | |
| asset_phrase | No | 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. | |
| cue_word_index | No | The word the picture cue for `asset` is placed on. | |
| gap_word_index | No | 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. | |
| word_index_last | No | Last 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_first | No | First word of the line to play, in **`asset`'s own** transcript — not the VO's. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_checkARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| render | Yes | The rendered file to listen to. Each hold's span is resolved live against the current edit and transcribed off this file. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_lsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_rmADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| clip_id | Yes | The VO track the hold was spliced into. | |
| gap_word_index | Yes | 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`. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_underADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| after | No | 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. | |
| asset | Yes | 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. | |
| under | No | How far below the VO the film audio sits, in LU. 13 by default. | |
| clip_id | Yes | The VO track whose words the span is measured in. | |
| fade_in | No | Seconds of fade as the film audio comes in. | |
| fade_out | No | Seconds of fade as it goes out. | |
| occurrence | No | Disambiguate `phrase_start`/`phrase_end` by count, **1-based**. Unset, an ambiguous phrase is refused rather than guessed at. | |
| phrase_end | No | Set the span's end by wording instead. | |
| phrase_start | No | Set the span's start by wording instead. | |
| word_index_end | No | Last VO word of the span. | |
| word_index_start | No | First 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
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_rmADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| clip_id | Yes | The VO track the entry was addressed against. | |
| word_index_start | Yes | The span's first VO word — the entry's address, with `clip_id`. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_editADestructiveIdempotent
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).
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| clip_id | No | The registered clip to attribute a single-source document to, when its media sits at a path this project does not know. | |
| document | Yes | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_mediaAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| mix | No | 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. | |
| copy | No | 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. | |
| path | No | 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. | |
| sheet | No | 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. | |
| source | Yes | 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. | |
| clip_id | No | 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. | |
| audio_stream | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
initAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | A name for the project, recorded in the manifest. Unset, the directory's own name is used. | |
| path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_mediaARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| recursive | No | Walk subdirectories too. On by default. | |
| source_dir | Yes | The directory to list. It names where footage lives rather than which project, so it is deliberately not confined to the bound project. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
locateARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| last | No | Last word index, inclusive. Defaults to `first`. | |
| path | No | 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. | |
| after | No | 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. | |
| first | No | First word index, inclusive. Address it one way per call: `first`/`last`, `source_start`/`source_end`, or `phrase`. | |
| phrase | No | Locate by wording. A phrase is naturally a range, so it resolves straight to first and last with no edge to pick. | |
| clip_id | Yes | The transcript, or the recording, the address belongs to. | |
| occurrence | No | 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. | |
| source_end | No | End of the source interval, in the recording's own seconds. | |
| source_start | No | Seconds into the original recording. Omit `source_end` to locate an instant. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_projectADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
musicADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| duck | No | 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. | |
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| after | No | 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. | |
| asset | No | 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. | |
| reset | No | Drop the bed entirely. | |
| under | No | Level the whole bed this many LU below the voice, measured. It is a fixed offset; `duck` is the moving one. | |
| rotate | No | Further assets to play in turn as each one runs out, overlapping by `crossfade`. `[]` clears them. | |
| src_in | No | Where inside the bed's own asset it starts, in seconds. | |
| clip_id | No | The transcript the bed's word indices address — the VO, not the music. | |
| fade_in | No | 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. | |
| fade_out | No | Seconds of fade at the bed's end. A fade pair the bed cannot hold refuses at build time rather than being clamped. | |
| passages | No | Replace the list of passages after the bed's own asset: each `{asset, word_index_start | phrase_start, src_in?, crossfade?, rotate?}`. `[]` clears them. | |
| clear_end | No | Drop the end word, returning the bed to running to the end of the edit. | |
| crossfade | No | 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. | |
| clear_duck | No | Return the bed to one level, with no ducking. | |
| occurrence | No | Disambiguate `phrase_start`/`phrase_end` by count, **1-based**. Unset, an ambiguous phrase is refused rather than guessed at. | |
| phrase_end | No | 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. | |
| clear_under | No | Return every asset to its own level. | |
| phrase_start | No | 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. | |
| word_index_end | No | Where the bed goes out. Unset means *to the end of the edit*, so a tail holds over silence. | |
| word_index_start | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_activateADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| variant | Yes | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_applyADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| variant | No | Which resolved variant to activate. Every declared variant is snapshotted regardless, so `pack_activate` can switch later with no file re-read. | default |
| pack_path | Yes | 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. | |
| install_fonts | No | Vendor the pack's own `fonts/` directory, if it ships one. Off by default, since it writes into `$HOME`. | |
| allow_fallback | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_captionsADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| preset | Yes | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_showARead-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."
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| variant | No | Report one variant rather than all of them. | |
| pack_path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_statusARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
pingARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
propertiesARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| clip_id | No | Add this clip's assets entry, framing windows and cue table to the report. | |
| word_index | No | With `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
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_transcodeAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| force | No | 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. | |
| clip_id | Yes | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
reelADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| end | Yes | Where it ends, in those same render seconds. `start`/`end` name the span to **keep**, the opposite direction from every other tool here. | |
| dest | Yes | 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. | |
| name | No | A name for the derived project. Unset, it is derived from `dest`. | |
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| start | Yes | Where the reel begins, in the seconds **an export plays at** — the same numbers `cut_by_time` takes, read off a watch. | |
| canvas | No | 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. | |
| confirm_suspect | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
reframeADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| fill | No | `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. | |
| pane | No | 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. | |
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| rect | No | `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. | |
| reset | No | With `clip_id`, drop that clip's overrides; with `src_start` as well, only the window there. Alone, drop every override. | |
| interp | No | 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`. | |
| clip_id | No | The clip to read or frame. Omit it to read the crops in force for every clip, including how much of each is kept. | |
| src_start | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_coverageARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| clip_id | No | Walk one clip's placements. Omit it for the whole project. | |
| threshold | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_detectAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| apply | No | 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. | |
| split | No | 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. | |
| frames | No | How many moments to sample inside each window before centring it on the faces found there. | |
| clip_id | No | Propose windows for one clip. Omit it for every placed clip. | |
| threshold | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_sheetADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| out | No | 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. | |
| page | No | Which page of rows to draw, from 1. Unset, the first. | |
| path | No | 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. | |
| moments | No | 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`. | |
| extremes | No | 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. | |
| per_page | No | 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. |
TDQS
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.
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.
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.
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.
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.
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_phraseARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| after | No | 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. | |
| fuzzy | No | 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. | |
| phrase | Yes | The words to find, as they were spoken. | |
| clip_id | Yes | The transcript to resolve against. | |
| occurrence | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
restoreADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| pad | No | Pass the same `pad` the original cut used to bring its padding sliver back, not only the words. | |
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| ranges | Yes | 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. | |
| clip_id | Yes | The clip whose cut material to bring back. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_addADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | One of `render`, `sheet`, `ab`, `control`. | |
| name | Yes | What to call this item in the served round. Re-using a name replaces that entry while its verdict stays attached. | |
| path | No | 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. | |
| source | Yes | The file to point at — never copied. A render already lives in `renders/`, a sheet in the sheet directory. | |
| baseline | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_listARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_verdictADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The registered item being answered. An unregistered name is refused. | |
| note | No | Anything to record beside the verdict. | |
| path | No | 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. | |
| verdict | Yes | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_timelineADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| margin | No | 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. | |
| clip_id | Yes | The clip to lay down as the timeline. | |
| edit_expr | No | auto-editor's edit language, passed straight through — e.g. `(or audio:0.03 motion:0.06)`. It replaces the threshold-based rule. | |
| threshold | No | auto-editor's audio loudness threshold, 0–1. Lower keeps quieter material. | |
| remove_silences | No | Silence-cut the clip on the way in, through auto-editor. On by default; false lays the whole clip down untouched. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_sheetADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| out | No | 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. | |
| page | No | Which page of rows to draw, from 1. Unset, the first. | |
| path | No | 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. | |
| per_page | No | 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. |
TDQS
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.
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.
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.
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.
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.
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_overlapARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | Where the clip would sit on the timeline, in seconds. | |
| cap | No | 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. | |
| path | No | 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. | |
| clip_id | Yes | The clip whose placement is being proposed. It need not be on the timeline yet, and usually is not. | |
| clip_in | No | Where inside the clip the proposed placement starts, in its own source seconds. Unset, its head. | |
| max_gap | No | 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. | |
| clip_out | No | Where it ends, in the clip's own source seconds. Unset, its end. | |
| min_seam | No | How wide a gap has to be to be reported as a `clean_seam`, in seconds. | |
| vo_clip_id | No | Which transcript is the VO. Unset, the project's own. The VO always needs a transcript; the placed clip does not. | |
| clip_evidence | No | `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
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_framesARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| fps | No | 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. | |
| path | No | 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. | |
| count | No | How many evenly-spaced frames to pull. They come back ranked darkest-first, with a montage of them as an image. | |
| times | No | Explicit seconds to sample as well as the evenly-spaced ones. | |
| target | Yes | The render to pull frames from. |
TDQS
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.
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.
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.
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.
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.
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.
synopsisADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| text | No | 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. | |
| clear | No | Remove this clip's synopsis. | |
| clip_id | No | The clip to read or write. Omit it to list every clip's synopsis and which are missing one. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
tailADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| fade | No | Recorded and echoed, not yet drawn: this build cuts to the card hard, at `seconds`. | |
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| asset | No | 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. | |
| reset | No | Drop the tail entirely. Note a derivation inherits none of it anyway and reports `tail_dropped`. | |
| seconds | No | The tail's **whole** length, card included — not a hold with `fade` added on top of it. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
thumbnailARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| at | Yes | 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. | |
| path | No | 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. | |
| clip_id | Yes | The clip to pull a frame from. | |
| interval | No | The grid `at` snaps to, in seconds. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_statusARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_viewARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| first | No | Index into the `words` list to start the window at. 0 by default. | |
| limit | No | Most entries of `words` to return; `words_next` says where to continue. The segments, seams and shots are always whole. | |
| clip_id | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
transcribeADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| model | No | The whisper model to run, e.g. `small.en`. Larger is slower, and there is no timeout. | turbo |
| clip_id | Yes | The clip whose own media whisper transcribes. | |
| language | No | Force a language code, e.g. `en`. Unset, whisper detects it, which it gets wrong on short or noisy clips. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_checksARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| clip_id | No | One clip to re-check. Omit it for every clip that has a transcript. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
undoADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_addAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| after | No | 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. | |
| phrase | No | 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. | |
| clip_id | Yes | The transcript holding the word. | |
| occurrence | No | 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. | |
| word_index | No | The word to mark. Give this or `phrase`. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_detectADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| pad | No | Widen the window each candidate is counted in, in seconds. | |
| path | No | 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. | |
| apply | No | 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. | |
| model | No | The whisper model to transcribe the render with, when no `transcript_path` is given. | |
| render | Yes | 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. | |
| clip_id | No | Limit the scan to one transcript. | |
| language | No | Force a language code for that transcription. | |
| transcript_path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_lsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_rmADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| after | No | 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. | |
| phrase | No | Address it by wording instead; it has to resolve to exactly one word. | |
| clip_id | Yes | The transcript holding the marked word. | |
| occurrence | No | 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. | |
| word_index | No | The marked word. Give this or `phrase`. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
verifyARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| model | No | The whisper model for the single-pass transcription. | |
| render | Yes | The finished render to transcribe and diff against the timeline. | |
| window | No | Length of each window in the windowed pass, in seconds. | |
| clip_id | No | Diff against one transcript's expected words rather than all of them. | |
| overlap | No | How far each window overlaps the one before, in seconds. | |
| language | No | Force a language code for it. | |
| windowed | No | 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. | |
| transcript_path | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_extendADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| after | No | 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. | |
| phrase | No | 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. | |
| clip_id | Yes | The track the gap opens in — the VO. | |
| seconds | No | How long the hold runs. An editorial call this makes no attempt to derive. | |
| occurrence | No | 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. | |
| word_index | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_synthADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | 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. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| seed | No | First seed of the range; seeds `seed .. seed+candidates-1` render in one process. A new range renders only what the cache lacks. | |
| text | Yes | 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. | |
| voice | No | 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. | |
| clip_id | No | With `word_index`, the track to splice the winner into. Omitted, nothing is spliced and the renders are just ranked. | |
| lexicon | No | 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. | |
| readback | No | 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. | |
| candidates | No | 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. | |
| flat_floor | No | 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. | |
| word_index | No | 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). | |
| flat_weight | No | How much likeness to subtract per semitone of flatness under the floor. 0 restores likeness-only ranking. | |
| max_seconds | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
93 tool updates
v0.25.0- Changed
add_captions39 fields changed- removed
Input schema / properties / burn / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / burn / descriptionAdded 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." - removed
Input schema / properties / burn / titleRemoved value: -"Burn" - added
Input schema / properties / burn / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / burn_output / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / burn_output / descriptionAdded value: +"Where the burned video goes. Unset, it is derived from `burn`'s own name." - removed
Input schema / properties / burn_output / titleRemoved value: -"Burn Output" - added
Input schema / properties / burn_output / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"Caption one transcript's words rather than every clip's." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / hold / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / hold / descriptionAdded value: +"How long a cue lingers after its last word, in seconds." - removed
Input schema / properties / hold / titleRemoved value: -"Hold" - added
Input schema / properties / hold / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / max_duration / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / max_duration / descriptionAdded value: +"Longest a single cue stays on screen, in seconds." - removed
Input schema / properties / max_duration / titleRemoved value: -"Max Duration" - added
Input schema / properties / max_duration / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / max_gap / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / max_gap / descriptionAdded value: +"Start a new cue when the silence between two words exceeds this many seconds." - removed
Input schema / properties / max_gap / titleRemoved value: -"Max Gap" - added
Input schema / properties / max_gap / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / max_words / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / max_words / descriptionAdded value: +"Most words in one caption cue." - removed
Input schema / properties / max_words / titleRemoved value: -"Max Words" - added
Input schema / properties / max_words / typeAdded value: +[ + "integer", + "null" +] - added
Input schema / properties / output / descriptionAdded value: +"Where to write the `.ass` sidecar, or the burned video under `burn`." - removed
Input schema / properties / output / titleRemoved value: -"Output" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / preset / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / preset / descriptionAdded value: +"Override the project's base look for this one file — `clean`, `karaoke` or `boxed`. Nothing here is written back to the project." - removed
Input schema / properties / preset / titleRemoved value: -"Preset" - added
Input schema / properties / preset / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"add_captionsArguments"
- Changed
assets5 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"assetsArguments"
- Changed
attach_transcript9 fields changed- added
Input schema / properties / clip_id / descriptionAdded 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." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / transcript_path / descriptionAdded value: +"The whisper JSON to ingest. It has to carry word-level timings — proofcut addresses words, not segments." - removed
Input schema / properties / transcript_path / titleRemoved value: -"Transcript Path" - removed
Input schema / titleRemoved value: -"attach_transcriptArguments"
- Changed
attenuate_noises19 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The clip to scan. It always reads that clip's **original** media, never a previous attenuated copy, so repeated calls never compound gain." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / confirm_suspect / descriptionAdded 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." - removed
Input schema / properties / confirm_suspect / titleRemoved value: -"Confirm Suspect" - added
Input schema / properties / db / descriptionAdded value: +"How far to pull each qualifying event down, in dB. Negative is quieter." - removed
Input schema / properties / db / titleRemoved value: -"Db" - added
Input schema / properties / max_event_seconds / descriptionAdded value: +"Longest an event may run and still qualify automatically. Anything longer is reported as `disqualified` and never written." - removed
Input schema / properties / max_event_seconds / titleRemoved value: -"Max Event Seconds" - added
Input schema / properties / max_gap_seconds / descriptionAdded 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." - removed
Input schema / properties / max_gap_seconds / titleRemoved value: -"Max Gap Seconds" - added
Input schema / properties / pad / descriptionAdded value: +"Seconds added either side of each event before it is pulled down." - removed
Input schema / properties / pad / titleRemoved value: -"Pad" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - removed
Input schema / titleRemoved value: -"attenuate_noisesArguments"
- Changed
attribute_speakers23 fields changed- added
Input schema / properties / apply / descriptionAdded 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." - removed
Input schema / properties / apply / titleRemoved value: -"Apply" - added
Input schema / properties / clip_id / descriptionAdded value: +"The co-hosted clip: one container, one mic per speaker, one transcript already attached." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / labels / anyOfRemoved value: -[ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } -] - added
Input schema / properties / labels / descriptionAdded value: +"What to call each stream, in the same order — one per stream. Unset, `speaker1`, `speaker2`." - added
Input schema / properties / labels / itemsAdded value: +{ + "type": "string" +} - removed
Input schema / properties / labels / titleRemoved value: -"Labels" - added
Input schema / properties / labels / typeAdded value: +[ + "array", + "null" +] - added
Input schema / properties / limit / descriptionAdded value: +"How many ambiguous spans to return; the reply also says how many there are in total." - removed
Input schema / properties / limit / titleRemoved value: -"Limit" - added
Input schema / properties / margin_db / descriptionAdded 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." - removed
Input schema / properties / margin_db / titleRemoved value: -"Margin Db" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / streams / anyOfRemoved value: -[ - { - "items": { - "type": "integer" - }, - "type": "array" - }, - { - "type": "null" - } -] - added
Input schema / properties / streams / descriptionAdded value: +"Which audio streams the speakers are on, as ffmpeg audio ordinals (`[0, 1]`). Unset, the container's readable audio streams in order." - added
Input schema / properties / streams / itemsAdded value: +{ + "type": "integer" +} - removed
Input schema / properties / streams / titleRemoved value: -"Streams" - added
Input schema / properties / streams / typeAdded value: +[ + "array", + "null" +] - removed
Input schema / titleRemoved value: -"attribute_speakersArguments"
- Changed
broll_brief9 fields changed- removed
Input schema / properties / fps / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fps / descriptionAdded value: +"The frame grid the shot positions are projected on. Defaults to the rate `export` would use." - removed
Input schema / properties / fps / titleRemoved value: -"Fps" - added
Input schema / properties / fps / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"broll_briefArguments"
- Changed
build_shots9 fields changed- removed
Input schema / properties / fps / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fps / descriptionAdded 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." - removed
Input schema / properties / fps / titleRemoved value: -"Fps" - added
Input schema / properties / fps / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"build_shotsArguments"
- Changed
canvas13 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / reset / descriptionAdded value: +"Drop the override and return to the footage-derived shape." - removed
Input schema / properties / reset / titleRemoved value: -"Reset" - removed
Input schema / properties / size / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / size / descriptionAdded 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." - removed
Input schema / properties / size / titleRemoved value: -"Size" - added
Input schema / properties / size / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"canvasArguments"
- Changed
caption_style81 fields changed- removed
Input schema / properties / bold / anyOfRemoved value: -[ - { - "type": "boolean" - }, - { - "type": "null" - } -] - added
Input schema / properties / bold / descriptionAdded value: +"Draw bold." - removed
Input schema / properties / bold / titleRemoved value: -"Bold" - added
Input schema / properties / bold / typeAdded value: +[ + "boolean", + "null" +] - removed
Input schema / properties / box / anyOfRemoved value: -[ - { - "type": "boolean" - }, - { - "type": "null" - } -] - added
Input schema / properties / box / descriptionAdded 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." - removed
Input schema / properties / box / titleRemoved value: -"Box" - added
Input schema / properties / box / typeAdded value: +[ + "boolean", + "null" +] - removed
Input schema / properties / box_colour / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / box_colour / descriptionAdded value: +"Colour of the box behind the type, when `box` is on." - removed
Input schema / properties / box_colour / titleRemoved value: -"Box Colour" - added
Input schema / properties / box_colour / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / font / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / font / descriptionAdded 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." - removed
Input schema / properties / font / titleRemoved value: -"Font" - added
Input schema / properties / font / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / highlight / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / highlight / descriptionAdded value: +"What a word turns as it is spoken. It only shows with `karaoke` on." - removed
Input schema / properties / highlight / titleRemoved value: -"Highlight" - added
Input schema / properties / highlight / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / hold / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / hold / descriptionAdded value: +"How long a cue lingers after its last word, in seconds." - removed
Input schema / properties / hold / titleRemoved value: -"Hold" - added
Input schema / properties / hold / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / karaoke / anyOfRemoved value: -[ - { - "type": "boolean" - }, - { - "type": "null" - } -] - added
Input schema / properties / karaoke / descriptionAdded 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." - removed
Input schema / properties / karaoke / titleRemoved value: -"Karaoke" - added
Input schema / properties / karaoke / typeAdded value: +[ + "boolean", + "null" +] - removed
Input schema / properties / margin / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / margin / descriptionAdded value: +"Distance from the frame edge, in canvas pixels." - removed
Input schema / properties / margin / titleRemoved value: -"Margin" - added
Input schema / properties / margin / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / max_duration / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / max_duration / descriptionAdded value: +"Longest a single cue stays on screen, in seconds." - removed
Input schema / properties / max_duration / titleRemoved value: -"Max Duration" - added
Input schema / properties / max_duration / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / max_gap / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / max_gap / descriptionAdded value: +"Start a new cue when the silence between two words exceeds this many seconds." - removed
Input schema / properties / max_gap / titleRemoved value: -"Max Gap" - added
Input schema / properties / max_gap / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / max_words / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / max_words / descriptionAdded value: +"Most words in one caption cue. Grouping is part of the look, which is why it is stored with it." - removed
Input schema / properties / max_words / titleRemoved value: -"Max Words" - added
Input schema / properties / max_words / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / outline_colour / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / outline_colour / descriptionAdded value: +"Colour of the outline around the type." - removed
Input schema / properties / outline_colour / titleRemoved value: -"Outline Colour" - added
Input schema / properties / outline_colour / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / outline_width / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / outline_width / descriptionAdded value: +"Outline thickness. With no box this is what holds the words apart from the picture." - removed
Input schema / properties / outline_width / titleRemoved value: -"Outline Width" - added
Input schema / properties / outline_width / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - removed
Input schema / properties / position / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / position / descriptionAdded value: +"Where captions sit, named: `bottom`, `top`, `top-right` and so on." - removed
Input schema / properties / position / titleRemoved value: -"Position" - added
Input schema / properties / position / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / preset / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / preset / descriptionAdded value: +"The base look: `clean`, `karaoke` (per-word highlight) or `boxed`. Everything else overrides one of its fields, and only the overrides are stored." - removed
Input schema / properties / preset / titleRemoved value: -"Preset" - added
Input schema / properties / preset / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / reset / descriptionAdded value: +"Drop every override first. `reset` together with `preset` starts clean from that preset." - removed
Input schema / properties / reset / titleRemoved value: -"Reset" - removed
Input schema / properties / shadow / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / shadow / descriptionAdded value: +"Drop-shadow distance." - removed
Input schema / properties / shadow / titleRemoved value: -"Shadow" - added
Input schema / properties / shadow / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / size / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / size / descriptionAdded value: +"Type size, against the project's canvas as the reference frame." - removed
Input schema / properties / size / titleRemoved value: -"Size" - added
Input schema / properties / size / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / text / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / text / descriptionAdded 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." - removed
Input schema / properties / text / titleRemoved value: -"Text" - added
Input schema / properties / text / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"caption_styleArguments"
- Changed
caption_view11 fields changed- removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"Show one transcript's captions rather than every clip's." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / firstAdded value: +{ + "default": 0, + "description": "Index of the first cue to return. 0 by default.", + "type": "integer" +} - added
Input schema / properties / limitAdded value: +{ + "default": 30, + "description": "Most cues to return; `cues_next` says where to continue.", + "type": "integer" +} - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"caption_viewArguments"
- Changed
card_new21 fields changed- removed
Input schema / properties / height / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / height / descriptionAdded value: +"Render height, given together with `width` or not at all." - removed
Input schema / properties / height / titleRemoved value: -"Height" - added
Input schema / properties / height / typeAdded value: +[ + "integer", + "null" +] - added
Input schema / properties / name / descriptionAdded value: +"The `<name>` in `card:<name>` — the key a cue points at. The SVG and the PNG are both written under `assets/cards/`." - removed
Input schema / properties / name / titleRemoved value: -"Name" - added
Input schema / properties / overwrite / descriptionAdded value: +"Redraw a card of this name that already exists. Refused without it, since a cue may already point at that card." - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / slots / descriptionAdded 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." - removed
Input schema / properties / slots / titleRemoved value: -"Slots" - added
Input schema / properties / template / descriptionAdded 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." - removed
Input schema / properties / template / titleRemoved value: -"Template" - removed
Input schema / properties / width / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / width / descriptionAdded 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." - removed
Input schema / properties / width / titleRemoved value: -"Width" - added
Input schema / properties / width / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"card_newArguments"
- Changed
card_reauthor11 fields changed- removed
Input schema / properties / name / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / name / descriptionAdded 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." - removed
Input schema / properties / name / titleRemoved value: -"Name" - added
Input schema / properties / name / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - removed
Input schema / titleRemoved value: -"card_reauthorArguments"
- Changed
card_render15 fields changed- removed
Input schema / properties / height / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / height / descriptionAdded value: +"Render height, given together with `width` or not at all." - removed
Input schema / properties / height / titleRemoved value: -"Height" - added
Input schema / properties / height / typeAdded value: +[ + "integer", + "null" +] - added
Input schema / properties / name / descriptionAdded value: +"The card to rasterise: `assets/cards/<name>.svg` becomes the PNG that `card:<name>` resolves to." - removed
Input schema / properties / name / titleRemoved value: -"Name" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / width / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / width / descriptionAdded 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." - removed
Input schema / properties / width / titleRemoved value: -"Width" - added
Input schema / properties / width / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"card_renderArguments"
- Changed
card_safe_zones9 fields changed- added
Input schema / properties / card / descriptionAdded 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." - removed
Input schema / properties / card / titleRemoved value: -"Card" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / platform / descriptionAdded 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." - removed
Input schema / properties / platform / titleRemoved value: -"Platform" - removed
Input schema / titleRemoved value: -"card_safe_zonesArguments"
- Changed
card_templates2 fields changed- added
Input schema / properties / nameAdded 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" + ] +} - removed
Input schema / titleRemoved value: -"card_templatesArguments"
- Added
changes - Changed
check_black17 fields changed- removed
Input schema / properties / fps / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fps / descriptionAdded value: +"The rate the timeline's own frame arithmetic is counted on." - removed
Input schema / properties / fps / titleRemoved value: -"Fps" - added
Input schema / properties / fps / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / min_duration / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / min_duration / descriptionAdded value: +"Shortest black run to report, in seconds." - removed
Input schema / properties / min_duration / titleRemoved value: -"Min Duration" - added
Input schema / properties / min_duration / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / pix_th / descriptionAdded value: +"How dark a pixel counts as black, 0–1." - removed
Input schema / properties / pix_th / titleRemoved value: -"Pix Th" - added
Input schema / properties / target / descriptionAdded 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." - removed
Input schema / properties / target / titleRemoved value: -"Target" - removed
Input schema / titleRemoved value: -"check_blackArguments"
- Changed
check_frames13 fields changed- removed
Input schema / properties / fps / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fps / descriptionAdded 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." - removed
Input schema / properties / fps / titleRemoved value: -"Fps" - added
Input schema / properties / fps / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / target / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / target / descriptionAdded 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." - removed
Input schema / properties / target / titleRemoved value: -"Target" - added
Input schema / properties / target / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"check_framesArguments"
- Changed
clip_rm7 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The clip to un-register. Its media on disk is never touched." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"clip_rmArguments"
- Changed
clip_role13 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The clip to read or set." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / reset / descriptionAdded value: +"Clear the role back to undeclared." - removed
Input schema / properties / reset / titleRemoved value: -"Reset" - removed
Input schema / properties / role / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / role / descriptionAdded 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." - removed
Input schema / properties / role / titleRemoved value: -"Role" - added
Input schema / properties / role / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"clip_roleArguments"
- Changed
contact_sheet11 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The clip whose head to look at." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / interval / descriptionAdded value: +"Seconds between tiles." - removed
Input schema / properties / interval / titleRemoved value: -"Interval" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / seconds / descriptionAdded 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." - removed
Input schema / properties / seconds / titleRemoved value: -"Seconds" - removed
Input schema / titleRemoved value: -"contact_sheetArguments"
- Changed
continuity_accept11 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The cue's own addressing transcript, as `continuity_check` reports it." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / kind / descriptionAdded value: +"Which finding to acknowledge: `rewind`, `replay`, `short_shot` or `stub`." - removed
Input schema / properties / kind / titleRemoved value: -"Kind" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / word_index / descriptionAdded value: +"The cue's word. With `clip_id` and `kind` it is the finding's address — one shot can carry more than one finding." - removed
Input schema / properties / word_index / titleRemoved value: -"Word Index" - removed
Input schema / titleRemoved value: -"continuity_acceptArguments"
- Changed
continuity_check15 fields changed- added
Input schema / properties / gap / descriptionAdded value: +"How much timeline may pass before re-showing an asset reads as a replay rather than a rewind, in seconds." - removed
Input schema / properties / gap / titleRemoved value: -"Gap" - added
Input schema / properties / min_shot / descriptionAdded value: +"Shortest a shot may run before it is reported as a short shot, in seconds. Stills are excluded." - removed
Input schema / properties / min_shot / titleRemoved value: -"Min Shot" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / scene_threshold / descriptionAdded 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." - removed
Input schema / properties / scene_threshold / titleRemoved value: -"Scene Threshold" - added
Input schema / properties / stub_tolerance / descriptionAdded value: +"How close a shot edge has to sit to its footage's own internal cut to be called a stub, in seconds." - removed
Input schema / properties / stub_tolerance / titleRemoved value: -"Stub Tolerance" - added
Input schema / properties / stubs / descriptionAdded value: +"Look for stubs. On by default, and it costs a scene-cut decode per distinct asset placed — `false` skips that." - removed
Input schema / properties / stubs / titleRemoved value: -"Stubs" - removed
Input schema / titleRemoved value: -"continuity_checkArguments"
- Changed
continuity_ls5 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"continuity_lsArguments"
- Changed
continuity_reject11 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The cue's own addressing transcript." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / kind / descriptionAdded value: +"Which finding to un-acknowledge: `rewind`, `replay`, `short_shot` or `stub`." - removed
Input schema / properties / kind / titleRemoved value: -"Kind" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / word_index / descriptionAdded value: +"The cue's word, with `clip_id` and `kind` the address the acknowledgement was stored under." - removed
Input schema / properties / word_index / titleRemoved value: -"Word Index" - removed
Input schema / titleRemoved value: -"continuity_rejectArguments"
- Changed
cue_add29 fields changed- added
Input schema / properties / after / descriptionAdded 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." - removed
Input schema / properties / after / titleRemoved value: -"After" - removed
Input schema / properties / asset / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / asset / descriptionAdded 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." - removed
Input schema / properties / asset / titleRemoved value: -"Asset" - added
Input schema / properties / asset / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / clip_id / descriptionAdded value: +"The transcript the cue is addressed against — the VO on a voiceover project, not the footage being shown. `asset` is what gets seen." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / occurrence / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / occurrence / descriptionAdded 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." - removed
Input schema / properties / occurrence / titleRemoved value: -"Occurrence" - added
Input schema / properties / occurrence / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / phrase / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / phrase / descriptionAdded value: +"Address the cue by what is said instead of by index. It binds to the phrase's **first** word — \"from this word onward\"." - removed
Input schema / properties / phrase / titleRemoved value: -"Phrase" - added
Input schema / properties / phrase / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / src_start / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / src_start / descriptionAdded 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." - removed
Input schema / properties / src_start / titleRemoved value: -"Src Start" - added
Input schema / properties / src_start / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / word_index / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index / descriptionAdded value: +"The word the picture starts on, in `clip_id`'s transcript. Give this or `phrase`, not both." - removed
Input schema / properties / word_index / titleRemoved value: -"Word Index" - added
Input schema / properties / word_index / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"cue_addArguments"
- Changed
cue_ls9 fields changed- removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"List one clip's cues. Omit it for the whole table." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"cue_lsArguments"
- Changed
cue_reresolve11 fields changed- added
Input schema / properties / apply / descriptionAdded 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." - removed
Input schema / properties / apply / titleRemoved value: -"Apply" - removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"Re-resolve one clip's entries. Omit it for every clip." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"cue_reresolveArguments"
- Changed
cue_rm21 fields changed- added
Input schema / properties / after / descriptionAdded 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." - removed
Input schema / properties / after / titleRemoved value: -"After" - added
Input schema / properties / clip_id / descriptionAdded value: +"The transcript the cue was addressed against." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / occurrence / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / occurrence / descriptionAdded 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." - removed
Input schema / properties / occurrence / titleRemoved value: -"Occurrence" - added
Input schema / properties / occurrence / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / phrase / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / phrase / descriptionAdded value: +"Address it by wording instead; it resolves to its first word, the way `cue_add` placed it." - removed
Input schema / properties / phrase / titleRemoved value: -"Phrase" - added
Input schema / properties / phrase / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / word_index / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index / descriptionAdded value: +"The word the cue sits on. Give this or `phrase`." - removed
Input schema / properties / word_index / titleRemoved value: -"Word Index" - added
Input schema / properties / word_index / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"cue_rmArguments"
- Changed
cut_by_time13 fields changed- added
Input schema / properties / confirm_suspect / descriptionAdded 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." - removed
Input schema / properties / confirm_suspect / titleRemoved value: -"Confirm Suspect" - added
Input schema / properties / pad / descriptionAdded value: +"Widen only the outer edges of each requested span, in seconds." - removed
Input schema / properties / pad / titleRemoved value: -"Pad" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / spans / descriptionAdded 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." - removed
Input schema / properties / spans / titleRemoved value: -"Spans" - removed
Input schema / titleRemoved value: -"cut_by_timeArguments"
- Changed
cut_by_transcript25 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The transcript the word ranges address." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / confirm_suspect / descriptionAdded 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." - removed
Input schema / properties / confirm_suspect / titleRemoved value: -"Confirm Suspect" - removed
Input schema / properties / cut / anyOfRemoved value: -[ - { - "items": { - "items": { - "type": "integer" - }, - "type": "array" - }, - "type": "array" - }, - { - "type": "null" - } -] - added
Input schema / properties / cut / descriptionAdded value: +"Inclusive word ranges to remove, e.g. `[[30, 45], [120, 131]]`. Pass exactly one of `cut` or `keep`." - added
Input schema / properties / cut / itemsAdded value: +{ + "items": { + "type": "integer" + }, + "type": "array" +} - removed
Input schema / properties / cut / titleRemoved value: -"Cut" - added
Input schema / properties / cut / typeAdded value: +[ + "array", + "null" +] - removed
Input schema / properties / keep / anyOfRemoved value: -[ - { - "items": { - "items": { - "type": "integer" - }, - "type": "array" - }, - "type": "array" - }, - { - "type": "null" - } -] - added
Input schema / properties / keep / descriptionAdded value: +"Inclusive word ranges to keep, everything else going. Pass exactly one of `cut` or `keep`." - added
Input schema / properties / keep / itemsAdded value: +{ + "items": { + "type": "integer" + }, + "type": "array" +} - removed
Input schema / properties / keep / titleRemoved value: -"Keep" - added
Input schema / properties / keep / typeAdded value: +[ + "array", + "null" +] - added
Input schema / properties / pad / descriptionAdded 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." - removed
Input schema / properties / pad / titleRemoved value: -"Pad" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / through_pause / descriptionAdded 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." - removed
Input schema / properties / through_pause / titleRemoved value: -"Through Pause" - removed
Input schema / titleRemoved value: -"cut_by_transcriptArguments"
- Changed
describe15 fields changed- removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded 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." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / force / descriptionAdded value: +"Describe clips that already have descriptions, replacing them. Without it they are skipped." - removed
Input schema / properties / force / titleRemoved value: -"Force" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / window / descriptionAdded 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." - removed
Input schema / properties / window / titleRemoved value: -"Window" - removed
Input schema / titleRemoved value: -"describeArguments"
- Changed
describe_ls13 fields changed- removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"List only this clip's windows." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / contains / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / contains / descriptionAdded value: +"Keep only windows whose text holds every whitespace-separated term, case-insensitively — so `\"kitchen knife\"` matches \"a knife on the kitchen counter\"." - removed
Input schema / properties / contains / titleRemoved value: -"Contains" - added
Input schema / properties / contains / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"describe_lsArguments"
- Changed
doctor1 field changed- removed
Input schema / titleRemoved value: -"doctorArguments"
- Changed
export30 fields changed- removed
Input schema / properties / export_format / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / export_format / descriptionAdded 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." - removed
Input schema / properties / export_format / titleRemoved value: -"Export Format" - added
Input schema / properties / export_format / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / fps / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fps / descriptionAdded 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." - removed
Input schema / properties / fps / titleRemoved value: -"Fps" - added
Input schema / properties / fps / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / loudness / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / loudness / descriptionAdded 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." - removed
Input schema / properties / loudness / titleRemoved value: -"Loudness" - added
Input schema / properties / loudness / typeAdded value: +[ + "number", + "null" +] - added
Input schema / properties / output / descriptionAdded value: +"Where to write the project file or the render. A file argument, not a project selector: it writes where you say." - removed
Input schema / properties / output / titleRemoved value: -"Output" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / preset / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / preset / descriptionAdded 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." - removed
Input schema / properties / preset / titleRemoved value: -"Preset" - added
Input schema / properties / preset / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / resolution / anyOfRemoved value: -[ - { - "items": { - "type": "integer" - }, - "type": "array" - }, - { - "type": "null" - } -] - added
Input schema / properties / resolution / descriptionAdded 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." - added
Input schema / properties / resolution / itemsAdded value: +{ + "type": "integer" +} - removed
Input schema / properties / resolution / titleRemoved value: -"Resolution" - added
Input schema / properties / resolution / typeAdded value: +[ + "array", + "null" +] - added
Input schema / properties / true_peak / descriptionAdded value: +"The dBTP ceiling the loudness pass limits under. -1.0 by default." - removed
Input schema / properties / true_peak / titleRemoved value: -"True Peak" - removed
Input schema / titleRemoved value: -"exportArguments"
- Changed
film_check13 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - removed
Input schema / properties / reference / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / reference / descriptionAdded 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." - removed
Input schema / properties / reference / titleRemoved value: -"Reference" - added
Input schema / properties / reference / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / reset / descriptionAdded value: +"Drop the stored reference." - removed
Input schema / properties / reset / titleRemoved value: -"Reset" - removed
Input schema / titleRemoved value: -"film_checkArguments"
- Changed
finish_check48 fields changed- added
Input schema / properties / black_min_duration / descriptionAdded value: +"Shortest black run to report, in seconds." - removed
Input schema / properties / black_min_duration / titleRemoved value: -"Black Min Duration" - removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"Diff against one transcript's expected words rather than all of them." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / duration_tolerance / descriptionAdded value: +"How far `final`'s duration may sit from the timeline's own arithmetic before it is a fault, in seconds." - removed
Input schema / properties / duration_tolerance / titleRemoved value: -"Duration Tolerance" - added
Input schema / properties / final / descriptionAdded 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." - removed
Input schema / properties / final / titleRemoved value: -"Final" - removed
Input schema / properties / fps / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fps / descriptionAdded value: +"The frame grid the timeline's arithmetic is counted on. Defaults to the rate `export` would have picked." - removed
Input schema / properties / fps / titleRemoved value: -"Fps" - added
Input schema / properties / fps / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / holds / anyOfRemoved value: -[ - { - "items": { - "additionalProperties": true, - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } -] - added
Input schema / properties / holds / descriptionAdded 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." - added
Input schema / properties / holds / itemsAdded value: +{ + "additionalProperties": true, + "type": "object" +} - removed
Input schema / properties / holds / titleRemoved value: -"Holds" - added
Input schema / properties / holds / typeAdded value: +[ + "array", + "null" +] - removed
Input schema / properties / language / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / language / descriptionAdded value: +"Force a language code for the transcription." - removed
Input schema / properties / language / titleRemoved value: -"Language" - added
Input schema / properties / language / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / overlap / descriptionAdded value: +"How far each window overlaps the one before, in seconds." - removed
Input schema / properties / overlap / titleRemoved value: -"Overlap" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / pix_th / descriptionAdded value: +"blackdetect's pixel threshold: how dark a pixel counts as black." - removed
Input schema / properties / pix_th / titleRemoved value: -"Pix Th" - removed
Input schema / properties / prepend_seconds / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / prepend_seconds / descriptionAdded 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." - removed
Input schema / properties / prepend_seconds / titleRemoved value: -"Prepend Seconds" - added
Input schema / properties / prepend_seconds / typeAdded value: +[ + "number", + "null" +] - added
Input schema / properties / recheck_pad / descriptionAdded 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." - removed
Input schema / properties / recheck_pad / titleRemoved value: -"Recheck Pad" - removed
Input schema / properties / transcript_path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / transcript_path / descriptionAdded value: +"An existing transcription of `final`, to diff again without re-transcribing." - removed
Input schema / properties / transcript_path / titleRemoved value: -"Transcript Path" - added
Input schema / properties / transcript_path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / window / descriptionAdded value: +"Length of each transcription window, in seconds." - removed
Input schema / properties / window / titleRemoved value: -"Window" - removed
Input schema / properties / windowed_model / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / windowed_model / descriptionAdded 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." - removed
Input schema / properties / windowed_model / titleRemoved value: -"Windowed Model" - added
Input schema / properties / windowed_model / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"finish_checkArguments"
- Changed
finish_report11 fields changed- added
Input schema / properties / continuity / descriptionAdded 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." - removed
Input schema / properties / continuity / titleRemoved value: -"Continuity" - added
Input schema / properties / framing / descriptionAdded 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." - removed
Input schema / properties / framing / titleRemoved value: -"Framing" - added
Input schema / properties / holds / descriptionAdded 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." - removed
Input schema / properties / holds / titleRemoved value: -"Holds" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"finish_reportArguments"
- Changed
fonts7 fields changed- added
Input schema / properties / install / descriptionAdded 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." - removed
Input schema / properties / install / titleRemoved value: -"Install" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"fontsArguments"
- Changed
footage_sheet19 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The registered clip to browse. This sheet reads the clip's **own source**, so it needs no edit, no cues and no transcript." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / interval / descriptionAdded 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." - removed
Input schema / properties / interval / titleRemoved value: -"Interval" - added
Input schema / properties / mode / descriptionAdded 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." - removed
Input schema / properties / mode / titleRemoved value: -"Mode" - removed
Input schema / properties / out / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / out / descriptionAdded 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." - removed
Input schema / properties / out / titleRemoved value: -"Out" - added
Input schema / properties / out / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / page / descriptionAdded value: +"Which page of rows to draw, from 1. Unset, the first." - removed
Input schema / properties / page / titleRemoved value: -"Page" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / per_page / descriptionAdded 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." - removed
Input schema / properties / per_page / titleRemoved value: -"Per Page" - removed
Input schema / titleRemoved value: -"footage_sheetArguments"
- Changed
get_transcript20 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The clip to read." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / first / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / first / descriptionAdded value: +"First word index to return, inclusive." - removed
Input schema / properties / first / titleRemoved value: -"First" - added
Input schema / properties / first / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / last / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / last / descriptionAdded value: +"Last word index to return, inclusive." - removed
Input schema / properties / last / titleRemoved value: -"Last" - added
Input schema / properties / last / typeAdded value: +[ + "integer", + "null" +] - added
Input schema / properties / limitAdded 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" +} - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / search / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / search / descriptionAdded 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." - removed
Input schema / properties / search / titleRemoved value: -"Search" - added
Input schema / properties / search / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"get_transcriptArguments"
- Changed
head33 fields changed- removed
Input schema / properties / asset / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / asset / descriptionAdded 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." - removed
Input schema / properties / asset / titleRemoved value: -"Asset" - added
Input schema / properties / asset / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / fade_in / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fade_in / descriptionAdded 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." - removed
Input schema / properties / fade_in / titleRemoved value: -"Fade In" - added
Input schema / properties / fade_in / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / fade_out / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fade_out / descriptionAdded value: +"Seconds of fade where the cold open hands over to the film." - removed
Input schema / properties / fade_out / titleRemoved value: -"Fade Out" - added
Input schema / properties / fade_out / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / gain_db / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / gain_db / descriptionAdded value: +"A flat level shift for the cold open, in dB, distinct from the fades. 0.0 is unity." - removed
Input schema / properties / gain_db / titleRemoved value: -"Gain Db" - added
Input schema / properties / gain_db / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / reset / descriptionAdded value: +"Drop the cold open entirely." - removed
Input schema / properties / reset / titleRemoved value: -"Reset" - removed
Input schema / properties / seconds / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / seconds / descriptionAdded 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." - removed
Input schema / properties / seconds / titleRemoved value: -"Seconds" - added
Input schema / properties / seconds / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / src_start / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / src_start / descriptionAdded value: +"Where inside that asset the cold open reads from, in source seconds. 0.0 on a first set." - removed
Input schema / properties / src_start / titleRemoved value: -"Src Start" - added
Input schema / properties / src_start / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / titleRemoved value: -"headArguments"
- Changed
hear21 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The clip whose source audio to listen to." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / end / descriptionAdded value: +"Where to stop, in the same source seconds. Past the end of the clip it is refused rather than clamped." - removed
Input schema / properties / end / titleRemoved value: -"End" - removed
Input schema / properties / language / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / language / descriptionAdded value: +"Force a language code, e.g. `en`. Unset, whisper detects it." - removed
Input schema / properties / language / titleRemoved value: -"Language" - added
Input schema / properties / language / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / model / descriptionAdded value: +"The whisper model for this windowed pass." - removed
Input schema / properties / model / titleRemoved value: -"Model" - added
Input schema / properties / overlap / descriptionAdded 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." - removed
Input schema / properties / overlap / titleRemoved value: -"Overlap" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / start / descriptionAdded value: +"Where to start listening, in that clip's own **source** seconds — never timeline seconds and never a word index." - removed
Input schema / properties / start / titleRemoved value: -"Start" - added
Input schema / properties / window / descriptionAdded value: +"Length of each window, in seconds." - removed
Input schema / properties / window / titleRemoved value: -"Window" - removed
Input schema / titleRemoved value: -"hearArguments"
- Changed
hold_add67 fields changed- added
Input schema / properties / after / descriptionAdded 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." - removed
Input schema / properties / after / titleRemoved value: -"After" - removed
Input schema / properties / asset / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / asset / descriptionAdded value: +"The film clip whose own audio plays in the gap, and whose picture the cue pins." - removed
Input schema / properties / asset / titleRemoved value: -"Asset" - added
Input schema / properties / asset / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / asset_phrase / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / asset_phrase / descriptionAdded 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." - removed
Input schema / properties / asset_phrase / titleRemoved value: -"Asset Phrase" - added
Input schema / properties / asset_phrase / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / clip_id / descriptionAdded value: +"The VO track the gap opens in." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / cue_phrase / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / cue_phrase / descriptionAdded value: +"Address the cue by wording; it binds its **first** word." - removed
Input schema / properties / cue_phrase / titleRemoved value: -"Cue Phrase" - added
Input schema / properties / cue_phrase / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / cue_word_index / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / cue_word_index / descriptionAdded value: +"The word the picture cue for `asset` is placed on." - removed
Input schema / properties / cue_word_index / titleRemoved value: -"Cue Word Index" - added
Input schema / properties / cue_word_index / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / fade_in / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fade_in / descriptionAdded value: +"Seconds of fade as the held audio comes in. Re-settable." - removed
Input schema / properties / fade_in / titleRemoved value: -"Fade In" - added
Input schema / properties / fade_in / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / fade_out / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fade_out / descriptionAdded value: +"Seconds of fade as it goes out. Re-settable." - removed
Input schema / properties / fade_out / titleRemoved value: -"Fade Out" - added
Input schema / properties / fade_out / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / gap_phrase / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / gap_phrase / descriptionAdded value: +"Address the gap by wording; it binds its **last** word, since the gap opens right after it." - removed
Input schema / properties / gap_phrase / titleRemoved value: -"Gap Phrase" - added
Input schema / properties / gap_phrase / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / gap_word_index / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / gap_word_index / descriptionAdded 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." - removed
Input schema / properties / gap_word_index / titleRemoved value: -"Gap Word Index" - added
Input schema / properties / gap_word_index / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / head_margin / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / head_margin / descriptionAdded value: +"Seconds kept before the line, so it does not start on the word. Re-settable on an already-spliced hold." - removed
Input schema / properties / head_margin / titleRemoved value: -"Head Margin" - added
Input schema / properties / head_margin / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / occurrence / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / occurrence / descriptionAdded value: +"Disambiguate `gap_phrase`/`cue_phrase`/`asset_phrase` by count, **1-based**. Unset, an ambiguous phrase is refused rather than guessed at." - removed
Input schema / properties / occurrence / titleRemoved value: -"Occurrence" - added
Input schema / properties / occurrence / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - removed
Input schema / properties / tail_margin / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / tail_margin / descriptionAdded value: +"Seconds kept after the line. Re-settable." - removed
Input schema / properties / tail_margin / titleRemoved value: -"Tail Margin" - added
Input schema / properties / tail_margin / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / under / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / under / descriptionAdded value: +"How far below the VO the held audio sits, in LU. Re-settable." - removed
Input schema / properties / under / titleRemoved value: -"Under" - added
Input schema / properties / under / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / word_index_first / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index_first / descriptionAdded value: +"First word of the line to play, in **`asset`'s own** transcript — not the VO's." - removed
Input schema / properties / word_index_first / titleRemoved value: -"Word Index First" - added
Input schema / properties / word_index_first / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / word_index_last / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index_last / descriptionAdded 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`." - removed
Input schema / properties / word_index_last / titleRemoved value: -"Word Index Last" - added
Input schema / properties / word_index_last / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"hold_addArguments"
- Changed
hold_check7 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / render / descriptionAdded value: +"The rendered file to listen to. Each hold's span is resolved live against the current edit and transcribed off this file." - removed
Input schema / properties / render / titleRemoved value: -"Render" - removed
Input schema / titleRemoved value: -"hold_checkArguments"
- Changed
hold_ls5 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"hold_lsArguments"
- Changed
hold_rm9 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The VO track the hold was spliced into." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / gap_word_index / descriptionAdded 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`." - removed
Input schema / properties / gap_word_index / titleRemoved value: -"Gap Word Index" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"hold_rmArguments"
- Changed
hold_under45 fields changed- added
Input schema / properties / after / descriptionAdded 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." - removed
Input schema / properties / after / titleRemoved value: -"After" - added
Input schema / properties / asset / descriptionAdded 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." - removed
Input schema / properties / asset / titleRemoved value: -"Asset" - added
Input schema / properties / clip_id / descriptionAdded value: +"The VO track whose words the span is measured in." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / fade_in / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fade_in / descriptionAdded value: +"Seconds of fade as the film audio comes in." - removed
Input schema / properties / fade_in / titleRemoved value: -"Fade In" - added
Input schema / properties / fade_in / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / fade_out / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fade_out / descriptionAdded value: +"Seconds of fade as it goes out." - removed
Input schema / properties / fade_out / titleRemoved value: -"Fade Out" - added
Input schema / properties / fade_out / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / occurrence / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / occurrence / descriptionAdded value: +"Disambiguate `phrase_start`/`phrase_end` by count, **1-based**. Unset, an ambiguous phrase is refused rather than guessed at." - removed
Input schema / properties / occurrence / titleRemoved value: -"Occurrence" - added
Input schema / properties / occurrence / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / phrase_end / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / phrase_end / descriptionAdded value: +"Set the span's end by wording instead." - removed
Input schema / properties / phrase_end / titleRemoved value: -"Phrase End" - added
Input schema / properties / phrase_end / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / phrase_start / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / phrase_start / descriptionAdded value: +"Set the span's start by wording instead." - removed
Input schema / properties / phrase_start / titleRemoved value: -"Phrase Start" - added
Input schema / properties / phrase_start / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - removed
Input schema / properties / under / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / under / descriptionAdded value: +"How far below the VO the film audio sits, in LU. 13 by default." - removed
Input schema / properties / under / titleRemoved value: -"Under" - added
Input schema / properties / under / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / word_index_end / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index_end / descriptionAdded value: +"Last VO word of the span." - removed
Input schema / properties / word_index_end / titleRemoved value: -"Word Index End" - added
Input schema / properties / word_index_end / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / word_index_start / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index_start / descriptionAdded 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." - removed
Input schema / properties / word_index_start / titleRemoved value: -"Word Index Start" - added
Input schema / properties / word_index_start / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"hold_underArguments"
- Changed
hold_under_rm9 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The VO track the entry was addressed against." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / word_index_start / descriptionAdded value: +"The span's first VO word — the entry's address, with `clip_id`." - removed
Input schema / properties / word_index_start / titleRemoved value: -"Word Index Start" - removed
Input schema / titleRemoved value: -"hold_under_rmArguments"
- Changed
import_edit13 fields changed- removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"The registered clip to attribute a single-source document to, when its media sits at a path this project does not know." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / document / descriptionAdded 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." - removed
Input schema / properties / document / titleRemoved value: -"Document" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - removed
Input schema / titleRemoved value: -"import_editArguments"
- Changed
import_media21 fields changed- removed
Input schema / properties / audio_stream / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / audio_stream / descriptionAdded 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." - removed
Input schema / properties / audio_stream / titleRemoved value: -"Audio Stream" - added
Input schema / properties / audio_stream / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded 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." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / copy / descriptionAdded 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." - removed
Input schema / properties / copy / titleRemoved value: -"Copy" - added
Input schema / properties / mix / descriptionAdded 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." - removed
Input schema / properties / mix / titleRemoved value: -"Mix" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / sheet / descriptionAdded 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." - removed
Input schema / properties / sheet / titleRemoved value: -"Sheet" - added
Input schema / properties / source / descriptionAdded 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." - removed
Input schema / properties / source / titleRemoved value: -"Source" - removed
Input schema / titleRemoved value: -"import_mediaArguments"
- Changed
init9 fields changed- removed
Input schema / properties / name / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / name / descriptionAdded value: +"A name for the project, recorded in the manifest. Unset, the directory's own name is used." - removed
Input schema / properties / name / titleRemoved value: -"Name" - added
Input schema / properties / name / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"initArguments"
- Changed
list_media9 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / recursive / descriptionAdded value: +"Walk subdirectories too. On by default." - removed
Input schema / properties / recursive / titleRemoved value: -"Recursive" - added
Input schema / properties / source_dir / descriptionAdded value: +"The directory to list. It names where footage lives rather than which project, so it is deliberately not confined to the bound project." - removed
Input schema / properties / source_dir / titleRemoved value: -"Source Dir" - removed
Input schema / titleRemoved value: -"list_mediaArguments"
- Changed
locate33 fields changed- added
Input schema / properties / after / descriptionAdded 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." - removed
Input schema / properties / after / titleRemoved value: -"After" - added
Input schema / properties / clip_id / descriptionAdded value: +"The transcript, or the recording, the address belongs to." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / first / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / first / descriptionAdded value: +"First word index, inclusive. Address it one way per call: `first`/`last`, `source_start`/`source_end`, or `phrase`." - removed
Input schema / properties / first / titleRemoved value: -"First" - added
Input schema / properties / first / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / last / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / last / descriptionAdded value: +"Last word index, inclusive. Defaults to `first`." - removed
Input schema / properties / last / titleRemoved value: -"Last" - added
Input schema / properties / last / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / occurrence / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / occurrence / descriptionAdded 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." - removed
Input schema / properties / occurrence / titleRemoved value: -"Occurrence" - added
Input schema / properties / occurrence / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / phrase / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / phrase / descriptionAdded value: +"Locate by wording. A phrase is naturally a range, so it resolves straight to first and last with no edge to pick." - removed
Input schema / properties / phrase / titleRemoved value: -"Phrase" - added
Input schema / properties / phrase / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / source_end / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / source_end / descriptionAdded value: +"End of the source interval, in the recording's own seconds." - removed
Input schema / properties / source_end / titleRemoved value: -"Source End" - added
Input schema / properties / source_end / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / source_start / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / source_start / descriptionAdded value: +"Seconds into the original recording. Omit `source_end` to locate an instant." - removed
Input schema / properties / source_start / titleRemoved value: -"Source Start" - added
Input schema / properties / source_start / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / titleRemoved value: -"locateArguments"
- Changed
migrate_project7 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - removed
Input schema / titleRemoved value: -"migrate_projectArguments"
- Changed
music75 fields changed- added
Input schema / properties / after / descriptionAdded 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." - removed
Input schema / properties / after / titleRemoved value: -"After" - removed
Input schema / properties / asset / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / asset / descriptionAdded 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." - removed
Input schema / properties / asset / titleRemoved value: -"Asset" - added
Input schema / properties / asset / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / clear_duckAdded value: +{ + "default": false, + "description": "Return the bed to one level, with no ducking.", + "type": "boolean" +} - added
Input schema / properties / clear_end / descriptionAdded value: +"Drop the end word, returning the bed to running to the end of the edit." - removed
Input schema / properties / clear_end / titleRemoved value: -"Clear End" - added
Input schema / properties / clear_under / descriptionAdded value: +"Return every asset to its own level." - removed
Input schema / properties / clear_under / titleRemoved value: -"Clear Under" - removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"The transcript the bed's word indices address — the VO, not the music." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / crossfade / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / crossfade / descriptionAdded 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." - removed
Input schema / properties / crossfade / titleRemoved value: -"Crossfade" - added
Input schema / properties / crossfade / typeAdded value: +[ + "number", + "null" +] - added
Input schema / properties / duckAdded 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" + ] +} - removed
Input schema / properties / fade_in / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fade_in / descriptionAdded 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." - removed
Input schema / properties / fade_in / titleRemoved value: -"Fade In" - added
Input schema / properties / fade_in / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / fade_out / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fade_out / descriptionAdded value: +"Seconds of fade at the bed's end. A fade pair the bed cannot hold refuses at build time rather than being clamped." - removed
Input schema / properties / fade_out / titleRemoved value: -"Fade Out" - added
Input schema / properties / fade_out / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / occurrence / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / occurrence / descriptionAdded value: +"Disambiguate `phrase_start`/`phrase_end` by count, **1-based**. Unset, an ambiguous phrase is refused rather than guessed at." - removed
Input schema / properties / occurrence / titleRemoved value: -"Occurrence" - added
Input schema / properties / occurrence / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / passages / anyOfRemoved value: -[ - { - "items": { - "additionalProperties": true, - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } -] - added
Input schema / properties / passages / descriptionAdded 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." - added
Input schema / properties / passages / itemsAdded value: +{ + "additionalProperties": true, + "type": "object" +} - removed
Input schema / properties / passages / titleRemoved value: -"Passages" - added
Input schema / properties / passages / typeAdded value: +[ + "array", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / phrase_end / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / phrase_end / descriptionAdded 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." - removed
Input schema / properties / phrase_end / titleRemoved value: -"Phrase End" - added
Input schema / properties / phrase_end / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / phrase_start / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / phrase_start / descriptionAdded 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." - removed
Input schema / properties / phrase_start / titleRemoved value: -"Phrase Start" - added
Input schema / properties / phrase_start / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / reset / descriptionAdded value: +"Drop the bed entirely." - removed
Input schema / properties / reset / titleRemoved value: -"Reset" - removed
Input schema / properties / rotate / anyOfRemoved value: -[ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } -] - added
Input schema / properties / rotate / descriptionAdded value: +"Further assets to play in turn as each one runs out, overlapping by `crossfade`. `[]` clears them." - added
Input schema / properties / rotate / itemsAdded value: +{ + "type": "string" +} - removed
Input schema / properties / rotate / titleRemoved value: -"Rotate" - added
Input schema / properties / rotate / typeAdded value: +[ + "array", + "null" +] - removed
Input schema / properties / src_in / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / src_in / descriptionAdded value: +"Where inside the bed's own asset it starts, in seconds." - removed
Input schema / properties / src_in / titleRemoved value: -"Src In" - added
Input schema / properties / src_in / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / under / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / under / descriptionAdded value: +"Level the whole bed this many LU below the voice, measured. It is a fixed offset; `duck` is the moving one." - removed
Input schema / properties / under / titleRemoved value: -"Under" - added
Input schema / properties / under / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / word_index_end / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index_end / descriptionAdded value: +"Where the bed goes out. Unset means *to the end of the edit*, so a tail holds over silence." - removed
Input schema / properties / word_index_end / titleRemoved value: -"Word Index End" - added
Input schema / properties / word_index_end / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / word_index_start / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index_start / descriptionAdded 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." - removed
Input schema / properties / word_index_start / titleRemoved value: -"Word Index Start" - added
Input schema / properties / word_index_start / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"musicArguments"
- Changed
pack_activate9 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / variant / descriptionAdded 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." - removed
Input schema / properties / variant / titleRemoved value: -"Variant" - removed
Input schema / titleRemoved value: -"pack_activateArguments"
- Changed
pack_apply15 fields changed- added
Input schema / properties / allow_fallback / descriptionAdded 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." - removed
Input schema / properties / allow_fallback / titleRemoved value: -"Allow Fallback" - added
Input schema / properties / install_fonts / descriptionAdded value: +"Vendor the pack's own `fonts/` directory, if it ships one. Off by default, since it writes into `$HOME`." - removed
Input schema / properties / install_fonts / titleRemoved value: -"Install Fonts" - added
Input schema / properties / pack_path / descriptionAdded 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." - removed
Input schema / properties / pack_path / titleRemoved value: -"Pack Path" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / variant / descriptionAdded value: +"Which resolved variant to activate. Every declared variant is snapshotted regardless, so `pack_activate` can switch later with no file re-read." - removed
Input schema / properties / variant / titleRemoved value: -"Variant" - removed
Input schema / titleRemoved value: -"pack_applyArguments"
- Changed
pack_apply_captions9 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / preset / descriptionAdded 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." - removed
Input schema / properties / preset / titleRemoved value: -"Preset" - removed
Input schema / titleRemoved value: -"pack_apply_captionsArguments"
- Changed
pack_show13 fields changed- removed
Input schema / properties / pack_path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / pack_path / descriptionAdded 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." - removed
Input schema / properties / pack_path / titleRemoved value: -"Pack Path" - added
Input schema / properties / pack_path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / variant / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / variant / descriptionAdded value: +"Report one variant rather than all of them." - removed
Input schema / properties / variant / titleRemoved value: -"Variant" - added
Input schema / properties / variant / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"pack_showArguments"
- Changed
pack_status5 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"pack_statusArguments"
- Changed
ping2 fields changed- removed
Input schema / titleRemoved value: -"pingArguments" - changed
Output schema / additionalPropertiesPrevious value: -{ - "type": "string" -}New value: +true
- Changed
properties13 fields changed- removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"Add this clip's assets entry, framing windows and cue table to the report." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / word_index / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index / descriptionAdded 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`." - removed
Input schema / properties / word_index / titleRemoved value: -"Word Index" - added
Input schema / properties / word_index / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"propertiesArguments"
- Changed
proxy_transcode9 fields changed- added
Input schema / properties / clip_id / descriptionAdded 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." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / force / descriptionAdded 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." - removed
Input schema / properties / force / titleRemoved value: -"Force" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"proxy_transcodeArguments"
- Changed
reel23 fields changed- removed
Input schema / properties / canvas / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / canvas / descriptionAdded 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." - removed
Input schema / properties / canvas / titleRemoved value: -"Canvas" - added
Input schema / properties / canvas / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / confirm_suspect / descriptionAdded 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." - removed
Input schema / properties / confirm_suspect / titleRemoved value: -"Confirm Suspect" - added
Input schema / properties / dest / descriptionAdded 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." - removed
Input schema / properties / dest / titleRemoved value: -"Dest" - added
Input schema / properties / end / descriptionAdded value: +"Where it ends, in those same render seconds. `start`/`end` name the span to **keep**, the opposite direction from every other tool here." - removed
Input schema / properties / end / titleRemoved value: -"End" - removed
Input schema / properties / name / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / name / descriptionAdded value: +"A name for the derived project. Unset, it is derived from `dest`." - removed
Input schema / properties / name / titleRemoved value: -"Name" - added
Input schema / properties / name / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / start / descriptionAdded value: +"Where the reel begins, in the seconds **an export plays at** — the same numbers `cut_by_time` takes, read off a watch." - removed
Input schema / properties / start / titleRemoved value: -"Start" - removed
Input schema / titleRemoved value: -"reelArguments"
- Changed
reframe28 fields changed- removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded 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." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / fillAdded 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" + ] +} - added
Input schema / properties / interp / descriptionAdded 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`." - removed
Input schema / properties / interp / titleRemoved value: -"Interp" - removed
Input schema / properties / pane / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / pane / descriptionAdded 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." - removed
Input schema / properties / pane / titleRemoved value: -"Pane" - added
Input schema / properties / pane / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - removed
Input schema / properties / rect / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / rect / descriptionAdded 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." - removed
Input schema / properties / rect / titleRemoved value: -"Rect" - added
Input schema / properties / rect / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / reset / descriptionAdded value: +"With `clip_id`, drop that clip's overrides; with `src_start` as well, only the window there. Alone, drop every override." - removed
Input schema / properties / reset / titleRemoved value: -"Reset" - removed
Input schema / properties / src_start / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / src_start / descriptionAdded 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." - removed
Input schema / properties / src_start / titleRemoved value: -"Src Start" - added
Input schema / properties / src_start / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / titleRemoved value: -"reframeArguments"
- Changed
reframe_coverage11 fields changed- removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"Walk one clip's placements. Omit it for the whole project." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / threshold / descriptionAdded 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." - removed
Input schema / properties / threshold / titleRemoved value: -"Threshold" - removed
Input schema / titleRemoved value: -"reframe_coverageArguments"
- Changed
reframe_detect17 fields changed- added
Input schema / properties / apply / descriptionAdded 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." - removed
Input schema / properties / apply / titleRemoved value: -"Apply" - removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"Propose windows for one clip. Omit it for every placed clip." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / frames / descriptionAdded value: +"How many moments to sample inside each window before centring it on the faces found there." - removed
Input schema / properties / frames / titleRemoved value: -"Frames" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / split / descriptionAdded 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." - removed
Input schema / properties / split / titleRemoved value: -"Split" - added
Input schema / properties / threshold / descriptionAdded 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." - removed
Input schema / properties / threshold / titleRemoved value: -"Threshold" - removed
Input schema / titleRemoved value: -"reframe_detectArguments"
- Changed
reframe_sheet22 fields changed- added
Input schema / properties / extremes / descriptionAdded 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." - removed
Input schema / properties / extremes / titleRemoved value: -"Extremes" - removed
Input schema / properties / moments / anyOfRemoved value: -[ - { - "items": { - "type": "number" - }, - "type": "array" - }, - { - "type": "null" - } -] - added
Input schema / properties / moments / descriptionAdded 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`." - added
Input schema / properties / moments / itemsAdded value: +{ + "type": "number" +} - removed
Input schema / properties / moments / titleRemoved value: -"Moments" - added
Input schema / properties / moments / typeAdded value: +[ + "array", + "null" +] - removed
Input schema / properties / out / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / out / descriptionAdded 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." - removed
Input schema / properties / out / titleRemoved value: -"Out" - added
Input schema / properties / out / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / page / descriptionAdded value: +"Which page of rows to draw, from 1. Unset, the first." - removed
Input schema / properties / page / titleRemoved value: -"Page" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / per_page / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / per_page / descriptionAdded 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." - removed
Input schema / properties / per_page / titleRemoved value: -"Per Page" - added
Input schema / properties / per_page / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"reframe_sheetArguments"
- Changed
resolve_phrase17 fields changed- added
Input schema / properties / after / descriptionAdded 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." - removed
Input schema / properties / after / titleRemoved value: -"After" - added
Input schema / properties / clip_id / descriptionAdded value: +"The transcript to resolve against." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / fuzzy / descriptionAdded 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." - removed
Input schema / properties / fuzzy / titleRemoved value: -"Fuzzy" - removed
Input schema / properties / occurrence / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / occurrence / descriptionAdded 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." - removed
Input schema / properties / occurrence / titleRemoved value: -"Occurrence" - added
Input schema / properties / occurrence / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / phrase / descriptionAdded value: +"The words to find, as they were spoken." - removed
Input schema / properties / phrase / titleRemoved value: -"Phrase" - removed
Input schema / titleRemoved value: -"resolve_phraseArguments"
- Changed
restore13 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The clip whose cut material to bring back." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / pad / descriptionAdded value: +"Pass the same `pad` the original cut used to bring its padding sliver back, not only the words." - removed
Input schema / properties / pad / titleRemoved value: -"Pad" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / ranges / descriptionAdded 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." - removed
Input schema / properties / ranges / titleRemoved value: -"Ranges" - removed
Input schema / titleRemoved value: -"restoreArguments"
- Changed
review_add15 fields changed- removed
Input schema / properties / baseline / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / baseline / descriptionAdded 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." - removed
Input schema / properties / baseline / titleRemoved value: -"Baseline" - added
Input schema / properties / baseline / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / kind / descriptionAdded value: +"One of `render`, `sheet`, `ab`, `control`." - removed
Input schema / properties / kind / titleRemoved value: -"Kind" - added
Input schema / properties / name / descriptionAdded value: +"What to call this item in the served round. Re-using a name replaces that entry while its verdict stays attached." - removed
Input schema / properties / name / titleRemoved value: -"Name" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / source / descriptionAdded value: +"The file to point at — never copied. A render already lives in `renders/`, a sheet in the sheet directory." - removed
Input schema / properties / source / titleRemoved value: -"Source" - removed
Input schema / titleRemoved value: -"review_addArguments"
- Changed
review_list5 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"review_listArguments"
- Changed
review_verdict13 fields changed- added
Input schema / properties / name / descriptionAdded value: +"The registered item being answered. An unregistered name is refused." - removed
Input schema / properties / name / titleRemoved value: -"Name" - removed
Input schema / properties / note / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / note / descriptionAdded value: +"Anything to record beside the verdict." - removed
Input schema / properties / note / titleRemoved value: -"Note" - added
Input schema / properties / note / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / verdict / descriptionAdded 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." - removed
Input schema / properties / verdict / titleRemoved value: -"Verdict" - removed
Input schema / titleRemoved value: -"review_verdictArguments"
- Changed
seed_timeline19 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The clip to lay down as the timeline." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / edit_expr / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / edit_expr / descriptionAdded value: +"auto-editor's edit language, passed straight through — e.g. `(or audio:0.03 motion:0.06)`. It replaces the threshold-based rule." - removed
Input schema / properties / edit_expr / titleRemoved value: -"Edit Expr" - added
Input schema / properties / edit_expr / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / margin / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / margin / descriptionAdded 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." - removed
Input schema / properties / margin / titleRemoved value: -"Margin" - added
Input schema / properties / margin / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / remove_silences / descriptionAdded value: +"Silence-cut the clip on the way in, through auto-editor. On by default; false lays the whole clip down untouched." - removed
Input schema / properties / remove_silences / titleRemoved value: -"Remove Silences" - added
Input schema / properties / threshold / descriptionAdded value: +"auto-editor's audio loudness threshold, 0–1. Lower keeps quieter material." - removed
Input schema / properties / threshold / titleRemoved value: -"Threshold" - removed
Input schema / titleRemoved value: -"seed_timelineArguments"
- Changed
shot_sheet13 fields changed- removed
Input schema / properties / out / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / out / descriptionAdded 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." - removed
Input schema / properties / out / titleRemoved value: -"Out" - added
Input schema / properties / out / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / page / descriptionAdded value: +"Which page of rows to draw, from 1. Unset, the first." - removed
Input schema / properties / page / titleRemoved value: -"Page" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / per_page / descriptionAdded 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." - removed
Input schema / properties / per_page / titleRemoved value: -"Per Page" - removed
Input schema / titleRemoved value: -"shot_sheetArguments"
- Changed
speech_overlap29 fields changed- added
Input schema / properties / at / descriptionAdded value: +"Where the clip would sit on the timeline, in seconds." - removed
Input schema / properties / at / titleRemoved value: -"At" - added
Input schema / properties / cap / descriptionAdded 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." - removed
Input schema / properties / cap / titleRemoved value: -"Cap" - added
Input schema / properties / clip_evidence / descriptionAdded 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." - removed
Input schema / properties / clip_evidence / titleRemoved value: -"Clip Evidence" - added
Input schema / properties / clip_id / descriptionAdded value: +"The clip whose placement is being proposed. It need not be on the timeline yet, and usually is not." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / clip_in / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_in / descriptionAdded value: +"Where inside the clip the proposed placement starts, in its own source seconds. Unset, its head." - removed
Input schema / properties / clip_in / titleRemoved value: -"Clip In" - added
Input schema / properties / clip_in / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / clip_out / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_out / descriptionAdded value: +"Where it ends, in the clip's own source seconds. Unset, its end." - removed
Input schema / properties / clip_out / titleRemoved value: -"Clip Out" - added
Input schema / properties / clip_out / typeAdded value: +[ + "number", + "null" +] - added
Input schema / properties / max_gap / descriptionAdded 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." - removed
Input schema / properties / max_gap / titleRemoved value: -"Max Gap" - added
Input schema / properties / min_seam / descriptionAdded value: +"How wide a gap has to be to be reported as a `clean_seam`, in seconds." - removed
Input schema / properties / min_seam / titleRemoved value: -"Min Seam" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / vo_clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / vo_clip_id / descriptionAdded value: +"Which transcript is the VO. Unset, the project's own. The VO always needs a transcript; the placed clip does not." - removed
Input schema / properties / vo_clip_id / titleRemoved value: -"Vo Clip Id" - added
Input schema / properties / vo_clip_id / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"speech_overlapArguments"
- Changed
spot_frames18 fields changed- added
Input schema / properties / count / descriptionAdded value: +"How many evenly-spaced frames to pull. They come back ranked darkest-first, with a montage of them as an image." - removed
Input schema / properties / count / titleRemoved value: -"Count" - removed
Input schema / properties / fps / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fps / descriptionAdded 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." - removed
Input schema / properties / fps / titleRemoved value: -"Fps" - added
Input schema / properties / fps / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / target / descriptionAdded value: +"The render to pull frames from." - removed
Input schema / properties / target / titleRemoved value: -"Target" - removed
Input schema / properties / times / anyOfRemoved value: -[ - { - "items": { - "type": "number" - }, - "type": "array" - }, - { - "type": "null" - } -] - added
Input schema / properties / times / descriptionAdded value: +"Explicit seconds to sample as well as the evenly-spaced ones." - added
Input schema / properties / times / itemsAdded value: +{ + "type": "number" +} - removed
Input schema / properties / times / titleRemoved value: -"Times" - added
Input schema / properties / times / typeAdded value: +[ + "array", + "null" +] - removed
Input schema / titleRemoved value: -"spot_framesArguments"
- Changed
synopsis15 fields changed- added
Input schema / properties / clear / descriptionAdded value: +"Remove this clip's synopsis." - removed
Input schema / properties / clear / titleRemoved value: -"Clear" - removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"The clip to read or write. Omit it to list every clip's synopsis and which are missing one." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / text / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / text / descriptionAdded 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." - removed
Input schema / properties / text / titleRemoved value: -"Text" - added
Input schema / properties / text / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"synopsisArguments"
- Changed
tail21 fields changed- removed
Input schema / properties / asset / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / asset / descriptionAdded 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." - removed
Input schema / properties / asset / titleRemoved value: -"Asset" - added
Input schema / properties / asset / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / fade / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / fade / descriptionAdded value: +"Recorded and echoed, not yet drawn: this build cuts to the card hard, at `seconds`." - removed
Input schema / properties / fade / titleRemoved value: -"Fade" - added
Input schema / properties / fade / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / reset / descriptionAdded value: +"Drop the tail entirely. Note a derivation inherits none of it anyway and reports `tail_dropped`." - removed
Input schema / properties / reset / titleRemoved value: -"Reset" - removed
Input schema / properties / seconds / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / seconds / descriptionAdded value: +"The tail's **whole** length, card included — not a hold with `fade` added on top of it." - removed
Input schema / properties / seconds / titleRemoved value: -"Seconds" - added
Input schema / properties / seconds / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / titleRemoved value: -"tailArguments"
- Changed
thumbnail11 fields changed- added
Input schema / properties / at / descriptionAdded 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." - removed
Input schema / properties / at / titleRemoved value: -"At" - added
Input schema / properties / clip_id / descriptionAdded value: +"The clip to pull a frame from." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / interval / descriptionAdded value: +"The grid `at` snaps to, in seconds." - removed
Input schema / properties / interval / titleRemoved value: -"Interval" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"thumbnailArguments"
- Changed
timeline_status5 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"timeline_statusArguments"
- Changed
timeline_view11 fields changed- removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded 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." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / firstAdded value: +{ + "default": 0, + "description": "Index into the `words` list to start the window at. 0 by default.", + "type": "integer" +} - added
Input schema / properties / limitAdded 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" +} - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"timeline_viewArguments"
- Changed
transcribe13 fields changed- added
Input schema / properties / clip_id / descriptionAdded value: +"The clip whose own media whisper transcribes." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / language / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / language / descriptionAdded value: +"Force a language code, e.g. `en`. Unset, whisper detects it, which it gets wrong on short or noisy clips." - removed
Input schema / properties / language / titleRemoved value: -"Language" - added
Input schema / properties / language / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / model / descriptionAdded value: +"The whisper model to run, e.g. `small.en`. Larger is slower, and there is no timeout." - removed
Input schema / properties / model / titleRemoved value: -"Model" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"transcribeArguments"
- Changed
transcript_checks9 fields changed- removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"One clip to re-check. Omit it for every clip that has a transcript." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"transcript_checksArguments"
- Changed
undo5 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"undoArguments"
- Changed
unspoken_add21 fields changed- added
Input schema / properties / after / descriptionAdded 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." - removed
Input schema / properties / after / titleRemoved value: -"After" - added
Input schema / properties / clip_id / descriptionAdded value: +"The transcript holding the word." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / occurrence / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / occurrence / descriptionAdded 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." - removed
Input schema / properties / occurrence / titleRemoved value: -"Occurrence" - added
Input schema / properties / occurrence / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / phrase / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / phrase / descriptionAdded 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." - removed
Input schema / properties / phrase / titleRemoved value: -"Phrase" - added
Input schema / properties / phrase / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / word_index / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index / descriptionAdded value: +"The word to mark. Give this or `phrase`." - removed
Input schema / properties / word_index / titleRemoved value: -"Word Index" - added
Input schema / properties / word_index / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"unspoken_addArguments"
- Changed
unspoken_detect27 fields changed- added
Input schema / properties / apply / descriptionAdded 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." - removed
Input schema / properties / apply / titleRemoved value: -"Apply" - removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"Limit the scan to one transcript." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / language / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / language / descriptionAdded value: +"Force a language code for that transcription." - removed
Input schema / properties / language / titleRemoved value: -"Language" - added
Input schema / properties / language / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / model / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / model / descriptionAdded value: +"The whisper model to transcribe the render with, when no `transcript_path` is given." - removed
Input schema / properties / model / titleRemoved value: -"Model" - added
Input schema / properties / model / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / pad / descriptionAdded value: +"Widen the window each candidate is counted in, in seconds." - removed
Input schema / properties / pad / titleRemoved value: -"Pad" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / render / descriptionAdded 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." - removed
Input schema / properties / render / titleRemoved value: -"Render" - removed
Input schema / properties / transcript_path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / transcript_path / descriptionAdded 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." - removed
Input schema / properties / transcript_path / titleRemoved value: -"Transcript Path" - added
Input schema / properties / transcript_path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"unspoken_detectArguments"
- Changed
unspoken_ls5 fields changed- removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / titleRemoved value: -"unspoken_lsArguments"
- Changed
unspoken_rm21 fields changed- added
Input schema / properties / after / descriptionAdded 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." - removed
Input schema / properties / after / titleRemoved value: -"After" - added
Input schema / properties / clip_id / descriptionAdded value: +"The transcript holding the marked word." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / occurrence / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / occurrence / descriptionAdded 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." - removed
Input schema / properties / occurrence / titleRemoved value: -"Occurrence" - added
Input schema / properties / occurrence / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / phrase / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / phrase / descriptionAdded value: +"Address it by wording instead; it has to resolve to exactly one word." - removed
Input schema / properties / phrase / titleRemoved value: -"Phrase" - added
Input schema / properties / phrase / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / word_index / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index / descriptionAdded value: +"The marked word. Give this or `phrase`." - removed
Input schema / properties / word_index / titleRemoved value: -"Word Index" - added
Input schema / properties / word_index / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"unspoken_rmArguments"
- Changed
verify29 fields changed- removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"Diff against one transcript's expected words rather than all of them." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / language / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / language / descriptionAdded value: +"Force a language code for it." - removed
Input schema / properties / language / titleRemoved value: -"Language" - added
Input schema / properties / language / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / model / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / model / descriptionAdded value: +"The whisper model for the single-pass transcription." - removed
Input schema / properties / model / titleRemoved value: -"Model" - added
Input schema / properties / model / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / overlap / descriptionAdded value: +"How far each window overlaps the one before, in seconds." - removed
Input schema / properties / overlap / titleRemoved value: -"Overlap" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / render / descriptionAdded value: +"The finished render to transcribe and diff against the timeline." - removed
Input schema / properties / render / titleRemoved value: -"Render" - removed
Input schema / properties / transcript_path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / transcript_path / descriptionAdded 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." - removed
Input schema / properties / transcript_path / titleRemoved value: -"Transcript Path" - added
Input schema / properties / transcript_path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / window / descriptionAdded value: +"Length of each window in the windowed pass, in seconds." - removed
Input schema / properties / window / titleRemoved value: -"Window" - added
Input schema / properties / windowed / descriptionAdded 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." - removed
Input schema / properties / windowed / titleRemoved value: -"Windowed" - removed
Input schema / titleRemoved value: -"verifyArguments"
- Changed
vo_extend27 fields changed- added
Input schema / properties / after / descriptionAdded 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." - removed
Input schema / properties / after / titleRemoved value: -"After" - added
Input schema / properties / clip_id / descriptionAdded value: +"The track the gap opens in — the VO." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - removed
Input schema / properties / occurrence / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / occurrence / descriptionAdded 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." - removed
Input schema / properties / occurrence / titleRemoved value: -"Occurrence" - added
Input schema / properties / occurrence / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / phrase / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / phrase / descriptionAdded 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." - removed
Input schema / properties / phrase / titleRemoved value: -"Phrase" - added
Input schema / properties / phrase / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - removed
Input schema / properties / seconds / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Input schema / properties / seconds / descriptionAdded value: +"How long the hold runs. An editorial call this makes no attempt to derive." - removed
Input schema / properties / seconds / titleRemoved value: -"Seconds" - added
Input schema / properties / seconds / typeAdded value: +[ + "number", + "null" +] - removed
Input schema / properties / word_index / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index / descriptionAdded 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." - removed
Input schema / properties / word_index / titleRemoved value: -"Word Index" - added
Input schema / properties / word_index / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"vo_extendArguments"
- Changed
vo_synth37 fields changed- added
Input schema / properties / candidates / descriptionAdded 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." - removed
Input schema / properties / candidates / titleRemoved value: -"Candidates" - removed
Input schema / properties / clip_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / clip_id / descriptionAdded value: +"With `word_index`, the track to splice the winner into. Omitted, nothing is spliced and the renders are just ranked." - removed
Input schema / properties / clip_id / titleRemoved value: -"Clip Id" - added
Input schema / properties / clip_id / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / flat_floor / descriptionAdded 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." - removed
Input schema / properties / flat_floor / titleRemoved value: -"Flat Floor" - added
Input schema / properties / flat_weight / descriptionAdded value: +"How much likeness to subtract per semitone of flatness under the floor. 0 restores likeness-only ranking." - removed
Input schema / properties / flat_weight / titleRemoved value: -"Flat Weight" - removed
Input schema / properties / lexicon / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / lexicon / descriptionAdded 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." - removed
Input schema / properties / lexicon / titleRemoved value: -"Lexicon" - added
Input schema / properties / lexicon / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / max_seconds / descriptionAdded 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." - removed
Input schema / properties / max_seconds / titleRemoved value: -"Max Seconds" - removed
Input schema / properties / path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / path / descriptionAdded 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." - removed
Input schema / properties / path / titleRemoved value: -"Path" - added
Input schema / properties / path / typeAdded value: +[ + "string", + "null" +] - added
Input schema / properties / plan / descriptionAdded value: +"Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it." - removed
Input schema / properties / plan / titleRemoved value: -"Plan" - added
Input schema / properties / readback / descriptionAdded 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." - removed
Input schema / properties / readback / titleRemoved value: -"Readback" - added
Input schema / properties / seed / descriptionAdded value: +"First seed of the range; seeds `seed .. seed+candidates-1` render in one process. A new range renders only what the cache lacks." - removed
Input schema / properties / seed / titleRemoved value: -"Seed" - added
Input schema / properties / text / descriptionAdded 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." - removed
Input schema / properties / text / titleRemoved value: -"Text" - removed
Input schema / properties / voice / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Input schema / properties / voice / descriptionAdded 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." - removed
Input schema / properties / voice / titleRemoved value: -"Voice" - added
Input schema / properties / voice / typeAdded value: +[ + "string", + "null" +] - removed
Input schema / properties / word_index / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - added
Input schema / properties / word_index / descriptionAdded 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)." - removed
Input schema / properties / word_index / titleRemoved value: -"Word Index" - added
Input schema / properties / word_index / typeAdded value: +[ + "integer", + "null" +] - removed
Input schema / titleRemoved value: -"vo_synthArguments"
92 tool updates
v0.24.0- First observed
add_captions - First observed
assets - First observed
attach_transcript - First observed
attenuate_noises - First observed
attribute_speakers - First observed
broll_brief - First observed
build_shots - First observed
canvas - First observed
caption_style - First observed
caption_view - First observed
card_new - First observed
card_reauthor - First observed
card_render - First observed
card_safe_zones - First observed
card_templates - First observed
check_black - First observed
check_frames - First observed
clip_rm - First observed
clip_role - First observed
contact_sheet - First observed
continuity_accept - First observed
continuity_check - First observed
continuity_ls - First observed
continuity_reject - First observed
cue_add - First observed
cue_ls - First observed
cue_reresolve - First observed
cue_rm - First observed
cut_by_time - First observed
cut_by_transcript - First observed
describe - First observed
describe_ls - First observed
doctor - First observed
export - First observed
film_check - First observed
finish_check - First observed
finish_report - First observed
fonts - First observed
footage_sheet - First observed
get_transcript - First observed
head - First observed
hear - First observed
hold_add - First observed
hold_check - First observed
hold_ls - First observed
hold_rm - First observed
hold_under - First observed
hold_under_rm - First observed
import_edit - First observed
import_media - First observed
init - First observed
list_media - First observed
locate - First observed
migrate_project - First observed
music - First observed
pack_activate - First observed
pack_apply - First observed
pack_apply_captions - First observed
pack_show - First observed
pack_status - First observed
ping - First observed
properties - First observed
proxy_transcode - First observed
reel - First observed
reframe - First observed
reframe_coverage - First observed
reframe_detect - First observed
reframe_sheet - First observed
resolve_phrase - First observed
restore - First observed
review_add - First observed
review_list - First observed
review_verdict - First observed
seed_timeline - First observed
shot_sheet - First observed
speech_overlap - First observed
spot_frames - First observed
synopsis - First observed
tail - First observed
thumbnail - First observed
timeline_status - First observed
timeline_view - First observed
transcribe - First observed
transcript_checks - First observed
undo - First observed
unspoken_add - First observed
unspoken_detect - First observed
unspoken_ls - First observed
unspoken_rm - First observed
verify - First observed
vo_extend - First observed
vo_synth
TDQS
Scored across 93 tools
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.
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.
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.
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
Related MCP Connectors
A real timeline video editor for AI agents: journaled edits, FFmpeg/MLT rendering, exports
MCP server for Clipkit — gives AI agents a video toolbox via the Clipkit schema.
FFmpeg as a service for AI agents: typed video editing tools, async jobs, downloadable outputs.
Edit video by talking to your AI — search footage, cut timelines, apply effects, add captions.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceVideo player for humans and AI. GUI + CLI + a built-in MCP server (39 tools) to drive playback, clip, transcribe, and search your media library from Claude, Cursor, or any MCP client. Local Whisper subtitles. MIT, local-first.MIT
- FlicenseNot gradedqualityBmaintenanceLocal-first AI video editing engine controlled by MCP-compatible AI hosts, enabling AI to inspect footage, propose edits, modify multitrack projects, and render locally while keeping user control.-
- AlicenseAqualityBmaintenanceGive any MCP client a real video editor — 32 typed tools over ffmpeg, Whisper and MediaPipe, plus an optional local UI with a drag-and-drop timeline.38MIT
- AlicenseNot gradedqualityBmaintenanceA real video editor for AI agents, served over MCP, enabling journaled timeline editing, rendering via FFmpeg/MLT, and deterministic CLI operation.1MIT