fcpxml-mcp-server
FCPXML MCP
The bridge between Final Cut Pro and AI. 53 tools that turn timeline XML into structured data Claude can read, edit, and generate.
Why This Exists
After directing 350+ music videos (Chief Keef, Migos, Masicka), I noticed the same editing bottlenecks on every project: counting cuts manually, extracting chapter markers one by one, hunting flash frames by scrubbing, building rough cuts clip by clip.
These are batch operations that don't need visual feedback. Export the XML, let Claude handle the tedium, import the result. That's the entire philosophy.
Related MCP server: final-cut-pro-mcp
See It In Action
You: "Run a health check on my wedding edit"
Claude: ✓ Analyzed WeddingFinal.fcpxml
├─ 247 clips · 42:18 total · 24fps · 1920×1080
├─ 3 flash frames detected (clips 44, 112, 198)
├─ 2 unintentional gaps at 12:04 and 31:47
├─ 14 duplicate source clips
└─ Health score: 72/100
You: "Fix the flash frames and gaps, then add chapter markers from
this transcript"
Claude: ✓ Extended adjacent clips to cover 3 flash frames
✓ Filled 2 gaps by extending previous clips
✓ Added 18 chapter markers from transcript
→ Saved: WeddingFinal_modified.fcpxmlImport the modified XML back into Final Cut Pro. Every change is non-destructive — your original file is never touched.
What Claude Actually Sees
This is the magic trick. When you export XML from Final Cut Pro, your timeline becomes structured data that Claude can reason about:
<!-- What FCP exports -->
<asset-clip ref="r2" offset="342/24s" name="Interview_A"
start="120s" duration="720/24s" format="r1">
<marker start="48/24s" duration="1/24s" value="Key quote"/>
<keyword start="0s" duration="720/24s" value="Interview"/>
</asset-clip># What Claude works with (after parsing)
Clip(
name="Interview_A",
offset=TimeValue(342, 24), # timeline position: 14.25s
start=TimeValue(120, 1), # source in-point: 2:00
duration=TimeValue(720, 24), # 30 seconds
markers=[Marker(value="Key quote", start=TimeValue(48, 24))],
keywords=["Interview"]
)Every time value stays as a rational fraction — 720/24s, not 30.0 — so trim, split, and speed operations have zero rounding error across any frame rate. Comparisons use cross-multiplication (a/b < c/d → a*d < c*b) to stay in integer-land end to end. Denominators are always normalized to positive values at construction, so sign lives on the numerator and cross-multiplication is always correct. Addition and subtraction share a single _binop() code path that handles same-denominator fast paths and LCM alignment in one place.
How It Works
┌──────────┐ ┌──────────────────────────────┐ ┌──────────┐
│ Final Cut│ │ parser.py → Python objects │ │ Final Cut│
│ Pro │─XML─>│ writer.py → Modify & save │─XML─>│ Pro │
│ │ │ rough_cut.py→ Generate new │ │ │
└──────────┘ │ diff.py → Compare │ └──────────┘
│ export.py → Resolve / FCP7 │
└──────────────────────────────┘
▲
Claude Desktop / MCP clientExport from FCP —
File → Export XML...Ask Claude — analyze, edit, generate, QC, export
Import back —
File → Import → XML
What This Is NOT
Not a plugin — it doesn't run inside Final Cut Pro
Not real-time — you work with the XML between exports
Not for creative calls — color, framing, motion still need your eyes
Quick Start
1. Clone & Install
git clone https://github.com/DareDev256/fcp-mcp-server.git
cd fcp-mcp-server
pip install -e .2. Configure Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
Using uv (recommended):
{
"mcpServers": {
"fcpxml": {
"command": "uv",
"args": ["--directory", "/path/to/fcp-mcp-server", "run", "server.py"],
"env": { "FCP_PROJECTS_DIR": "/Users/you/Movies" }
}
}
}Using pip:
{
"mcpServers": {
"fcpxml": {
"command": "python",
"args": ["/path/to/fcp-mcp-server/server.py"],
"env": { "FCP_PROJECTS_DIR": "/Users/you/Movies" }
}
}
}3. Use It
Export XML from Final Cut Pro, open Claude Desktop, and ask it to work with your timeline.
When To Use This
Good For | Not Ideal For |
Batch marker insertion (100 chapters from a transcript) | Creative editing decisions (no visual feedback) |
QC before delivery (flash frames, gaps, duplicates) | Real-time adjustments (export/import cycle) |
Data extraction (EDL, CSV, chapter markers) | Fine-tuning cuts (faster directly in FCP) |
Template generation (rough cuts from tagged clips) | Anything visual (color, framing, motion) |
Automated assembly (montages from keywords + pacing) | |
Timeline health checks (validation, stats, scoring) |
Prompt Cookbook
Copy-paste these into Claude Desktop. Each one maps to a real tool chain under the hood.
Analysis
"Give me a full breakdown of ProjectX.fcpxml — clips, duration, frame rate, markers, everything"
"Show me pacing analysis for my timeline — where are the slow sections?"
"Export an EDL and CSV of all clips with timecodes"QC & Fixes
"Run a health check on my timeline and fix anything under 2 frames"
"Find all gaps and flash frames, then auto-fix them"
"Are there any duplicate source clips I can consolidate?"Markers & Chapters
"Add chapter markers from this transcript: [paste transcript]"
"Import markers from my-subtitles.srt onto the timeline"
"List all markers and export them as YouTube chapter timestamps"Generation
"Build a 60-second rough cut from clips tagged 'Interview' — medium pacing"
"Generate a montage from all B-roll clips with accelerating pacing"
"Create an A/B roll: Interview_A as primary, B-roll cuts every 8 seconds"Cross-NLE & Reformat
"Export this timeline for DaVinci Resolve"
"Convert to FCP7 XML so I can open it in Premiere"
"Reformat my 16:9 timeline to 9:16 for Instagram Reels"Under the Hood
When you say "Run a health check on my wedding edit", Claude chains these tools:
analyze_timeline → stats, frame rate, resolution
detect_flash_frames → clips under threshold duration
detect_gaps → unintentional silence/black
detect_duplicates → repeated source media
validate_timeline → structural health score (0-100)Each tool returns structured text that Claude synthesizes into the summary you see. No magic — just batch XML queries that would take 20 minutes by hand.
Pre-Built Prompts
Select these from Claude's prompt menu (⌘/) — they chain multiple tools automatically.
Prompt | What It Does |
qc-check | Full quality control — flash frames, gaps, duplicates, health score |
youtube-chapters | Extract chapter markers formatted for YouTube descriptions |
rough-cut | Guided rough cut — shows clips, suggests structure, generates |
timeline-summary | Quick overview — stats, pacing, keywords, markers, assessment |
cleanup | Find and auto-fix flash frames and gaps |
All 53 Tools
Category | Tools | What It Does |
Analysis | 11 | Stats, clips, markers, keywords, EDL/CSV, pacing |
Multi-Track | 3 | Connected clips, compound clips, secondary lanes |
Roles | 4 | List, assign, filter, export stems |
QC & Validation | 4 | Flash frames, duplicates, gaps, health score |
Editing | 9 | Markers, trim, reorder, transitions, speed, split |
Batch Fixes | 3 | Auto-fix flash frames, rapid trim, fill gaps |
Comparison | 1 | Diff two timelines — added/removed/moved/trimmed |
Reformat | 1 | Aspect ratio conversion (9:16, 1:1, 4:5, custom) |
Silence | 2 | Detect and remove silence candidates |
NLE Export | 2 | DaVinci Resolve v1.9, FCP7 XMEML v5 |
Generation | 3 | Rough cuts, montages, A/B roll |
Beat Sync | 2 | Import beat markers, snap cuts to beats |
Import | 2 | SRT/VTT subtitles, YouTube chapters → markers |
Audio | 1 | Add audio clips, music beds at any lane |
Compound | 2 | Create/flatten compound clips |
Templates | 2 | Pre-built timeline structures (intro/outro, lower thirds, music video) |
Effects | 1 | List FCP transition effects with UUIDs |
53 |
Analysis — 11 tools
list_projects · analyze_timeline · list_clips · list_library_clips · list_markers · find_short_cuts · find_long_clips · list_keywords · export_edl · export_csv · analyze_pacing
Multi-Track — 3 tools
list_connected_clips · add_connected_clip · list_compound_clips
Roles — 4 tools
list_roles · assign_role · filter_by_role · export_role_stems
QC & Validation — 4 tools
detect_flash_frames · detect_duplicates · detect_gaps · validate_timeline
Editing — 9 tools
add_marker · batch_add_markers · insert_clip · trim_clip · reorder_clips · add_transition · change_speed · delete_clips · split_clip
Batch Fixes — 3 tools
fix_flash_frames · rapid_trim · fill_gaps
Comparison · Reformat · Silence
diff_timelines · reformat_timeline · detect_silence_candidates · remove_silence_candidates
NLE Export — 2 tools
export_resolve_xml (DaVinci Resolve FCPXML v1.9) · export_fcp7_xml (Premiere Pro / Resolve / Avid XMEML v5)
Generation — 3 tools
auto_rough_cut · generate_montage · generate_ab_roll
Beat Sync — 2 tools
import_beat_markers · snap_to_beats
Import — 2 tools
import_srt_markers · import_transcript_markers (supports SMPTE HH:MM:SS:FF with frame-accurate placement)
v0.6.0 — Audio, Compound, Templates, Effects — 6 tools
list_effects · add_audio · create_compound_clip · flatten_compound_clip · list_templates · apply_template
Environment Variables
Variable | Required | Default | Description |
| No |
| Root directory for FCPXML file discovery via |
| No | — | Route LLM calls through any OpenAI-compatible proxy (LiteLLM, OpenRouter, Ollama, vLLM) |
Compatibility
Component | Supported Versions |
FCPXML format | v1.8 – v1.11 |
Final Cut Pro | 10.4+ |
Python | 3.10, 3.11, 3.12 |
MCP protocol | 1.0 |
Export targets | |
→ DaVinci Resolve | FCPXML v1.9 |
→ Premiere Pro / Avid | FCP7 XMEML v5 |
Architecture
fcp-mcp-server/ ~8.9k lines Python
├── server.py MCP entry point — 53 tools, 5 prompts, resource discovery
│ _resolve_io_paths() / _setup_modifier() / _setup_generator()
│ _format_clip_table() / _markdown_table() / _format_batch_result()
│ _raw_markers_to_batch()
│ _detect_flash_frames() / _detect_gaps() / _detect_duplicate_groups()
│ consolidate path validation, QC detection, rendering, handler boilerplate
├── fcpxml/
│ ├── README.md Developer guide — TimeValue, clip hierarchy, modifier patterns
│ ├── models.py TimeValue, Timecode, Clip, ConnectedClip, MarkerType, Timeline
│ ├── parser.py FCPXML → Python (spine, connected clips, roles, markers)
│ ├── writer.py Modify & write (markers, trim, gaps, transitions, silence)
│ │ FCPXMLModifier: index-based editing (clips/resources/formats dicts)
│ │ FCPXMLWriter: generate new FCPXML from Python objects
│ │ Helpers: _resolve_asset, _absorb_into_neighbor, _ripple_from_index
│ ├── rough_cut.py Generate timelines (rough cuts, montages, A/B roll)
│ ├── diff.py Timeline comparison engine (identity matching, threshold docs)
│ ├── export.py DaVinci Resolve v1.9 + FCP7 XMEML v5 export
│ ├── safe_xml.py Centralized defusedxml wrappers (XXE/entity-bomb protection) + serialize_xml()
│ └── templates.py Template system (intro/outro, lower thirds, music video)
├── tests/ 912 tests across 18 suites
│ ├── test_models.py TimeValue math, Timecode formatting, MarkerType contracts
│ ├── test_parser.py FCPXML parsing, connected clips, edge cases
│ ├── test_writer.py Clip editing, marker writing, speed changes
│ ├── test_fcpxml_writer.py FCPXMLWriter generation from Python objects
│ ├── test_server.py MCP tool handlers, dispatch, path validation
│ ├── test_rough_cut.py Rough cut generation, montage, A/B roll
│ ├── test_diff.py Moved clips, transitions, markers, clip identity
│ ├── test_export.py Attribute stripping, compound flattening, audio tracks
│ ├── test_features_v05.py Multi-track, roles, diff, reformat, export
│ ├── test_features_v06.py Audio, compound clips, templates, effects, validation
│ ├── test_marker_pipeline.py Marker builder, batch modes, output format
│ ├── test_speed_cutting.py Speed cutting, montage config, pacing curves
│ ├── test_security.py Input validation, XML sanitization, XXE protection
│ ├── test_edge_cases.py Boundary arithmetic, clip collisions, split/diff edges
│ ├── test_diversity.py Boundary conditions across diff, models, validation
│ ├── test_refactored_helpers.py _index_elements, _iter_spine_clips, serialize_xml edges
│ └── test_targeted_gaps.py Targeted branch coverage for diff, export, models
├── docs/
│ └── WORKFLOWS.md 8 production workflow recipes
└── examples/
└── sample.fcpxml 9 clips, 24fps — test fixtureSecurity
Every tool handler is hardened against adversarial input — critical for MCP servers where prompts may be LLM-generated, not human-typed.
Layer | Protection |
File I/O | Path traversal blocked, null bytes rejected, symlinks resolved, 100 MB size limit |
Output sandbox | All generation, write, export, beat sync, subtitle, and reformat handlers enforce |
Subprocess bounds |
|
Speed validation |
|
Directory listing | Confined to |
XML parsing |
|
JSON depth limit | Iterative BFS depth checker rejects payloads nested beyond 50 levels — immune to RecursionError even at ~1000 nesting |
Batch limits | Marker batch operations capped at 10,000 entries — prevents memory exhaustion from adversarial payloads with millions of markers |
Inline text limits | Inline transcript arguments capped at ~1 MB — file-based inputs go through |
Symlink filtering |
|
Marker strings | Sanitized via |
Role values | Stripped of control characters before XML attribute assignment |
URI parsing | MCP resource URIs parsed via |
Output suffixes | Path separators and special characters stripped — no traversal via suffix injection |
Marker types |
|
132 security-specific tests across test_security.py covering XXE, path traversal, sandbox boundaries, output path anchoring, input validation, subprocess bounds, minidom hardening, JSON depth limits, role sanitization, ffmpeg parameter bounds, symlink filtering, file count caps, and write-handler sandbox enforcement. Ruff S (bandit) rules enforced in CI — S314/S320 block unsafe XML parsing, S105 catches hardcoded passwords, S108 flags insecure temp paths. Security events (null bytes, sandbox escapes, unhandled exceptions) are logged via Python logging for audit trails.
Timestamp Parsing — How Import Tools Place Markers
All subtitle and transcript import tools (import_srt_markers, import_transcript_markers) funnel through a single internal function: _parse_timestamp_parts() in server.py. Understanding it matters when timestamps don't land where you expect.
Supported Formats
Format | Example | Parts | Result |
Minutes:Seconds |
| 2 | 90.0s |
H:MM:SS |
| 3 | 3930.0s |
HH:MM:SS.ms |
| 3 | 135.5s |
SMPTE (HH:MM:SS:FF) |
| 4 | 3610.5s @ 24fps |
The SMPTE 4-part format converts the frame component to fractional seconds: frames / frame_rate. The default rate is 24fps — pass frame_rate= to override for 25fps (PAL) or 30fps (NTSC) projects.
The Import Pipeline
SRT / VTT / YouTube chapters / plain transcript
│
▼
parse_srt() / parse_vtt() / parse_transcript_timestamps()
│ │ │
└────────────────┴──────────────────────┘
│
split on ':'
│
▼
_parse_timestamp_parts(parts, frame_rate=24.0)
│
▼
total seconds (float)
│
▼
marker placed on timelineEdge Cases
Unrecognized part counts (1 part, 5+ parts) return
None— the marker is silently skipped, not placed incorrectlyZero frame rate — falls back to base seconds (frames ignored) rather than dividing by zero
Milliseconds — only carried in 3-part format via
float()on the seconds component ("15.500"→15.5)Frame rounding — SMPTE frames are divided exactly (
12/24 = 0.5), not rounded to the nearest frame boundary. The resulting float is converted to FCPXML's rationalTimeValuedownstream, preserving precision
Why This Matters
Before v0.6.20, the 4-part SMPTE parser silently dropped frames — 01:00:10:12 became 3610.0s instead of 3610.5s. At 24fps, that's up to ~0.96 seconds of drift per marker. If you imported a subtitle file with SMPTE timecodes, every marker was slightly off. This was subtle enough to pass QC but visible when scrubbing.
Design Principles
Principle | Implementation |
Rational time, never floats | All durations are fractions ( |
Non-destructive by default | Modified files get |
Single source of truth |
|
Security-first | 10-layer defense-in-depth across all 53 handlers — see Security for the full matrix |
Dispatch, not conditionals |
|
Documentation
Guide | What's Inside |
8 production recipes — QC pipelines, beat-synced assembly, cross-NLE handoffs, documentary A/B roll | |
How this server composes with GitNexus, filesystem, and memory MCP servers | |
Full version history from v0.1.0 to present |
Testing
uv run --extra dev pytest tests/ -v # or: python3 -m pytest tests/ -v
ruff check . --exclude docs/ # lint — must pass before committing795 tests across 17 suites covering models, parser, writer, FCPXMLWriter generation, server handlers, rough cut generation, speed cutting & pacing curves, marker pipeline, refactored helper functions (_index_elements, _iter_spine_clips, _find_spine_clip_at_seconds, _require_clip, _require_spine_clip, _resolve_asset, serialize_xml), recent fix regressions (rapid_trim directions, min_duration, offset recalculation, interval timing accuracy, gap skipping, duplicate-name clip operations across trim/speed/split/delete/markers), security hardening (XXE, entity expansion, path traversal, sandbox boundaries, minidom defense-in-depth, JSON depth limits, input validation, ffmpeg bounds, write-handler sandboxing), connected clips, roles, diff, export, compound clip flattening, audio track generation, templates, effects, boundary conditions, and backward compatibility.
Requirements
Python 3.10+ · Final Cut Pro 10.4+ (FCPXML 1.8+) · Claude Desktop or any MCP client
Dependencies (auto-installed):
mcp,defusedxmlSee Compatibility for full version matrix
Roadmap
Core FCPXML parsing (v1.8–1.11)
Timeline analysis, markers, EDL/CSV export
Clip editing (trim, reorder, split, speed, transitions)
QC tools (flash frames, gaps, duplicates, health scoring)
Generation (rough cuts, montages, A/B roll, beat sync)
MCP Prompts + Resources (auto-discovery)
Subtitle & transcript import as markers
Multi-track (connected clips, compound clips, roles)
Timeline diff + social media reformat
Silence detection & cleanup
Cross-NLE export (DaVinci Resolve, Premiere Pro, Avid)
Audio sync detection
Premiere Pro native XML support
Known Issues
Issue | Impact | Workaround |
Still images crash FCP | PNG/JPEG assets referenced directly in FCPXML crash Final Cut Pro on import ( | Convert stills to short MOVs before referencing: |
Non-standard timebases | FCP rejects time values with denominators outside its standard set (e.g. | Fixed in v0.5.29 — TimeValue arithmetic now uses LCM, and speed changes snap to frame boundaries in 2400-tick timebase. |
Malformed frameDuration crash | A | Fixed in v0.6.23 — writer now validates both numerator and denominator, falling back to 30.0 fps. |
Duplicate clip names corrupt edits | When multiple spine clips share the same name (e.g. | Fixed in v0.6.37–0.6.39 — all methods now resolve clips via |
Contributing
PRs welcome. If you're a video editor who codes (or a coder who edits), let's build this together.
Credits
Built by @DareDev256 — former music video director (350+ videos), now building AI tools for creators.
License
MIT — see LICENSE.
Available Tools
15 toolsdeliverA
Get the edit out: export to other NLEs, CSV, EDL and stems, reformat, relink media, or push straight into a running Final Cut Pro. Exports and push refuse a cut with no rendered preview of its current state (pass confirm_unreviewed=true to ship anyway). Actions: export_csv, export_edl, export_fcp7_xml, export_resolve_xml, export_role_stems, reformat_timeline, relink_media, push_to_fcp, list_fcp_libraries.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations the description carries the burden and does well: it discloses the unreviewed-cut refusal, the confirm_unreviewed override, and that filepath actions refuse if the file no longer matches expected_sha256. It omits auth/permission needs and whether reformat/relink mutate or destroy source media.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with scope and guardrails, each earning its place. The trailing action list partly repeats the enum, which is the only real redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a nine-action dispatcher with no annotations and no output schema, the description covers the key precondition and the sha256 safety net. It stops short of describing where exports land or what stems/reformat produce, which an agent would still have to discover.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the args object already documents filepath, expected_sha256, and sha256 reporting; the description's action enumeration duplicates the enum. Baseline 3 is correct since the schema does the heavy lifting, though the sha256 guard is echoed usefully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a concrete domain (getting an edit out: export, reformat, relink, push) and enumerates the nine actions it dispatches, so an agent can tell it apart from edit/preview siblings. It is clear but the umbrella verb 'deliver' only becomes precise via the action list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a real usage rule: exports and push_to_fcp refuse a cut with no rendered preview of its current state, with the confirm_unreviewed=true escape hatch. It does not contrast when to use export_* versus preview or edit, so routing among siblings is left partly implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagnoseA
Find problems in a timeline: gaps, flash frames, duplicates, dead air, and beat structure. Read-only. Run before editing. Actions: validate_timeline, detect_gaps, detect_duplicates, detect_flash_frames, detect_silence_candidates, detect_media_silence, detect_beats, find_short_cuts, find_long_clips, diff_timelines.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the whole burden; it does disclose the important trait "Read-only", which prevents an agent from fearing mutation. However, it says nothing about cost/latency across the ten actions, whether results are exhaustive, or what a "problem" result looks like, and the expected_sha256 refusal semantics live only in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and tight: purpose, safety trait, and timing rule come first, and the action list is a useful index. The action list is partially redundant with the enum already present in the schema, which keeps it out of 5 territory.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a ten-action, nested-args tool with no output schema, the description omits what a caller receives back (findings format, severity, counts), which is the main gap it should have closed. Purpose and safety are covered adequately, so it is minimally complete but not rich.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the enum values and the args/expected_sha256 contract are already fully documented. The description's action list merely restates the enum rather than adding per-action argument meaning, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb+resource ("Find problems in a timeline") and enumerates the specific problem classes it looks for (gaps, flash frames, duplicates, dead air, beats), which is far more informative than the bare name. It stops short of the 5 because it never contrasts itself with plausible siblings like inspect or find, so an agent must infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Run before editing" gives a clear lifecycle position for the tool, which is genuine usage guidance. There are no exclusions or named alternatives (e.g., when to use diagnose vs inspect), so it lands at a solid 4 rather than 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
editB
Change clips on the timeline: insert, delete, trim, split, reorder, retime, remove silence, and attach audio, B-roll or transitions. Writes a new file. Actions: insert_clip, delete_clips, trim_clip, split_clip, reorder_clips, change_speed, rapid_trim, add_transition, add_audio, add_connected_clip, assign_role, fill_gaps, fix_flash_frames, remove_silence_candidates, remove_media_silence, set_keyframes, delete_keyframes, batch_keyframes, set_animation_curve, set_speed_curve, reset_speed.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses that the tool 'Writes a new file', implying the source is not mutated in place, which is the single most important behavioral trait for a write tool. It says nothing about failure/refusal behavior, overwrite safety, ripple side effects, or that actions differ widely in destructiveness, so the disclosure is partial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first clause and the write behavior is stated early, before the enumeration. The 21-item action list is long and duplicates the schema enum, but for a mega-tool that breadth is defensible for agent routing, so it stays tight overall.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a 21-action, deep-nested, no-output-schema tool where the description covers only the umbrella purpose and the action roster. The rich schema compensates for parameter detail, but cross-action context (which actions produce new files vs modify in place, typical sequencing, expected results) is left entirely unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema is unusually rich, including per-action conditionals and detailed field docs, so the baseline is 3. The description's action enumeration merely restates the schema enum and adds no parameter meaning beyond what the schema already carries.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Change clips on the timeline') and enumerates the operation categories plus every action name, so an agent can tell this is the mutation umbrella tool. It does not explicitly contrast with siblings like organize or generate, which could plausibly also alter a project, so it stops short of 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use / when-not-to-use guidance, no prerequisite sequencing (e.g. that clip_path must come from a prior inspect.list_keyframes call, which only surfaces in the schema), and no routing between the 21 actions. 'Writes a new file' is a behavioral fact, not usage guidance, so an agent gets little help choosing this tool over its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
findA
Natural-language shot search. find_shots (filepath, query, limit=10, visual=false, clip_name?) ranks moments by what was said (transcript), what was logged (names, keywords, notes, markers, audio events) and, when a local vision model is installed, what the frames look like — the first line of every result names which tiers answered and why one could not. find_index (captions=true, backend) warms scenes and captions and reports which clips have no transcript (it never transcribes or goes online). find_to_timeline (min_source_separation=1, output_path?) assembles the hits into a _found selects reel and reports its diversity score. Actions: find_index, find_shots, find_to_timeline.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers: the ranking tiers used, the fact that the first result line explains which tiers answered and which could not, find_index's hard boundary (no transcription, no network), the diversity score returned by find_to_timeline, and the expected_sha256 refuse-on-mismatch guard on filepath actions. It stops short of naming permission or write side effects beyond the reel.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The block is dense but every sentence carries information, and it is front-loaded with the core purpose. The trailing 'Actions: find_index, find_shots, find_to_timeline.' merely restates the schema enum, and the single-paragraph form makes three distinct operations harder to scan than bullets would.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a high-complexity dispatcher with three sub-operations, nested args, and no output schema or annotations, the description covers each action's parameters and observable behavior well. Remaining gaps are minor: return shapes are not described (acceptable given no output schema) and find_shots' write side effects on filepath inputs are only implied.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema's args object is free-form, so the description is the only place that enumerates the real per-action parameters and defaults (limit=10, visual=false, clip_name?, captions=true, backend, min_source_separation=1, output_path?) and defines expected_sha256's semantics. This adds substantial meaning the schema cannot provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Each action is given a concrete verb+resource: find_shots is 'natural-language shot search', find_index 'warms scenes and captions', find_to_timeline 'assembles the hits into a _found selects reel'. An agent can tell the three operations apart. It never contrasts itself with siblings like index, transcript, or scenes, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a workflow (index warms caches, shots searches, to_timeline builds a reel) and notes that find_index 'never transcribes or goes online', which constrains when it is useful. But there is no explicit 'use X when Y' or stated exclusion relative to the sibling tools; usage must be inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
genA
Generative fill, quote-then-confirm. gen_quote(provider, seconds, prompt, model?) prices a job from a dated table (fal: kling-2.5, wan-2.5; gemini: veo-3.1; runway/luma are honest stubs) and returns a quote id. gen_fill_gap(filepath, prompt, gap_index|at), gen_broll(filepath, clip_name, prompt, seconds=5, at?) and gen_extend_clip(filepath, clip_name, seconds=5) REFUSE without quote_id + confirm=true, a matching job, a key in the environment (FAL_KEY / GEMINI_API_KEY) and a price under FCP_MCP_GEN_MAX_USD (default 5). The result is probed with ffprobe for its real fps and length, saved under generated/ next to the project, attached as a connected clip with role generated and a marker naming prompt and provider, DTD-validated and journaled. Actions: gen_quote, gen_fill_gap, gen_broll, gen_extend_clip.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so richly: it names the required environment keys (FAL_KEY / GEMINI_API_KEY), the hard price ceiling FCP_MCP_GEN_MAX_USD (default 5), the exact refusal conditions, and post-execution side effects (ffprobe verification, output saved under generated/, clip attached with role `generated`, marker, DTD validation, journaling). This is far beyond what structured fields provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a dense single paragraph, but it is front-loaded (capability and quote-then-confirm model first, side effects after) and nearly every clause conveys actionable information. Slight deduction for run-on density that makes the per-action parameter lists harder to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-action tool with no output schema, the description covers the quote return (a quote id), the execution side effects, and the safety gates needed to invoke it correctly. It never states the shape of the fill-result response, but the described attach/journal behavior gives an agent enough to proceed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema only defines a generic `args` object, so the description does real work by spelling out per-action arguments and signatures — provider, seconds, prompt, model?, filepath, clip_name, gap_index|at — plus defaults like seconds=5. The only gap is that it omits expected_sha256, which the schema documents instead.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a concrete capability family (generative fill: quoting, gap fill, b-roll, clip extension) and enumerates the four actions, so an agent knows exactly what it does. It falls short of a 5 because the tool name 'gen' is opaque and the description never distinguishes it from the similarly named sibling 'generate', leaving a real risk of picking the wrong tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The quote-then-confirm workflow is spelled out as a precondition: gen_quote must run first to obtain a quote id, and the fill actions refuse without quote_id + confirm=true. What's missing is guidance on choosing among the fill actions themselves (gap_index vs clip_name vs at) and any explicit contrast with the 'generate' sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generateB
Build new timeline structure from source clips: rough cuts, montages, A/B roll, templates and compound clips. Actions: auto_rough_cut, generate_ab_roll, generate_montage, apply_template, create_compound_clip, flatten_compound_clip, import_edl_json.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden. It says structures are 'built' from source clips, hinting at creation, but does not state that this writes/modifies project files, what happens to existing timeline content, whether flatten_compound_clip is destructive, or what permissions are required. The sha256 guard and filepath handling live in the schema, not here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the purpose before the action list; there is no filler. The action enumeration is slightly redundant with the enum but is useful for quick scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Seven distinct operations share a single free-form args object with no output schema, yet the description gives no per-action argument requirements — an agent must infer what auto_rough_cut versus import_edl_json needs. Naming the actions is a start, but for this complexity the definition is only minimally adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the args object already documents the filepath/expected_sha256 pattern, so the baseline is 3. The description's action list merely restates the enum values already in the schema, adding no per-action argument meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: 'Build new timeline structure from source clips,' then enumerates the capabilities (rough cuts, montages, A/B roll, templates, compound clips). This distinguishes it reasonably from siblings like edit or inspect, though it never names a sibling or explicitly draws the line between generating new structures and editing existing ones.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the seven listed actions tell the agent what kinds of operations exist, but there is no statement of when to choose generate over edit, or when one action is preferable to another (e.g. auto_rough_cut vs generate_montage). No exclusions, prerequisites, or sequencing guidance are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
indexA
The analysis cache under ~/.fcp-mcp/index.db. index_status shows what is cached and how old it is; index_build warms it for every source in a timeline (args: filepath, with_transcript); index_clear drops it. Every other tool works with the index off (FCP_MCP_INDEX=off) — this only makes the second question fast. Actions: index_status, index_build, index_clear.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose persistence location, the environment flag that bypasses it, and that index_clear destroys cached data. It stops short of describing build cost, permissions, or concurrency behavior, but the safety-relevant traits (opt-in, destructive clear) are present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense paragraph that front-loads the resource definition and then maps each action to its effect. Nearly every clause earns its place, though the trailing action list slightly duplicates the schema enum.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a multiplexed cache tool with no output schema, the description covers what the cache is, where it lives, each action's effect, and its optionality. It does not sketch the shape of index_status output beyond 'what is cached and how old it is,' which is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema baseline is 3, but the description adds meaning the schema lacks by naming the per-action args (filepath, with_transcript) and tying index_build to a timeline source. This goes beyond restating the generic action/args structure.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens by naming the resource concretely (the analysis cache at ~/.fcp-mcp/index.db) and enumerates the three sub-actions the tool dispatches. It distinguishes itself from siblings by stating that every other tool works with the index off, though the top-level verb 'index' alone would not convey this.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Each action is paired with its role: index_status reports cache contents/age, index_build warms it for every source in a timeline, index_clear drops it. It also gives an explicit when-not by noting the index is optional (FCP_MCP_INDEX=off) and that it only speeds up the second question, which tells the agent not to treat this as mandatory.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspectB
Read a timeline or project without changing it. Use this first to understand what you are working with. Actions: list_projects, analyze_timeline, analyze_pacing, list_clips, list_markers, list_roles, list_keywords, list_effects, list_templates, list_library_clips, list_compound_clips, list_connected_clips, filter_by_role, list_keyframes, list_speed_points.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does disclose the most important trait: this is a non-mutating read operation. It says nothing about permissions, supported input formats beyond the schema's own field notes, or failure modes for missing/corrupt files, so the reporting is only partial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences followed by a flat action list, with the read-only constraint and the 'use first' directive front-loaded before the enumeration. The list is long but functional; no sentence is filler, though the trailing list lacks any grouping or ordering rationale.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 15-action dispatcher with no annotations and no output schema, the description covers the essentials (read-only, when to reach for it, available operations) but not the payoff: it never indicates what any action returns, nor references the expected_sha256 staleness check that guards against acting on an outdated file.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so filepath, clip_path, args, and the expected_sha256 guard are already documented in the schema, including the versioning safeguard. The description adds nothing about parameter meaning beyond restating the action names, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Read a timeline or project') and adds the key scoping constraint 'without changing it', which cleanly separates it from mutating siblings like edit, mark, generate, and deliver. It enumerates all 15 actions, though it does not explain what each action does, so an agent still has to infer what analyze_pacing vs. analyze_timeline return.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use this first to understand what you are working with' gives a clear sequencing heuristic for entering an unfamiliar file. However, it names no alternative (find, view, scenes, transcript) and gives no guidance on when NOT to use it or how to choose among the 15 listed actions, leaving the hardest selection decision to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
markB
Add or import markers and chapters, including from SRT/VTT subtitles, transcripts, and beat analysis. Actions: add_marker, batch_add_markers, import_srt_markers, import_transcript_markers, import_beat_markers, snap_to_beats.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It implies mutation ('add', 'import') but says nothing about side effects, whether changes are reversible, what file is modified, or permission requirements. The only behavioral detail (sha256 refusal) lives in the schema's args description, not here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences with the capability front-loaded and the action list trailing as supporting detail. No filler, though the action enumeration duplicates the schema enum.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a multi-action tool with a nested free-form args object and no output schema, the description covers the broad purpose but leaves each action's required arguments to inference. It is minimally viable rather than complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters (action enum, args object) are documented in the schema, so the baseline is 3. The description only restates the action values already enumerated in the schema and adds no per-action argument semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Add or import markers and chapters') and enumerates the concrete actions the tool performs, so an agent knows exactly what domain it covers. It doesn't explicitly contrast with siblings like edit or organize, which are generic names, but the marker/chapter scope is distinctive enough.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The action list implies when each operation applies (e.g., import_srt_markers for subtitle files, import_beat_markers for beat analysis), but there is no explicit statement of when to choose this tool over edit or organize, nor any prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
organizeA
Bulk library logging and the ledger. organize_auto proposes keywords per clip from cached captions and the transcript (apply=true writes them). Select clips with clip_name (glob), keyword and/or role, then organize_keywords (keywords, mode add|remove|replace), organize_rate (rating favorite|rejected|clear) or organize_roles (audio_role, video_role); each writes a _organized copy. history lists every recorded operation for the file's folder (limit); undo (n) moves the outputs of the last n writes into the journal's undone/ folder — it never deletes and refuses when a file changed since it was written. Actions: organize_auto, organize_keywords, organize_rate, organize_roles, history, undo.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and largely succeeds: it discloses that apply=true actually writes, that each action produces a _organized copy rather than mutating in place, that undo moves outputs to a journal undone/ folder and never deletes, and that writes are refused when a file changed since it was written. These guard rails and side-effect semantics are exactly what an agent needs to call a write tool safely.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Content is front-loaded and dense with no filler prose. The trailing 'Actions: ...' sentence merely restates the action enum already present in the schema, which is a small redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-action multiplexer with a nested args object and no output schema, the description covers the write/copy semantics, selection criteria, ledger behavior, and undo guard conditions well. It does not characterize the shape of returned data (e.g., what organize_auto proposes or what history emits), leaving a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the schema's args is an opaque nested object; the description compensates by naming the real inner arguments (clip_name glob, keyword, role, mode add|remove|replace, rating favorite|rejected|clear, audio_role, video_role, limit, n). This adds meaningful semantics beyond the structured fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a concrete function (bulk library logging/ledger) and enumerates the six operations the multiplexer exposes (organize_auto, organize_keywords, organize_rate, organize_roles, history, undo), so an agent can tell what each action does. It stops short of differentiating the tool from siblings like mark, edit, or inspect, which could plausibly overlap with rating/keyword work.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear workflow: select clips with clip_name (glob), keyword and/or role, then dispatch to organize_keywords, organize_rate, or organize_roles, and it explains organize_auto's caption/transcript source. It never states when to prefer a sibling tool or when not to use this one, so context is clear but exclusions are absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
previewB
See the edit without opening Final Cut Pro. Render a proxy video of the timeline, a contact sheet of every cut, a single frame, or a filmstrip-plus-waveform check read from the SOURCE MEDIA rather than from the XML. Run preview_check to confirm a fix actually landed. Actions: preview_render, preview_sheet, preview_frame, preview_check, preview_timeline.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations the description carries the full burden, and it does disclose one important trait: output is read from SOURCE MEDIA rather than the XML. However it says nothing about permissions, cost of rendering proxies, output formats, or how the read-only/mutating nature of the actions varies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the value proposition ('See the edit without opening Final Cut Pro') and packs the action list into a single trailing sentence. Slightly dense given five actions are named, but no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a five-way dispatcher with no output schema and no annotations, the description covers the broad purpose and one action's usage, but leaves the distinct inputs and outputs of preview_render, preview_sheet, preview_frame, and preview_timeline unspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema itself documents 'action' and the 'args' object including the expected_sha256 guard, so the description does not need to explain parameters. It repeats the enum values already listed in the schema, adding no meaning beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb and resource ('render a proxy video of the timeline, a contact sheet, a single frame...') and enumerates all five dispatched actions. It distinguishes itself from the editing siblings by being the no-FCP viewing path, though it never explicitly contrasts itself with 'view' or 'inspect'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides one concrete routing rule ('Run preview_check to confirm a fix actually landed'), which is genuinely useful, but gives no when-to-use guidance for the other four actions nor any guidance on when to prefer this over 'view', 'inspect', or 'scenes'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scenesA
Shot boundaries. detect_scenes reads every source in a timeline and reports cuts in timeline time (args: filepath, clip_name?, backend auto|content|adaptive|ffmpeg, threshold?, min_scene_len=0.5); scenes_to_markers writes a marker at each cut; scenes_split cuts the clips there. PySceneDetect via the scenes extra, ffmpeg without it — the result names which one answered. Actions: detect_scenes, scenes_to_markers, scenes_split.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose real behavior: scenes_to_markers writes markers, scenes_split actually cuts clips (a mutation), and the runtime dependency determines whether PySceneDetect or ffmpeg answers, with the result naming the backend. It stops short of saying whether the split is destructive to source files, whether it is reversible, or what permissions/backups are needed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the resource, then packed with action semantics and defaults in a couple of dense sentences; nothing is padding. The telegraphic fragments ('ffmpeg without it — the result names which one answered') are terse but still parseable, at a slight cost to readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by stating that detect_scenes reports cuts in timeline time and that results name the answering backend. Combined with the three action descriptions and the arg defaults, an agent has enough to invoke it correctly; the main missing piece is the destructive/reversibility profile of scenes_split.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only exposes a generic 'args' object plus a bare action enum, so the description is doing the real work: it enumerates filepath, optional clip_name, backend with its auto|content|adaptive|ffmpeg values, threshold, and the min_scene_len=0.5 default. That is genuine added meaning over the schema, though it does not explain how threshold interacts with the backend choice.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a precise resource statement ('Shot boundaries') and then names all three sub-actions with a specific verb+object for each: detect_scenes reads sources and reports cuts, scenes_to_markers writes a marker per cut, scenes_split cuts the clips. The three internal operations are mutually distinguished, and no sibling tool (inspect, edit, mark, transcript, etc.) overlaps this resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a workflow ordering — detect_scenes produces the cuts, the other two consume them — and notes which backend (PySceneDetect vs plain ffmpeg) will answer. However it never states when to prefer detect_scenes alone versus chaining to markers or split, nor any exclusion or prerequisite, so action selection is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
transcriptB
Transcribe source media locally and edit the timeline by what was SAID rather than by timecode. Also removes filler words. Actions: transcribe_media, edit_by_transcript, remove_filler_words, transcript_pack.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses that transcription is 'local' and that filler words are removed, but says nothing about whether actions write files, what gets overwritten, or the sha256 refusal guard documented only in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, with the core purpose front-loaded before the action enumeration. No filler, though the action list partially duplicates the enum rather than adding information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A four-action tool with a nested, generic args object and no output schema needs per-action intent, sequencing, and write-behavior notes; the description provides none of these. An agent cannot tell what each action consumes or returns from the description alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the args object is self-documented, so the baseline is 3. The description's action list merely mirrors the enum and adds no per-action argument meaning beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb+resource ('Transcribe source media locally and edit the timeline') and contrasts the editing paradigm against the sibling 'edit' tool by timecode. The four action names are enumerated, but the overall umbrella purpose of a multi-action tool is only loosely bounded.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The action list implies usage but never states when to pick transcribe_media vs edit_by_transcript vs transcript_pack, nor the ordering between them. No exclusions or alternative tools are named, so the agent must infer the workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
viewA
See the cut inline. view_timeline(filepath, thumbnails=true, words=true) returns the timeline — lanes, clips, markers, gaps, cached transcript words and filmstrip thumbnails — as an exact rational-time JSON payload that hosts with MCP Apps render as an interactive timeline (clip details, range selection, inspect / find-similar / marker / delete buttons that call the other tools). view_clip(filepath, clip_name) is the inspect button. Read-only; edits go through edit and mark. Actions: view_timeline, view_clip.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it explicitly declares read-only semantics, describes the interactive MCP Apps rendering and the buttons that call other tools, and names the sha256 refusal behavior (via the schema). It omits any auth/permission or rate-limit notes, so it falls short of exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, no filler — the return payload is front-loaded and the routing note trails. The opening 'See the cut inline' is idiomatic and slightly opaque, but the specifics immediately follow and every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must explain returns, and it describes view_timeline's payload thoroughly plus the UI affordances. It does not describe what view_clip returns and says nothing about pagination or size limits, leaving a small gap for a two-action tool with nested args.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema is a generic {action, args} envelope with only 100% coverage of placeholder text, so the description is what actually documents the per-action parameters and defaults: view_timeline(filepath, thumbnails=true, words=true) and view_clip(filepath, clip_name). This adds real meaning the structured fields do not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the two concrete operations (view_timeline, view_clip) with their signatures and states exactly what view_timeline returns — lanes, clips, markers, gaps, transcript words, filmstrip thumbnails as rational-time JSON. It also distinguishes the tool from siblings by declaring 'Read-only; edits go through edit and mark.' An agent can tell this apart from edit/mark/inspect without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It supplies clear routing context: read-only viewing here, mutations via edit and mark, and 'view_clip is the inspect button' ties it to the inspect sibling. However it never states the selection rule between view_timeline and view_clip beyond naming them, so the when-to-use distinction is left partly implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
watchA
Close the round-trip. Watch the Final Cut Pro export folder, detect the XML the moment it lands, and diff it against the last one seen. Pair with deliver.push_to_fcp for a full loop: push in, edit, Cmd-E, watch_pull. Actions: watch_start, watch_status, watch_stop, watch_pull.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action, e.g. {"filepath": "/path/to/project.fcpxml"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256). | |
| action | Yes | Which operation to run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It does disclose meaningful traits: event-driven detection ('the moment it lands') and statefulness ('diff it against the last one seen'), implying a stored baseline. But it omits whether watch_start blocks, where watch state persists, what happens if started twice, and what each action returns.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded and the workflow/action list follows in a single compact paragraph. The opening fragment 'Close the round-trip' is slightly promotional, but overall there is little waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-action dispatcher with a nested args object and no output schema, the description covers the overall purpose but leaves the individual action semantics and returns unexplained. An agent still lacks enough to invoke watch_status or watch_pull confidently, though the high schema coverage partly compensates.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the enum action values and the nested args object are already documented, giving a baseline of 3. The description repeats the action names without explaining each action's arguments or behavior, so it adds no meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names specific verbs and a resource: watch the Final Cut Pro export folder, detect XML on landing, and diff it against the previous version. It also enumerates the four actions (watch_start, watch_status, watch_stop, watch_pull), so an agent can tell what capabilities it exposes. It references the sibling workflow (deliver.push_to_fcp) but does not fully differentiate itself from the other siblings like preview or inspect.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context for use: 'Pair with deliver.push_to_fcp for a full loop: push in, edit, Cmd-E, watch_pull', which tells the agent when this tool belongs in a workflow. However, it offers no explicit when-not-to-use guidance and no exclusions relative to alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
15 tool updates
v0.26.0- Changed
deliver1 field changed- changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
- Changed
diagnose1 field changed- changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
- Changed
edit3 fields changed- added
Input schema / allOfAdded value: +[ + { + "if": { + "properties": { + "action": { + "const": "set_animation_curve" + } + }, + "required": [ + "action" + ] + }, + "then": { + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "clip_path": { + "description": "Exact clip_path returned by inspect.list_keyframes; never a clip name.", + "type": "string" + }, + "filepath": { + "description": "Input FCPXML or .fcpxmld bundle.", + "type": "string" + }, + "output_path": { + "description": "New output under the source directory; existing paths are refused. Defaults to a numbered _keyframes sibling.", + "type": "string" + }, + "points": { + "items": { + "additionalProperties": false, + "oneOf": [ + { + "required": [ + "time" + ] + }, + { + "required": [ + "frame" + ] + } + ], + "properties": { + "control_in": { + "description": "Incoming cubic Bezier control in absolute property units, not an offset. Omit on the first point.", + "oneOf": [ + { + "type": "number" + }, + { + "items": { + "type": "number" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + } + ] + }, + "control_out": { + "description": "Outgoing cubic Bezier control in absolute property units, not an offset. Omit on the last point.", + "oneOf": [ + { + "type": "number" + }, + { + "items": { + "type": "number" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + } + ] + }, + "easing": { + "description": "Outgoing segment parameter: linear u; ease 3u^2-2u^3; easeIn u^2; easeOut 2u-u^2. Omit on last point. Defaults to linear.", + "enum": [ + "linear", + "ease", + "easeIn", + "easeOut" + ], + "type": "string" + }, + "frame": { + "minimum": 0, + "type": "integer" + }, + "time": { + "description": "Rational seconds relative to the visible clip start, e.g. 24/25s.", + "pattern": "^\\d+(?:/[1-9]\\d*)?s$", + "type": "string" + }, + "value": { + "oneOf": [ + { + "type": "number" + }, + { + "items": { + "type": "number" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + } + ] + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "maxItems": 100, + "minItems": 2, + "type": "array" + }, + "property": { + "description": "position uses native FCPXML [x,y] coordinates; scale uses positive multipliers (one number or [x,y]); rotation degrees; opacity 0..1. Volume is not supported; use set_keyframes for audio levels.", + "enum": [ + "position", + "scale", + "rotation", + "opacity" + ], + "type": "string" + }, + "tolerance": { + "description": "Maximum Euclidean vector / absolute scalar error at project frames, in property units. Defaults: position 0.05, scale 0.001, rotation 0.1, opacity 0.001. Smaller values emit more keys; limits 18000 evaluated frames and 1000 output keys. Not a pixel or between-frame bound.", + "exclusiveMinimum": 0, + "type": "number" + } + }, + "required": [ + "filepath", + "clip_path", + "property", + "points" + ], + "type": "object" + } + }, + "required": [ + "args" + ] + } + }, + { + "if": { + "properties": { + "action": { + "const": "set_keyframes" + } + }, + "required": [ + "action" + ] + }, + "then": { + "properties": { + "args": { + "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": { + "property": { + "const": "position" + } + }, + "required": [ + "property" + ] + }, + "then": { + "properties": { + "keyframes": { + "items": { + "properties": { + "curve": { + "enum": [ + "linear" + ] + }, + "interp": { + "enum": [ + "linear" + ] + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "property": { + "const": "scale" + } + }, + "required": [ + "property" + ] + }, + "then": { + "properties": { + "keyframes": { + "items": { + "properties": { + "curve": { + "enum": [ + "linear" + ] + }, + "interp": { + "enum": [ + "linear" + ] + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "property": { + "const": "rotation" + } + }, + "required": [ + "property" + ] + }, + "then": { + "properties": { + "keyframes": { + "items": { + "properties": { + "curve": { + "enum": [ + "linear" + ] + }, + "interp": { + "enum": [ + "linear" + ] + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "property": { + "const": "opacity" + } + }, + "required": [ + "property" + ] + }, + "then": { + "properties": { + "keyframes": { + "items": { + "not": { + "properties": { + "interp": { + "enum": [ + "ease", + "easeIn", + "easeOut" + ] + } + }, + "required": [ + "interp", + "curve" + ] + }, + "properties": { + "curve": { + "enum": [ + "linear" + ] + }, + "interp": { + "enum": [ + "linear", + "ease", + "easeIn", + "easeOut" + ] + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "property": { + "const": "volume" + } + }, + "required": [ + "property" + ] + }, + "then": { + "properties": { + "keyframes": { + "items": { + "properties": { + "curve": { + "enum": [ + "linear" + ] + }, + "interp": { + "enum": [ + "linear" + ] + } + } + } + } + } + } + } + ], + "properties": { + "clip_path": { + "description": "Exact clip_path returned by inspect.list_keyframes; never a clip name.", + "type": "string" + }, + "filepath": { + "description": "Input FCPXML or .fcpxmld bundle.", + "type": "string" + }, + "keyframes": { + "items": { + "additionalProperties": false, + "oneOf": [ + { + "required": [ + "time" + ] + }, + { + "required": [ + "frame" + ] + } + ], + "properties": { + "curve": { + "description": "Compatibility input for native linear normalization; only linear is accepted. Omit to preserve an existing point; new points default to linear. Native spatial smooth/Bezier handles are not exposed by this action.", + "enum": [ + "linear" + ], + "type": "string" + }, + "frame": { + "description": "Clip-relative frame index.", + "minimum": 0, + "type": "integer" + }, + "interp": { + "description": "Native temporal interpolation: opacity supports ease/easeIn/easeOut; other properties accept linear only. Serialized without per-frame baking. Omit to preserve an existing point; new points default to linear. Explicit linear normalizes interpolation attributes per property. For nonlinear opacity interp, omit curve; its native encoding removes that attribute.", + "enum": [ + "linear", + "ease", + "easeIn", + "easeOut" + ], + "type": "string" + }, + "time": { + "description": "Rational seconds relative to the visible clip start, e.g. 24/25s.", + "pattern": "^\\d+(?:/[1-9]\\d*)?s$", + "type": "string" + }, + "value": { + "oneOf": [ + { + "type": "number" + }, + { + "items": { + "type": "number" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + } + ] + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "mode": { + "default": "merge", + "description": "Merge updates matching times; replace replaces this property's curve.", + "enum": [ + "merge", + "replace" + ], + "type": "string" + }, + "output_path": { + "description": "New output under the source directory; existing paths are refused. Defaults to a numbered _keyframes sibling.", + "type": "string" + }, + "property": { + "description": "position uses native FCPXML [x,y] coordinates; scale uses positive multipliers (one number or [x,y]); rotation degrees; opacity 0..1; volume numeric dB (Final Cut interpolates native gain, not a linear dB ramp).", + "enum": [ + "position", + "scale", + "rotation", + "opacity", + "volume" + ], + "type": "string" + } + }, + "required": [ + "filepath", + "clip_path", + "property", + "keyframes" + ], + "type": "object" + } + }, + "required": [ + "args" + ] + } + }, + { + "if": { + "properties": { + "action": { + "const": "delete_keyframes" + } + }, + "required": [ + "action" + ] + }, + "then": { + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "clip_path": { + "description": "Exact clip_path returned by inspect.list_keyframes; never a clip name.", + "type": "string" + }, + "filepath": { + "description": "Input FCPXML or .fcpxmld bundle.", + "type": "string" + }, + "output_path": { + "description": "New output under the source directory; existing paths are refused. Defaults to a numbered _keyframes sibling.", + "type": "string" + }, + "property": { + "description": "position uses native FCPXML [x,y] coordinates; scale uses positive multipliers (one number or [x,y]); rotation degrees; opacity 0..1; volume numeric dB (Final Cut interpolates native gain, not a linear dB ramp).", + "enum": [ + "position", + "scale", + "rotation", + "opacity", + "volume" + ], + "type": "string" + }, + "times": { + "description": "Remove these relative times; omit or null to remove the property's animation.", + "items": { + "description": "Rational seconds relative to the visible clip start, e.g. 24/25s.", + "pattern": "^\\d+(?:/[1-9]\\d*)?s$", + "type": "string" + }, + "maxItems": 1000, + "minItems": 1, + "type": [ + "array", + "null" + ] + } + }, + "required": [ + "filepath", + "clip_path", + "property" + ], + "type": "object" + } + }, + "required": [ + "args" + ] + } + }, + { + "if": { + "properties": { + "action": { + "const": "batch_keyframes" + } + }, + "required": [ + "action" + ] + }, + "then": { + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "filepath": { + "description": "Input FCPXML or .fcpxmld bundle.", + "type": "string" + }, + "operations": { + "items": { + "oneOf": [ + { + "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": { + "property": { + "const": "position" + } + }, + "required": [ + "property" + ] + }, + "then": { + "properties": { + "keyframes": { + "items": { + "properties": { + "curve": { + "enum": [ + "linear" + ] + }, + "interp": { + "enum": [ + "linear" + ] + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "property": { + "const": "scale" + } + }, + "required": [ + "property" + ] + }, + "then": { + "properties": { + "keyframes": { + "items": { + "properties": { + "curve": { + "enum": [ + "linear" + ] + }, + "interp": { + "enum": [ + "linear" + ] + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "property": { + "const": "rotation" + } + }, + "required": [ + "property" + ] + }, + "then": { + "properties": { + "keyframes": { + "items": { + "properties": { + "curve": { + "enum": [ + "linear" + ] + }, + "interp": { + "enum": [ + "linear" + ] + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "property": { + "const": "opacity" + } + }, + "required": [ + "property" + ] + }, + "then": { + "properties": { + "keyframes": { + "items": { + "not": { + "properties": { + "interp": { + "enum": [ + "ease", + "easeIn", + "easeOut" + ] + } + }, + "required": [ + "interp", + "curve" + ] + }, + "properties": { + "curve": { + "enum": [ + "linear" + ] + }, + "interp": { + "enum": [ + "linear", + "ease", + "easeIn", + "easeOut" + ] + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "property": { + "const": "volume" + } + }, + "required": [ + "property" + ] + }, + "then": { + "properties": { + "keyframes": { + "items": { + "properties": { + "curve": { + "enum": [ + "linear" + ] + }, + "interp": { + "enum": [ + "linear" + ] + } + } + } + } + } + } + } + ], + "properties": { + "action": { + "const": "set" + }, + "clip_path": { + "description": "Exact clip_path returned by inspect.list_keyframes; never a clip name.", + "type": "string" + }, + "keyframes": { + "items": { + "additionalProperties": false, + "oneOf": [ + { + "required": [ + "time" + ] + }, + { + "required": [ + "frame" + ] + } + ], + "properties": { + "curve": { + "description": "Compatibility input for native linear normalization; only linear is accepted. Omit to preserve an existing point; new points default to linear. Native spatial smooth/Bezier handles are not exposed by this action.", + "enum": [ + "linear" + ], + "type": "string" + }, + "frame": { + "description": "Clip-relative frame index.", + "minimum": 0, + "type": "integer" + }, + "interp": { + "description": "Native temporal interpolation: opacity supports ease/easeIn/easeOut; other properties accept linear only. Serialized without per-frame baking. Omit to preserve an existing point; new points default to linear. Explicit linear normalizes interpolation attributes per property. For nonlinear opacity interp, omit curve; its native encoding removes that attribute.", + "enum": [ + "linear", + "ease", + "easeIn", + "easeOut" + ], + "type": "string" + }, + "time": { + "description": "Rational seconds relative to the visible clip start, e.g. 24/25s.", + "pattern": "^\\d+(?:/[1-9]\\d*)?s$", + "type": "string" + }, + "value": { + "oneOf": [ + { + "type": "number" + }, + { + "items": { + "type": "number" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + } + ] + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "mode": { + "default": "merge", + "description": "Merge updates matching times; replace replaces this property's curve.", + "enum": [ + "merge", + "replace" + ], + "type": "string" + }, + "property": { + "description": "position uses native FCPXML [x,y] coordinates; scale uses positive multipliers (one number or [x,y]); rotation degrees; opacity 0..1; volume numeric dB (Final Cut interpolates native gain, not a linear dB ramp).", + "enum": [ + "position", + "scale", + "rotation", + "opacity", + "volume" + ], + "type": "string" + } + }, + "required": [ + "action", + "clip_path", + "property", + "keyframes" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "action": { + "const": "delete" + }, + "clip_path": { + "description": "Exact clip_path returned by inspect.list_keyframes; never a clip name.", + "type": "string" + }, + "property": { + "description": "position uses native FCPXML [x,y] coordinates; scale uses positive multipliers (one number or [x,y]); rotation degrees; opacity 0..1; volume numeric dB (Final Cut interpolates native gain, not a linear dB ramp).", + "enum": [ + "position", + "scale", + "rotation", + "opacity", + "volume" + ], + "type": "string" + }, + "times": { + "description": "Remove these relative times; omit or null to remove the property's animation.", + "items": { + "description": "Rational seconds relative to the visible clip start, e.g. 24/25s.", + "pattern": "^\\d+(?:/[1-9]\\d*)?s$", + "type": "string" + }, + "maxItems": 1000, + "minItems": 1, + "type": [ + "array", + "null" + ] + } + }, + "required": [ + "action", + "clip_path", + "property" + ], + "type": "object" + } + ] + }, + "maxItems": 100, + "minItems": 1, + "type": "array" + }, + "output_path": { + "description": "New output under the source directory; existing paths are refused. Defaults to a numbered _keyframes sibling.", + "type": "string" + } + }, + "required": [ + "filepath", + "operations" + ], + "type": "object" + } + }, + "required": [ + "args" + ] + } + }, + { + "if": { + "properties": { + "action": { + "const": "set_speed_curve" + } + }, + "required": [ + "action" + ] + }, + "then": { + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "clip_path": { + "description": "Exact clip_path returned by inspect.list_keyframes; never a clip name.", + "type": "string" + }, + "filepath": { + "description": "Input FCPXML or .fcpxmld bundle.", + "type": "string" + }, + "frame_sampling": { + "default": "floor", + "description": "FCP frame sampling mode; optical flow is evaluated by FCP, not this server.", + "enum": [ + "floor", + "nearest-neighbor", + "frame-blending", + "optical-flow-classic", + "optical-flow" + ], + "type": "string" + }, + "output_path": { + "description": "New file/bundle under the input directory; never overwrite. Defaults to numbered _retimed sibling.", + "type": "string" + }, + "preserve_pitch": { + "default": true, + "description": "Write FCP native preservesPitch for retimed audio.", + "type": "boolean" + }, + "ripple": { + "default": true, + "description": "Shift following spine clips by the duration change. False requires unchanged duration.", + "type": "boolean" + }, + "speed_keyframes": { + "description": "Ordered points, starting at zero. Last time is output duration. Integrating speed determines source consumed, which may extend the old trim within the asset.", + "items": { + "additionalProperties": false, + "oneOf": [ + { + "required": [ + "time" + ] + }, + { + "required": [ + "frame" + ] + } + ], + "properties": { + "frame": { + "description": "Output clip-relative project frame index.", + "minimum": 0, + "type": "integer" + }, + "speed": { + "description": "Playback multiplier: 0.5 half speed, 2 double speed; forward only.", + "exclusiveMinimum": 0, + "maximum": 100, + "type": "number" + }, + "time": { + "description": "Output clip-relative rational time, on a project frame boundary.", + "pattern": "^\\d+(?:/[1-9]\\d*)?s$", + "type": "string" + }, + "transition": { + "default": "linear", + "description": "Outgoing segment: hold this speed or linearly ramp to the next. Final point ends the clip.", + "enum": [ + "hold", + "linear" + ], + "type": "string" + } + }, + "required": [ + "speed" + ], + "type": "object" + }, + "maxItems": 1000, + "minItems": 2, + "type": "array" + } + }, + "required": [ + "filepath", + "clip_path", + "speed_keyframes" + ], + "type": "object" + } + }, + "required": [ + "args" + ] + } + }, + { + "if": { + "properties": { + "action": { + "const": "reset_speed" + } + }, + "required": [ + "action" + ] + }, + "then": { + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "clip_path": { + "description": "Exact clip_path returned by inspect.list_keyframes; never a clip name.", + "type": "string" + }, + "filepath": { + "description": "Input FCPXML or .fcpxmld bundle.", + "type": "string" + }, + "output_path": { + "description": "New file/bundle under the input directory; never overwrite. Defaults to numbered _retimed sibling.", + "type": "string" + }, + "ripple": { + "default": true, + "description": "Shift following spine clips by the duration change. False requires unchanged duration.", + "type": "boolean" + } + }, + "required": [ + "filepath", + "clip_path" + ], + "type": "object" + } + }, + "required": [ + "args" + ] + } + } +] - changed
Input schema / properties / action / enumPrevious value: -[ - "insert_clip", - "delete_clips", - "trim_clip", - "split_clip", - "reorder_clips", - "change_speed", - "rapid_trim", - "add_transition", - "add_audio", - "add_connected_clip", - "assign_role", - "fill_gaps", - "fix_flash_frames", - "remove_silence_candidates", - "remove_media_silence" -]New value: +[ + "insert_clip", + "delete_clips", + "trim_clip", + "split_clip", + "reorder_clips", + "change_speed", + "rapid_trim", + "add_transition", + "add_audio", + "add_connected_clip", + "assign_role", + "fill_gaps", + "fix_flash_frames", + "remove_silence_candidates", + "remove_media_silence", + "set_keyframes", + "delete_keyframes", + "batch_keyframes", + "set_animation_curve", + "set_speed_curve", + "reset_speed" +] - changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
- Changed
find1 field changed- changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
- Added
gen - Changed
generate1 field changed- changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
- Changed
index1 field changed- changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
- Changed
inspect3 fields changed- added
Input schema / allOfAdded value: +[ + { + "if": { + "properties": { + "action": { + "const": "list_keyframes" + } + }, + "required": [ + "action" + ] + }, + "then": { + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "clip_path": { + "description": "Exact clip_path returned by inspect.list_keyframes; never a clip name.", + "type": "string" + }, + "filepath": { + "description": "Input FCPXML or .fcpxmld bundle.", + "type": "string" + } + }, + "required": [ + "filepath" + ], + "type": "object" + } + }, + "required": [ + "args" + ] + } + }, + { + "if": { + "properties": { + "action": { + "const": "list_speed_points" + } + }, + "required": [ + "action" + ] + }, + "then": { + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "clip_path": { + "description": "Exact clip_path returned by inspect.list_keyframes; never a clip name.", + "type": "string" + }, + "filepath": { + "description": "Input FCPXML or .fcpxmld bundle.", + "type": "string" + } + }, + "required": [ + "filepath" + ], + "type": "object" + } + }, + "required": [ + "args" + ] + } + } +] - changed
Input schema / properties / action / enumPrevious value: -[ - "list_projects", - "analyze_timeline", - "analyze_pacing", - "list_clips", - "list_markers", - "list_roles", - "list_keywords", - "list_effects", - "list_templates", - "list_library_clips", - "list_compound_clips", - "list_connected_clips", - "filter_by_role" -]New value: +[ + "list_projects", + "analyze_timeline", + "analyze_pacing", + "list_clips", + "list_markers", + "list_roles", + "list_keywords", + "list_effects", + "list_templates", + "list_library_clips", + "list_compound_clips", + "list_connected_clips", + "filter_by_role", + "list_keyframes", + "list_speed_points" +] - changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
- Changed
mark1 field changed- changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
- Changed
organize1 field changed- changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
- Changed
preview1 field changed- changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
- Changed
scenes1 field changed- changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
- Changed
transcript1 field changed- changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
- Added
view - Changed
watch1 field changed- changed
Input schema / properties / args / descriptionPrevious value: -"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}."New value: +"Arguments for the chosen action, e.g. {\"filepath\": \"/path/to/project.fcpxml\"}. Any action that takes a filepath also accepts expected_sha256: the call refuses if the file no longer hashes to it (every write result and analyze_timeline report the current sha256)."
75 tool updates
v0.22.1- Removed
add_audio - Removed
add_connected_clip - Removed
add_marker - Removed
add_transition - Removed
analyze_pacing - Removed
analyze_timeline - Removed
apply_template - Removed
assign_role - Removed
auto_rough_cut - Removed
batch_add_markers - Removed
change_speed - Removed
create_compound_clip - Removed
delete_clips - Added
deliver - Removed
detect_beats - Removed
detect_duplicates - Removed
detect_flash_frames - Removed
detect_gaps - Removed
detect_media_silence - Removed
detect_silence_candidates - Added
diagnose - Removed
diff_timelines - Added
edit - Removed
edit_by_transcript - Removed
export_csv - Removed
export_edl - Removed
export_fcp7_xml - Removed
export_resolve_xml - Removed
export_role_stems - Removed
fill_gaps - Removed
filter_by_role - Added
find - Removed
find_long_clips - Removed
find_short_cuts - Removed
fix_flash_frames - Removed
flatten_compound_clip - Added
generate - Removed
generate_ab_roll - Removed
generate_montage - Removed
import_beat_markers - Removed
import_srt_markers - Removed
import_transcript_markers - Added
index - Removed
insert_clip - Added
inspect - Removed
list_clips - Removed
list_compound_clips - Removed
list_connected_clips - Removed
list_effects - Removed
list_fcp_libraries - Removed
list_keywords - Removed
list_library_clips - Removed
list_markers - Removed
list_projects - Removed
list_roles - Removed
list_templates - Added
mark - Added
organize - Added
preview - Removed
push_to_fcp - Removed
rapid_trim - Removed
reformat_timeline - Removed
relink_media - Removed
remove_filler_words - Removed
remove_media_silence - Removed
remove_silence_candidates - Removed
reorder_clips - Added
scenes - Removed
snap_to_beats - Removed
split_clip - Removed
transcribe_media - Added
transcript - Removed
trim_clip - Removed
validate_timeline - Added
watch
7 tool updates
v0.13.1- Added
add_marker - Added
assign_role - Added
batch_add_markers - Added
detect_gaps - Added
export_edl - Added
list_compound_clips - Added
list_projects
10 tool updates
v0.13.0- Removed
add_marker - Removed
assign_role - Removed
batch_add_markers - Removed
detect_gaps - Added
edit_by_transcript - Removed
export_edl - Removed
list_compound_clips - Removed
list_projects - Added
remove_filler_words - Added
transcribe_media
3 tool updates
v0.12.0- Added
detect_beats - Added
detect_media_silence - Added
remove_media_silence
3 tool updates
v0.9.0- Added
list_fcp_libraries - Added
push_to_fcp - Added
relink_media
53 tool updates
v0.6.63- First observed
add_audio - First observed
add_connected_clip - First observed
add_marker - First observed
add_transition - First observed
analyze_pacing - First observed
analyze_timeline - First observed
apply_template - First observed
assign_role - First observed
auto_rough_cut - First observed
batch_add_markers - First observed
change_speed - First observed
create_compound_clip - First observed
delete_clips - First observed
detect_duplicates - First observed
detect_flash_frames - First observed
detect_gaps - First observed
detect_silence_candidates - First observed
diff_timelines - First observed
export_csv - First observed
export_edl - First observed
export_fcp7_xml - First observed
export_resolve_xml - First observed
export_role_stems - First observed
fill_gaps - First observed
filter_by_role - First observed
find_long_clips - First observed
find_short_cuts - First observed
fix_flash_frames - First observed
flatten_compound_clip - First observed
generate_ab_roll - First observed
generate_montage - First observed
import_beat_markers - First observed
import_srt_markers - First observed
import_transcript_markers - First observed
insert_clip - First observed
list_clips - First observed
list_compound_clips - First observed
list_connected_clips - First observed
list_effects - First observed
list_keywords - First observed
list_library_clips - First observed
list_markers - First observed
list_projects - First observed
list_roles - First observed
list_templates - First observed
rapid_trim - First observed
reformat_timeline - First observed
remove_silence_candidates - First observed
reorder_clips - First observed
snap_to_beats - First observed
split_clip - First observed
trim_clip - First observed
validate_timeline
TDQS
Scored across 15 tools
The 15 tools are grouped into clearly labeled high-level purposes (inspect, diagnose, edit, mark, generate, etc.), but each tool bundles many overlapping sub-actions under vague verbs. The flat tool names 'inspect' and 'diagnose' overlap heavily (both read-only analysis), and 'generate' vs 'gen' (generative fill) are confusingly adjacent, as are 'scenes' vs 'index' vs 'find' which all touch indexing/scene detection.
Names are consistent in style (all lowercase single-word verb/noun groupings) but inconsistent in convention — some are plain verbs (inspect, edit, mark), some are nouns (transcript, scenes), and one is an abbreviation (gen) that nearly duplicates generate. The sub-action names inside descriptions are snake_case but the top-level tool names are not, mixing conventions.
15 tools is at the upper edge of reasonable, but this is a mega-server where only 15 names actually hide well over a hundred sub-actions, making the surface feel deceptively compact while functionally enormous. Each named tool is a mini-server rather than a task, which strains the 'one tool = one clear action' model.
The surface is remarkably complete for a Final Cut Pro XML workflow — inspection, diagnostics, editing, marking, generation, transcription, delivery, preview, watching, indexing, scene detection, organization, search, viewing, and generative fill are all covered. Lifecycle coverage from read through edit, export, round-trip and search is thorough with few obvious gaps.
Maintenance
Related MCP Connectors
MCP server for Clipkit — gives AI agents a video toolbox via the Clipkit schema.
Screenplay, film and story toolkit over MCP: PDF formatting, stats, diagnosis, video prompts.
Hosted MCP tools for FFmpeg-style video and audio processing through FFMPEG API.
AI video editor for agents and humans: timeline, captions, color, audio and generation as MCP tools.
Related MCP Servers
- AlicenseBqualityCmaintenanceThe most capable MCP server for Final Cut Pro — 88 tools covering FCPXML editing, live FCP control, parametric puppets, and media analysis.88183 PyPI12MIT
- AlicenseNot gradedqualityDmaintenanceMCP server that enables AI to control Final Cut Pro on macOS, including reading libraries/projects, importing FCPXML, and creating title or storyboard projects.MIT
- FlicenseNot gradedqualityAmaintenanceEnables Claude and other MCP clients to read, edit, and generate real Final Cut Pro timelines from FCPXML, including cut detection, markers, roles, silence removal, transcript-based editing, cross-NLE export, and pushing changes into a running Final Cut Pro. Every write is journaled and undoable, with validation and safety checks for reliable timeline edits.-
- FlicenseNot gradedqualityAmaintenanceEnables an MCP client like Claude to read, edit, and generate real Final Cut Pro timelines from exported FCPXML, covering cut and flash-frame detection, silence and gap removal, markers, keyframes, speed ramps, transcript-based editing, cross-NLE export, and pushing the result into a running Final Cut Pro. Every write is journaled with its sha256 so changes can be undone and unreviewed cuts refused.-