capcut-mcp
by alex28042
README.md
# capcut-mcp
MCP server that creates and edits **CapCut desktop drafts** locally. CapCut has no public API, so this server writes the project files CapCut reads from disk (`draft_content.json` + `draft_meta_info.json`). You build the timeline through MCP tools and then open the project in CapCut desktop to preview and export.
## Tools
| Tool | Description |
|---|---|
| `create_draft` | Creates an empty draft (default canvas 1080x1920 @ 30fps) |
| `list_drafts` | Lists drafts in the drafts folder |
| `get_draft` | Returns the timeline: tracks, segments, timings |
| `add_video` | Adds a video clip (duration/dimensions detected via ffprobe) |
| `add_image` | Adds a still image (default 5s on screen) |
| `add_audio` | Adds music or voiceover to an audio track |
| `add_text` | Adds a text overlay with color, size and position |
Placement rules: segments append to the end of their track by default (`atSeconds` overrides). If a segment overlaps an existing one, a new track is created automatically, so overlays "just work".
## Setup
```bash
pnpm install
pnpm build
```
Register in Claude Code:
```bash
claude mcp add --scope user capcut -- node /absolute/path/to/capcut-mcp/dist/index.js
```
### Configuration
| Env var | Default | Purpose |
|---|---|---|
| `CAPCUT_DRAFT_ROOT` | `~/Movies/CapCut/User Data/Projects/com.lveditor.draft` | Where drafts are read/written (CapCut's folder on macOS) |
Installing **ffmpeg** (`brew install ffmpeg`) is recommended: `ffprobe` detects media duration and dimensions automatically. Without it, image dimensions fall back to macOS `sips`, and video/audio clips require an explicit `durationSeconds`.
## Architecture
Layered, dependency-injected design. `CompositionRoot` is the only place where concrete classes are instantiated; every collaborator is injected through constructor interfaces (ports & adapters).
```mermaid
classDiagram
class DraftToolController {
+registerOn(server)
}
class DraftService {
+createDraft()
+addVideo() / addImage() / addAudio() / addText()
+listDrafts() / getDraft()
}
class DraftDocument {
+insertSegment()
+addMaterial()
+summary()
}
class DraftRepository {
<<interface>>
}
class MediaProbe {
<<interface>>
}
class FileChecker {
<<interface>>
}
class FsDraftRepository
class ChainMediaProbe
class FfprobeMediaProbe
class SipsImageProbe
class MaterialFactory
class SegmentFactory
class DraftContentFactory
DraftToolController --> DraftService
DraftService --> DraftRepository
DraftService --> MediaProbe
DraftService --> FileChecker
DraftService --> MaterialFactory
DraftService --> SegmentFactory
DraftService --> DraftContentFactory
DraftRepository <|.. FsDraftRepository
MediaProbe <|.. ChainMediaProbe
ChainMediaProbe o--> FfprobeMediaProbe
ChainMediaProbe o--> SipsImageProbe
FsDraftRepository --> DraftDocument
```
Patterns in play:
- **Facade** — `DraftService` exposes one use case per tool and owns the workflow.
- **Repository** — `FsDraftRepository` isolates all disk I/O and the meta-info bookkeeping.
- **Factory** — `DraftContentFactory` / `MaterialFactory` / `SegmentFactory` encapsulate CapCut's JSON blocks.
- **Strategy + Chain of Responsibility** — `MediaProbe` implementations try ffprobe first, then `sips`.
- **Dependency Injection** — constructor injection everywhere; `IdGenerator` and `Clock` are injected too, which keeps every unit test deterministic (see `src/testing/fakes.ts`).
`DraftDocument` wraps the raw draft JSON and only mutates the parts it understands, preserving any field CapCut adds on its own.
## Validation
Verified end to end against **CapCut desktop 3.3.0 (macOS)**: generated drafts show up in CapCut's project list with the right duration, open in the editor, and the full timeline loads — video, photo, audio (with volume) and text overlays with their exact timings. CapCut's own autosave round-trips the generated structure without dropping anything.
## Limitations
- **Media must live on a stable user path** (e.g. under `~/Movies` or `~/Documents`). CapCut marks files under `/tmp` as "not accessible" and asks to relink them.
- No effects, transitions, keyframes or exports yet — CapCut itself does the rendering/export.
- Drafts heavily edited inside CapCut can contain features this server does not model; it will preserve them on load/save, but it only manipulates video/image/audio/text segments.
## Development
```bash
pnpm test # vitest unit tests
pnpm typecheck
pnpm dev # run from sources (tsx)
```
TDQS
A3.6/5.0
Scored across 7 tools
Disambiguation5/5
Each tool targets a distinct media type (audio, image, text, video) or draft operation (create, get, list), with no overlapping purposes.
Naming Consistency5/5
All tools follow a consistent verb_noun pattern (e.g., add_audio, create_draft, list_drafts), making them predictable.
Tool Count5/5
7 tools is well-scoped for a video editing assistant, covering essential draft and media operations without bloat.
Completeness4/5
Covers draft creation, listing, and adding media, but lacks remove/update operations for media or export functionality, which are minor gaps.
Maintenance
ActivityStale
ResponsivenessNo issues