Skill v1.0.0
currentAutomated scan100/100name: final-cut-pro description: Edit Final Cut Pro timelines with natural language via FCPXML. Use when the user wants to analyze, cut, trim, mark up, transcribe, montage, or export a Final Cut Pro project, mentions .fcpxml or .fcpxmld files, asks to remove silence or filler words from a video edit, wants a rough cut assembled from source clips, wants markers or chapters added from a transcript or SRT, or wants an edit pushed into a running Final Cut Pro. Requires the fcp-mcp-server MCP server. metadata: version: "1.0.0"
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. | |
view | See the cut inline. view_timeline returns the timeline as an exact rational-time JSON payload — lanes, clips, markers, gaps, cached transcript words, filmstrip thumbnails — that a host with MCP Apps (Claude Desktop, claude.ai, VS Code, Goose) renders as an interactive timeline from the ui://fcp/timeline resource; without Apps support the JSON block is the answer. Clicking a clip there calls view_clip (the inspect button) or find_shots; the marker and delete buttons call mark and edit, so the journal and the project guard apply. Read-only. | |
gen | Generative fill behind a money gate. gen_quote (provider fal kling-2.5 / wan-2.5, gemini veo-3.1; runway / luma are honest stubs) prices the job from a dated, unverified table and returns a quote id. gen_fill_gap, gen_broll and gen_extend_clip REFUSE without quote_id + confirm=true, a job that still matches the quote, the provider's key in the environment (FAL_KEY, GEMINI_API_KEY, sent only in the auth header) and a price under FCP_MCP_GEN_MAX_USD (default 5). Always quote first and show the operator the price before confirming. The result is ffprobed for its real fps and length, saved under generated/ beside the project, attached as a connected clip with role generated and a marker naming prompt and provider, DTD-validated and journaled. |
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.
- `offset` is the timeline position. `start` is 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).
- `.fcpxmld` bundles are directories, wrapping
Info.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. The preview:// resource and preview_timeline both draw from the XML — they show what was WRITTEN, so they cannot tell a fixed cut from a broken one. preview_check reads 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.