MCP tools
Connect an agent, and the calls it uses to read and change your timeline without burning tokens.
Register the MCP server (mcp-server.js) once at user scope as fablecut: claude mcp add -s user fablecut -- node "<path-to>/fablecut/mcp-server.js". Every Claude Code session then has these tools:
fablecut_status- auto-starts the editor server, returns URL + project summary. Call first.fablecut_docs- returns this document (section: "…"returns only matching##sections).fablecut_get_project/fablecut_set_project- read / replace the timeline JSON.fablecut_get_project {compact:true}returns a one-line-per-clip summary instead.fablecut_patch_project- apply targeted ops (add/update/remove clip/media, set project fields) without round-tripping the document. Prefer this for edits.fablecut_import_media- copy a local file (or download anhttps://URL) into./media/and register it. The storedsrcis always/media/….fablecut_analyze_reference- turn a reference video into an edit blueprint (shots, beats, BPM, energy, drop) + extract its music. See Remake a reference video.fablecut_encode_profiles- list export presets fromencoding-profiles.json(each is a raw ffmpeg args list). Setproject.encodeProfilevia patch to pin a project default.
Token-efficient editing important for agents#
Editing via full get→modify→set costs thousands of tokens per change. Cheaper:
- Plan from
fablecut_get_project {compact:true}(≈10× smaller than the JSON) andfablecut_status- fetch the full JSON only to inspect exact keyframes. - Edit with
fablecut_patch_projectops - send only what changes, e.g.{ops:[{op:"updateClip", id:"c_v2", set:{props:{filterPreset:"noir"}}}]}. It re-reads the latest document internally, so it is merge-safe by design (no CONFLICT dance) and never destroys concurrent UI tweaks. - Docs: request
fablecut_docs {section:"schema"}(or Recipes, "Remake", …) instead of the whole manual; skip it entirely if the schema is already in context. - Media questions (duration, fps, size): read them from the registered media entries - don't shell out to ffprobe; the browser probes and writes them back.
- Batch related changes into ONE patch call (ops apply in order, one revision bump).
fablecut_set_project is conflict-checked. The MCP server remembers the revision from the most recent fablecut_get_project call. If project.json has been written by anyone else since that read (e.g. the user dragged a clip in the UI), fablecut_set_project refuses with a "CONFLICT - not saved" error instead of overwriting. Protocol:
fablecut_get_project→ read the document and note itsrevision.- Apply your edits in memory, bump
revision. fablecut_set_project→ if it succeeds you're done.- On conflict: call
fablecut_get_projectagain to get the latest document, re-apply your intended changes on top of it, bumprevision, and callfablecut_set_projectagain.
Pass force: true to fablecut_set_project only when the user explicitly asks to overwrite conflicting changes. fablecut_import_media only appends a new media entry and always merges safely - no conflict check needed.
For Claude Desktop, add to its MCP config: {"mcpServers":{"fablecut":{"command":"node","args":["<path-to>/fablecut/mcp-server.js"]}}} Direct file editing of project.json (below) works too and is equivalent.
Installing as a Claude Code plugin (/plugin marketplace add ronak-create/FableCut, then /plugin install fablecut@fablecut) does the registration for you.
Where the files are#
project.json, media/, exports/, analysis/ and library/ normally sit in the repo next to server.js. Set FABLECUT_DATA_DIR to move all five somewhere else; the code and the static app files stay in the install directory either way. The plugin sets this so a plugin update can replace the install directory without touching anyone's timeline or footage. Don't assume project.json is beside mcp-server.js - call fablecut_status, which reports the real paths.
Tests (and nothing else) may set FABLECUT_NO_FS_WATCH=1 to skip fs.watch. On Windows, libuv can abort the process when a file is created under a temp data dir. Production leaves watching on so the UI live-reloads.