Add MCP Server for AI-Powered Final Cut Pro Automation#3514
Add MCP Server for AI-Powered Final Cut Pro Automation#3514elliotttate wants to merge 2 commits intoCommandPost:developfrom
Conversation
Adds a Model Context Protocol (MCP) server that exposes CommandPost's full automation capabilities to AI assistants like Claude. 76 tools covering timeline editing, effects, transitions, retiming, markers, keywords, generators, titles, import/export, and arbitrary Lua scripting. Key components: - MCP server (TypeScript/Node.js) communicating via WebSocket - Token-based authentication with auto-generated SHA-256 session tokens - Operation verification (before/after state, undo text, clip deltas) - Automatic FCP dialog detection and handling - Operation chaining with result passing between steps CommandPost changes: - WebSocket message handler: execute/batch message types, auth, audit log, plugin name-only matching for transitions - WebSocket manager: auth token generation, server-only mode - PrimaryToolbar: FCP v12 compatibility (direct checkbox matching) - Timeline/Contents: defensive nil handling, empty table returns - MediaImport: Go-to-folder path support - Menu finder: safe nil checks for pattern matching
|
Here's a video showing it performing different actions like responding to the request "Make a cut any time a scene change occurs on this clip": https://youtu.be/kAegHnTTVOk |
New fcp_scene_detect_and_cut tool that uses ffmpeg's scdet filter to detect scene changes in a video file, then blades the FCP timeline at all detected cut points in a single batch operation. Features: - Configurable sensitivity threshold and minimum gap between cuts - Dry run mode to preview detected cuts without blading - Auto-detects video frame rate for accurate timecode conversion - Per-cut status reporting for retry on failure - Uses Trim > Blade All menu for reliable batch cutting
|
Added an example of how you can do almost anything and a practical use case. I just told it to make cuts to all the scene changes in my clip. It used FFMPEG to detect them, then made cuts and then added an MCP tool to do this faster in the future. Video example: https://youtu.be/kAegHnTTVOk |
|
Well, this is pretty epic. THANK YOU! I'll try properly review today and watch all your videos. Curious why we need a Node server? Can't we just do the same thing in Lua? I believe we already have a pull request that does this? Will likely merge in and then address any issues. Stay tuned. |
|
Yeah, I would be interested in seeing if this could be reimplemented in Lua. I understand why: there are lots of Node MCP servers out there already, makes it easier to get it up and running. It’s a toss-up: building from scratch is also going to introduce bugs etc. |
|
Great work! |
Summary
This PR adds a Model Context Protocol (MCP) server to CommandPost, enabling AI assistants (such as Claude, ChatGPT, or any MCP-compatible client) to control Final Cut Pro and macOS workflows through CommandPost's existing automation infrastructure.
The server exposes 76 tools spanning timeline editing, effects, transitions, retiming, markers, keywords, generators, titles, import/export, color correction, and arbitrary Lua scripting — all accessible over a standard JSON-RPC protocol.
Architecture
How It Works
MCP Protocol Layer (
src/mcp-server/src/index.ts) — A Node.js server implementing the Model Context Protocol specification. It communicates with AI assistants via stdio using JSON-RPC, translating tool calls into CommandPost operations.WebSocket Transport (
src/mcp-server/src/commandpost.ts) — A WebSocket client that maintains a persistent connection to CommandPost's built-in WebSocket server. Handles message correlation via unique IDs, automatic reconnection, request timeouts, deduplication of broadcast responses, and back-pressure protection (max 100 pending requests).CommandPost WebSocket Server (
src/plugins/core/websocket/manager/) — Enhanced with new message types (execute,batch), token-based authentication, audit logging, and improved plugin matching. The server generates a SHA-256 session token on startup, writes it to a well-known file path, and validates every incoming message.Lua Execution Environment — Tool handlers generate Lua code that runs inside CommandPost's Hammerspoon environment with full access to
hs.*APIs,cp.*modules, Final Cut Pro's accessibility tree, and all registered CommandPost plugins.Authentication
The WebSocket connection uses shared-secret authentication:
~/Library/Application Support/CommandPost/mcp-auth-tokenwithchmod 600authfield; messages without valid tokens are rejectedCOMMANDPOST_AUTH_TOKENenvironment variableOperation Verification
Editing tools use a
withVerificationwrapper that captures timeline state before and after operations:{ "before": { "clipCount": 4, "timecode": "00:00:15:00" }, "after": { "clipCount": 5, "timecode": "00:00:15:00", "undoText": "Undo Blade", "clips": [...] }, "verified": { "undoText": "Undo Blade", "clipDelta": 1, "tcChanged": false } }Three verification signals confirm success:
undoText— FCP's own name for the last action (read via AX, not menu reads that steal focus)clipDelta— Change in clip count (+1 = added, -1 = removed)tcChanged— Whether the playhead movedFocus Management
FCP keyboard shortcuts require the app to be frontmost. The server:
activateFinalCutPro()before shortcut-based operationsgetMenuItems()to avoid stealing focus during verification{plain = true}on allselectMenucalls to prevent Lua pattern matching crashes from special characters in menu item namesDialog Handling
A
handleFCPDialoghelper automatically detects and handles FCP modal dialogs (e.g., "not enough extra media beyond clip edges" when applying transitions). It scans for AXSheets and AXModal windows, reads their text content, and clicks the appropriate button. This is integrated into bothwithVerificationand individual tool handlers.Complete Tools Reference (76 tools)
System & Connection (9 tools)
commandpost_pingcommandpost_list_handlerscommandpost_get_handler_infocommandpost_execute_luacommandpost_execute_actioncommandpost_chain_prevcommandpost_get_preferencecommandpost_set_preferencecommandpost_alertFinal Cut Pro — Application (6 tools)
fcp_launchfcp_quitfcp_restartfcp_statusfcp_select_menu["File", "Share", "Master File..."])fcp_do_shortcutFinal Cut Pro — Timeline (9 tools)
fcp_timeline_showfcp_timeline_playbackfcp_timeline_navigatefcp_timeline_selectall,none,at_playhead, orby_index(1-based, skips transitions)fcp_timeline_bladefcp_timeline_deletefcp_timeline_clipboardfcp_timeline_zoomfcp_timeline_get_infoFinal Cut Pro — Effects & Plugins (4 tools)
fcp_apply_effect"Blur/Gaussian","Stylize/Comic Book")fcp_apply_transition"Dissolves/Cross Dissolve") with automatic dialog handlingfcp_apply_generator"Solids/Custom","Backgrounds/Gradient")fcp_apply_title"Basic Title","Bumper/Opener/Basic Title")Final Cut Pro — Discovery (6 tools)
fcp_list_effectsfcp_list_audio_effectsfcp_list_transitionsfcp_list_generatorsfcp_list_titlesfcp_list_markersFinal Cut Pro — Browser & Libraries (3 tools)
fcp_browser_showfcp_browser_list_librariesfcp_browser_select_libraryFinal Cut Pro — Inspector & Viewer (2 tools)
fcp_inspector_showfcp_viewer_showFinal Cut Pro — Color (1 tool)
fcp_color_boardFinal Cut Pro — Export & Import (4 tools)
fcp_exportfcp_export_xmlfcp_import_mediafcp_import_xmlFinal Cut Pro — Projects & Playhead (5 tools)
fcp_open_projectfcp_project_propertiesfcp_get_playhead_positionfcp_set_playhead_positionfcp_get_project_settingsFinal Cut Pro — Markers & Keywords (2 tools)
fcp_add_markerfcp_add_keywordFinal Cut Pro — Clip Operations (10 tools)
fcp_rename_clipfcp_rate_clipfcp_get_selected_clipsfcp_get_clip_propertiesfcp_set_clip_propertiesfcp_duplicate_clipfcp_enable_disable_clipfcp_create_compound_clipfcp_create_auditionfcp_break_apart_compoundFinal Cut Pro — Speed & Retime (2 tools)
fcp_retimefcp_speed_customFinal Cut Pro — Advanced (9 tools)
fcp_split_at_timecodefcp_set_rangefcp_clear_rangefcp_captionsfcp_multicam_switch_anglefcp_assign_rolefcp_stabilizationfcp_proxy_togglefcp_batch_apply_transitionFinal Cut Pro — Window & Undo (3 tools)
fcp_window_layoutfcp_undo_redofcp_pasteboardFinal Cut Pro — Workflow (1 tool)
fcp_assemble_rough_cutFCP v12 Compatibility Fixes
This PR includes several fixes for Final Cut Pro v12 (12.0+):
PrimaryToolbar.lua
FCP v12 no longer wraps toolbar checkboxes in
AXGroupelements — they are now direct children of the toolbar. Updated all five checkbox properties (keywordEditor,backgroundTasksWindow,browserShowing,timelineShowing,inspectorShowing) to fall back to AXDescription-based matching when the legacy AXGroup wrapper is not found. Fully backwards-compatible with pre-v12.Menu Item Relocation
"Rename Clip" moved from the
Modifymenu to theClipmenu in FCP v12. The rename tool triesClip > Rename Clipfirst, falling back toModify > Rename Clip.Lua Pattern Safety
All
selectMenucalls now pass{plain = true}to disable Lua pattern matching. This prevents crashes when menu items contain special pattern characters like%(e.g., "Normal (100%)"),.,(, or).Plugin Name-Only Matching
findFCPXPluginBySimplifiedPathin the WebSocket message handler now supports name-only matching as a fallback. This allows matching"Cross Dissolve"without requiring the full"Dissolves/Cross Dissolve"path — important for transitions and other plugins that lack filesystem path metadata.Defensive Nil Handling
Contents:clipsUI()andContents:positionClipsUI()return empty tables{}instead ofnilto prevent downstream nil index errorsTimeline:isShowing()uses a safer prop composition:gsub()and:find()on potentially nil stringsFiles Changed
New Files
src/mcp-server/src/index.tssrc/mcp-server/src/commandpost.tssrc/mcp-server/README.mdsrc/mcp-server/package.json@modelcontextprotocol/sdk,wssrc/mcp-server/test.mjssrc/mcp-server/test-edit-workflow.mjssrc/mcp-server/test-edit-workflow-mini.mjssrc/mcp-server/test-edit-workflow-storm.mjs.mcp.jsonModified Files
src/plugins/core/websocket/manager/message-handler.luaexecute/batchmessage types, auth, audit logging, plugin matchingsrc/plugins/core/websocket/manager/init.luagetAuthTokenPath(), server-only modesrc/extensions/cp/apple/finalcutpro/main/PrimaryToolbar.luasrc/extensions/cp/apple/finalcutpro/import/MediaImport.luasetPath()andimportFiles()methods for programmatic media importsrc/extensions/cp/apple/finalcutpro/timeline/Contents.lua{}instead ofnilfrom clip query methodssrc/extensions/cp/apple/finalcutpro/timeline/Timeline.luaisShowingpropsrc/extensions/cp/apple/finalcutpro/menu.luaSetup
Test Plan