Final Cut Pro editing via FCPXML
Before you touch anything
Always inspect then diagnose before you edit. Timelines carry structure
that is not obvious from a filename, and an edit against a wrong assumption is
expensive to undo.
inspectwith actionanalyze_timelinefor shape, duration, resolution.diagnosewith actionvalidate_timelinefor gaps, flash frames, duplicates.- Read the
preview://<path>resource to actually SEE the timeline before you change anything. It renders a self-contained HTML timeline, including connected clips on their own lane rows, so you can see B-roll and audio layers, not just the primary storyline.
The seven groups
| Group | Use it for |
|---|---|
inspect | Read-only understanding. Start here, always. |
diagnose | Find problems: gaps, flash frames, dead air, duplicates, beats. |
edit | Change clips: insert, delete, trim, split, reorder, retime, remove silence. |
mark | Markers and chapters, including SRT/VTT and beat import. |
generate | Build new structure: rough cuts, montages, A/B roll, templates, and import_edl_json from a video-use cut list. |
transcript | Transcribe locally, then edit or clean up by what was SAID. transcript_pack puts the whole shoot on one page — read it before planning a dialogue edit. Every action takes backend: "elevenlabs" for speaker labels and audio events; that uploads the media to ElevenLabs and needs ELEVENLABS_API_KEY — the default local never leaves the machine. |
deliver | Export to other NLEs, reformat, relink, push into FCP. |
preview | SEE the edit: proxy render, contact sheet, and a filmstrip+waveform read from the source media. |
watch | Close the round-trip: notice the operator's Cmd-E export and diff it against the last one. |
index | The analysis cache. index_status says how old it is; index_build warms every source in a timeline; index_clear drops it. Nothing depends on it. |
scenes | Shot boundaries from the pixels. detect_scenes lists cuts per clip in source and timeline time (PySceneDetect when installed via [scenes], else ffmpeg's coarser scene filter); scenes_to_markers drops a marker on each; scenes_split cuts the clips there. Results are cached in the index. |
organize | Bulk library logging and the ledger. organize_auto proposes keywords per clip from cached captions and the transcript (apply=true writes them). Select clips by clip_name glob, keyword and/or role, then organize_keywords (add/remove/replace), organize_rate (favorite/rejected/clear) or organize_roles — each writes a _organized copy. history lists every recorded operation for the file's folder; undo moves the last n outputs into the journal's undone/ folder (never deletes, refuses if a file changed since). |
find | "Where is the bit where…" as a router. find_shots ranks moments by what was said (transcript), what was logged (names, keywords, notes, markers, audio events) and, with the [find] extra and a downloaded local model, what the frames look like — the first line names which tiers answered and why one could not. find_index warms scenes and captions and reports which clips have no transcript (never transcribes, never online). find_to_timeline assembles the hits into a _found selects reel with a diversity score. |
Every call takes {"action": "...", "args": {...}}. If you pass an action the
group does not own, the error lists the valid ones — read it rather than
guessing.
FCPXML facts that will bite you
- Time is rational, never float.
3600/2400sis 1.5 seconds. Never do float math on timecode and never round it yourself. offsetis the timeline position.startis the source in-point. They are different numbers and confusing them silently shifts an edit.- Library clips and timeline clips are different elements.
<asset-clip>lives in the library,<clip>lives on the timeline. - Markers are children of clips, not siblings.
- The
<spine>is the primary storyline. Connected clips hang off spine clips by lane: positive is above (video), negative is below (audio). .fcpxmldbundles are directories, wrappingInfo.fcpxmlplus sidecar data. Sidecars must be preserved on save or object-tracking and Cinematic data is destroyed.- Duplicate clip names are common. Prefer element-based operations over name lookups where a tool offers both.
Silence removal: pick the right one
There are two detect-then-fix pairs, and they are not interchangeable. Both
follow the same split as every other detect/fix pair in this server: the
detector lives in diagnose, the fixer lives in edit.
detect_media_silence(diagnose) →remove_media_silence(edit) reads the actual source audio with ffmpeg. Accurate, slower, needs ffmpeg installed.detect_silence_candidates(diagnose) →remove_silence_candidates(edit) uses timeline heuristics only. Fast, no ffmpeg, and it guesses.
Use the media versions when correctness matters. Say which one you used.
Working order that tends to hold
inspect→diagnose→ read thepreview://resource.transcriptwith actiontranscript_packif the edit is dialogue-driven — one page of everything said, so the plan is made from the words rather than the clip names.generatefor the assembly,editfor the refinement,markfor chapters.previewwith actionpreview_checkover the range you changed, before offering the edit as done. This is what makes the edit non-blind. Thepreview://resource andpreview_timelineboth draw from the XML — they show what was WRITTEN, so they cannot tell a fixed cut from a broken one.preview_checkreads the media. Do not substitute one for the other, and do not skip it because the tool call reported success.deliver, either exporting orpush_to_fcpinto the running app.watchwith actionwatch_startonce per session, thenwatch_pullafter the operator exports. Final Cut Pro has NO programmatic export — Apple never shipped one — so the loop only closes when they press Cmd-E. Say so plainly rather than waiting in silence.
Do not
- Do not edit without a diagnose pass. Flash frames and gaps compound.
- Do not assume ffmpeg or Whisper are installed. Both degrade gracefully and return nothing rather than erroring, so check the response.
- Do not read a
preview_rendersummary past the word UNVERIFIED. It means the rendered file's duration could not be read back, so nothing about that render has been confirmed. - Do not ignore a
Substituted:line. The proxy renders transitions as hard cuts, so a dissolve in the timeline is NOT what you are looking at. - Do not claim an edit landed in Final Cut Pro unless
push_to_fcpwas called and reported success. Writing an .fcpxml file is not the same as importing it. - Do not trust a tool's own success message as proof the timeline looks
right. Read
preview://and look.