A small control surface that steers Final Cut Pro.
Ask for an edit in a sentence. Watch it land in seconds. Approve anything that cuts. Undo any of it.
A trim tab is the sliver of rudder that moves the whole rudder. Trimtab is that for Final Cut Pro: a dynamic library injected into a patched copy of the app, exposing its real editing engine over a local socket, with an assistant on top that works the way an editor does. You keep the helm. It does the reaching.
Trimtab builds on earlier MIT-licensed work for the engine and the plugin framework; its copyright notice is preserved in LICENSE. What sits on top is new, and it is built around one idea: assisted editing you can trust. Every action is visible, every action is reversible, the editor approves anything risky, and the assistant speaks the editor's own language: selection, markers, timecode.
Press ⌘⇧P inside Final Cut, type, press Return.
| You say | What happens | Measured |
|---|---|---|
| fade this text in and out | Opacity keyframes on the selected title, half a second each side. | 5.3 s, including the first launch of the session |
| make the fade a full second | The same keyframes, moved. | 2.8 s |
| what did you just change? | An answer from the edit log, not from memory. | 1.5 s |
| delete every clip shorter than a second | A proposal: one row per clip, Apply or Discard. Nothing is cut until you say so. | one keypress to apply |
| do my notes | Your to-do markers become edits, one per note, and the markers tick themselves off. | 4 edits applied in 0.3 s |
One request is one Cmd-Z. The panel shows each edit as it lands, with how long it took.
Preview before apply. Anything that deletes material, touches more than a few clips, or answers all or every comes back as a proposal. The panel lists the intended edits as rows under a one-line summary. Return applies them as a single undo step named in the Edit menu. Esc discards. The assistant asks before it cuts.
Do my notes. Editors leave to-do markers while watching: tighten this, fade the music here, retitle Chapter One. Trimtab reads each note as an instruction and the clip under it as the target, proposes the whole set at once, and completes the markers on apply. A note it cannot turn into a concrete edit is named in the answer, not guessed at.
An edit ledger. Every edit is logged per project: what was asked, what was done, the before and after. What did you change today? is answered from the record. One edit can be reverted on its own without unwinding the ones after it. The day's changes export as a note for a client or as markers on the timeline.
House style. Standing instructions per project, such as titles fade half a second or dialogue to −16 LUFS, that the assistant applies without being told. Say from now on… and it saves the rule. Say add a title and the fade is already there.
Every window Trimtab draws shares one visual language: charcoal surfaces over Final Cut's own chrome, a mono panel name beside the traffic lights, quiet bordered keys, and a single accent, Final Cut's selection yellow, reserved for the live thing: the selected clip, the running turn, the key that applies.
![]() |
![]() |
![]() |
![]() |
flowchart LR
subgraph FCP["Final Cut Pro (patched copy in ~/Applications/Trimtab)"]
direction TB
dylib["Trimtab.framework<br/>loaded by LC_LOAD_DYLIB"]
engine["Flexo · Ozone · TimelineKit · LunaKit<br/>78,000 classes, called directly"]
ask["Ask panel · Log · Transcript · Captions<br/>Mixer · Sections · Lua · Vision Pro"]
dylib --> engine
dylib --> ask
end
rpc["JSON-RPC on 127.0.0.1:9876<br/>250 methods, one call per edit"]
mcp["mcp/server.py<br/>MCP tools, batches, profiles"]
claude["Claude Code<br/>in the panel or in a terminal"]
you["you"]
dylib --- rpc
rpc --> mcp --> claude
you -->|⌘⇧P| ask
you -->|terminal| claude
Nothing simulates input. No AppleScript, no synthetic keystrokes, no accessibility clicking. Each verb is a direct call into Final Cut's editing engine, inside an undo group, and each edit returns a delta of what changed.
The Ask panel keeps one long-lived Claude Code process per project and feeds it the live timeline context on every turn, which is why a follow-up lands in under three seconds. The same tools serve any MCP client from a terminal.
Trimtab never modifies your Final Cut Pro. It makes a copy under ~/Applications/Trimtab/, injects the framework, re-signs the copy, and leaves the App Store app alone. Open the same library in either one.
Before you start. These are the things a fresh Mac needs, each once.
| macOS 14 or later and Final Cut Pro 11, the Trial, or Creator Studio, installed from the App Store. | |
Xcode command line tools (xcode-select --install). They provide the compiler, codesign, and the Swift toolchain the transcription helpers build with. |
|
Python 3.10 or newer for the MCP server. The Python that ships with the command line tools is 3.9 and is too old; brew install python@3.12 or python.org both work. make mcp-setup stops with a clear message if it finds only 3.9. |
|
Claude Code 2.1 or newer, signed in, for the Ask panel: install it from claude.com/claude-code, then run claude once in Terminal and log in. Without it the panel says so and offers nothing else; terminal MCP sessions and every other panel work regardless. |
|
Internet on first build: make fetches the Sentry framework once, and make transcribers resolves Swift packages. Transcription downloads its model on first use: about 600 MB for Parakeet, 800 MB to 1.5 GB for Whisper, into ~/Library/Application Support/FluidAudio and the helper's cache. |
|
Quit Final Cut Pro before make deploy; it replaces the framework inside the patched copy. |
git clone https://github.com/DrazanProjects/Trimtab.git
cd Trimtab
./patcher/patch_fcp.sh # copies, patches and signs Final Cut Pro
make mcp-setup # Python environment for the MCP server
make all && make deploy # builds Trimtab and installs it into the copy
make transcribers && make deploy # optional: on-device transcription and captions
./Scripts/launch.sh # starts the patched copypatch_fcp.sh finds whichever edition is installed. With more than one, TRIMTAB_EDITION=standard|trial|creator chooses. A GUI patcher lives in patcher/ and builds with Xcode.
Connect a terminal session. Copy .mcp.json.example to .mcp.json, fill in the two paths, and start Claude Code in the repository. The Ask panel needs no configuration.
{
"mcpServers": {
"trimtab": {
"command": "/Users/you/.venvs/trimtab-mcp/bin/python",
"args": ["/path/to/Trimtab/mcp/server.py"],
"env": { "TRIMTAB_MCP_PROFILE": "editing" }
}
}
}make mcp-doctor checks the environment, the config, and that the bridge is listening.
When something is missing, the panel says which step.
| The panel says | Do this |
|---|---|
| Claude Code is not installed… | Install Claude Code, run claude in Terminal once to sign in. |
| Not logged in · Please run /login | Run claude in Terminal and log in; the panel uses that login. |
| Claude Code exited (1): unknown option… | Your Claude Code is older than 2.1; run claude update. The panel already drops the one optional flag old builds reject. |
| The Trimtab MCP server has no Python environment | make mcp-setup in the checkout, with Python 3.10 or newer on your PATH. |
| Could not find mcp/server.py | make deploy in the checkout; it copies the server to ~/Applications/Trimtab/mcp. |
| … transcriber not found. Re-run the Trimtab patcher, or pick a different engine. | make transcribers && make deploy, or use the GUI patcher, which ships the helpers. |
| No project is open | Open a project in the timeline; the panel edits what Final Cut shows. |
Tool profiles. Every tool's schema rides along in the model's context, so the server exposes a focused set by default.
TRIMTAB_MCP_PROFILE |
Tools | For |
|---|---|---|
ask |
about 80 | the Ask panel |
editing (default) |
about 140 | a terminal editing session |
full |
about 250 | developing Trimtab: Vision Pro, immersive, LiveCam, dual timelines, FlexMusic, debug, runtime metadata |
Hidden tools stay reachable through raw_call and run_batch.
Editing verbs — one call each, addressed by clip:N, sel, or playhead
trim_clip · delete_clips · delete_range · blade_at_times · add_title · set_title_text · fade_clip · rename_clip · apply_effect · apply_transition · set_inspector_property · set_keyframes · set_clip_volumes · normalize_loudness · add_markers_at_times · timeline_action (every Final Cut menu verb) · run_batch (many calls, one undo step)
The assistant's memory
propose_edits · get_todo_markers · complete_markers · get_edit_ledger · revert_edit · export_edit_ledger · get_house_style · set_house_style
Panels and plug-ins
| Transcript editor | Transcribe the timeline, click a word to seek, delete words to cut, remove silences in one pass. |
| Captions | Styled social captions, word-by-word highlight, SRT and TXT export, native FCP captions. |
| Audio mixer | Twelve strips with faders, meters, solo, mute, bus effects; loudness measurement and normalisation. |
| Sections and structure | A section strip over the timeline; song structure and beat detection; cuts that land on beats; a song cut from a folder of clips. |
| Scene detection | Scene changes as markers or blades. |
| URL import and batch export | Pull media from a URL into the browser; export many projects at once. |
| BRAW, VP9, MKV | Native decode paths for formats Final Cut does not read. |
| Vision Pro and immersive | Preview immersive frames, send them to a headset, edit AIME metadata. |
| LiveCam, dual timelines, FlexMusic, montage | Camera in, two timelines side by side, adaptive music, automatic montage. |
| Lua REPL and in-process debugger | Live code inside Final Cut; trace methods, watch notifications, hot-load plug-ins. |
| OpenTimelineIO and FCPXML | Exchange in both directions; paste FCPXML straight into the timeline. |
- Reversible. Quit the patched copy, open the same library in the App Store app, keep editing. Nothing is migrated or locked.
- One Cmd-Z per request. Every request runs inside a named undo group.
undo_statusshows what Cmd-Z will do before you press it. - Proposals for the big ones. Deletions and wide changes wait for Apply.
- Crash reporting is off. Trimtab ships without a Sentry DSN. Set
TrimtabSentryDSNto point it at your own project if you want reports. - Legal. Reverse engineering for interoperability is protected in the US (DMCA §1201(f)) and the EU. Trimtab is MIT.
Final Cut updates can break the patch; re-patch and carry on.
The bridge is a JSON-RPC 2.0 server. Anything with a socket can drive it.
echo '{"jsonrpc":"2.0","method":"system.version","id":1}' | nc 127.0.0.1 9876- MCP tools in
mcp/server.py: add a function, register it in a profile, and every AI client sees it. - Bridge methods in
Sources/TrimtabServer.m: a handler, a table entry, a line of metadata. Selection-driven handlers gettarget=, playhead-relative ones getat=, for free. - Lua inside Final Cut: ⌃⌥L opens a REPL with an
skmodule; drop files into~/Library/Application Support/Trimtab/lua/auto/for live coding. - Native plug-ins in ObjC, Swift, or C++ link against
Trimtab.frameworkand hot-load withdebug.loadPlugin. - Panels adopt the shared look with one call,
Trimtab_adoptTheme, fromSources/TrimtabTheme.h.
| Read | For |
|---|---|
CLAUDE.md |
the one-page operating guide an agent gets on every turn |
docs/AGENT_REFERENCE.md |
every verb, debug key and workflow |
docs/FCP_API_REFERENCE.md |
Final Cut's internal classes and notifications |
docs/LUA_SDK_REFERENCE.md · docs/LUA_SCRIPTING_GUIDE.md |
the Lua SDK |
docs/RUNTIME_INTROSPECTION_GUIDE.md · docs/DEBUG_TOOLS_GUIDE.md |
exploring and debugging inside the process |
docs/MCP_IMPROVEMENTS.md |
the friction log behind each round of changes |
CHANGELOG.md |
what changed, and the inherited history before it |
Tests: python3 -m pytest tests/test_mcp_tool_annotations.py tests/test_mcp_profiles_and_params.py runs without Final Cut; python3 tests/test_mcp_endpoints.py runs against a live bridge.
Trimtab forked from an MIT-licensed project whose copyright notice is preserved in LICENSE. The proposal flow, notes, ledger, house style, the Ask panel, the shared theme, and the one-call verbs are Trimtab's. Everything is MIT.
Questions and bugs: GitHub Issues.






