Skip to main content
Glama

A browser video editor that AI agents can drive.

Hacker News — front page DEV — Top 7 of the week Official MCP registry Mentioned in Awesome MCP Servers Glama score Glama — #18 Best Browser Automation MCP Servers Docs Discord

English · 简体中文 · 日本語 · Español · Português (BR)

https://github.com/user-attachments/assets/2430b854-168b-4a9a-af2e-489e5efa7543

FableCut is a Premiere-style non-linear video editor that runs entirely in your browser — and exposes its whole timeline as one JSON document. Edit it by hand, from the UI, or let an AI agent (Claude Code, Claude Desktop, or anything that speaks MCP/REST) cut your video for you while you watch the timeline update live.

Zero npm dependencies. One node server.js. That's it.

FableCut editor

Sponsors

Sidrune AI — One API for GPT, Claude, and other leading AI models. Sign up and get $3 in API credit.

Related MCP server: premiere-pro-mcp

Why it's interesting

Most "AI video" tools hide the edit behind an API. FableCut flips that: the project file is the interface. project.json describes media, clips, tracks, effects, keyframes and transitions — any process that can write JSON can edit video, and the open browser UI hot-reloads within ~150 ms via server-sent events. A human and an agent can work on the same timeline at the same time.

Features

Editing

  • Video + audio tracks (default 3+4; add more with +V / +A in the track header; right-click an empty header → Remove track), drag/trim/split/snap, undo/redo

  • Settings (cog in the top bar) — optional prefs stored in this browser via localStorage. Enable Link timeline and Project bin selection so picking a timeline clip highlights its media in Project, and clicking a Project item selects every timeline clip that uses it (off by default).

  • Video + audio tracks (default 3+4), drag/trim/split/snap, undo/redo

    • +V / +A in the track header add a video or audio lane (up to 16 each)

    • Right-click an empty track header → Remove track (disabled if the lane has clips, or if it would leave you with zero video/audio tracks)

    • Track header S solos that lane (mutes all others); click again to restore the previous mute state. Using the mute toggle while soloed exits solo.

    • Track targeting — click a track's name to target / untarget it (lit = targeted). Split, insert, ripple, close gap and jump-to-cut touch targeted tracks only; the eye / speaker toggle is output-only (hide from preview and export) and no longer blocks edits. A selected clip is edited wherever it sits.

    • Track lock — the padlock in the track header. Nothing on a locked track can be moved, trimmed, split or deleted, and ripples leave it in place while the other tracks shift — lock the music bed and re-cut the picture freely.

  • Clip lock, disable and unlink — right-click a clip (or use the toggles at the top of the inspector): Lock pins it like a locked track; Disable (⇧E) keeps it on the timeline but hides it from preview and export; Unlink (Ctrl/Cmd+L) splits a video from its audio so they move separately, and Link re-joins them once they line up again. Agents see locks too: fablecut_patch_project refuses to edit locked clips unless the op says force: true.

    • Dropping a video with more audio channels than A-tracks adds the missing lanes automatically (up to 16) and toasts how many were added; each channel becomes a linked stem on its own A-track

  • Direct manipulation on the monitor — click a clip or title on the preview to move, resize (corner handles), or rotate (top handle, Shift-snap) it directly

  • Timeline multi-select — rubber-band marquee (drag on empty track area), Ctrl/Cmd/Shift+click to add/remove clips, Ctrl+A to select all, Esc to deselect. Drag any selected clip to move the whole group; Delete removes all selected; S splits all selected at the playhead. Inspector shows an "N clips selected" banner.

  • Beat & cue markers (tap m on the beat during playback) — name and colour them, drag them on the ruler, jump with ⇧m / Alt+⇧m or the Markers list; snapping targets (clip edges, playhead, markers, IN/OUT, keyframes, frame grid) are picked from the ▾ beside Snap

  • Press Alt+t to add an in/out transition based on the playhead position over the selected clip. The last used transition is remembered as the default. Drag the overlay triangle to adjust duration; Delete clears the focused transition.

  • Real decoded audio waveforms on clips

  • Mixer — the Mixer tab beside the Inspector has a strip per audio track (fader, pan, mute, solo, meter) and a master fader with a live LUFS readout. Preview and export run through the same mix, so what you hear is what renders.

  • Clip gain, channels and Normalize — each audio clip has a Gain (dB, before volume and keyframes), a Channels mode (stereo, mono, left, right, swap) and Normalize: measure the selected clips (ITU-R BS.1770 loudness or sample peak) and set their gain to hit −14 / −16 / −23 LUFS or −1 dBFS. Linked stems share one gain so a stereo pair stays balanced.

  • Volume line, fades and crossfades — every audio clip shows its volume as a line you drag; Ctrl/Cmd-click adds a keyframe, Alt-click removes one. Corner grips drag fades in and out, drawn with their real curve (constant power, constant gain or exponential). Shift+D crossfades the cut next to the selection, borrowing spare media from both sides so nothing else moves.

  • Auto-duck — select the music, pick the dialogue track and an amount, and the music dips wherever someone speaks (ramping down just before, back up after). It rides on top of the music's own volume, so re-running or clearing it never touches your levels. Agents use fablecut_auto_duck.

  • Audio effects and presets — EQ, high/low-pass, compressor, limiter, noise gate, delay, reverb, distortion, stereo width and pitch shift, chained per clip, per track (Mixer → FX), per bus and on the master. Presets: Clean voice, Podcast, Radio, Deep voice, Telephone, Cinematic, Wide and Muffled, all tweakable afterwards. Preview and export run the same effects. Agents use the setFx patch op.

  • Effect automation — the ◆ beside an effect setting keys it at the playhead, like clip keyframes: sweep a filter into the drop, open up a reverb at the end. Agents use setFxKeys.

  • Submix buses — + Bus in the Mixer adds a bus with its own effects, fader, pan, mute and meter; route tracks into it from the menu under each track's name (all the dialogue through one compressor and one fader).

  • Noise reduction — the inspector's Noise control (Light / Medium / Strong) measures the file's noise floor and renders a cleaned copy with ffmpeg; the clip's audio switches to it and Off switches back. Agents use fablecut_denoise.

  • Silence removal — the inspector's Silence section (or right-click → Find silences) listens to a take and marks every pause on the timeline; Cut extracts them all in one undo step, keeping a little quiet beside each phrase so words aren't clipped. Agents use fablecut_silence.

  • Project bin folders — tree view with expand/collapse; drag media or folders to nest; right-click the Project tab → New folder; drop files onto a folder to import into it

  • Media management — each file's frame rate, codecs, audio channels and size (ffprobe); search by name, codec, resolution or #tag; filter by favorites, used / unused, kind, tag or collection; sort by any detail or by times used; a list view with metadata columns; favorites, tags and collections; Find timeline instances and Reveal in project; offline files flagged with a "Media offline" slate, Relink… (finds moved files by name and size) and Replace file…

  • Projects — a dashboard of every project with pictures, notes and tags: open, create from a canvas or a saved project template, duplicate, rename, archive and delete, import an old project file; media is shared, so copies cost no footage

  • Sequences — several timelines in one project (a 16:9 and a 9:16 cut, cut-downs, alternatives) sharing its media and compositions, each with its own canvas, frame rate, mix and delivery settings; switch from the menu at the left of the timeline toolbar

  • Versions — non-destructive history: save a version (Ctrl/Cmd+S), automatic versions every 10 minutes and before an agent edits, compare a version with now, restore (the current state is kept as a version first), mark the final cut; backups carry every version, and an unreadable project.json is recovered at startup

  • Proxies — light, frame-accurate H.264 copies of 4K / HEVC / ProRes footage made in the background (ffmpeg); edit on the proxy with the monitor's Proxy button, export always renders the originals

  • Import from URL — + URL downloads an HTTPS video/audio/image into ./media/ (same-origin after import). Remote SVG is refused. Agents use fablecut_import_media with an https:// path. The URL is not kept as media.src — that would taint the canvas and break export.

  • Audio Hold — timeline toolbar toggle: while paused, loops one frame of audio at the playhead (useful when stepping frame-by-frame). Scrubbing or frame-step retargets the held slice; meters stay live. Play / Pause turns it off.

  • Canvas aspect presets (16:9, 9:16 reels, 4:5, 1:1) + project FPS select (24 / 25 / 30 / 50 / 60; non-preset rates show as Custom) + safe-area guides

  • Export frame / reframing — composition canvas can be larger than the delivery crop (exportFrame in project.json). Preview dims the overscan; drag the Export frame handle to reframe (e.g. 16:9 canvas → 9:16 export). Fast export crops to the frame; WebCodecs and Realtime export are disabled while a frame is set

  • Program Monitor zoom — mouse-wheel over the preview zooms the composition toward the cursor (fit → up to 2 screen pixels per canvas pixel). Magnified view uses native scrollbars so overflow stays reachable; middle-click or Alt+drag pans. The Fit button (shown while zoomed) resets to the fit-to-stage baseline

  • Full J/K/L shuttle — L plays forward, J in reverse; tap again for 1.5×/2×/4×, the other key turns around, K stops. Hold K and tap J/L to step a frame, or hold both to crawl at ¼ speed. Preview only, never the export

  • Typed timecode — click the playhead readout (or type digits) to jump: 01:15:00, 1500, +30, 12.5; the IN / OUT readouts take typed times too

  • Resizable workspace: drag the divider between monitor and timeline (double-click resets), plus S/M/L timeline track-density presets (S hides thumbnails for compact tracks)

  • Zoom to selection (⇧Z) frames all selected clips, not just one

  • IN/OUT work area — set markers with i and o (⇧I / ⇧O to clear). The Program Monitor shows playhead as current / sequence duration; when markers are set, IN, marked duration, and OUT stack on the right. Export has a Range dropdown (Entire timeline / IN–OUT; defaults to IN–OUT when markers exist) so you can keep markers for split/trim and still export the full sequence. Enabling Limit constrains playback to the marked range and maps Home / End to the IN and OUT positions rather than the full timeline. t splits clips at the markers; ⇧t trims clips to the work (between marker in and marker out) area.

  • Find & close gaps — a gap is a stretch where every targeted track is empty (black frames). g jumps the playhead to the next shared gap (wraps; respects IN/OUT when both are set). ⇧G closes the gap under the playhead by pulling later clips left on all targeted tracks (locked clips stay put).

  • Trim tools — a tool picker in the timeline toolbar (or V B R Y U): Selection, Ripple edit (drag a clip edge and everything after it follows, so no gap opens), Rolling edit (drag a cut between two clips; nothing else moves), Slip (change which part of the source a clip shows without moving it) and Slide (move a clip while its neighbours trim to make room). Every tool respects source length, targeting, locks and linked audio, and shows the offset beside the pointer while you drag. Agents run the same edits — split, ripple delete, lift / extract, insert / overwrite, ripple / roll / slip / slide and crossfade — as fablecut_patch_project ops, on the same code.

  • Lift / Extract — ; removes the IN→OUT range on the targeted tracks and leaves the gap; ' removes it and closes the gap. Both also sit in the timeline toolbar.

  • Jump to cut — ↑ / ↓ move the playhead to the previous / next edit (clip In or Out). With a clip selected, the first taps land on that clip’s start then end (Premiere-style); with no selection they walk cuts on targeted tracks. In the Source monitor they jump among 0, In, Out, and duration. Left/right still step frames; Home/End still go to the sequence (or IN/OUT with Limit).

  • Ripple delete — the timeline Ripple delete button (or ⇧Del) removes the selection and pulls later clips left on each targeted track to close the gap; plain Del still lifts (leaves a gap). Linked AV partners always move together, even on untargeted tracks (sync lock); locked clips are never deleted or moved.

  • Reset a property — Ctrl/Cmd+click an inspector label or slider restores that effect/prop to its default and clears every keyframe on the channel (scale → 1, opacity → 1, paired fields like Crop L/R reset together; transition labels clear the in/out transition). Shift+click a label is playhead-local: if you are parked on a keyframe it removes that keyframe only; otherwise it sets the value at the playhead to the default (auto-keys if the channel is already animated).

  • Replace media — the inspector's Source button (any video/audio/image/svg clip) swaps the underlying file while keeping position, trim, keyframes, transitions and every effect. Pick another item already in the bin or Browse file… to import and replace in one step. A video's linked L/R audio companions are swapped along with it; a shorter replacement clamps the trim to fit and toasts that it did so.

  • Multi-channel video audio — a video with more than 2 audio channels gets a linked audio clip per channel, not just L/R (5.1, 7.1…). Extra audio tracks (A5, A6, …, capped at 16) are created automatically as needed; replacing a clip's media re-syncs the linked channel clips to the new source's channel count, adding/dropping extras and new tracks as needed.

Look

  • 14 one-click filter presets (cinematic, teal-orange, noir, vintage, cyberpunk, sunset, midnight…)

  • Adjustment layers — one clip grades everything below it, Premiere-style

  • Color workspace (top bar → Color): live waveform, RGB parade, vectorscope and histogram beside the program monitor, and a Color tab that grades the selected clip on the GPU — lift / gamma / gain / offset wheels, exposure, white balance with a picker (click something white), blacks / shadows / midtones / highlights / whites, log-style contrast with a pivot, soft rolloff and saturation, plus curves — luma and R / G / B, hue vs hue, hue vs saturation, hue vs luma and saturation vs luma, with a picker that marks a colour from the monitor, and layers (secondaries): a correction limited by an HSL qualifier and / or an ellipse, rect, polygon, bezier or free-hand mask (feathered, invertible, keyframable, dragged on the monitor), with a matte view. Copy / paste a grade across shots. Agents grade with the setGrade patch op and read the result as numbers with fablecut_scopes (levels, clipping, colour cast)

  • Quick filter sliders: brightness/contrast/saturation/hue, temperature & tint, blur, grayscale/sepia/invert, vignette, animated film grain

  • 17 blend modes (screen, multiply, overlay, color-burn, exclusion, hue, luminosity…), fit modes (contain/cover/stretch), per-edge cropping, corner radius, flip H/V

  • Masks — isolate any part of a clip (video, image, SVG, text or an adjustment layer): rectangle, ellipse, bezier pen and free-hand shapes, several per clip, combined with add / subtract / intersect / difference, each with feather, expansion, invert and opacity, all keyframable (outlines morph). Draw and edit them on the monitor, with a matte view. Agents use the setMask patch op and measure with fablecut_scopes

  • Shapes and motion graphics — shape layers of rectangles, ellipses, polygons, stars, lines and pen-drawn bezier paths in groups, with fill, stroke, dashes and trim paths for draw-ons; null objects, parenting and an anchor point on every clip; every value keyframes, edited right on the monitor. Agents use the setShape and setParent patch ops

  • Motion paths, motion blur and text on a path — bend a clip's travel into a curve with handles on the monitor, turn it along the way, blur fast moves with a shutter angle (preview and export), and set titles along lines, arcs, circles or drawn paths. Agents use the setMotionPath and setTextPath patch ops

  • Compositions — nested sequences: build a lower third, a logo sting or a scene once and place it anywhere as one clip that moves, masks, grades and blends like a picture, while its video and audio play and export as usual. Open one to edit it on the timeline, or precompose a selection. Agents use the addComp, inComp and precompose patch ops

  • Animation presets and templates — 33 ready-made entrances, exits, emphases and loops that fit any clip where it sits, and templates (lower thirds, logo animations, 9:16 / 1:1 / 16:9 social layouts) whose text, colours and logo you fill in, each placed as its own comp. Save your own animations and comps to the library for every project. Agents use the applyPreset, addTemplate and setTemplate patch ops

  • Motion tracking — follow a point or a region (with its scale and rotation) through a video clip, then make a mask follow it or pin a title, sticker or any clip to it; the result is ordinary editable keys. Agents use fablecut_track

  • Track mattes — cut a clip with the picture on the track above by its alpha or its luma (inverted or not): text filled with video, shape reveals, texture cut-outs. The matte track hides itself. Agents use setMatte

  • Chroma key (green screen) with tolerance/softness + spill suppression

  • AI background removal (person cut-out, in-browser via MediaPipe)

Motion

  • Keyframe animation on ~25 properties with easing

  • Keyframe markers on clips — diamonds on the clip body at each unique keyframe time (tooltip lists channels; a count badge when several share a time). Ctrl/Cmd+← / Ctrl/Cmd+→ jumps the playhead to the previous / next keyframe (selected clips first, else clips under the playhead). Inspector fields show the interpolated value at the playhead; changing one updates the keyframe you’re on, or inserts one if that channel is already keyed. Dragging a clip in the program monitor (move / scale / rotate) writes the same way. The ◆ button adds a keyframe at the playhead, or removes the one you’re parked on; ✕ clears the whole channel. When the playhead is outside the selected clip, keyframed fields and ◆ buttons are disabled (they show the nearest edge value) — keyframe edits only apply where the playhead actually is; unanimated properties stay editable anywhere

  • Keyframe graphs — toggle a property’s curve in the inspector to show an interpolated value graph beside the program monitor; click the graph to seek

  • Speed ramps — keyframe speed and the engine time-remaps video and the export audio mix (the fast-into-slow-mo reel move)

  • Camera shake and RGB-split/chromatic aberration, both animatable

  • 17 transitions: fades, slides, wipes (4 directions), zoom, iris, spin, blur, whip-pan, glitch, pop

Text

  • Title styles — one-tap cohesive looks (Impact, Elegant, Kinetic cut, Neon, Handwritten, Luxury, and more); new titles vary the font, placement and animation automatically instead of defaulting to one flat style

  • Kinetic captions: typewriter, word-pop, word-slide, karaoke, letter-pop, wave, bounce, shake, clip-reveal, zoom-in, font-cut (rhythmic typeface cuts), rise-mask

  • Neon glow for that TikTok caption look

  • Font editor: system fonts, drop-in custom fonts (library/fonts/), and any Google Font by name — loaded automatically

  • Gradient fills, outline, background pills, letter-spacing, line-height, weights, italic, uppercase, soft shadows

  • Text layout — horizontal Align: left / center / right / justify (extra spaces between words). Drag a title’s corner handles to create a text box (boxW / boxH); further corner drags resize it (opposite corner stays fixed; Ctrl/Cmd resizes from center; Shift locks aspect). Inside a box, text wraps at the fixed font size by default; enable Scale to fit to shrink the font so the whole block fits. V-align (top / middle / bottom) places the text block vertically in the box. Set Box W/H to 0 to return to hug-content sizing.

Animated SVG clips

  • A first-class svg clip kind: CSS-@keyframes-animated SVGs render frame-accurately in preview and export (the compositor freezes the animation at any time). Agents can author their own vector overlays — lower-thirds, confetti, sparkles — as plain .svg files. Starters included.

Remake a reference video

  • Give it a reference edit (a reel you like) and get back an edit blueprint: shot boundaries, music beats + BPM, a loudness curve, per-shot energy, the drop — plus the reference's music track extracted into your media, ready to rebuild the same idea with your own footage. Zero extra dependencies (ffmpeg does the decoding; onset/tempo detection is plain Node). node analyze.js ref.mp4, POST /api/analyze, or the fablecut_analyze_reference MCP tool.

Look at the footage

  • An agent (or you, over REST) can fetch an actual image of any moment: GET /api/frame?src=/media/x.mp4&t=3.2 returns a JPEG of that frame, and &frames=12 returns a 4×3 contact sheet across the clip — a cheap survey of everything a 3-minute take holds. Grabs are cached under analysis/frames/.

  • The fablecut_frame MCP tool wraps it and returns the image inline, so a multimodal model can look. Pass a time instead of a path and it renders the composed timeline through the editor's own compositor — graded, all tracks, identical to what export produces — so "is this grade right?" and "what did I actually build?" have a visual answer.

  • Together with the analyzer above, agents pick footage by looking at it instead of guessing from an energy number.

Asset library

  • library/ folders surface as tabs in the UI: Elements (overlay art), Sound FX, SVG — drop files in, the open editor refreshes live

Export

  • Delivery presets: YouTube, YouTube Shorts, Instagram Reels, TikTok, X, LinkedIn, Master, Broadcast (ProRes 422 HQ), Web, Archive (lossless FFV1) and Custom. Every setting is a control: resolution and reframing (crop, fit or stretch to another shape), frame rate, codec (H.264, HEVC, AV1, VP9, ProRes, DNxHR, XDCAM HD422, FFV1) and hardware encoder, CRF / VBR / CBR, max rate, keyframe interval, pixel format, color, container, audio codec, bitrate and rate, loudness normalization (−14 / −16 / −23 / −24 LUFS with a true-peak ceiling), a file-name template and metadata. Save your own presets; the dialog warns about upscaling, crops and platform limits before it renders, and every finished file is read back and checked — size, frame rate, frame count, codecs, length, loudness, true peak and file size

  • Batch export: one project → many files (master, YouTube 1080p, a 9:16 reel, a square, a 720p preview…) from one render per frame rate and range (up to 8 outputs each) — every frame is drawn once and each output's ffmpeg encodes it. Batch outputs are saved with the project; an export queue runs them back to back with progress, stop, retry and open

  • Fast export: browser renders every frame + an offline audio mix; ffmpeg encodes them with a delivery preset, or a raw encoding profile from encoding-profiles.json (keeps rendering if you switch tabs). Encode and upload run ahead of the compositor so a fast timeline is not stalled by toBlob

  • WebCodecs export: the browser HW-encodes Annex-B H.264; the server stream-copies and muxes audio. Faster uploads; bitrate/VBR-CBR in the Export dialog. Unavailable while an export frame is set (use Fast)

  • Realtime MediaRecorder fallback when ffmpeg or WebCodecs isn't available

  • Agents export too: fablecut_export runs the Fast export in the open editor, or in a headless Chrome / Edge the server starts, and returns the file path; preset and delivery pick and adjust a delivery preset; outputs makes several files in one go

  • Export Range dropdown: Entire timeline or IN–OUT (defaults to IN–OUT when markers are set). Effective IN/OUT export bounds are clamped to projDur().

Quick start

npx -y fablecut       # → http://localhost:7777

Your projects, media and exports go to ~/FableCut. Or run it from a clone:

git clone https://github.com/ronak-create/FableCut.git
cd FableCut
node server.js        # → http://localhost:7777

Requirements: Node 18+ and a Chromium-based browser. ffmpeg on PATH is optional but recommended (fast export + upload remuxing). AI background removal fetches its model from a CDN on first use.

The server binds 127.0.0.1 only (v1.3.1+). To use it from another device on your LAN, opt in explicitly: HOST=0.0.0.0 FABLECUT_ALLOWED_HOSTS=<your-ip> node server.js.

Drop media into the window (or ./media/), paste an HTTPS URL via + URL, drag clips onto the timeline, edit, export.

To keep your work outside the checkout, set FABLECUT_DATA_DIR — it moves project.json, media/, exports/, analysis/ and library/ to a directory you choose. Leave it unset and everything stays in the repo, exactly as before.

Or install it as a Claude Code plugin

/plugin marketplace add ronak-create/FableCut
/plugin install fablecut@fablecut

That registers the MCP server for you and adds three skills — edit-video, remake-reel and motion-graphics. Your timeline and footage live in the plugin's own data directory, so an update never touches them. Node 18+ and (optionally) ffmpeg still need to be on your machine.

Driving it with an AI agent

Everything an agent needs is in CLAUDE.md — the complete schema, semantics and recipes. Point any capable model at that file and it can operate the editor end to end.

📖 Browsable docs: the same manual as web pages, one page per topic (MCP tools, the project.json schema, clip props, recipes, REST API, export): fablecut.space/docs.

Three equivalent control surfaces:

  1. MCP (best for Claude Code / Claude Desktop) — register the bundled zero-dependency MCP server once:

    claude mcp add -s user fablecut -- npx -y fablecut mcp

    No clone or path needed; your work lives in ~/FableCut. From a clone, point at the file instead:

    claude mcp add -s user fablecut -- node "<path-to>/fablecut/mcp-server.js"

    OpenCode can use the same stdio server from its project or global opencode.json configuration:

    {
      "$schema": "https://opencode.ai/config.json",
      "mcp": {
        "fablecut": {
          "type": "local",
          "command": ["node", "/absolute/path/to/FableCut/mcp-server.js"],
          "enabled": true
        }
      }
    }

    For another MCP client, register a local stdio server with this equivalent command. The exact key names vary by client, but the command and arguments do not:

    {
      "name": "fablecut",
      "transport": "stdio",
      "command": "npx",
      "args": ["-y", "fablecut", "mcp"]
    }

    (From a clone: "command": "node", "args": ["/absolute/path/to/FableCut/mcp-server.js"].)

    The server is intentionally client-neutral. It speaks MCP over stdio and does not require Claude-specific environment variables. With a clone, keep the path absolute. Node 18 or newer either way.

    Tools: fablecut_status (auto-starts the editor), fablecut_docs, fablecut_get_project, fablecut_set_project, fablecut_patch_project, fablecut_import_media, fablecut_analyze_reference, fablecut_frame, fablecut_encode_profiles, fablecut_normalize_audio, fablecut_auto_duck, fablecut_denoise, fablecut_silence, fablecut_export, fablecut_scopes, fablecut_track.

    FableCut is also published on the official MCP registry as io.github.ronak-create/fablecut — each release ships an MCPB bundle (fablecut.mcpb) that MCPB-capable clients can install directly.

    The surface is token-efficient by design: agents patch the timeline with small ops (fablecut_patch_project) instead of round-tripping the whole document, read a compact one-line-per-clip summary (fablecut_get_project {compact:true}), and fetch only the manual sections they need (fablecut_docs {section:"props"}).

  2. The file — read project.json, modify, bump revision, write. The UI live-reloads.

  3. REST — GET/PUT /api/project, POST /api/upload, POST /api/import-url, GET /api/library, GET /api/export/profiles, SSE at /api/events. See CLAUDE.md for the full list.

Example: ask Claude Code "cut these six clips to the beat markers, add a teal-orange grade, put a word-pop caption on top and a whoosh on every cut" — and watch the timeline rebuild itself.

Or hand it a reference: "here's a reel I like — analyze it and remake it with my clips, same music". The agent calls fablecut_analyze_reference, gets the blueprint (cuts, beats, BPM, energy, drop, extracted music), and rebuilds the structure shot-for-shot with your footage.

The agent can see, not just measure. fablecut_analyze_reference gives it the ears — where the cuts land, which shots hit hard. fablecut_frame gives it the eyes: ask for any moment of any clip ({path, t:3.2}) and the call comes back with an actual image the model can look at, or ask for a 12-frame contact sheet to survey a whole clip in one call ({path, frames:12}). Pass a time with no path and it renders the composed timeline — graded, all tracks, exactly as export would. So footage gets chosen by looking at it rather than guessing from a number, and a grade gets checked against the real picture.

Conflict-safe concurrent editing: the UI, the MCP tools, and direct project.json writes all agree on a revision counter. If you edit a clip in the UI while an agent is mid-task, the agent's next write is rejected (409 from the REST API / a conflict error from fablecut_set_project) instead of silently overwriting your change. The UI similarly detects when an agent write supersedes a not-yet-saved local tweak and tells you with a toast instead of dropping it silently.

Project layout

server.js        zero-dependency HTTP server: static hosting, REST API, SSE,
                 ffmpeg export pipeline
app.js           the editor: timeline UI, compositor, keyframes, text engine,
                 SVG rasterizer, chroma key, exporters
index.html       single-page UI
style.css        dark editor theme
mcp-server.js    stdio MCP server exposing the editor to AI agents
analyze.js       reference-video analyzer: shots, beats/BPM, energy, drop,
                 music extraction (module + CLI)
CLAUDE.md        the agent manual (schema + recipes) — also served by fablecut_docs
encoding-profiles.json
                 Fast-export ffmpeg presets (hot-reloaded)
project.json     your timeline (created on first run; gitignored)
media/           project footage (gitignored)
analysis/        cached edit blueprints from /api/analyze (gitignored)
library/         default assets: elements/ sfx/ svg/ fonts/
exports/         finished renders (gitignored)

Architecture Overview

flowchart TD

subgraph group_interaction["Editing Experience"]
  node_browser_ui["Browser Editor<br/>[app.js]"]
  node_timeline_model["Timeline Model<br/>[app.js]"]
  node_ruler_worker["Ruler Worker<br/>[ruler-worker.js]"]
end

subgraph group_project_media["Project And Media"]
  node_project_store[("Project Store<br/>[paths.js]")]
  node_media_store[("Media Store<br/>[paths.js]")]
  node_asset_library[("Asset Library<br/>[server.js]")]
  node_url_importer["URL Importer<br/>[import-url.js]"]
end

subgraph group_agent_api["Agent Control"]
  node_rest_api["REST Server<br/>[server.js]"]
  node_mcp_server["MCP Server<br/>[mcp-server.js]"]
  node_sse_hub["Change Notifications<br/>[server.js]"]
end

subgraph group_playback_export["Playback And Export"]
  node_compositor["Canvas Compositor<br/>[app.js]"]
  node_audio_engine["Audio Engine<br/>[app.js]"]
  node_audio_meter["Audio Meter<br/>[meter-worklet.js]"]
  node_export_engine["Export Engine<br/>[server.js]"]
  node_encoding_profiles["Encoding Profiles<br/>[encode-profiles.js]"]
end

subgraph group_analysis["Analysis Tools"]
  node_reference_analyzer["Reference Analyzer<br/>[analyze.js]"]
end

node_human(("Human Editor"))
node_ai_agent(("AI Agent"))
node_ffmpeg["FFmpeg"]

node_human -->|"edits timeline"| node_browser_ui
node_ai_agent -->|"sends tools"| node_mcp_server
node_browser_ui -->|"updates project"| node_timeline_model
node_timeline_model -->|"persists JSON"| node_project_store
node_browser_ui -->|"calls REST"| node_rest_api
node_rest_api -->|"reads writes"| node_project_store
node_rest_api -->|"serves media"| node_media_store
node_rest_api -->|"lists assets"| node_asset_library
node_mcp_server -->|"checks server"| node_rest_api
node_mcp_server -->|"patches project"| node_project_store
node_mcp_server -->|"imports media"| node_url_importer
node_url_importer -->|"stores downloads"| node_media_store
node_rest_api -->|"downloads URLs"| node_url_importer
node_rest_api -->|"broadcasts changes"| node_sse_hub
node_sse_hub -->|"pushes changes"| node_browser_ui
node_timeline_model -->|"renders timeline"| node_compositor
node_timeline_model -->|"routes clips"| node_audio_engine
node_audio_engine -->|"measures audio"| node_audio_meter
node_browser_ui -->|"uploads frames"| node_rest_api
node_rest_api -->|"streams export"| node_export_engine
node_export_engine -->|"loads profile"| node_encoding_profiles
node_export_engine -->|"encodes video"| node_ffmpeg
node_reference_analyzer -->|"analyzes media"| node_ffmpeg
node_reference_analyzer -->|"writes music"| node_media_store
node_ai_agent -.->|"requests analysis"| node_reference_analyzer
node_browser_ui -.->|"draws ruler"| node_ruler_worker

click node_browser_ui "https://github.com/ronak-create/fablecut/blob/main/app.js"
click node_timeline_model "https://github.com/ronak-create/fablecut/blob/main/app.js"
click node_compositor "https://github.com/ronak-create/fablecut/blob/main/app.js"
click node_audio_engine "https://github.com/ronak-create/fablecut/blob/main/app.js"
click node_audio_meter "https://github.com/ronak-create/fablecut/blob/main/meter-worklet.js"
click node_rest_api "https://github.com/ronak-create/fablecut/blob/main/server.js"
click node_mcp_server "https://github.com/ronak-create/fablecut/blob/main/mcp-server.js"
click node_sse_hub "https://github.com/ronak-create/fablecut/blob/main/server.js"
click node_project_store "https://github.com/ronak-create/fablecut/blob/main/paths.js"
click node_media_store "https://github.com/ronak-create/fablecut/blob/main/paths.js"
click node_asset_library "https://github.com/ronak-create/fablecut/blob/main/server.js"
click node_url_importer "https://github.com/ronak-create/fablecut/blob/main/import-url.js"
click node_export_engine "https://github.com/ronak-create/fablecut/blob/main/server.js"
click node_encoding_profiles "https://github.com/ronak-create/fablecut/blob/main/encode-profiles.js"
click node_reference_analyzer "https://github.com/ronak-create/fablecut/blob/main/analyze.js"
click node_ruler_worker "https://github.com/ronak-create/fablecut/blob/main/ruler-worker.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_browser_ui,node_timeline_model,node_ruler_worker toneBlue
class node_project_store,node_media_store,node_asset_library,node_url_importer toneAmber
class node_rest_api,node_mcp_server,node_sse_hub toneMint
class node_compositor,node_audio_engine,node_audio_meter,node_export_engine,node_encoding_profiles toneRose
class node_reference_analyzer,node_human,node_ai_agent,node_ffmpeg toneIndigo

Authoring animated SVG overlays

SVGs animate with plain CSS @keyframes. One convention: never hardcode animation-delay — set --d: 0.4s instead, and the compositor drives time by pausing all animations and rebasing their delays. Full rules + a skeleton in CLAUDE.md; working examples in library/svg/.

Notes

  • The repo ships with 20 Google Fonts (library/fonts/, OFL — see LICENSES.md there) and a set of self-authored SVG overlays and animated elements (library/elements/, library/svg/, MIT like the rest of the repo).

  • library/sfx/ is yours to fill (gitignored): sound-effect sites typically don't allow redistributing their files in a public repo, so FableCut doesn't — library/sfx/README.md lists good free sources.

  • Export runs in the browser because the compositor is the browser; agents ask you to click Export (or render directly with ffmpeg from media/).

Community

Questions, ideas, showing off an edit, or want to help shape what's next? Join the FableCut Discord. Bugs and feature requests are still best filed as GitHub issues. Rather email? Write to hello@fablecut.space, or support@fablecut.space for help.

License

MIT

Available Tools

18 tools
fablecut_analyze_referenceA

Analyze a reference video into an EDIT BLUEPRINT so a similar edit can be rebuilt with different footage over the same music. Returns: shot boundaries (cuts) with per-shot audio energy, music beats + BPM, a loudness curve, the detected drop, and extracts the reference's music track into media/ (registered in the project, ready to place on A1). Remake recipe: copy the reference's width/height/fps to the project, write beats into project markers, lay the extracted music on A1, then place one clip per blueprint shot at the same start/duration — pick calm footage for low-energy shots and action for high-energy ones, and make the biggest moment land on drop. See the 'Remake a reference video' section of fablecut_docs.

NameRequiredDescriptionDefault
pathYesThe reference video: an absolute file path (copied into media/ automatically) or an existing '/media/…' src
thresholdNoScene-cut sensitivity 0–1 (default: adaptive 0.30→0.20→0.12). Lower it if obvious cuts are missed, raise it if too many false cuts.
registerMusicNoExtract the reference's music and register it as project media (default true)

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries full behavioral disclosure burden. It explains that the path is copied into media automatically, threshold has adaptive defaults, and registerMusic extracts and registers the music track on A1. No contradictions or hidden side effects are apparent.

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

Conciseness4/5

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

The description is moderately long but well-structured: purpose first, then outputs, then recipe, then cross-reference. Each sentence adds value, but minor redundancy (e.g., 'Remake recipe' repeats some info). Still efficient for the amount of detail.

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

Completeness5/5

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

Despite no output schema, the description thoroughly explains the return values (shot boundaries, per-shot audio energy, beats, BPM, loudness curve, drop, extracted music) and provides a complete recipe for using the blueprint. It also references documentation for further details. No gaps identified.

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

Parameters4/5

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

Schema coverage is 100%, and the description adds value: for 'path' it clarifies absolute vs. media/ src; for 'threshold' it explains adaptive default values (0.30→0.20→0.12) and tuning guidance; for 'registerMusic' it describes extraction and registration. This enhances understanding beyond the schema.

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

Purpose5/5

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

The description clearly states the tool analyzes a reference video into an EDIT BLUEPRINT for rebuilding with different footage over same music. It lists specific outputs (shot boundaries, per-shot audio energy, beats, BPM, loudness curve, drop, extracted music) and distinguishes from siblings via cross-reference to documentation.

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

Usage Guidelines4/5

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

The description explicitly says when to use (analyze reference for remake) and provides a step-by-step remake recipe. It does not explicitly state when not to use, but the context and sibling tool names imply its specific role. Cross-reference to docs enhances guidance.

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

fablecut_auto_duckA

Duck music under dialogue: finds where the voice tracks have sound (RMS above threshold, short gaps bridged so the music doesn't pump between words) and writes duck keyframes (dB) on the given music clips — a dip of amount dB ramping down attack s before speech and back up release s after. The duck multiplies the clip's volume, so its own level, volume keyframes and fades are untouched, and re-running replaces the previous dips (amount 0 clears them). Voice = every audio clip on under tracks (default: all audio tracks the music isn't on). Linked stems of a music clip get the same keys. The same pipeline as the editor's Auto-duck. Needs ffmpeg + ffprobe on PATH. Refuses locked clips unless force:true.

NameRequiredDescriptionDefault
forceNoAlso change clips the user locked (only when they asked)
underNoAudio tracks holding the voice, e.g. ["A1"] (default: every other audio track)
amountNoDip depth in dB, -40…0 (default -12; 0 removes the ducking)
attackNoSeconds to ramp down before speech (default 0.3)
clipIdsYesThe music / bed clips to duck
releaseNoSeconds to ramp back up after speech (default 0.6)
thresholdNoVoice detection level in dBFS (default -40; raise it if room noise triggers ducks)

TDQS

A4.6/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so richly: it is a mutation (writes keyframes), it multiplies clip volume so level/keyframes/fades are untouched, re-running replaces previous dips, linked stems get the same keys, requires ffmpeg+ffprobe on PATH, and refuses locked clips unless force. These are exactly the side-effect and prerequisite facts an agent needs.

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

Conciseness4/5

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

Front-loaded with the core action and free of filler, but very dense with long multi-clause sentences (em dashes, parentheticals) that pack several behaviors into each line. Efficient rather than wasteful, though slightly heavy to parse.

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

Completeness5/5

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

For a 7-parameter mutation with no output schema, it covers what the agent needs: side effects, idempotency, dependency requirements, lock/force behavior, stem propagation, and what it writes. Nothing essential for correct invocation is missing.

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

Parameters4/5

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

Schema coverage is 100%, so baseline is 3, but the description adds real meaning beyond the schema — the interpolation/ramp semantics of attack and release, the gap-bridging rationale behind threshold, the defaulting logic of `under` ('every audio track the music isn't on'), and that amount 0 removes ducking.

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

Purpose5/5

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

States a specific verb and resource ('Duck music under dialogue') plus the exact mechanism (finds voice via RMS threshold, writes duck keyframes in dB on the music clips). It clearly separates this from sibling audio tools like normalize_audio or denoise by naming the ducking/auto-duck pipeline explicitly.

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

Usage Guidelines4/5

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

Explains when this applies (ducking music under voice) and gives operational triggers: raise threshold if room noise triggers ducks, amount 0 clears, force to touch locked clips. It does not explicitly name sibling alternatives to prefer in other situations, so it stops short of full when/when-not routing.

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

fablecut_denoiseA

Reduce background noise (hiss, hum, room tone) on audio clips: ffmpeg's FFT denoiser renders a cleaned FLAC of each clip's whole source file into media/, and the clip — with its linked stems — switches to it (the picture keeps its own file, so links and timing stay intact). The same as the inspector's Noise control. amount 'off' switches back to the original. Re-running reuses a file already rendered. Needs ffmpeg + ffprobe on PATH. Refuses locked clips unless force:true.

NameRequiredDescriptionDefault
forceNoAlso change clips the user locked (only when they asked)
amountNoHow hard to pull the noise down (default medium); off restores the original audio
clipIdsYesAudio clips, or video clips with linked audio stems

TDQS

A4.4/5.0
Behavior5/5

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

No annotations are provided, so the description carries the full burden and does so well: discloses that it renders a new FLAC into media/, that linked stems switch while the picture file stays (preserving links/timing), that re-runs are idempotent (reuses rendered file), the ffmpeg+ffprobe PATH prerequisite, and locked-clip refusal behavior. These are exactly the side effects an agent must know before invoking.

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

Conciseness4/5

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

Dense but front-loaded: purpose first, then mechanism, revert, idempotency, prerequisites, and force. Every sentence earns its place, though the parenthetical about picture files is slightly nested.

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

Completeness5/5

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

For a mutation tool with no annotations and no output schema, the description covers purpose, side effects, file layout, idempotency, prerequisites, and refusal semantics – more than enough for correct invocation.

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

Parameters3/5

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

Schema coverage is 100% – all three params are documented including the enum, defaults, and semantics of 'off'. The description adds the 'off restores original' behavior and force rationale, but the schema already carries most of this, so baseline 3 is appropriate.

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

Purpose5/5

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

States a specific verb and resource ('Reduce background noise... on audio clips') and names concrete noise types (hiss, hum, room tone). Distinguishes itself from siblings like fablecut_normalize_audio and fablecut_auto_duck by identifying the exact mechanism (FFT denoiser / Noise control), so an agent can route correctly without opening a schema.

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

Usage Guidelines4/5

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

Explains when to use and what state changes occur, and covers the 'off' revert and force/locked-clip condition. Lacks explicit contrast with sibling audio tools (normalize_audio, auto_duck), which is the only gap.

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

fablecut_docsA

Return the FableCut project schema documentation: clips, tracks, props, keyframe animation, transitions, and editing recipes. Read this before editing. TOKEN TIP: pass section to fetch only the '## …' section(s) you need (substring match, e.g. "props", "Recipes", "Remake") instead of the whole manual.

NameRequiredDescriptionDefault
sectionNoReturn only '## ' sections whose heading contains this text (case-insensitive). Omit for the full document.

TDQS

A4.7/5.0
Behavior4/5

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

The description indicates a read-only retrieval operation ('Return the documentation'), but does not explicitly state it has no side effects. Since no annotations are provided, the description carries the full burden; it successfully conveys the non-destructive nature through context.

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

Conciseness5/5

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

Two clear sentences plus a token tip. Front-loaded with purpose, no superfluous words. Every sentence earns its place.

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

Completeness4/5

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

For a simple documentation retrieval tool with one optional parameter, the description covers purpose, usage, and filtering. It could mention what happens if a section is not found, but given the lack of output schema and low complexity, it is adequately complete.

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

Parameters5/5

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

The description adds significant value beyond the schema: explains the substring match behavior, provides concrete examples (props, Recipes, Remake), and offers a token-saving tip. This fully compensates for the schema's brief parameter description.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Return the FableCut project schema documentation'. It lists specific content areas (clips, tracks, props, etc.) and distinguishes itself from sibling tools which handle project data manipulation or analysis.

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

Usage Guidelines5/5

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

Explicitly advises 'Read this before editing', indicating when to use this tool (before making edits). The token tip provides optimization guidance. While alternatives are not named, the context signals show siblings operate on projects, not documentation.

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

fablecut_encode_profilesA

List what fablecut_export can make. DELIVERY PRESETS (structured settings, the Export dialog's Preset list): youtube, youtube-shorts, instagram-reels, tiktok, x, linkedin, master (project size), broadcast (ProRes 422 HQ), web (720p), archive (lossless FFV1), custom — plus presets the user saved — each a spec of resolution, fps, codec (h264, hevc, av1, vp9, prores, dnxhr, mpeg2 XDCAM, ffv1), rate control (crf / vbr / cbr), keyframe interval, pixel format, color, container, audio, a file-name template and metadata. {preset:'youtube'} returns one preset's full spec; the encoders this ffmpeg can use are listed (hardware ones only when they work on this machine). ENCODING PROFILES (encoding-profiles.json): raw ffmpeg argument lists plus jpegQuality, extension and color, for anything the presets do not cover; edit the file on disk (hot-reloaded); {profile:'hq'} returns one, detail:true includes every args array. Both are dry-run against ffmpeg when an export starts, so bad settings are refused before rendering.

NameRequiredDescriptionDefault
detailNoInclude the full ffmpeg args array per encoding profile (default: a truncated summary)
presetNoReturn one delivery preset's full spec (youtube, broadcast, a saved preset id …)
profileNoReturn one encoding profile by id instead of the full list

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so thoroughly: it names the config file (encoding-profiles.json), states it is edited on disk and hot-reloaded, discloses that settings are dry-run against ffmpeg at export start so bad config is refused before rendering, and warns that hardware encoders appear only when functional locally. These are exactly the operational traits an agent cannot infer from the schema.

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

Conciseness4/5

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

The purpose is front-loaded and the two-mode structure is easy to scan. However, the long parenthetical enumerations of preset ids, codecs, rate-control modes, and container details are largely re-derivable from the tool's own output, making the middle section denser than it needs to be.

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

Completeness4/5

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

For a zero-required-parameter, no-output-schema discovery tool, the description supplies return shape (per-preset spec fields, truncated vs. full args arrays), the backing file, and the validation model. What the no-argument default call returns as a whole is only implied, which is the one gap.

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

Parameters4/5

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

Schema coverage is 100%, so 3 is the floor, and the description earns extra by giving concrete usage forms ('{preset:"youtube"}' returns one full spec; '{profile:"hq"}' with detail:true includes every args array) and by clarifying that the default is a truncated summary. It largely echoes the schema's own wording, which keeps it from a 5.

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

Purpose5/5

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

Opens with a concrete verb and resource: 'List what fablecut_export can make,' then splits the answer into two named categories (DELIVERY PRESETS and ENCODING PROFILES) with their backing artifacts. This distinguishes it cleanly from the sibling fablecut_export, which performs the render rather than the discovery.

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

Usage Guidelines4/5

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

The division of labor is implied well: presets cover standard destinations, and encoding profiles exist 'for anything the presets do not cover,' giving the agent a selection rule between the two branches. It also tells the agent that encoders are listed only when they actually work on this machine. There is no explicit 'use this before calling fablecut_export' statement or named exclusion, so it falls 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.

fablecut_exportA

Render the timeline to a video file in exports/ — the editor's own Fast export (same compositor, audio mix and encoding profile as the Export button), so the file matches what the user sees. It runs in a browser: an open editor tab takes the job (the user sees the progress bar), or with no tab open the server starts headless Chrome / Edge (set FABLECUT_CHROME to pick one) and closes it afterwards. Waits for the file by default and returns its path. Range: the project's inPoint→outPoint when set, else the whole timeline (or pass range). Needs ffmpeg on PATH. One export at a time. Long edits: pass wait:false, then poll with {job}; {cancel:job} stops one.

NameRequiredDescriptionDefault
jobNoReport on an export started earlier instead of starting one
waitNoBlock until the file is written (default true)
rangeNoWhole timeline, or the project's inPoint→outPoint (default: in-out when either is set)
whereNoauto (default): an open editor tab, else headless · tab: only an open tab · headless: always a background browser, leaving the user's tab alone
cancelNoCancel this export job
presetNoDelivery preset: youtube, youtube-shorts, instagram-reels, tiktok, x, linkedin, master, broadcast, web, archive, custom, or a saved preset's id (fablecut_encode_profiles lists them). The output is reframed to the preset's size — cropped from the middle (or from the project's exportFrame), or padded with reframe:'fit'
outputsNoSeveral files, rendered once per frame rate (up to 8 outputs per render): true = the project's checked batch outputs (project.outputs, set with setProject {outputs:[…]}), or a list like [{preset:'master'}, {preset:'youtube'}, {preset:'instagram-reels'}, {preset:'custom', width:1080, height:1080, filename:'{project}_square_{res}'}, {preset:'web', filename:'{project}_preview_{res}'}]. Outputs with the same fps share one render; the reply lists every file
profileNoEncoding profile id (raw ffmpeg args, fablecut_encode_profiles) instead of a preset. With neither: project.delivery, else project.encodeProfile, else the server's default profile
timeoutNoSeconds to wait before returning the job's status instead (default 900); the export keeps running
deliveryNoDelivery settings over the preset (or over custom): {width, height (null = the picture's size), fps (null = the project's), reframe:'fill'|'fit'|'stretch', container:'mp4'|'mov'|'mkv'|'webm'|'mxf', video:{codec:'h264'|'hevc'|'av1'|'vp9'|'prores'|'dnxhr'|'mpeg2'|'ffv1', encoder?, rate:'crf'|'vbr'|'cbr', crf, bitrate (kb/s), maxrate (kb/s), keyint (s), pixFmt, speed:'fast'|'balanced'|'best', profile (prores: proxy|lt|standard|hq|4444|4444xq · dnxhr: lb|sq|hq|hqx|444)}, audio:{codec:'aac'|'opus'|'mp3'|'pcm16'|'pcm24'|'flac'|'none', bitrate (kb/s), sampleRate, channels, loudness (LUFS target: -14 streaming/social, -16 podcast, -23 EBU R128, -24 ATSC; null = as mixed), truePeak (dBTP ceiling, default -1)}, color:'bt709'|'bt709-full'|'bt601-625'|'bt601-525', filename:'{project}_{preset}_{res}' (tokens {project} {preset} {res} {w} {h} {fps} {codec} {date} {time} {range} {n}), metadata:{title, artist, description, copyright, date, keywords}}. Anything left out comes from the preset; impossible combinations are corrected and the reply says how. Every finished file is checked against what was asked (size, fps, frames, codecs, length, loudness, true peak, file size) and the reply lists the checks

TDQS

A4.6/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does it well: browser-tab vs headless Chrome/Edge, FABLECUT_CHROME env var, ffmpeg on PATH, one-export-at-a-time concurrency, timeout keeps export running, impossible combinations corrected. It does not state file-overwrite/collision behavior or permission requirements, which keeps it short of a 5.

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

Conciseness4/5

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

Front-loaded with the core action in the first clause, then operational detail; every sentence carries distinct information for a genuinely complex tool. It is dense, but not padded.

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

Completeness5/5

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

No output schema exists, and the description compensates: it states it returns the file path by default, that the reply lists every file for multi-output renders, and that each finished file is validated with checks listed in the reply. Complete 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.

Parameters4/5

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

Schema coverage is 100% and already details every param, so baseline is 3, but the description adds operational meaning not obvious from per-field schema docs—linking wait:false → {job} → {cancel:job} into a polling workflow and stating the default inPoint→outPoint range behavior.

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

Purpose5/5

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

Specific verb+resource ('Render the timeline to a video file in exports/') with a precise mechanism (editor's Fast export: same compositor, audio mix, encoding profile) so it is unmistakable what this does. Clearly distinct from sibling tools like fablecut_import_media or fablecut_encode_profiles.

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

Usage Guidelines5/5

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

Explicit routing: use wait:false for long edits then poll with {job}, {cancel:job} to stop, where:auto/tab/headless semantics, and the preset-vs-profile fallback chain. Tells the agent exactly when and how to pick each mode.

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

fablecut_frameA

LOOK at the footage — returns an actual image, not just numbers. REQUIRES A VISION-CAPABLE MODEL: if you cannot read images, pass text:true instead (or skip this tool and use fablecut_analyze_reference). Three modes. (1) One frame of a source clip: pass path (an absolute file path, or a '/media/…' src — read where it lies, never copied) and t in seconds. (2) A contact sheet: pass frames (2–60) for one grid image with that many moments spread across the clip (from/to to survey part of it) — the cheap way to see what a whole clip holds. (3) With no path, time renders the COMPOSED TIMELINE at that moment through the editor's own compositor, graded and multi-track, exactly as export would. Use it before choosing a clip's in point, or to pick footage matching a blueprint's shots[] energy — seeing beats guessing. Needs ffmpeg on PATH (timeline mode runs in the open editor tab, else a headless browser).

NameRequiredDescriptionDefault
tNoSeconds into the source clip (default 0). Ignored when `frames` is passed.
toNoContact sheet: end of the range (default: the clip's duration)
colsNoContact-sheet columns (omit for the squarest layout — 6 frames give 3×2, 12 give 4×3)
fromNoContact sheet: start of the range to survey (default 0)
pathNoSource clip to look at: an absolute file path or a '/media/…' src. Read in place — nothing is copied into media/. Omit to render the timeline instead.
textNoReturn TEXT measurements instead of the image, for a client or model that cannot see one: brightness and luma levels, dominant named colours with their share, texture (detail within the frame, 0–100), and for a contact sheet a per-cell line with change-since-the-previous-cell. Measurements, NOT a caption — they say what the picture is made of, never what is in it. Use when you have no vision.
timeNoTIMELINE seconds to render, when `path` is omitted (default: the editor's playhead)
whereNoTimeline mode only: auto (default): an open editor tab, else headless · tab · headless
widthNoPixel width of the returned image (default 768 for one frame, 320 per cell for a sheet)
framesNoContact-sheet mode: number of moments to sample across the clip, 2–60 (default 12)
timeoutNoTimeline mode: seconds to wait for the render (default 60)

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries the entire burden and does so: it discloses the vision-capability requirement, that `path` is read in place and never copied, that ffmpeg must be on PATH, and that timeline mode runs in the open editor tab or falls back to a headless browser. These are non-obvious operational constraints an agent would otherwise discover only by failure.

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

Conciseness4/5

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

The critical fact (image output, vision requirement) is front-loaded before the modal breakdown, and the three modes are cleanly numbered. It is long for a single paragraph and the trailing ffmpeg/browser note is slightly buried, but nearly every clause carries distinct information.

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

Completeness5/5

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

An 11-parameter tool with no output schema and no annotations is covered well: mode disambiguation, defaults, ranges, dependencies on a vision model and ffmpeg, and the fallback sibling are all addressed. Since the tool returns an image rather than structured data, no output-schema explanation is needed.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning beyond the schema by explaining the mode-selection logic: `path` present means source frame, `frames` present means contact sheet, neither means timeline via `time`. It also clarifies the default image widths and the 2–60 frame range, though per-parameter detail largely duplicates the schema.

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

Purpose5/5

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

"LOOK at the footage — returns an actual image, not just numbers" names a specific verb and output, and the three modes are enumerated explicitly (single frame, contact sheet, composed timeline). It differentiates itself from fablecut_analyze_reference by calling out that sibling as the non-vision fallback, so an agent can choose between them without opening either schema.

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

Usage Guidelines5/5

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

It states exactly when to use it ("before choosing a clip's `in` point, or to pick footage matching a blueprint's shots[] energy") and gives explicit alternatives and exclusions: pass `text:true` if not vision-capable, or skip this tool and use fablecut_analyze_reference. That is when/when-not/alternative coverage in full.

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

fablecut_get_projectA

Get the FableCut project (the timeline document). TOKEN TIP: pass compact:true for a one-line-per-clip summary (ids, tracks, timings, non-default props) — usually all you need to plan an edit; fetch the full JSON only when you must inspect exact keyframes.

NameRequiredDescriptionDefault
compactNoReturn a compact human-readable summary instead of the full JSON

TDQS

A4.1/5.0
Behavior3/5

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

No annotations are provided, so the description must cover behavioral aspects. It describes the output format options but does not mention error conditions, permissions, side effects, or whether the operation is idempotent (implied read-only). The description is adequate but not thorough.

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

Conciseness5/5

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

The description is two sentences long, front-loaded with the purpose, and the second sentence efficiently delivers a valuable tip. Every sentence serves a purpose with no redundancy.

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

Completeness3/5

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

Given only one optional parameter and no output schema or annotations, the description covers the main scenario (obtaining the project with optional compact format). However, it omits details like error handling, what the full JSON looks like, or behavior when the project is missing. It is minimally viable but not comprehensive.

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

Parameters4/5

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

The input schema covers the parameter compact with a basic description. The description adds meaningful context: 'one-line-per-clip summary (ids, tracks, timings, non-default props)' and advises when to use each mode, going beyond what the schema provides.

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

Purpose5/5

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

The description clearly states the verb 'Get' and resource 'FableCut project (the timeline document)', distinguishing it from sibling tools that patch or set projects. The compact option is also mentioned, adding specificity.

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

Usage Guidelines4/5

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

The token tip provides explicit guidance on when to use compact:true versus full JSON, which helps the agent decide the parameter value. However, it does not compare against sibling tools like fablecut_status or fablecut_analyze_reference, so usage boundaries are not fully delineated.

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

fablecut_import_mediaA

Import a media file into FableCut's media library and register it in the project. Pass a local absolute path (copied, including .svg) or an https:// URL (downloaded into ./media/; video/audio/image only — remote SVG is refused). The URL is never kept as the playback src — CORS would break export. Returns the created media entry (use its id in clips).

NameRequiredDescriptionDefault
pathYesAbsolute path to a local file, or an https:// URL to download

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does: it discloses side effects (local files are copied, remote files downloaded into ./media/), a refused input class (remote SVG/CORS-breaking URLs), and the deliberate decision not to retain the URL as the playback src. It also states the return value and how to use it.

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

Conciseness5/5

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

Three tight sentences, front-loaded with what the tool does and then the input rules and return value. Every clause adds actionable information with no filler.

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

Completeness5/5

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

For a single-parameter import tool with no output schema, the description covers the operation, input forms, failure modes, side effects (copy/download location), and the shape of the result plus how to use the returned id. Nothing material is missing.

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

Parameters4/5

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

Schema coverage is 100% so the baseline is 3, but the description adds real semantics beyond the schema: accepted source forms, format restrictions, and the .svg local-vs-remote distinction that the schema's one-line description does not convey.

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

Purpose5/5

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

States a specific verb (import) and resource (a media file into FableCut's media library and the project), and the scope is narrow enough to distinguish it from siblings like fablecut_patch_project or fablecut_analyze_reference. An agent can identify the operation without opening the schema.

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

Usage Guidelines4/5

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

Gives concrete selection rules for the single input: a local absolute path (copied, .svg allowed) vs. an https:// URL (downloaded, video/audio/image only, remote SVG refused). It does not mention any alternative tool or when this is the wrong choice relative to siblings, 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.

fablecut_normalize_audioA

Loudness-normalize clips: measures each clip's source audio (ITU-R BS.1770 integrated LUFS, or sample peak) after its channel routing and sets props.gain (clip gain, dB) so it lands on the target — the same measurement as the editor's Normalize button. Linked stems (a video's per-channel audio clips) are measured together and get one shared gain, so a stereo pair stays balanced; passing a video clip normalizes its stems. Volume keyframes / fades are untouched (they ride on top). Typical targets: -14 LUFS streaming/social, -16 LUFS podcast/dialogue, -23 LUFS broadcast, or mode 'peak' at -1 dBFS. Needs ffmpeg + ffprobe on PATH. Refuses locked clips unless force:true.

NameRequiredDescriptionDefault
modeNoMeasure integrated loudness (default) or sample peak
forceNoAlso change clips the user locked (only when they asked)
targetNoTarget level: LUFS for mode lufs (default -14), dBFS for mode peak (default -1)
clipIdsYesClips to normalize (audio, or video with audio)

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so richly: the measurement standard (ITU-R BS.1770 integrated LUFS / sample peak), that it writes props.gain in dB, that linked stems share one gain so a stereo pair stays balanced, that it refuses locked clips unless force:true, and that volume keyframes/fades are left untouched.

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

Conciseness4/5

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

A single dense paragraph that is front-loaded with the core action and wastes little, though the run-on style packs many clauses (stems, keyframes, prerequisites, locking) together. Every clause is informative, so it stays efficient despite its length.

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

Completeness4/5

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

For a 4-param mutation tool with no annotations or output schema, the description is nearly complete on behavior and prerequisites. The one gap is that it never states what the call returns (e.g., measured values), which the missing output schema would otherwise need it to cover.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: target units depend on mode (LUFS vs dBFS), the force flag's intent ('only when they asked'), and concrete target values. It clarifies the mode/target interplay better than the schema alone.

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

Purpose5/5

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

States a specific verb and resource ('Loudness-normalize clips') plus the exact mechanism (measures source audio, sets props.gain). An agent can instantly differentiate this from siblings like fablecut_denoise or fablecut_auto_duck, which perform unrelated audio operations.

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

Usage Guidelines4/5

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

Provides concrete usage context via typical targets (-14 LUFS streaming, -16 podcast, -23 broadcast, peak at -1 dBFS) and states a prerequisite (ffmpeg + ffprobe on PATH). It does not explicitly name a sibling alternative or state when not to use it, so it falls 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.

fablecut_patch_projectA

Apply targeted edits to the FableCut project WITHOUT round-tripping the whole document — PREFER THIS over get+set for every edit (it is ~10-100x cheaper in tokens and merge-safe by design: it re-reads the latest document from disk, applies your ops in order, bumps revision once, saves atomically). Ops: {op:'addClip', clip:{…}} (id auto-generated if omitted) · {op:'updateClip', id, set:{…}} · {op:'removeClip', id} · {op:'addMedia', media:{…}} · {op:'removeMedia', id} · MEDIA BIN: {op:'updateMedia', id | ids, set:{name?, favorite?:true|false, tags?:[…], folderId?}, addTags?:[…], removeTags?:[…]} (organize media; fps, codec, audio channels and size are probed from the file and read-only) · {op:'setCollection', id?, name?, media?:[…ids] (replaces), add?:[…], remove?:[…]} (a collection groups media across folders; a new id or name creates it) · {op:'removeCollection', id} · {op:'relinkMedia', id, src:'/media/…'} (the same footage found elsewhere — an OFFLINE file in the compact view; clips keep their In points) · {op:'replaceMedia', id, src, name?} (a different file behind the media — every clip using it switches, keeping its timing, trimmed to fit a shorter file; import the new file first with fablecut_import_media) · {op:'setProject', set:{name|width|height|fps|background|markers|disabledTracks|lockedTracks|untargetedTracks|encodeProfile|delivery|outputs|master}} (markers = the full list [{t, label?, color?}], color: gold|red|orange|green|cyan|blue|purple|pink; master = {gain}, the master fader in dB; delivery = a delivery preset id or spec — see fablecut_export — that exports use by default; outputs = the batch list, [preset id | spec, …] up to 16, exported together by fablecut_export {outputs:true}) · {op:'setTrack', id:'A1', set:{gain?, pan?, out?}} (audio-track fader in dB −60…+12, pan −1…1, out = a submix bus id or 'master'; null or 0 resets) · {op:'setBus', id:'B1', set:{name?, gain?, pan?, mute?}} (submix bus, created if missing; route tracks into it with setTrack out) · {op:'removeBus', id} · {op:'setFx', target:'clip'|'track'|'bus'|'master', id?, preset?:'podcast'|… OR fx:[{type,…params}], append?:true} (audio effects — validated; presets: clean-voice, podcast, radio, deep-voice, telephone, cinematic, wide, muffled; fx:null clears; on a clip it applies to its linked stems too) · {op:'setFxKeys', target, id?, index?|type?, param, keys:[{t, v, ease?}]|null} (automate one effect parameter: t is clip-local for a clip's effects, timeline seconds otherwise; see the 'Audio mix' docs section) · {op:'setGrade', id | ids:[…], grade:{exposure?, temp?, tint?, lift?, gamma?, gain?, offset?, contrast?, pivot?, blacks?, shadows?, midtones?, highlights?, whites?, lowSoft?, highSoft?, saturation?, curves?:{y?, r?, g?, b?}, hueHue?, hueSat?, hueLuma?, satLuma?, layers?:[…], on?}, replace?:true} (color grade on video / image / svg / adjust clips — wheels are [r, g, b, master]; curves are [[x, y], …] point lists on 0…1 and merge per channel; hue curves are [[hue°, value], …] — one point = a ±40° band; layers replaces the whole layer list; merges key by key, null resets a key, replace:true starts from neutral, grade:null clears; see the 'Color' docs section; measure the result with fablecut_scopes) · {op:'setGradeLayer', id | ids, layer: index | 'name', set:{name?, on?, qualifier?:{hue?:[centre°, width°, soft°], sat?:[lo, hi, soft], luma?:[lo, hi, soft], invert?}, mask?:{shape:'ellipse'|'rect'|'poly', x, y, w, h, rotation?, feather?, invert?, points?, keys?:[{t, x?, y?, …}]}, …any grade key}, replace?:true, remove?:true} (a secondary: a grade applied only where the qualifier × mask select; a new name or index = length adds a layer; qualifier and mask merge key by key; check what it selects with fablecut_scopes matte:{clip, layer}) · {op:'setMask', id | ids, mask?: index | 'name', set:{shape?:'rect'|'ellipse'|'bezier'|'freehand', mode?:'add'|'subtract'|'intersect'|'difference', invert?, opacity?, feather? (px), expand? (px, − shrinks), x?, y? (centre, 0…1 of the clip's picture), w?, h?, scale?, rotation?, points?:[[dx, dy, inX?, inY?, outX?, outY?], …] (bezier, around x, y), stroke?:[[u, v], …] (freehand: fitted into a bezier), keys?:[{t, ease?, x?, y?, w?, h?, scale?, rotation?, feather?, expand?, opacity?, points?}], name?, on?}, replace?:true, remove?:true} (clip masks on video / image / svg / text / adjust clips: the clip shows only where its masks combine to, bottom-up; mask left out, an unknown name or index = length adds one — a new mask needs shape; set merges key by key; masks follow the clip's transform; check with fablecut_scopes mask:{clip}) · {op:'removeMask', id, mask} · {op:'setMaskKeys', id, mask, keys:[…]|null} (animate a mask; t = seconds from the clip's start) · {op:'setMatte', id | ids, matte:'alpha'|'alpha-inverted'|'luma'|'luma-inverted'|null, track?:'V3'|null} (track matte: the picture on the video track directly above — or track — cuts the clip by its alpha or its brightness, inverted or not; that track stops drawing while it is a matte; null clears). · {op:'removeTrack', id, track: name | index} (delete a motion track stored by fablecut_track; what follows it keeps its keys). MOTION GRAPHICS: a shape layer is addClip {kind:'shape', track, start, duration, props:{shapes:[…]}} (no mediaId); a null is addClip {kind:'null', …} — invisible, a parent for other clips. {op:'setShape', id | ids, shape?: index | 'name' | '2.0' (path into a group), set:{type?:'rect'|'ellipse'|'polygon'|'star'|'line'|'path'|'group', name?, on?, x?, y? (px from the layer's origin), rotation?, scale?, opacity?, w?, h?, radius? (rect corners), sides?, inner? (star 0.05…1), points?:[[x, y, inX?, inY?, outX?, outY?], …] (line: 2, path: 2…128, px around x, y), closed? (path), fill?, stroke? ('#rrggbb' | '#rrggbbaa' | 'none'), strokeWidth?, lineCap?, lineJoin?, dash?:[on, off…], trimStart?, trimEnd? (0…100 — a draw-on), trimOffset?, items?:[…] (group), keys?:[{t, ease?, …any of x y rotation scale opacity w h radius inner strokeWidth trimStart trimEnd trimOffset fill stroke points}]}, replace?:true, remove?:true} (shape left out, an unknown name or index = length adds one — a new shape needs type; set merges key by key) · {op:'removeShape', id, shape} · {op:'setParent', id | ids, parent: clip id | null, keep?: true, at?} (the clip moves, turns and scales with its parent; keep:true — the default — keeps it where it is at time at, default its start; opacity and effects are not inherited). COMPOSITIONS (nested sequences): project.comps = [{id, name, width, height, duration, background?, tracks?, clips:[…]}]; a clip {kind:'comp', compId, start, in, duration} places one (draws like a picture of the comp's size — transform, masks, grade, blend, blur all apply — and its media plays and exports). {op:'addComp', comp:{id?, name, duration, width?, height?, background?, clips?:[…]}} · {op:'updateComp', id, set:{name?, width?, height?, duration?, background?, tracks?}} · {op:'removeComp', id} (refused while used) · {op:'precompose', ids:[…], name?, id?} (the clips move into a new comp; a comp clip takes their place) · {op:'inComp', comp, ops:[…]} (run clip and timeline ops on the comp's own clips — addClip, updateClip, setShape, split, …; nests). SEQUENCES (several timelines in one project — e.g. a 16:9 cut and a 9:16 cut sharing the media and comps; the open one is the top level of the document, which every op, export and the compact view use): {op:'addSequence', name?, from?:'empty'|'open'| (empty takes the open one's canvas and frame rate; a copy takes its whole timeline), width?, height?, fps?, open?:true} · {op:'openSequence', id} (changes what the user's editor shows — only when asked, or to work on it) · {op:'updateSequence', id, set:{name?, index?}} · {op:'removeSequence', id} (only when the user asked) · {op:'inSequence', sequence, ops:[…]} (run any clip, timeline, track or setProject op on a sequence without opening it). PRESETS AND TEMPLATES: {op:'applyPreset', id | ids, preset, length?, at?} keys a named animation onto visual clips, relative to where they sit (in: fade-in, pop-in, slide-up-in, slide-down-in, slide-left-in, slide-right-in, drop-in, zoom-in, spin-in, whip-in, rise-blur, draw-on · out: fade-out, pop-out, slide-up-out, slide-down-out, slide-left-out, slide-right-out, zoom-out, spin-out, whip-out, sink-blur, draw-off · at (an emphasis at timeline time at): pulse, shake, wobble, bounce, flash · loop (the whole clip): float, breathe, sway, spin, wiggle — or a saved one, or an inline {anchor:'in'|'out'|'at'|'whole', length, keys:{channel:[{t, v, ease?}]}} where scale / opacity multiply and the rest add). {op:'addTemplate', template, start?, track?, duration?, fields?:{key: value}, id?, compId?, name?} places a template as its own comp + a comp clip (lower-third-bar, lower-third-underline, lower-third-boxes [name, title, accent…] · logo-ring, logo-slam, logo-lines [logo = a media id, brand / tagline, accent] · social-story 1080x1920, social-quote 1080x1080, social-end-card [text fields, accent, background]); {op:'setTemplate', id: its clip or comp, fields?, duration?} changes the fields or the length (the exit keeps its timing). {op:'savePreset', id, name, anchor?} / {op:'saveTemplate', comp, name?, fields?} save to library/presets and library/templates for every project.MOTION PATHS: x and y keyed at the same time are a position key; curve handles pin / pout (px) on those x and y keys bend the path between keys ({op:'setMotionPath', id | ids, path:'smooth'|'straight', autoOrient?:bool} sets them for you; props.autoOrient turns the clip along its path). props.motionBlur = shutter angle 0…720 (180 = film look), props.motionBlurSamples 2…32. TEXT ON A PATH: {op:'setTextPath', id | ids, path:'line'|'arc'|'circle'|'wave'|{type:'path'|'line'|'ellipse'|'rect'|'polygon'|'star', …shape item geometry, keys?}|null, offset? (% along, keyable as pathOffset), align?:'start'|'center'|'end'} — the title runs along the path (more lines on parallel curves below it), every textAnim plays along it. Every visual clip also has props.anchorX / anchorY (px from its picture's centre: the point x / y place and rotation / scale turn around) and shape clips props.trimStart / trimEnd / trimOffset (trim every path in the layer) — all keyframable. props.blend: normal · multiply · screen · overlay · darken · lighten · color-dodge · color-burn · hard-light · soft-light · difference · exclusion · hue · saturation · color · luminosity · lighter. TIMELINE EDITS — the editor's own split / ripple / trim code, so linked stems, track targeting (untargetedTracks) and locks behave exactly as in the UI; times in seconds: {op:'split', at, ids?} (no ids: every targeted track) · {op:'rippleDelete', ids} (later clips close the hole) · {op:'closeGap', at} · {op:'lift'|'extract', from?, to?} (remove a range; extract closes it; default = project inPoint/outPoint, which then clear) · {op:'insert'|'overwrite', mediaId, at, in?, duration?} (three-point edit: insert pushes later clips right, overwrite replaces what is there; a video brings one audio stem per channel) · {op:'rippleTrim'|'roll', id, side:'in'|'out', delta} · {op:'slip'|'slide', id, delta} (clamped to the media; the note says what was applied) · {op:'crossfade', ids? | at, duration?} (constant-power audio crossfade, borrowing handles from both sides). Any of these takes tracks:[…] to target lanes for that op only. setProject also takes inPoint / outPoint. updateClip merge rules: top-level keys are replaced (keyframes/transitionIn/transitionOut wholesale), props merges key-by-key, and setting any key to null deletes it. LOCKS: the user can lock clips (locked:true) and tracks (lockedTracks); updateClip / removeClip on a locked clip — or on a clip linked to one — and addClip onto a locked track are refused. Leave locked material alone; only if the user asked you to change it, pass force:true on that op (or unlock first: updateClip set:{locked:null}, which is always allowed). All-or-nothing: an invalid op aborts the whole patch unsaved. Optional baseRevision: the revision your ops were planned against (from fablecut_get_project, fablecut_status or the previous patch result) — if the project has moved past it (e.g. the user edited in the UI meanwhile), the patch is refused with CONFLICT and the current revision, nothing saved; re-check the clips you touch, then retry with the new revision. Omit it to apply on top of whatever is latest.

NameRequiredDescriptionDefault
opsYesEdit operations, applied in order (see tool description for shapes). Any op may carry force:true to override a lock the user set.
baseRevisionNoRevision these ops were planned against. If project.json has moved past it, the patch is refused with CONFLICT (nothing saved). Omit to apply on top of the latest revision.

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does so well: it discloses that the document is re-read from disk, ops applied in order, revision bumped once, save is atomic, the patch is all-or-nothing, and baseRevision produces a CONFLICT with nothing saved. What holds it below 5 is that the safety profile is buried inside an extremely long block rather than stated as a short, scannable set of guarantees.

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

Conciseness2/5

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

The routing guidance is correctly front-loaded, and the op catalog is separated by category headers, but the whole thing runs to well over a thousand words for a two-parameter tool — effectively an inlined manual that duplicates material a fablecut_docs sibling likely owns. Length of this magnitude raises selection cost and dilutes the one sentence an agent actually needs to choose the tool.

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

Completeness5/5

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

For a merge-patch tool with no output schema, the definition covers everything an agent needs: op grammar, merge/replace rules, lock refusal and override, conflict detection and retry protocol, and where the revision comes from. Nothing important about calling it correctly is left unstated.

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

Parameters5/5

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

Schema coverage is 100% for only two top-level params, but the schema's 'ops' item is an untyped object that defers entirely to the description. The description compensates fully by enumerating op shapes, merge semantics (top-level replaced, props key-by-key, null deletes), and per-op optional fields like force and ids.

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

Purpose5/5

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

The opening sentence states a specific verb and resource ('Apply targeted edits to the FableCut project') plus the key differentiator: no full-document round-trip. It explicitly names the pattern it replaces ('get+set') and is therefore distinguishable from fablecut_get_project / fablecut_set_project without opening any schema.

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

Usage Guidelines5/5

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

It gives an explicit routing rule ('PREFER THIS over get+set for every edit') with a quantified rationale (~10-100x cheaper, merge-safe). It also scopes dangerous sub-operations ('openSequence … only when asked', 'removeSequence … only when the user asked') and tells the agent when to pass force:true versus leaving locked material alone.

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

fablecut_projectsA

Several projects in one FableCut: the projects dashboard. ./project.json (what every other tool reads and edits) is always the OPEN project; the others are stored beside it and share media/, exports/ and the library, so a duplicate or a template copies no footage. Actions: list (default; archived:'only'|'all' to see archived ones) · open {id} — switches the editor to that project (the open one is saved first; editor tabs reload; your next fablecut_get_project reads the new one) · new {name, template?, fps?, width?, height?, notes?, tags?, open?:true} — template is a built-in canvas (landscape-1080 default, vertical-1080, square-1080, portrait-1350, uhd-4k, landscape-720) or a saved template id · duplicate {id, name?, open?:false} · update {id, name?, notes?, tags?} · archive / unarchive {id} · delete {id} (archived projects only) · templates · save_template {id, name} (the project's canvas, tracks, clips and media references) · delete_template {template}. Opening another project changes what the user sees — only open, archive or delete when the user asked for it.

NameRequiredDescriptionDefault
idNoThe project (p_…), from list
fpsNonew: frame rate (default: the template's)
nameNonew / duplicate / update: the project's name · save_template: the template's name
openNonew (default true) / duplicate (default false): open it afterwards
tagsNonew / update: labels (replaces the list)
notesNonew / update: free-text notes (brief, client, deadline …)
widthNonew: canvas width (default: the template's)
actionNoWhat to do (default list)
heightNonew: canvas height (default: the template's)
archivedNolist: archived projects too, or only them
templateNonew: the template to start from · delete_template: the saved template's id

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the burden and does well: open saves the current project first and reloads editor tabs, delete is restricted to archived projects, and duplicates/templates copy no footage because media/ is shared. Gaps remain on whether delete is permanent, what archive means to the user, and error behavior.

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

Conciseness4/5

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

Concept and the ./project.json relationship are front-loaded, then actions are enumerated in a compact ·-separated list, with the safety caveat last. It is dense and run-on in places, but the tightness is justified by 11 actions and nothing is padding.

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

Completeness4/5

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

For an 11-param, 11-action mutation tool with no annotations and no output schema, the description covers the critical semantics: defaults, shared-media behavior, side effects of open, and delete safety. It omits return-value detail and error conditions, which would matter given the absence of an output schema.

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

Parameters4/5

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

Schema coverage is 100%, so baseline is 3, but the description adds cross-parameter meaning the schema can't: which params apply to which action, that archived:'only'|'all' exposes archived projects, that template accepts built-in canvas names or a saved template id, and that open defaults differ for new (true) vs duplicate (false).

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

Purpose5/5

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

The opening sentence names the resource (the projects dashboard) and the multi-action scope, and the follow-up sentence positions ./project.json as the OPEN project every other tool reads and edits. An agent can tell immediately this is the project-management hub rather than an editor-content tool like fablecut_get_project or fablecut_patch_project.

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

Usage Guidelines4/5

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

It states the default action (list) and gives an explicit exclusion: 'only open, archive or delete when the user asked for it.' It also routes forward by noting the next fablecut_get_project call reads the newly opened project. What's missing is explicit guidance on when to prefer this tool over fablecut_set_project/fablecut_get_project for project-level vs. content-level work.

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

fablecut_proxyA

Proxies: light H.264 copies (540p by default, 720p or 1080p; never larger than the source) of heavy footage — 4K, HEVC, ProRes, long phone clips — that the editor plays while the user edits, so playback and scrubbing stay smooth. Export, fablecut_frame, fablecut_scopes and every measurement always read the original, so a proxy never changes the result. Without create or delete it reports each video's proxy (ready, being made with its progress, failed, none). create:true makes them (one at a time, in the background on the server) and waits until they are done unless wait:false; delete:true removes them. mediaIds defaults to every video in the project. The user turns proxy playback on or off with the monitor's Proxy button. Needs ffmpeg on PATH.

NameRequiredDescriptionDefault
waitNoWith create: wait until every proxy is done (default true)
createNoMake proxies for these files
deleteNoDelete their proxies
heightNoProxy height in pixels (default 540)
timeoutNoSeconds to wait with create (default 900)
mediaIdsNoVideo media ids (default: all video media)

TDQS

A4.9/5.0
Behavior5/5

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

With no annotations provided, the description carries the full behavioral burden and does so well: it discloses background server-side creation, one-at-a-time processing, wait behavior, status reporting including progress and failure, deletion behavior, and the ffmpeg dependency. It also clearly states the critical invariant that proxies never affect export or measurement results.

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

Conciseness5/5

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

The description is front-loaded with what a proxy is and why it matters, then moves through reporting, creation, deletion, defaults, and prerequisites. Despite being dense, every sentence contributes operational context and there is no wasteful repetition.

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

Completeness5/5

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

For a six-parameter tool with no output schema and no annotations, the description is complete enough to call correctly: it covers the default report mode, create/delete behavior, wait semantics, default media scope, playback implications, status values, and the ffmpeg requirement. No major agent decision is left without guidance.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful semantics beyond the schema for create, delete, wait, height, and mediaIds. It explains defaults such as mediaIds covering every video in the project and height never exceeding the source, though timeout is left primarily to the schema.

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

Purpose5/5

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

The description states a specific verb and resource: it proxies heavy video footage with light H.264 copies for smooth editing playback, while also reporting, creating, or deleting proxies. It clearly distinguishes proxy behavior from export, frame extraction, and scopes by explaining that those always read the original.

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

Usage Guidelines5/5

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

It explicitly identifies the use case: heavy footage such as 4K, HEVC, ProRes, and long phone clips that need smooth playback and scrubbing. It also clarifies when create/delete are omitted versus set, and warns that export, fablecut_frame, fablecut_scopes, and every measurement read the original, which effectively routes the agent away from using proxies for final results.

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

fablecut_scopesA

Measure the graded picture at one moment — what the editor's scopes show, as numbers: luma levels (min, 1st percentile, median, mean, 99th percentile, max on 0–1), the % of pixels crushed to black / clipped to white, mean R/G/B, average saturation, and the colour cast of the midtones (hue name + strength; neutral below 0.01), plus the clips on screen with their grades, masks, track mattes and blend modes. Rendered by the same compositor as export (an open editor tab, else headless Chrome / Edge), over the export frame when one is set. Use it to check a grade: e.g. a cast strength above ~0.03 on footage that should be neutral, whitePct above ~1 (clipped highlights), or a median far from ~0.4 for a normally exposed shot. The user's playhead does not move.

NameRequiredDescriptionDefault
maskNoAlso measure a clip's masks: {clip}. Adds how much of that clip's picture the masks keep (coverage %, the feathered matte measured alone) and how much of the frame the masked clip covers
timeNoTimeline seconds to measure (default: the editor's playhead)
matteNoAlso measure what one grade layer selects: {clip, layer} (layer = index into the clip's grade.layers). Adds the matte's coverage (% of that clip's picture) and the levels / colour of the selected pixels after grading
whereNoauto (default): an open editor tab, else headless · tab · headless
timeoutNoSeconds to wait (default 60)

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses the rendering path (same compositor as export; open editor tab else headless Chrome/Edge), that measurement is over the export frame when set, the non-mutating nature (playhead does not move), and a sensible default timeout. It omits failure modes and any statement of required permissions, keeping it short of a 5.

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

Conciseness4/5

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

Purpose is front-loaded, but the middle sentence is a dense enumeration of every returned metric, and the numeric examples with tilde thresholds add length. Because there is no output schema, spelling out the returns earns its place, so the density is justified rather than wasteful.

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

Completeness5/5

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

Complex, nested-object tool with no output schema, yet the description fully enumerates the return values and semantics (levels, clipped/crushed percentages, cast hue/strength with a neutral cutoff), the rendering fallback, and the default frame/time behavior. An agent has everything it needs to call it and interpret results.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all five parameters including the nested mask/matte objects and the where enum. The description adds only indirect semantics ('over the export frame when one is set', playhead default for time), so the baseline 3 is appropriate.

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

Purpose5/5

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

States a specific verb and resource ('Measure the graded picture at one moment') plus exactly what the tool returns (numeric luma levels, clip/clip percentages, RGB means, saturation, colour cast, on-screen clips with grades/mattes/blends). Calling out that it returns numbers and is rendered by the same compositor as export implicitly separates it from image-producing siblings like fablecut_frame and fablecut_export.

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

Usage Guidelines4/5

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

Gives concrete when-to-use guidance with actionable thresholds ('cast strength above ~0.03 on footage that should be neutral', 'whitePct above ~1', 'median far from ~0.4'). It clarifies that the playhead is not moved, but never names an alternative sibling or states when not to use it, so the guidance is strong but not fully routing.

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

fablecut_set_projectA

Replace the FableCut project JSON. Pass the COMPLETE document (read with fablecut_get_project, modify, send back whole). Revision is auto-bumped; the open editor UI hot-reloads instantly so the user sees the edit live. CONFLICT-SAFE: if the project changed on disk since your last fablecut_get_project (e.g. the user tweaked something in the UI), the call errors instead of overwriting — re-read, re-apply your edit on top of the latest document, and retry.

NameRequiredDescriptionDefault
forceNoOverwrite even if the project changed since it was last read (discards those external/user changes). Only when the user explicitly asks.
projectYesThe complete project document (see fablecut_docs for schema)

TDQS

A4.6/5.0
Behavior5/5

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

Discloses auto-bumped revision, instant hot-reload, conflict error and retry pattern, and force overwrite behavior. No annotations to contradict.

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

Conciseness5/5

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

Three concise, front-loaded sentences covering all crucial aspects without waste.

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

Completeness4/5

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

Explains behavior well but lacks description of return value. Given set operation, minor gap.

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

Parameters4/5

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

Schema coverage is 100%, description adds value by clarifying the 'project' must be complete and the read-modify-write cycle, and explains 'force' usage.

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

Purpose5/5

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

Clearly states it replaces the project JSON with the complete document, distinguishing from patch tools. Verb 'replace' with resource 'project' is specific.

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

Usage Guidelines4/5

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

Explicitly instructs to read, modify, send whole. Provides conflict-safety retry guidance. Could mention that partial updates should use fablecut_patch_project.

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

fablecut_statusA

FableCut video editor: ensure the editor web server is running (auto-starts it), and get the editor URL, project summary and media library. Call this first in a session.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description discloses key behavior: auto-starting the web server. Does not detail error handling or idempotency, but for a status tool, this is adequate transparency.

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

Conciseness5/5

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

A single sentence that concisely conveys purpose, behavior, and usage recommendation. No wasted words.

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

Completeness4/5

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

For a zero-parameter tool with no output schema, the description covers core functionality and usage. Could mention response details more explicitly, but overall complete.

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

Parameters4/5

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

No parameters in schema, so baseline 4 applies. Description adds no parameter info, but none is needed.

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

Purpose5/5

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

The description clearly identifies the tool as ensuring the editor web server is running (auto-start) and retrieving the editor URL, project summary, and media library. It distinguishes from siblings by stating 'Call this first in a session.'

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

Usage Guidelines4/5

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

Explicitly states 'Call this first in a session,' providing clear usage guidance as a prerequisite. Lacks details on when not to use or alternatives, but the instruction is sufficient for an agent.

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

fablecut_trackA

Follow something in a video clip frame by frame (motion tracking, in the editor: an open tab, else headless Chrome / Edge) and store it on the clip as a named track (props.tracks). Then, in the same call, make a mask follow it (apply:{mask}) or pin another clip to it (apply:{clip} — a title, sticker, blur box… its x / y, and optionally scale / rotation, get keyframes that ride on the track, keeping where it is at at). What to follow: region {x, y, w, h} or point {x, y} (+ size), as fractions of the clip's picture (0…1, y down) at time at; or leave both out with apply:{mask} to follow what that mask covers. To re-apply an existing track, pass its name with apply and no region. Pick something with detail (a corner, a logo, text, an eye), not a flat area; the result reports match quality (≥ 0.8 is solid) and where the region was lost, if it was. Check the outcome with fablecut_scopes or by looking at the keyed clip.

NameRequiredDescriptionDefault
atNoTimeline seconds where the region is as given (default: the clip's start)
toNoTimeline seconds to stop at (default: the clip's end / start)
clipYesThe video clip to track in
nameNoThe track's name (default: the mask's name, or Track n). An existing name is extended / replaced over the tracked range
sizeNoWith point: the region's width, fraction of the picture's width (default 0.08)
applyNoBake the track into keys: {mask: index | name} (the mask's x / y — and scale / rotation when tracked — follow) or {clip: id, scale?, rotation?, at?} (that clip rides on the track)
forceNoAllow changing locked clips — only when the user asked
pointNoA spot to follow at `at` (fractions of the picture); a square region of `size` around it is matched
scaleNoAlso follow the region's size (zooms, objects moving closer)
whereNoauto (default): an open editor tab, else headless · tab · headless
regionNoThe area to follow at `at`: centre x, y and size w, h, fractions of the clip's picture
timeoutNoSeconds to wait (default 300)
rotationNoAlso follow the region's rotation
directionNoTrack from `at` to the clip's end (default), to its start, or both

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses the execution environment (open tab vs headless Chrome/Edge), that results are persisted to props.tracks, that an existing name is extended/replaced over the tracked range, and that match quality (>=0.8) and lost-region locations are reported. It stops short of stating permission or locked-clip semantics beyond the force flag.

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

Conciseness4/5

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

It is front-loaded with the core action and the optional apply step, and given a 14-parameter tool most clauses earn their place. The prose is a dense single paragraph with stacked parentheticals, which makes it heavier to parse than ideal, but there is little outright padding.

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

Completeness5/5

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

For a complex, no-output-schema tool the description covers the essentials an agent needs: what is produced (a named track), the two application modes in the same call, target-selection heuristics, execution venue, and how to verify the result. Nothing required to invoke it correctly is missing.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema by explaining the interplay between region, point (+size), and apply (region-less implies following the mask) and by describing how the name default is derived. That relational context is not recoverable from the field descriptions alone.

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

Purpose5/5

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

The first sentence states a specific verb (follow/motion track) and resource (something in a video clip, frame by frame), and it names its own output artifact (a named track stored on the clip). It also routes the agent to fablecut_scopes for verification, so it is distinguishable from siblings despite there being no direct tracker alternative.

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

Usage Guidelines4/5

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

It states when and how to use it: pick a detailed target (corner, logo, text, eye) rather than a flat area, and use apply:{mask} with no region to inherit the mask's coverage. It does not name a competing tool to prefer or give explicit exclusions, but the practical selection guidance is clear.

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

fablecut_versionsA

A project's version history: saved copies you can go back to, never destructive. Actions: list (default) · save {name?, note?, final?} — keep the project as it is now (do this before big or risky edits, and when the user is happy with a cut) · diff {version, to?} — what changed from that version to now (or to another version): clips added / removed / changed, length, media, settings · restore {version} — put that version back; the current state is saved as a version first, so a restore can itself be undone · update {version, name?, note?, final?} — rename, annotate, or mark the one final cut · delete {version}. project defaults to the open one (fablecut_projects lists ids). Versions are also made on their own: every 10 minutes while the project changes, and before an agent's first edit of a session or a fablecut_set_project rewrite. Restoring changes what the user sees: only when they asked.

NameRequiredDescriptionDefault
toNodiff: compare to this version instead of the current project
nameNosave / update: the version's name (default "Version NN")
noteNosave / update: what this version is ("client cut, shorter intro")
finalNosave / update: mark it the final cut (one per project)
actionNoWhat to do (default list)
projectNoThe project (p_…); default the open one
versionNoThe version: its number (3) or "v3"

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so: it declares the tool is never destructive, that restore first snapshots current state so it can be undone, and that versions are auto-created every 10 minutes plus before an agent's first edit or a set_project rewrite. These are non-obvious side effects an agent could not infer elsewhere.

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

Conciseness4/5

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

Front-loaded with the resource and the safety claim, then structured as an action list with inline guidance. It is dense and long for one paragraph, but nearly every clause carries actionable information; a bulleted layout would scan better.

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

Completeness5/5

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

A 7-parameter, 6-action mutation tool with no annotations and no output schema — the description covers action semantics, side effects, defaults, consumers of version ids (fablecut_projects), and the human-visible consequence of restore. Nothing essential is missing for correct invocation.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond it: which parameters belong to which action (save/diff/restore/update signatures), that project defaults to the open one, and that version accepts a number. The 'to' semantics for diff are useful too. It stops short of covering edge cases like 'final' uniqueness enforcement, which the schema mentions.

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

Purpose5/5

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

The opening clause names the resource precisely (a project's version history, saved copies) and the description then enumerates all six actions with their payloads (list/save/diff/restore/update/delete). An agent can distinguish this from siblings like fablecut_projects or fablecut_set_project without opening a schema.

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

Usage Guidelines5/5

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

Explicit triggers are given per action: save 'before big or risky edits, and when the user is happy with a cut', restore 'only when they asked', diff to see what changed. It also states the default (list) and warns that restoring changes what the user sees, which functions as a when-not rule.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv1.16.0
    • Changedfablecut_encode_profiles3 fields changed
      • changedInput schema / properties / detail / description
        Previous value: -"Include the full ffmpeg args array per profile (default: a truncated summary)"New value: +"Include the full ffmpeg args array per encoding profile (default: a truncated summary)"
      • addedInput schema / properties / preset
        Added value: +{
        +  "description": "Return one delivery preset's full spec (youtube, broadcast, a saved preset id …)",
        +  "type": "string"
        +}
      • changedInput schema / properties / profile / description
        Previous value: -"Return one profile by id instead of the full list"New value: +"Return one encoding profile by id instead of the full list"
    • Changedfablecut_export4 fields changed
      • addedInput schema / properties / delivery
        Added value: +{
        +  "description": "Delivery settings over the preset (or over custom): {width, height (null = the picture's size), fps (null = the project's), reframe:'fill'|'fit'|'stretch', container:'mp4'|'mov'|'mkv'|'webm'|'mxf', video:{codec:'h264'|'hevc'|'av1'|'vp9'|'prores'|'dnxhr'|'mpeg2'|'ffv1', encoder?, rate:'crf'|'vbr'|'cbr', crf, bitrate (kb/s), maxrate (kb/s), keyint (s), pixFmt, speed:'fast'|'balanced'|'best', profile (prores: proxy|lt|standard|hq|4444|4444xq · dnxhr: lb|sq|hq|hqx|444)}, audio:{codec:'aac'|'opus'|'mp3'|'pcm16'|'pcm24'|'flac'|'none', bitrate (kb/s), sampleRate, channels, loudness (LUFS target: -14 streaming/social, -16 podcast, -23 EBU R128, -24 ATSC; null = as mixed), truePeak (dBTP ceiling, default -1)}, color:'bt709'|'bt709-full'|'bt601-625'|'bt601-525', filename:'{project}_{preset}_{res}' (tokens {project} {preset} {res} {w} {h} {fps} {codec} {date} {time} {range} {n}), metadata:{title, artist, description, copyright, date, keywords}}. Anything left out comes from the preset; impossible combinations are corrected and the reply says how. Every finished file is checked against what was asked (size, fps, frames, codecs, length, loudness, true peak, file size) and the reply lists the checks",
        +  "type": "object"
        +}
      • addedInput schema / properties / outputs
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "boolean"
        +    },
        +    {
        +      "items": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "type": "array"
        +    }
        +  ],
        +  "description": "Several files, rendered once per frame rate (up to 8 outputs per render): true = the project's checked batch outputs (project.outputs, set with setProject {outputs:[…]}), or a list like [{preset:'master'}, {preset:'youtube'}, {preset:'instagram-reels'}, {preset:'custom', width:1080, height:1080, filename:'{project}_square_{res}'}, {preset:'web', filename:'{project}_preview_{res}'}]. Outputs with the same fps share one render; the reply lists every file"
        +}
      • addedInput schema / properties / preset
        Added value: +{
        +  "description": "Delivery preset: youtube, youtube-shorts, instagram-reels, tiktok, x, linkedin, master, broadcast, web, archive, custom, or a saved preset's id (fablecut_encode_profiles lists them). The output is reframed to the preset's size — cropped from the middle (or from the project's exportFrame), or padded with reframe:'fit'",
        +  "type": "string"
        +}
      • changedInput schema / properties / profile / description
        Previous value: -"Encoding profile id (fablecut_encode_profiles); default: project.encodeProfile, else the server default"New value: +"Encoding profile id (raw ffmpeg args, fablecut_encode_profiles) instead of a preset. With neither: project.delivery, else project.encodeProfile, else the server's default profile"
    • Addedfablecut_projects
    • Addedfablecut_proxy
    • Addedfablecut_versions
  2. 4 tool updatesv1.14.0
    • Addedfablecut_frame
    • Changedfablecut_patch_project1 field changed
      • addedInput schema / properties / baseRevision
        Added value: +{
        +  "description": "Revision these ops were planned against. If project.json has moved past it, the patch is refused with CONFLICT (nothing saved). Omit to apply on top of the latest revision.",
        +  "type": "integer"
        +}
    • Changedfablecut_scopes1 field changed
      • addedInput schema / properties / mask
        Added value: +{
        +  "description": "Also measure a clip's masks: {clip}. Adds how much of that clip's picture the masks keep (coverage %, the feathered matte measured alone) and how much of the frame the masked clip covers",
        +  "properties": {
        +    "clip": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "clip"
        +  ],
        +  "type": "object"
        +}
    • Addedfablecut_track
  3. 1 tool updatev1.11.0
    • Addedfablecut_scopes
  4. 4 tool updatesv1.10.0
    • Addedfablecut_auto_duck
    • Addedfablecut_denoise
    • Addedfablecut_export
    • Addedfablecut_normalize_audio
  5. 3 tool updatesv1.9.0
    • Addedfablecut_encode_profiles
    • Changedfablecut_import_media1 field changed
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path to the source file on disk"New value: +"Absolute path to a local file, or an https:// URL to download"
    • Changedfablecut_patch_project1 field changed
      • changedInput schema / properties / ops / description
        Previous value: -"Edit operations, applied in order (see tool description for shapes)"New value: +"Edit operations, applied in order (see tool description for shapes). Any op may carry force:true to override a lock the user set."
  6. 7 tool updatesv0.1.0
    • First observedfablecut_analyze_reference
    • First observedfablecut_docs
    • First observedfablecut_get_project
    • First observedfablecut_import_media
    • First observedfablecut_patch_project
    • First observedfablecut_set_project
    • First observedfablecut_status

TDQS

A4.3/5.0

Scored across 18 tools

Disambiguation4/5

Most tools have sharply defined roles: get/set/patch project are explicitly differentiated, frame returns images while scopes returns measurements, and the audio tools cover loudness, ducking, and denoise separately. Some management/inspection tools such as status, projects, and get_project all expose project context, so an agent must read descriptions to choose correctly, but the boundaries are mostly clear.

Naming Consistency4/5

All tools use the same fablecut_ prefix and snake_case, making the set predictable and readable. However, the names mix verb-led actions (import_media, set_project, analyze_reference) with noun-only resource/management tools (status, docs, projects, versions), so it is not a uniform verb_noun convention.

Tool Count4/5

Eighteen tools is slightly heavy, but the server covers a broad professional video-editing workflow including media import, timeline editing, color, audio, tracking, export, projects, versions, and analysis. Each tool has a distinct role, so the count is reasonable for the domain even if a few advanced capabilities could be consolidated.

Completeness5/5

The surface is extensive: it covers project inspection and targeted editing, media import, timeline operations, color and scopes, motion tracking, audio normalization/ducking/denoise, proxies, export presets, frame inspection, versioning, and multi-project management. Obvious lifecycle operations appear reachable through the patch/project tools, leaving few dead ends for an editing agent.

Maintenance

ActivityActive
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers