Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ jobs:
- run: pnpm test

- run: pnpm build

# The Claude Desktop extension: validates the manifest and packs it.
- run: pnpm build:mcpb
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,7 @@ dist
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.vite/

# Claude Desktop extension build (pnpm build:mcpb) and release assets
/build/
/release/
15 changes: 13 additions & 2 deletions .releaserc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,18 @@
"@semantic-release/release-notes-generator",
["@semantic-release/changelog", { "changelogFile": "CHANGELOG.md" }],
["@semantic-release/npm", { "tarballDir": "release", "npmPublish": false }],
["@semantic-release/exec", { "publishCmd": "npm publish --provenance --access public" }],
"@semantic-release/github"
[
"@semantic-release/exec",
{
"prepareCmd": "pnpm build:mcpb",
"publishCmd": "npm publish --provenance --access public"
}
],
[
"@semantic-release/github",
{
"assets": [{ "path": "release/*.mcpb", "label": "Claude Desktop extension (.mcpb)" }]
}
]
]
}
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ clip --help
clip ui # opens http://127.0.0.1:5573
```

**As a Claude Desktop extension** (one click, no Node or config file):

1. Install FFmpeg: `brew install ffmpeg` on macOS, `winget install Gyan.FFmpeg` on Windows.
2. Download [`makemyclip-editor.mcpb`](https://github.com/MakeMyClip/editor/releases/latest/download/makemyclip-editor.mcpb) and double-click it, or drag it into Claude Desktop.

Put your videos in the extension's **Media folder** (by default `Documents/MakeMyClip`); the editor reads and writes only there. The extension doesn't include FFmpeg (see [License](#license)): it finds the one Homebrew, MacPorts, winget, Scoop or Chocolatey installed, or you pick it in the extension's settings, along with the optional whisper model.

**As an MCP server** (drive it from Claude Desktop / Cursor / any MCP client — no API key, on your existing Claude):

```jsonc
Expand Down Expand Up @@ -266,7 +273,7 @@ Every edit is undoable (`clip timeline undo` / `redo`, `clip timeline log`), and
- **Language:** TypeScript (Node 24+) and React 19 (browser UI)
- **Timeline schema:** [Zod](https://zod.dev/) (shared with the [MakeMyClip.com](https://makemyclip.com) web app)
- **Subprocess:** [execa](https://github.com/sindresorhus/execa) — args as an array, no shell injection
- **FFmpeg:** bundled via `ffmpeg-static`, with `MAKEMYCLIP_FFMPEG_PATH` override or system-binary fallback
- **FFmpeg:** downloaded by `ffmpeg-static` when the npm package installs, with a `MAKEMYCLIP_FFMPEG_PATH` override and an installed FFmpeg as the fallback (the Claude Desktop extension always uses an installed one)
- **Transcription:** optional, user-installed [whisper.cpp](https://github.com/ggml-org/whisper.cpp), run as a subprocess
- **MCP:** [`@modelcontextprotocol/sdk`](https://modelcontextprotocol.io/) — the `clip mcp` server (Claude Desktop / any MCP client)
- **UI:** Hono server + Vite + React, plain CSS
Expand All @@ -279,7 +286,7 @@ Every edit is undoable (`clip timeline undo` / `redo`, `clip timeline log`), and
### Setup & installation

**Do I need FFmpeg installed separately?**
No. MakeMyClip Editor bundles FFmpeg via `ffmpeg-static`, so installing the npm package or running `npx skills add MakeMyClip/editor` is all you need. For your own FFmpeg build (LGPL-only, custom codecs, hardware acceleration), set `MAKEMYCLIP_FFMPEG_PATH` to its path and the bundled binary is ignored.
Not for the npm package, the CLI or the Claude Code skill: `ffmpeg-static` downloads an FFmpeg build for your platform when the package installs. The Claude Desktop extension is the exception: it doesn't include FFmpeg, so install it first (`brew install ffmpeg` or `winget install Gyan.FFmpeg`). For your own FFmpeg build (LGPL-only, custom codecs, hardware acceleration), set `MAKEMYCLIP_FFMPEG_PATH` to its path and the downloaded binary is ignored. `clip doctor` shows which FFmpeg runs.

**What platforms does it run on?**
macOS, Linux, and Windows — anywhere Node 24+ runs. The browser UI binds to `127.0.0.1` and needs no internet connection.
Expand Down Expand Up @@ -325,8 +332,8 @@ Every edit appends to `session.json` and produces a new output file in the works
**Is it free?**
Yes — MIT-licensed, free forever for local editing. No paid tier, no signup, no upsell in the editor. Paid AI-generation features (voice synthesis, music, stock footage) will live on [MakeMyClip.com](https://makemyclip.com) when they ship, behind a separate `@makemyclip/generation` package.

**What's the license situation with the bundled FFmpeg?**
The MakeMyClip Editor source code is [MIT](./LICENSE). The bundled FFmpeg binary (via `ffmpeg-static`) is GPL-licensed because it includes codecs like libx264 and libx265. Subprocess invocation keeps GPL terms confined to the binary, not your application code. For LGPL-only or custom-build requirements (e.g. iOS App Store), set `MAKEMYCLIP_FFMPEG_PATH` to your own binary.
**What's the license situation with FFmpeg?**
The MakeMyClip Editor source code is [MIT](./LICENSE). FFmpeg is a separate program the editor runs as a subprocess, so its license covers the binary, not your application code. The build `ffmpeg-static` downloads is GPLv3 on Intel Macs, Windows and Linux. On Apple Silicon it is a build with nonfree parts that FFmpeg marks as not redistributable, so the Claude Desktop extension ships no FFmpeg at all. For LGPL-only or custom-build requirements (e.g. iOS App Store), set `MAKEMYCLIP_FFMPEG_PATH` to your own binary.

**How is this different from running FFmpeg directly?**
FFmpeg is one binary with a complex CLI; MakeMyClip Editor is 19 named tools with typed inputs, a session log, snapshot/undo, a browser UI, and an agent-callable API. You're still running FFmpeg under the hood — but with a catalog any LLM can call, input validation that prevents bad commands, and a log you can inspect or version-control.
Expand Down Expand Up @@ -415,4 +422,9 @@ Built on the work of [FFmpeg](https://ffmpeg.org/), [whisper.cpp](https://github

## License

[MIT](./LICENSE) for the editor source; GPL for the bundled FFmpeg binary (subprocess-isolated). Use it, fork it, ship it.
[MIT](./LICENSE) for the editor source. FFmpeg is a separate program, run as a subprocess under its own license:

- **npm package, CLI, Claude Code skill:** `ffmpeg-static` downloads an FFmpeg build from its GitHub releases when the package installs. The Intel macOS, Windows and Linux builds are GPLv3. The Apple Silicon build includes nonfree parts and isn't redistributable.
- **Claude Desktop extension (`.mcpb`):** includes no FFmpeg. It runs the one you install.

Set `MAKEMYCLIP_FFMPEG_PATH` to use an FFmpeg of your choice. Use it, fork it, ship it.
2 changes: 2 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
"includes": [
"src/**/*",
"tests/**/*",
"scripts/**/*",
"mcpb/**/*",
"*.json",
"*.md",
"!dist",
Expand Down
3 changes: 3 additions & 0 deletions docs/backlog/apple-silicon-ffmpeg-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Redistributable FFmpeg for Apple Silicon

`ffmpeg-static`'s darwin-arm64 binary (FFmpeg 6.0 from osxexperts) is built with `--enable-nonfree`, and `ffmpeg -L` says it is not legally redistributable. npm installs on Apple Silicon download it, and the Claude Desktop extension ships no FFmpeg because of it. Find or build a GPL arm64 FFmpeg with drawtext and vidstab (a pinned CI build from source, with its corresponding source published) so Apple Silicon users get a redistributable build, and so the `.mcpb` could include FFmpeg for one-click setup.
5 changes: 3 additions & 2 deletions llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

- **Name:** MakeMyClip Editor (npm `@makemyclip/editor`, current release v0.4.0)
- **Type:** Agent-driven video editor (not generative AI)
- **Backend:** FFmpeg (bundled via `ffmpeg-static`); optional user-installed whisper.cpp for transcription
- **Backend:** FFmpeg (downloaded by `ffmpeg-static` at npm install; the Claude Desktop extension uses an installed FFmpeg); optional user-installed whisper.cpp for transcription
- **Surfaces:** Claude Code skill · `clip` CLI · browser UI at `127.0.0.1:5573` · MCP server (`clip mcp`)
- **Agent access:** Claude Code skill + MCP server (`clip mcp`); no API key — the editor embeds no language model, it runs on whichever Claude you already use
- **Tests:** 741 passing
- **License:** MIT (code) + GPL (bundled FFmpeg binary, subprocess-isolated)
- **License:** MIT (code); FFmpeg runs as a subprocess under its own license (GPLv3 builds from `ffmpeg-static`, except a nonfree Apple Silicon build; the `.mcpb` ships no FFmpeg)

## What v0.4.0 does

Expand All @@ -29,6 +29,7 @@
- CLI: `npm i -g @makemyclip/editor` then `clip --help`
- Browser UI: `clip ui` (opens http://127.0.0.1:5573)
- MCP server: `npx -y @makemyclip/editor mcp` (stdio), with `MAKEMYCLIP_WORKSPACE` set to the media folder
- Claude Desktop extension: install FFmpeg, then open https://github.com/MakeMyClip/editor/releases/latest/download/makemyclip-editor.mcpb
- Transcription (optional): install whisper.cpp (macOS: `brew install whisper-cpp`), download a model such as `ggml-base.en.bin`, set `MAKEMYCLIP_WHISPER_MODEL` to its path
- Setup check: `npx -y @makemyclip/editor doctor` (or the MCP `doctor` tool) lists what's missing and how to fix it

Expand Down
119 changes: 119 additions & 0 deletions mcpb/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
{
"$schema": "https://raw.githubusercontent.com/modelcontextprotocol/mcpb/main/dist/mcpb-manifest-v0.3.schema.json",
"manifest_version": "0.3",
"name": "makemyclip-editor",
"display_name": "MakeMyClip Editor",
"version": "0.0.0-development",
"description": "Local video editor: remove silence, edit by transcript, add captions, export to Final Cut Pro, Resolve or Premiere.",
"long_description": "MakeMyClip Editor is an open-source (MIT) video editor that Claude drives through a timeline you can undo. Ask Claude to cut the pauses or repeated takes out of a recording, cut words using its transcript, add captions, and render an mp4 or export a project for Final Cut Pro, DaVinci Resolve or Premiere Pro. Everything runs on your computer, with no account and no API key.\n\n**Needs FFmpeg.** This extension doesn't include FFmpeg. Install it with `brew install ffmpeg` (macOS) or `winget install Gyan.FFmpeg` (Windows); the extension finds it on its own, or pick the program in the FFmpeg setting. Transcripts and captions also need a local whisper.cpp and a model file. Ask Claude \"is my setup OK?\" and it runs the editor's setup check, with the fix for anything missing.\n\nThe editor only reads and writes files inside the media folder you choose.",
"author": {
"name": "MakeMyClip",
"url": "https://makemyclip.com"
},
"repository": {
"type": "git",
"url": "https://github.com/MakeMyClip/editor"
},
"homepage": "https://github.com/MakeMyClip/editor",
"documentation": "https://github.com/MakeMyClip/editor#readme",
"support": "https://github.com/MakeMyClip/editor/issues",
"icon": "icon.png",
"server": {
"type": "node",
"entry_point": "dist/cli.js",
"mcp_config": {
"command": "node",
"args": ["${__dirname}/dist/cli.js", "mcp"],
"env": {
"MAKEMYCLIP_BUNDLE": "mcpb",
"MAKEMYCLIP_WORKSPACE": "${user_config.workspace}",
"MAKEMYCLIP_FFMPEG_PATH": "${user_config.ffmpeg_path}",
"MAKEMYCLIP_WHISPER_MODEL": "${user_config.whisper_model}",
"MAKEMYCLIP_WHISPER_PATH": "${user_config.whisper_path}"
}
}
},
"tools": [
{
"name": "timeline_show",
"description": "Read the timeline (tracks, clips, timings, whether it can render) and optionally the frame at a time."
},
{
"name": "timeline_edit",
"description": "Apply editing verbs as one undoable change: add media, text or color, trim, move, split, remove, remove silence, cut words or retakes, caption speech, transition."
},
{
"name": "timeline_check",
"description": "Review every hard cut for clipped words or clicks, with a contact sheet of the frames around each cut."
},
{
"name": "timeline_transcript",
"description": "Transcribe a clip with the local whisper.cpp and return its words with timeline times."
},
{
"name": "timeline_undo",
"description": "Undo the most recent timeline edit."
},
{
"name": "timeline_redo",
"description": "Redo the most recently undone timeline edit."
},
{
"name": "timeline_export",
"description": "Export the timeline as an mp4, an FCPXML project (Final Cut Pro, DaVinci Resolve) or FCP7 XML (Premiere Pro)."
},
{
"name": "doctor",
"description": "Check the setup (FFmpeg and its filters, the media folder, a caption font, the optional whisper.cpp) and say how to fix what's missing."
}
],
"keywords": [
"video",
"video-editing",
"ffmpeg",
"captions",
"transcription",
"silence-removal",
"fcpxml",
"final-cut-pro",
"davinci-resolve",
"premiere-pro"
],
"license": "MIT",
"compatibility": {
"platforms": ["darwin", "win32"],
"runtimes": {
"node": ">=24.0.0"
}
},
"user_config": {
"workspace": {
"type": "directory",
"title": "Media folder",
"description": "The editor reads and writes files only inside this folder: put the videos you want to edit here, and exports land here too. Leave blank for a MakeMyClip folder in your Documents.",
"required": false,
"default": ""
},
"ffmpeg_path": {
"type": "file",
"title": "FFmpeg",
"description": "Optional: the ffmpeg program to use. Leave blank to use an installed FFmpeg (Homebrew, MacPorts, winget, Scoop, Chocolatey, or on PATH).",
"required": false,
"default": ""
},
"whisper_model": {
"type": "file",
"title": "Whisper model",
"description": "Optional, for transcripts, retake removal and captions: a whisper.cpp model file such as ggml-base.en.bin.",
"required": false,
"default": ""
},
"whisper_path": {
"type": "file",
"title": "whisper-cli",
"description": "Optional: the whisper.cpp whisper-cli program. Leave blank to use an installed one (Homebrew, or on PATH).",
"required": false,
"default": ""
}
}
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"scripts": {
"build": "tsup && pnpm build:ui",
"build:ui": "vite build --config src/ui/web/vite.config.ts",
"build:mcpb": "tsx scripts/build-mcpb.ts",
"dev": "tsx src/cli.ts",
"dev:ui": "vite --config src/ui/web/vite.config.ts",
"start": "node dist/cli.js",
Expand All @@ -79,6 +80,7 @@
"zod": "^4.6.7"
},
"devDependencies": {
"@anthropic-ai/mcpb": "2.1.2",
"@biomejs/biome": "^2.6.4",
"@semantic-release/changelog": "^7.0.0",
"@semantic-release/commit-analyzer": "^13.0.1",
Expand Down
Loading
Loading