fcp-mcp — Final Cut Pro MCP Server

io.github.dreliq9Published by GitHub account dreliq9v0.2.0Updated Oct 24, 2026

Final Cut Pro MCP — 88 tools: FCPXML engine, live FCP control, media analysis, puppets.

Overview

AI-generated overview

Lets an assistant inspect, generate, and transactionally edit Final Cut Pro FCPXML, run QC checks, and optionally control Final Cut Pro live on macOS.

What you can do
Provides 97 tools across profiles for FCPXML parsing, clip/marker/effect listing, pacing and timeline analysis, A/B diffing, structural validation, and QC checks such as flash frames, gaps, duplicates, frame rates, audio levels, and safe zones. It can generate projects and timelines, edit markers, keywords, titles, audio, transitions, trims, splits, and roles, and export to EDL, DaVinci Resolve XML, or Premiere FCP7 XMEML. A durable workflow layer prepares candidates, shows a semantic diff, and commits only after hash approval. Optional live tools use AppleScript to open libraries, control playback, run menu commands and shortcuts, and dispatch Compressor encodes.
When to use it
Use it when you work with Final Cut Pro on macOS and want an assistant to inspect or repair FCPXML, run pre-cut QC, batch-edit timelines, generate rough cuts or puppet animations, or hand verified XML to Final Cut Pro. It is also useful for converting captions or assembly edits into other NLE formats.
Requirements
Local macOS process installed from PyPI as fcp-mcp; Python 3.10+, macOS 15.6 or later with Final Cut Pro, and FFmpeg on PATH for media tools; Apple Compressor optional. Live control needs FCP_MCP_ENABLE_LIVE_CONTROL=1 and a running Final Cut Pro; some queries need Accessibility permissions. Optional variables include FCP_MCP_OUTPUT_DIR, FCP_MCP_ALLOWED_ROOTS, and FCP_MCP_STATE_DIR.
Before you install
Live control, Accessibility, and Compressor actions are opt-in and can change or export projects; the default workflow profile avoids direct mutation. Import-bridge snapshots are retained without automatic cleanup and consume disk space, and deleting state removes duplicate-dispatch evidence. The built-in validator is not a complete Apple schema validator, so import important outputs into a disposable Final Cut Pro project. The controls assume a trusted OS account and do not isolate against same

Installation

In SourceWeft

  1. Open fcp-mcp — Final Cut Pro MCP Server in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

fcp-mcp — Final Cut Pro MCP Server

Trusted, local, human-approved Final Cut Pro workflows. fcp-mcp inspects, generates, and transactionally edits FCPXML, then optionally hands verified artifacts to Final Cut Pro. The default profile never performs direct live or offline mutation.

This development catalog adds three import-bridge tools to the v0.3.0 baseline across four profiles. It is a bounded FCPXML interchange and tested Final Cut Pro handoff surface—not a claim of complete autonomous Final Cut Pro control. The default workflow is inspect, prepare, review, hash approval, then commit.

You: "Find and repair flash frames in hero.fcpxml."Claude → fcpxml_detect_flash_frames → fcpxml_workflow_prepare       → review semantic diff + candidate hash → fcpxml_workflow_commitResult: the reviewed candidate is atomically committed with durable evidence

Start here:

Project Structure

fcp-mcp/├── src/fcp_mcp/│   ├── __init__.py│   ├── __main__.py              # python -m fcp_mcp CLI│   ├── cli.py                   # serve, doctor, doctor --json, --version│   ├── config.py                # immutable environment configuration│   ├── contracts.py             # stable errors + structured diagnostics│   ├── diagnostics.py           # non-mutating runtime readiness checks│   ├── observability.py         # text/JSON transaction events│   ├── server.py                # MCP v2 entry and profile-selected handlers│   ├── tool_metadata.py         # MCP safety annotation presets│   ├── automation/│   │   └── osascript.py         # argv-isolated AppleScript/JXA runner│   ├── security/│   │   └── paths.py             # allowed-root and output policy│   ├── fcpxml/│   │   ├── parser.py            # FCPXML → Python object tree│   │   ├── writer.py            # transactional XML mutation/writing│   │   ├── models.py            # TimeValue, Timecode, Clip, Timeline, etc.│   │   ├── time_utils.py        # rational-arithmetic timecode│   │   ├── analysis.py          # pacing, flash frames, gaps, duplicates│   │   ├── validator.py         # DTD-style structural validation│   │   ├── generator.py         # programmatic project/timeline creation│   │   ├── puppet.py            # character puppet system│   │   ├── diff.py              # timeline A/B comparison│   │   └── transaction.py       # validated atomic FCPXML commits│   ├── fcp_control/             # AppleScript bridge for live FCP control│   ├── media/│   │   └── ffprobe.py           # ffprobe wrapper for media analysis│   ├── pipeline/                # multi-step workflows│   ├── workflow/                # durable prepare, approval, commit, recovery│   └── utils/│       ├── atomic_write.py       # backup, replace, rollback│       ├── safe_xml.py          # defusedxml hardening│       └── paths.py             # trusted system path helpers├── tests/                       # complete unit + contract suite├── scripts/                     # docs, coverage, and wheel gates├── docs/│   ├── README.md                # documentation map and status│   ├── research/                # dated research records│   └── reviews/                 # release evidence and decisions├── examples/│   ├── quickstart.py            # install verification│   └── GALLERY.md               # workflow gallery with prompts├── pyproject.toml├── server.json                  # MCP Registry manifest├── LLM_GUIDE.md                 # operational guide for agents├── WORKFLOWS.md                 # production recipes├── CHANGELOG.md├── ROADMAP.md├── CONTRIBUTING.md└── LICENSE

Setup

Prerequisites

  • Python 3.10+
  • macOS 15.6 or later with Final Cut Pro
  • FFmpeg on $PATH (for media_* tools): brew install ffmpeg
  • Apple Compressor (optional, for compressor_* tools)

Install

Install the current published release from PyPI:

bash
pipx install fcp-mcp

Or from source (for contributors):

bash
git clone https://github.com/dreliq9/fcp-mcp.gitcd fcp-mcppython3 -m venv .venvsource .venv/bin/activatepip install -e ".[dev]"

Verify

bash
fcp-mcp --versionfcp-mcp doctorfcp-mcp doctor --jsonpython examples/quickstart.py

doctor exits 0 when ready, 1 when offline service is usable but optional capabilities are degraded, and 2 when configuration blocks required runtime behavior. MCP clients can call the same structured surface through fcp_doctor.

Connect to Claude Code

bash
claude mcp add-json fcp '{"type":"stdio","command":"fcp-mcp"}' --scope user

Or if you installed from source, point at your venv's Python:

bash
claude mcp add-json fcp '{"type":"stdio","command":"/FULL/PATH/TO/.venv/bin/fcp-mcp"}' --scope user

Or edit ~/.claude.json directly:

json
{  "mcpServers": {    "fcp": {      "type": "stdio",      "command": "fcp-mcp"    }  }}

Claude Desktop

Add the same config to your Claude Desktop config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

Verify connection

bash
claude mcp list       # from terminal/mcp                  # inside Claude Code

Catalog Profiles

Select a profile with FCP_MCP_PROFILE. The default workflow profile keeps the inspect → prepare → review → hash approval → commit sequence bounded and reviewable.

ProfileToolsPromptsResourcesPurpose
inspect3020Offline inspection and diagnostics
workflow (default)3433Reviewable transactional FCPXML edits
edit7653Direct offline mutation, import preparation, and workflows
full9753All offline tools and opt-in live FCP, media, and Compressor tools

The 97 tools include the youtube-mcp.materialized-clip-plan/v1 provenance adapter, fcpxml_generate_from_clip_plan, in edit and full only. Live FCP control remains independently disabled unless FCP_MCP_ENABLE_LIVE_CONTROL=1; choosing full does not grant that authority.

Available Tools (97 in full)

The full catalog combines 96 domain tools across 14 functional categories with fcp_doctor.

CategoryCountWhat it does
inspect8Parse, list clips/markers/effects/roles, analyze pacing, timeline stats, A/B diff
qc10Flash frames, gaps, duplicates, media links, frame rates, audio levels, safe zones, duration, structural validation, aggregate QC report
edit12Markers, keywords, titles, audio, transitions, trim, split, delete, reorder, speed, role assign, reformat
heal3Fix flash frames, fill gaps, remove silence
batch4Markers, rename, role assign, apply transition across many clips
generate5New project/timeline, rough cuts, montages, and provenance-preserving clip-plan FCPXML
templates3List and save FCPXML templates; fcpxml_apply_template remains unsupported_contract in v0.3.0
io5Import SRT/EDL, export EDL + DaVinci Resolve XML + Premiere FCP7 XMEML
live20AppleScript-backed library/events/projects, playback, menu/keyboard, share, and discovery
import bridge3Validated destination-bound XML preparation, one approved native request, and metadata reconciliation
puppet7Parametric character rigs in FCPXML with motion presets
media10ffprobe + ffmpeg info, loudness, silence, beats, scenes, thumbnails, and audio-to-MIDI
compressor2List Compressor settings and dispatch encode jobs
workflow4Prepare, inspect, hash-approve, commit, or cancel durable edit runs

Key Features

Three layers in one server

Most FCP MCPs pick a lane. DareDev256/fcpxml-mcp-server is FCPXML-only. elliotttate/finalcutpro-mcp is AppleScript/JXA-heavy with thin FCPXML. fcp-mcp does both — and adds media analysis (ffprobe) and a parametric puppet system on top. An agent can open a library, inspect the active timeline, patch the XML, re-import, trigger Share, and dispatch a Compressor job — end to end.

Rational-arithmetic timecode

Time values are stored as fractions ("720/24s") and only collapsed to floats at display boundaries. Frame-accurate across 23.976 / 24 / 29.97 / 59.94 / drop-frame — no rounding drift when splitting, trimming, or concatenating.

Scoped and transactional XML handling

All .fcpxml reads go through defusedxml via utils/safe_xml.py — XXE, entity expansion, and external entities are blocked by default. The parser enforces configured XML size and depth limits.

User paths are resolved beneath configured roots after symlink resolution. FCPXML writes are serialized to a secure temporary file beside the destination, structurally validated, backed up when replacing an existing destination, atomically committed, and validated again. The built-in validator checks the invariants it implements; it is not a complete Apple schema validator. Import into a disposable Final Cut Pro project is the authoritative compatibility gate for important outputs. On a release workstation with Final Cut Pro installed, preflight a candidate against the DTD matching its declared FCPXML version:

bash
python scripts/apple_dtd_gate.py path/to/candidate.fcpxml

This gate reads the DTD from the installed Final Cut Pro application bundle; the project does not copy or redistribute Apple's schema. A passing DTD check does not replace the disposable-project import because Final Cut Pro also checks media and application-level semantics.

fcpxml_assign_role, fcpxml_batch_assign_roles, and their workflow operations assign audio roles. For an asset-clip, fcp-mcp writes Apple's audioRole attribute and continues to read legacy role values for compatibility.

Reviewable transactional edits

The default profile exposes four workflow tools: fcpxml_workflow_prepare, fcpxml_workflow_status, fcpxml_workflow_commit, and fcpxml_workflow_cancel.

Prepare runs a fixed, bounded edit graph and stores the candidate, semantic diff, validation evidence, and event chain beneath the private FCP_MCP_STATE_DIR. It does not create or change the public destination. Review the returned summary and diff_uri, then pass the exact returned candidate_sha256 to commit as expected_candidate_sha256. Client approval is cryptographically bound to that candidate but is recorded as client_unverified_human; the server cannot independently prove that a human approved a chat message.

Three read-only templates expose durable evidence: fcp-workflow://runs/{run_id}, fcp-workflow://runs/{run_id}/events, and fcp-workflow://runs/{run_id}/diff. Candidate XML is deliberately private and is not exposed as a resource. Interrupted commits are assessed from durable evidence and can be explicitly reconciled with:

bash
fcp-mcp workflow reconcile RUN_ID --json

This is a bounded workflow engine, not a generic graph runtime. It does not use MCP Tasks or run background autonomous agents.

Cross-NLE export

Same timeline out to three targets:

  • fcpxml_export_resolve — DaVinci Resolve-flavored XML (v1.9)
  • fcpxml_export_fcp7 — Premiere-compatible XMEML (FCP7 format)
  • fcpxml_export_edl — flat EDL for color-grading and archive pipelines

Parametric character puppets

puppet_* tools build animated character rigs entirely in FCPXML — no third-party motion templates required. Parts, keyframes, and presets (walk, talk, wave, multi-character compositions) emit XML for structural validation followed by a disposable-project FCP import gate.

QC before you cut

fcpxml_qc_report("hero.fcpxml")  → Markdown validation summary and timeline statistics  → gaps and flash frames with timecodes  → duplicate sources  → pacing distribution

Media links, frame rates, audio levels, safe zones, and target duration are separate fcpxml_check_* tools. Run the specific checks you need instead of assuming the aggregate report includes them.

Programmatic XML import bridge

fcpxml_prepare_import(path, library_path) prepares one named event/project without contacting Final Cut. It requires an existing .fcpbundle, scoped local media files, and a matching installed Apple DTD. Its private artifact contains Apple's documented import-options library URL. Media is copied into private snapshots within FCP_MCP_WORKFLOW_MAX_ARTIFACT_BYTES (aggregate staged media plus staged XML; default 268,435,456 bytes / 256 MiB per preparation), and Final Cut is asked to copy assets into its library. Warnings remain visible. Conflicting embedded destinations are rejected. Factory Motion template UIDs and matching installed factory locators are supported; external Motion templates and locator resources are rejected. Media bookmarks are removed in favor of the reviewed snapshot URLs.

Dispatch uses a separate sealed copy of the reviewed XML, with pinned identities and hashes for every staged file. The bridge checks these after native preflight. Files are mode 0400 and snapshot directories 0500; public path tools cannot access the reserved staging tree. Snapshots are retained for asynchronous reads, including after metadata observation; there is no automatic cleanup. This consumes disk space. Retain the entire private import state under FCP_MCP_STATE_DIR/import-bridge, including snapshots, plans and dispatch records, across requests, reconciliation and evidence/recovery decisions. Keep the source XML unchanged until dispatch. Do not delete, move or change permissions on prepared snapshots. Acceptance or matching metadata does not establish that Final Cut has finished reading them. Deleting state also removes duplicate-dispatch evidence; its absence does not authorize another import.

Use a stable private FCP_MCP_STATE_DIR for retained work. Managed workspaces may normalize directory permissions, invalidating the 0500 seal. Temporary locations such as /private/tmp can avoid that normalization for a bounded test, but the OS or another process may remove their contents; they are not a persistent-retention guarantee. If state, permissions or identities change, stop and investigate; do not repair permissions or bypass verification to force a send. No cleanup or state-migration behavior is provided by this bridge.

These controls assume a trusted OS account and installed Final Cut application. They do not isolate against malicious processes running as the same user or root, which can change permissions or replace paths before the app reads them. The three bridge tools reject unknown arguments and require strict schema types.

Review that artifact and target before approving the returned plan_sha256. With the full profile, live control enabled, and client approval mode, fcp_request_import(prepared_id, expected_plan_sha256) inspects the exact open library, blocks existing event names, records intent, and sends one Open Document AppleEvent. accepted_unverified means the event returned without error; it does not mean the import completed. Preflight is not atomic with native processing, so app state can change and Final Cut may still prompt. Apple may create a library if the target disappears before processing. Native errors/timeouts stay ambiguous, and recorded requests are never automatically resent. An unresolved request also blocks another request into that library.

fcp_reconcile_import(prepared_id) reads app metadata and updates private bookkeeping. metadata_observed establishes only the expected library URL, event/project identity and duration. It does not verify timeline content or rendering. Missing, mismatched or unavailable observations require waiting or manual inspection, without another import. CLI approval mode blocks bridge dispatch; it is not silently replaced by client approval. XML export and rendering still depend on Final Cut. The older fcp_import_xml tool is unchanged.

Apple contracts: programmatic import and import options.

Live FCP control

When FCP is running, fcp_* tools wire through AppleScript:

fcp_open_library(...)fcp_get_timeline_info()    → current project, active range, playheadfcp_playback("play" | "pause" | "goto" | "in_out")fcp_menu_command("File > Export > Export Using Compressor Settings...")fcp_keyboard_shortcut("cmd+shift+e")fcp_share("YouTube — 4K")fcp_discover_effects()     → every installed effect/transition/title

Output Files

By default, modified FCPXMLs are written next to their input with a _modified suffix. Override per-call via the output_path parameter, or set the canonical directory for relative and generated outputs:

bash
export FCP_MCP_OUTPUT_DIR=/your/path

FCP_PROJECTS_DIR remains a legacy fallback when FCP_MCP_OUTPUT_DIR is unset. Relative input paths resolve beneath the output directory.

Allow additional input roots with the macOS path separator (:):

bash
export FCP_MCP_ALLOWED_ROOTS="/Users/me/Movies:/Volumes/Media"

Absolute and symlink-resolved inputs outside those roots are rejected. For an input-backed operation, explicit outputs may be beneath the output directory or the input file's parent. Input and output resolving to the same file are always rejected. Replacing an existing destination creates a sibling backup named <file>.bak.<UTC timestamp>.<transaction UUID>.

Live FCP, Accessibility, and Compressor actions are opt-in:

bash
export FCP_MCP_ENABLE_LIVE_CONTROL=1

Leave it unset for offline-only use. Runtime and transaction events use text by default; set FCP_MCP_LOG_FORMAT=json for JSON lines.

Workflow state defaults to the macOS application-support directory. Override it when isolation is required:

bash
export FCP_MCP_STATE_DIR=/your/private/state

Examples

See the full gallery for tool sequences and workflow breakdowns. Sample prompts:

  • "Run the structural QC report on hero.fcpxml and fix every reported flash frame."
  • "Convert these .srt captions into FCPXML title clips on the V2 track."
  • "Take my assembly-edit XML and re-export it as a DaVinci Resolve XML for color."
  • "List every clip on the timeline, then batch-assign the 'dialogue' role to all interview clips."
  • "Open the active library, seek to the first marker, and dispatch a ProRes 422 HQ bounce via Compressor."
  • "Build a 3-character puppet scene: one walking, one talking, one waving. 5-second timeline."

Architecture

Claude Code / Claude Desktop / any MCP client        │        │  stdio (JSON-RPC)        ▼   fcp-mcp server (fcp_mcp/server.py, MCP SDK v2)        │        ├── fcpxml/parser + writer + models ← rational-arithmetic, defusedxml-hardened        ├── fcpxml/analysis + validator     ← QC, pacing, flash frames, gaps        ├── fcpxml/generator + puppet       ← programmatic timeline construction        ├── fcpxml/diff                     ← A/B timeline comparison        ├── workflow/                       ← prepare, verify, approve, commit, recover        ├── private workflow ledger         ← candidates, events, hashes, reconciliation        ├── fcp_control/ (AppleScript)      ← live FCP when available        ├── media/ffprobe                   ← clip info, loudness, scenes, frames        └── Compressor (CLI dispatch)       ← automated encodes              │              ▼        .fcpxml (v1.11+) / EDL / DaVinci XML / FCP7 XMEML / ProRes / H.264

Troubleshooting

fcp-mcp: command not found — make sure the venv you installed into is on your PATH, or use the absolute path to the venv's bin/fcp-mcp in your MCP config.

ffmpeg: command not found on media_ calls* — brew install ffmpeg. FFmpeg is not bundled.

fcp_* tools return "Final Cut Pro is not running" — launch FCP first. Live tools require an active FCP process on macOS and FCP_MCP_ENABLE_LIVE_CONTROL=1.

fcp_* tools fail silently on newer FCP versions — FCP's scripting surface is limited compared to pre-FCPX versions. Menu items and keyboard shortcuts are the reliable path; some JXA queries are gated behind Accessibility permissions (System Settings → Privacy & Security → Accessibility → Claude/Terminal).

fcpxml_* tools report structural validation failures — run fcpxml_validate for the implemented checks. Passing this validator is not proof of complete Apple/FCP compatibility. Run python scripts/apple_dtd_gate.py path/to/result.fcpxml on a Mac with Final Cut Pro installed, then import an important result into a disposable Final Cut Pro project before relying on it.

path_outside_scope — add the media location to FCP_MCP_ALLOWED_ROOTS. External volumes are not implicitly trusted.

same_file_forbidden — choose a different output. fcp-mcp never overwrites its source path, even when the caller supplies it explicitly.

unsupported_contract from fcpxml_apply_template — template listing and saving remain available, but clip substitution has no stable schema and remains intentionally unavailable in v0.3.0.

Tests failing on import — activate the venv and reinstall: pip install -e ".[dev]".


Planned Work

See ROADMAP.md for the full plan. Highlights:

  • MCP Prompts — shipped: qc-check, youtube-chapters, cleanup, rough-cut, beat-sync
  • Proxy/Resolve round-trip — proxy-aware offline/online workflows

Acknowledgments

fcp-mcp was co-developed by Adam Steen and Claude (Anthropic).

License

MIT — see LICENSE.

Source: README.md at commit 20ea2a3

Tools

0
SourceWeft has not started this package in its sandbox yet, so its tools are not known.

Version history

1
  1. v0.2.0LatestSep 16, 2026

Score

50% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts

    Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.

  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listed15 pts

    Answer tools/list without a credential, or ship a package that starts in a sandbox without one.

  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts