# 2886 06 Implementation Roadmap 1df057e9

> FCP MCP Server - Implementation Roadmap

- Skill: `tools-only/2886-06-implementation-roadmap-1df057e9` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tools-only/2886-06-implementation-roadmap-1df057e9`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-only/2886-06-implementation-roadmap-1df057e9/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: tools-only (https://skillmd.com/u/tools-only)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/tools-only/2886-06-implementation-roadmap-1df057e9

---

# FCP MCP Server - Implementation Roadmap

Step-by-step plan to build all editing features.

---

## Current State

✅ **DONE:**
- Repository structure
- Basic parser (read FCPXML)
- 10 read-only MCP tools
- Claude Desktop integration config

🔄 **IN PROGRESS:**
- Writer module architecture
- Tool schemas for editing

---

## Implementation Order

### Sprint 1: Core Write Operations (Week 1)

**Day 1-2: TimeValue & Writer Foundation**
```
Tasks:
□ Implement TimeValue class with all operations
□ Create FCPXMLWriter base class
□ Implement _detect_fps()
□ Implement _build_clip_index()
□ Implement save()
□ Write unit tests for TimeValue
```

**Day 3-4: Marker Operations**
```
Tasks:
□ Implement add_marker()
□ Implement batch_add_markers()
□ Handle marker types (standard, chapter, todo)
□ Handle marker colors
□ Test with real FCP export
□ Verify re-import into FCP
```

**Day 5-6: Trim Operations**
```
Tasks:
□ Implement trim_clip() - absolute timecodes
□ Implement trim_clip() - delta trimming
□ Implement _ripple_after_clip()
□ Test with ripple=True and ripple=False
□ Edge case: trim to zero duration (should fail)
□ Edge case: trim beyond clip bounds (should clamp)
```

**Day 7: Reorder Operations**
```
Tasks:
□ Implement reorder_clips() - move to start/end
□ Implement reorder_clips() - move to timecode
□ Implement reorder_clips() - after/before clip
□ Implement _recalculate_offsets()
□ Test multi-clip moves
```

---

### Sprint 2: Advanced Edit Operations (Week 2)

**Day 1-2: Transitions**
```
Tasks:
□ Implement add_transition() - cross-dissolve
□ Implement add_transition() - fade variants
□ Find FCP effect reference IDs
□ Test position: start, end, both
□ Handle transition overlap calculation
```

**Day 3-4: Speed Changes**
```
Tasks:
□ Implement change_speed() - constant speed
□ Implement change_speed() - speed ramps
□ Create timeMap XML structure
□ Test slow-mo (0.5x) and fast (2x)
□ Test speed ramp with different curves
□ Verify frame blending options
```

**Day 5-6: Split & Delete**
```
Tasks:
□ Implement split_clip() - single split point
□ Implement split_clip() - multiple split points
□ Implement delete_clip() - with ripple
□ Implement delete_clip() - with gap
□ Test split preserves clip attributes
□ Test delete updates clip index
```

**Day 7: Selection & Batch**
```
Tasks:
□ Implement select_by_keyword()
□ Implement batch_trim()
□ Test keyword matching modes (any, all, none)
□ Test batch operations on 10+ clips
```

---

### Sprint 3: Auto Rough Cut (Week 3)

**Day 1-2: Ingest Phase**
```
Tasks:
□ Implement ingest_source_clips()
□ Parse asset-clips from library exports
□ Parse clips from event exports
□ Extract all metadata (keywords, ratings, favorites)
□ Test with 100+ clip library
```

**Day 3-4: Score Phase**
```
Tasks:
□ Implement score_clips()
□ Implement keyword matching scoring
□ Implement rating/favorite scoring
□ Implement duration fit scoring
□ Test scoring produces sensible rankings
```

**Day 5-6: Select Phase**
```
Tasks:
□ Implement select_clips_for_segment()
□ Implement all priority modes
□ Implement pacing-based duration calculation
□ Test clip selection respects already_used
□ Test segment duration targets
```

**Day 7: Assemble Phase**
```
Tasks:
□ Implement assemble_rough_cut()
□ Create proper FCPXML document structure
□ Add asset resources correctly
□ Add transitions between segments
□ Test complete rough cut generation
□ Import result into FCP - verify it works
```

---

### Sprint 4: Polish & Ship (Week 4)

**Day 1-2: Error Handling**
```
Tasks:
□ Add validation for all inputs
□ Graceful handling of malformed FCPXML
□ Clear error messages for common issues
□ Logging throughout
```

**Day 3-4: Integration Testing**
```
Tasks:
□ Create test suite with real FCP exports
□ Test each tool end-to-end
□ Test tool combinations (marker + trim + reorder)
□ Performance testing with large projects
```

**Day 5-6: Documentation**
```
Tasks:
□ Complete README with all tools
□ Add usage examples for each tool
□ Create tutorial: "Your first rough cut"
□ Add troubleshooting guide
□ Record demo video
```

**Day 7: Launch**
```
Tasks:
□ Final testing pass
□ Version bump to 1.0.0
□ Push to GitHub
□ Submit to MCP registry
□ Write launch posts
□ Share with FCP communities
```

---

## Testing Strategy

### Unit Tests

```python
# tests/test_timevalue.py
def test_from_timecode_hmsf():
    tv = TimeValue.from_timecode("00:01:30:15", fps=30)
    assert tv.to_seconds() == 90.5

def test_from_timecode_fcpxml():
    tv = TimeValue.from_timecode("2700/30s")
    assert tv.to_seconds() == 90.0

def test_addition():
    a = TimeValue(30, 30)  # 1 second
    b = TimeValue(60, 30)  # 2 seconds
    c = a + b
    assert c.to_seconds() == 3.0

def test_simplify():
    tv = TimeValue(60, 30)
    simplified = tv.simplify()
    assert simplified.numerator == 2
    assert simplified.denominator == 1
```

### Integration Tests

```python
# tests/test_writer_integration.py
def test_add_marker_reimports():
    """Marker added by writer should be visible in FCP."""
    # 1. Create modified FCPXML
    writer = FCPXMLWriter("fixtures/sample.fcpxml")
    writer.add_marker("clip_0", "00:00:10:00", "Test Marker", MarkerType.CHAPTER)
    writer.save("output/test_marker.fcpxml")
    
    # 2. Parse it back
    parser = FCPXMLParser("output/test_marker.fcpxml")
    timeline = parser.parse()
    
    # 3. Verify marker exists
    marker_names = [m.name for m in timeline.markers]
    assert "Test Marker" in marker_names

def test_trim_preserves_structure():
    """Trimming shouldn't corrupt other timeline elements."""
    writer = FCPXMLWriter("fixtures/sample.fcpxml")
    original_clip_count = len(writer.clips)
    
    writer.trim_clip("clip_0", trim_end="-1s")
    writer.save("output/test_trim.fcpxml")
    
    parser = FCPXMLParser("output/test_trim.fcpxml")
    timeline = parser.parse()
    
    # Same number of clips
    assert len(timeline.clips) == original_clip_count
```

### Golden Set Tests

```python
# tests/golden_set.py
"""
Golden set: known-good FCPXML files that must parse correctly.
If any fail, we broke backward compatibility.
"""

GOLDEN_FILES = [
    "fixtures/golden/simple_timeline.fcpxml",
    "fixtures/golden/multicam_project.fcpxml",
    "fixtures/golden/compound_clips.fcpxml",
    "fixtures/golden/with_effects.fcpxml",
    "fixtures/golden/fcp_10_6_export.fcpxml",
    "fixtures/golden/fcp_10_7_export.fcpxml",
    "fixtures/golden/fcp_10_8_export.fcpxml",
]

@pytest.mark.parametrize("filepath", GOLDEN_FILES)
def test_golden_file_parses(filepath):
    parser = FCPXMLParser(filepath)
    timeline = parser.parse()
    assert timeline is not None
    assert len(timeline.clips) > 0
```

---

## Risk Mitigation

### Risk: FCPXML format changes between FCP versions

**Mitigation:**
- Test against multiple FCP export versions (10.6, 10.7, 10.8)
- Use conservative parsing (ignore unknown elements)
- Version detection in parser
- Golden set tests for each version

### Risk: Generated FCPXML rejected by FCP

**Mitigation:**
- Always validate output XML
- Round-trip testing (export → modify → import)
- Use FCP's own exports as templates
- Keep original attributes we don't understand

### Risk: Data loss from edit operations

**Mitigation:**
- Never overwrite original by default
- Backup before destructive operations
- Validate timeline integrity after each operation
- Undo capability (save original state)

### Risk: Performance with large projects

**Mitigation:**
- Lazy loading of clip metadata
- Index-based clip lookup
- Stream parsing for very large files
- Progress callbacks for long operations

---

## File Structure (Final)

```
fcp-mcp-server/
├── server.py                 # MCP server entry point
├── fcpxml/
│   ├── __init__.py
│   ├── parser.py             # Read operations
│   ├── writer.py             # Write operations
│   ├── rough_cut.py          # Auto rough cut algorithm
│   ├── models.py             # Data classes
│   └── utils.py              # TimeValue, converters
├── tests/
│   ├── __init__.py
│   ├── test_parser.py
│   ├── test_writer.py
│   ├── test_rough_cut.py
│   ├── test_timevalue.py
│   ├── golden_set.py
│   └── fixtures/
│       ├── sample.fcpxml
│       └── golden/
├── examples/
│   ├── basic_usage.py
│   ├── rough_cut_example.py
│   └── batch_markers.py
├── docs/
│   ├── TOOL_REFERENCE.md
│   ├── FCPXML_GUIDE.md
│   └── TROUBLESHOOTING.md
├── pyproject.toml
├── requirements.txt
├── LICENSE
└── README.md
```

---

## Definition of Done

A feature is complete when:

1. ✅ Code implemented and working
2. ✅ Unit tests passing
3. ✅ Integration test with real FCP export
4. ✅ Re-import into FCP verified
5. ✅ Error handling for edge cases
6. ✅ Documented in README
7. ✅ Example usage provided

