Labsco
yubraaj11 logo

ffmpeg-mcp

β˜… 5

from yubraaj11

A Python package for media processing using FFmpeg and FastMCP.

πŸ”₯πŸ”₯πŸ”₯πŸ”₯βœ“ VerifiedFreeQuick setup

ffmpeg-mcp

ffmpeg-mcp 🎬⚑

Edit video and audio by just talking to your AI assistant.

ffmpeg-mcp is a Model Context Protocol server that puts the full power of FFmpeg behind a clean set of tools your LLM can call β€” clip, crop, scale, overlay, concatenate with transitions, extract frames/audio, make GIFs, and more. No command-line flags to memorize.


✨ Why ffmpeg-mcp?

FFmpeg is incredibly powerful and incredibly hard to remember. ffmpeg-mcp hands that power to your AI assistant so you can say what you want in plain English:

"Grab the first 10 seconds of demo.mov, scale it to 1080p, slap my logo in the top-right corner, and turn it into a GIF."

…and the model orchestrates the right tools for you. Each tool is a small, validated Python function β€” easy to read, reuse, and extend.

  • πŸ—£οΈ Natural-language video editing β€” works in any MCP client (Claude Desktop, Cursor, Cline, …)
  • 🧱 12 focused tools β€” composable building blocks instead of one giant black box
  • βœ… Input validation built in β€” paths are checked for existence, emptiness, and validity before FFmpeg runs
  • 🧩 Hackable β€” add a new tool by writing one function and registering it

πŸ› οΈ Available Tools

ToolWhat it doesKey parameters
get_video_metadataProbe a file for streams, codecs, duration, etc.input_video_path
extract_framesSave frames as images (evenly, by interval, or 1/sec)input_video_path, number_of_frames?, timestamp_offset?
extract_audioPull audio out to a .wav fileinput_video_path
scale_videoUpscale to 1080p / 2k / 4k, aspect-preservinginput_video_path, resolution="1080p"
crop_videoCrop to a regioninput_video_path, width, height, x_offset, y_offset, safe_crop
clip_videoCut a sub-clip by start + durationinput_video_path, start_timestamp, duration
make_gifTurn a segment into an optimized GIFinput_video_path, start_timestamp, duration
overlay_imageComposite an image (logo/watermark) with timing & opacityinput_video_path, overlay_image_path, positioning, opacity, start_time, duration
overlays_videoOverlay a (looping) video onto anotherinput_video_path, overlay_video_path, positioning, scale
trim_and_concat_operationTrim multiple clips and stitch them togetherinputs: [{path, start_time?, end_time?}], width, height
get_normalized_clipsNormalize clips to a common res/fps/codec (in parallel)input_video_clips, resolution, frame_rate, crf
concat_clips_with_transitionConcatenate clips with an xfade transitioninput_video_clips, transition_type="fade", transition_duration

? marks optional parameters. concat_clips_with_transition supports many transitions β€” fade, wipeleft, slideup, circlecrop, dissolve, pixelize, radial, and dozens more.


🧰 Project Layout

ffmpeg_mcp/
β”œβ”€β”€ main.py              # MCP server entry point β€” registers all tools
β”œβ”€β”€ services/            # one module per tool
β”œβ”€β”€ configs/             # colored logging setup
└── exceptions/          # structured error messages
utils/                   # validation decorators & helpers

Every tool returns either the output file path or a structured JSON error (status, error_type, message, time), so failures are easy for the model to read and recover from.


🀝 Contributing

Contributions are very welcome! Adding a tool is roughly:

  1. Write a function in ffmpeg_mcp/services/your_tool.py.
  2. Export it from ffmpeg_mcp/services/__init__.py.
  3. Register it in main.py with mcp.tool(name_or_fn=your_tool).

Please run the linter before opening a PR:

uv run ruff check .

Found a bug or have an idea? Open an issue β€” and if this project saves you from another ffmpeg man-page dive, consider leaving a ⭐.


πŸ“š Built With