Teaching Claude Code to Direct: A Stateful Video-Editing Skill Built on Gemini's Interactions API and MCP A developer built omni-skill-claude, a Claude Code skill that wraps Google's gemini-omni-flash-preview model in a FastMCP server, enabling stateful video editing from the terminal. The skill leverages Gemini's Interactions API to allow iterative edits without re-prompting, supporting tasks like generating videos from text, animating images, interpolating keyframes, restyling clips, and uploading to YouTube. TL;DR: omni-skill-claude wraps Google's gemini-omni-flash-preview model Omni Flash in a tiny FastMCP server and packages it as a Claude Code skill. You type "generate a video of a fox running through snow" into Claude Code, and it just... does it. Then you say "make it nighttime with snowfall" and it editsthe same videowithout re-prompting the whole scene. It can also animate a still image, interpolate between two keyframes, restyle a video you already have — and when you're happy, upload the result to YouTube. Without leaving your terminal. Most video-generation workflows are stateless . You send a prompt, you get frames back, and the model immediately forgets everything. Want to tweak the result? You re-describe the entire scene and pray the character, lighting, and camera work survive the round trip. Narrator: they don't. Google's Omni Flash — gemini-omni-flash-preview — takes a different approach. It's the video-generation model in Google's Gemini "Omni" line: built for fast, high-fidelity clips, and — the headline feature — wired into the stateful Interactions API , which lets you iterate on a video across multiple turns while the model keeps the visual context server-side. The "Omni" part isn't branding fluff — the model accepts genuinely mixed multimodal input. A single request's input can be a plain string, or a list of typed parts: text parts, base64-encoded image parts, and document parts pointing at a video you've uploaded via the Gemini File API. The model composes whatever you hand it into one clip. That single mechanism covers five distinct ways to make a video: .mp4 out — landscape 16:9 or portrait 9:16 , chosen at generation time.And on top of all five sits the stateful layer: every one of those calls made with store=True returns an interaction ID , and any result can then be refined turn after turn with incremental edit prompts — same characters, same lighting, same camera language — because the model retrieves the stored visual context instead of making you re-describe it. Three practical realities to know going in: generation is synchronous and slow the call blocks until the video is ready , it's billable per generation , and outputs get big fast — past ~4 MB you want File-API delivery instead of inline base64. The server and skill below exist largely to absorb those realities for you. This repo glues all of that into Claude Code , so your coding agent can generate and iteratively refine videos as a natural part of a session. It ships as two things in one repo: omni-video-agent , a single-file FastMCP app in server.py exposing exactly eight tools. omni-video that teaches Claude The Interactions API is Gemini's stateful endpoint. The core loop looks like this: client.interactions.create ... with a prompt and store=True . interaction id previous interaction id , and the model edits the So instead of this stateless suffering : "A tracking shot of a red fox running through fresh snow at golden hour, birch trees, low sun, shallow depth of field, and now alsoat night with heavy snowfall" ...you write this: "Make it nighttime with heavy snowfall." That's it. The stored context holds the rest. A few practical details the server handles for you: 16:9 landscape or 9:16 portrait and inline default — the video comes back as base64, fine for short clips or uri — the output lands on the Google File API and the server polls until it's ready, then downloads it. Videos get big fast; past ~4 MB, uri saves you from payload-limit failures you'd otherwise discover the hard way.The Model Context Protocol is an open standard for connecting AI assistants to tools and data. Before it, giving a model access to some service meant writing a bespoke integration for each assistant — N assistants × M services, everyone reinventing the same plumbing. MCP collapses that: a tool author writes one MCP server that exposes typed tools, and any MCP-capable client Claude Code, Claude Desktop, and a growing list of others can discover and call them with no per-client glue code. An MCP server is usually a small local process that speaks JSON-RPC over stdio. The client launches it, asks "what tools do you have?", and from then on the model can call them like functions. The omni-video-agent server exposes exactly eight: | Tool | What it does | |---|---| generate video | Text → video. Saves locally as .mp4 , returns the path + an interaction ID. | edit video | Stateful edit: takes the previous interaction ID + a description of only the change. | animate image | A still image + a motion prompt → the image comes to life. | interpolate images | Two keyframe images + a transition prompt → the video between them. | generate with subjects | Reference images of people/objects + a scene prompt → those subjects, directed. | edit user video | Uploads a video you already have via the Gemini File API and restyles it "Make it a Pixar animation style" . | upload to youtube | Publishes a finished .mp4 via the YouTube Data API v3 one-time OAuth setup; defaults to private . | get help | The full tool reference, delivery-mode guidance, and cinematic prompting tips. | Errors come back as 🔴 ... text strings rather than protocol errors, so the agent can read and react to them. Two conventions run through the whole surface. Every video tool takes a delivery parameter — 'inline' default; the video comes back as base64 in the response or 'uri' the output lands on the Google File API and the server polls until it's ACTIVE , then downloads — use it for anything over ~4 MB . And every video tool returns a text report carrying the saved local path plus the interaction ID to chain into the next edit. Videos land on disk as