Skip to content
Content
Skill

/cassette-video-edit

Edit, trim, cut, caption, subtitle, reframe, combine, add background music to, or export video, audio, and image files through Cassette. Use this skill whenever the user asks to change, preview, or render a media file in the project — even if they never say "Cassette" or name a

From plugin
oh-my-cassette
1472 skills1 command1 MCP
Install
$ npx -y skills add Cassette-Editor/oh-my-cassette --skill cassette-video-edit --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/cassette-video-edit

Context preview

The summary Claude sees to decide when to auto-load this skill.

Edit, trim, cut, caption, subtitle, reframe, combine, add background music to, or export video, audio, and image files through Cassette. Use this skill whenever the user asks to change, preview, or render a media file in the project — even if they never say "Cassette" or name a

SKILL.md

cassette-video-edit.SKILL.md
name: cassette-video-edit
description: Edit, trim, cut, caption, subtitle, reframe, combine, add background music to, or export video, audio, and image files through Cassette. Use this skill whenever the user asks to change, preview, or render a media file in the project — even if they never say "Cassette" or name a tool — for example "trim the intro off demo.mp4", "add subtitles to this clip", "make me a 30-second cut with music", "why is there dead air at the start". Drives the local Oh My Cassette stdio MCP tools in Codex or Claude as one multi-turn conversation with the Cassette agent, with per-turn timeline previews, guided questions, and rendering only on explicit export.
version: 2.1.0
license: MIT
metadata:
  tags: [cassette, video, codex, claude, hermes, opencode, mcp, media-editing]
  category: media

Oh My Cassette local workflow

Cassette edits the media; you carry the messages. The `cassette` MCP server is a local stdio child process that opens no port and talks directly to the separate Cassette backend. Do not start or depend on the separate FastAPI web-demo server for this workflow — that is a different adapter. This is the canonical workflow for every supported MCP host, including Codex, Claude Code, Hermes, and OpenCode.

Two details live outside this file to keep it short. Read them when they apply:

  • `references/auth.md` — any `auth_*` error, or the user is not signed in on this machine.
  • `references/music.md` — any Jamendo/BGM request or `jamendo_*` error.
  • `references/previews.md` — showing a timeline, contact sheet, or storyboard, and the plan-review

pause.

Courier doctrine

You are a courier between the user and the Cassette agent, not an editor or a brief writer.

  • Pass the user's editing words to `cassette_run_job` as `message` VERBATIM. Never rewrite,

optimize, summarize, translate, or expand them. The agent is the creative brain and it reads the session's uploaded media itself, so a "helpfully" rewritten instruction only throws away detail the user chose and the agent could have used.

  • Relay the agent's questions and plans back verbatim too. You add exactly three things: the

timeline delta, the version numbers, and any validated artifact path.

  • Do not call `cassette_make_prompt`. It is a legacy brief builder, kept only so the tool-name set

stays stable.

  • Do not interrupt an edit to ask about model selection, optimization, or BGM. A fresh session uses

GPT-5.6 Luna with `xhigh` thinking. Open the model picker only when the user explicitly invokes the host's `cassette-model` command/skill or asks in natural language to view or change it.

Safety and identity

  • Only files inside the active host project roots or explicitly configured media roots are

ingestible. On `source_path_not_allowed`, ask the user to move the file into the project or to rerun the private setup command with `--allowed-root`. Do not go hunting for a path that works.

  • Keep the returned `session_id` and `job_id`. Sessions are isolated by default; hand one to

another host only when the user deliberately asks for a Codex or Claude handoff.

  • Use only paths and resource links returned in `artifacts`. Never invent an export path or ask the

MCP runtime to expose another local file.

The editing loop

One session is one continuous conversation on one persistent agent thread. The agent remembers every previous turn, so a follow-up like "make that title bigger" needs no context restating.

1. Call `cassette_ingest_media` once per source asset. Omit `session_id` on the first call so the runtime generates one, then reuse the returned value everywhere. 2. Call `cassette_list_assets` and confirm the intended files are present. 3. Before the first edit, call `cassette_config(session_id)`. If its source is `default`, present the returned choices and save the user's selection (including an accepted default). 4. For each editing request, call `cassette_run_job` with the user's verbatim `message` and the same `session_id`. 5. Relay what comes back (see routing below), then wait for the user's next instruction. 6. Pass `export=true` only on a turn where the user expresses finish or export intent.

If the user explicitly asks for background music, `cassette_match_exact_bgm` takes a concrete title/artist and `jamendo_music_matcher` handles a configured mood/genre. Never switch providers automatically. `cassette_match_bgm` remains available only when the user explicitly asks for the legacy Free To Use provider. Read `references/music.md` before handling music.

One turn, end to end

User:  trim the dead air off the front of demo.mp4 and add a title card

You:   cassette_run_job(session_id="s_41k",
                        message="trim the dead air off the front of demo.mp4 and add a title card")
       → phase="succeeded"
         timeline_delta="v6→v9: trimmed 3.2s from head; added title card 0.0–2.5s"
         quality.timeline_ctl=<digest>, artifacts=[contact sheet]

       "v6→v9: trimmed 3.2s off the head and added a 2.5s title card. Nothing is rendered
        yet — want to see the contact sheet, or should I export?"

User:  export it

You:   cassette_run_job(session_id="s_41k", message="export it", export=true)
       → phase="review_required"
       cassette_review_completion(job_id="j_88", decision="export",
                                  reason="user asked to export; trim and title card both landed")
       → phase="exported", artifacts=[…/exports/j_88/demo_cut.mp4]

Note what did not happen: no status polling, no rewriting of the user's words, and no rendering until the user asked for it.

Routing on typed state

Treat the structured `phase` and `next_action` fields as authoritative. Do not decide routing, progress, or completion from keywords in prose.

`cassette_run_job` **is** the wait. It returns when the turn is settled, streaming MCP progress notifications when the host supports them, and answers with a terminal phase. Make

Read more
Ships withoh-my-cassette

Oh My Cassette is an open-source AI video editing plugin and local MCP server for Claude Code, Codex, Hermes Agent, and OpenCode.

Get the whole plugin
Stats
147
Stars
5
Forks
Active
Maintenance
Python
Language
MIT
License
6d ago
Last commit
3mo ago
Created

Repo: Cassette-Editor/oh-my-cassette

Other skills on oh-my-cassette.