Skip to main content
Glama
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