ffmpeg-mcp
The ffmpeg-mcp server gives AI assistants the ability to perform video and audio editing using FFmpeg through natural language commands, eliminating the need to remember complex command-line flags.
Get Video Metadata — Probe a file to retrieve stream info, codecs, duration, and technical details.
Extract Frames — Save frames as images, either evenly spaced, at a time interval, or one per second.
Extract Audio — Strip the audio track from a video and save it as a
.wavfile.Clip Video — Cut a sub-clip by specifying a start time and duration.
Crop Video — Crop to a region using width, height, and x/y offset parameters.
Scale Video — Upscale to 1080p, 2K, or 4K while preserving aspect ratio.
Make a GIF — Convert a video segment into an optimized GIF.
Overlay Image — Composite an image (e.g., logo/watermark) with control over position, opacity, scale, and timing.
Overlay Video — Place a looping video on top of another with positioning and scaling options.
Trim & Concatenate — Trim multiple clips and stitch them together into one video.
Normalize Clips — Batch-normalize multiple clips in parallel to a common resolution, frame rate, codec, and compression settings.
Concatenate with Transitions — Join clips with smooth xfade transitions (e.g., fade, wipeleft, dissolve, circlecrop, and more).
Provides tools for media processing including video metadata retrieval, frame and audio extraction, scaling, cropping, clipping, GIF creation, and video concatenation with transitions and overlays.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ffmpeg-mcp extract the audio from recording.mp4"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.

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
Related MCP server: ff-toolkit
🛠️ Available Tools
Tool | What it does | Key parameters |
| Probe a file for streams, codecs, duration, etc. |
|
| Save frames as images (evenly, by interval, or 1/sec) |
|
| Pull audio out to a |
|
| Upscale to |
|
| Crop to a region |
|
| Cut a sub-clip by start + duration |
|
| Turn a segment into an optimized GIF |
|
| Composite an image (logo/watermark) with timing & opacity |
|
| Overlay a (looping) video onto another |
|
| Trim multiple clips and stitch them together |
|
| Normalize clips to a common res/fps/codec (in parallel) |
|
| Concatenate clips with an |
|
?marks optional parameters.concat_clips_with_transitionsupports many transitions —fade,wipeleft,slideup,circlecrop,dissolve,pixelize,radial, and dozens more.
📦 Requirements
Verify FFmpeg is available:
ffmpeg -version🚀 Quick Start
1. Clone & install
git clone https://github.com/yubraaj11/ffmpeg-mcp.git
cd ffmpeg-mcp
uv sync --frozen2. Connect it to your MCP client
Point your client at the server using the snippets below. Replace /path/to/ffmpeg-mcp with the absolute path to your clone.
{
"mcpServers": {
"ffmpeg-mcp": {
"command": "uv",
"args": ["--directory", "/path/to/ffmpeg-mcp/ffmpeg_mcp", "run", "main.py"],
"env": { "PYTHONPATH": "/path/to/ffmpeg-mcp" }
}
}
}{
"mcpServers": {
"ffmpeg-mcp": {
"autoApprove": [],
"disabled": false,
"timeout": 60,
"command": "uv",
"args": ["--directory", "/path/to/ffmpeg-mcp/ffmpeg_mcp", "run", "main.py"],
"env": { "PYTHONPATH": "/path/to/ffmpeg-mcp" },
"transportType": "stdio"
}
}
}3. Restart your client and start editing
"Extract 5 evenly-spaced frames from
intro.mp4.""Make a 3-second GIF from
clip.movstarting at 12s.""Concatenate
a.mp4,b.mp4, andc.mp4with a 1-secondwipelefttransition between them."
Processed files are written under ffmpeg_mcp/processed_elements/.
🧰 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 & helpersEvery 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:
Write a function in
ffmpeg_mcp/services/your_tool.py.Export it from
ffmpeg_mcp/services/__init__.py.Register it in
main.pywithmcp.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
fastmcp— the MCP server frameworkffmpeg-python— Python bindings for FFmpegpydantic— data validationcolorlog— colored logs
Available Tools
12 toolsclip_videoA
Generate a video clip from the given video file using ffmpeg-python.
Args: input_video_path (str): Path to the source video file. start_timestamp (float, optional): Start time in seconds. Defaults to 0.0. duration (float, optional): Clip length in seconds. Defaults to 5.0.
Returns: str: Path to the generated clip, or an exception message string on failure.
Inputs: input_video_path (required), start_timestamp, duration.
concat_clips_with_transitionA
Concatenate multiple video clips with transitions.
Args: input_video_clips (List[str]): A list of file paths (strings) to the video clips that will be concatenated. transition_type (str, optional): The type of transition to apply between clips. Supported transitions include: - fade (default), fadeblack, fadewhite, distance - wipeleft, wiperight, wipeup, wipedown - slideleft, slideright, slideup, slidedown - smoothleft, smoothright, smoothup, smoothdown - circlecrop, rectcrop, circleclose, circleopen - horzclose, horzopen, vertclose, vertopen - diagbl, diagbr, diagtl, diagtr - hlslice, hrslice, vuslice, vdslice - dissolve, pixelize, radial, hblur - wipetl, wipetr, wipebl, wipebr - zoomin, fadegrays, squeezev, squeezeh - hlwind, hrwind, vuwind, vdwind - coverleft, coverright, coverup, coverdown transition_duration (float, optional): Duration of the transition effect in seconds.
Returns: str: The absolute path to the final concatenated video with transitions applied.
Inputs: input_video_clips (required), transition_type, transition_duration. Returns: result
crop_videoB
Crop a video using ffmpeg-python.
Params: input_video_path: Path to input video (required) safe_crop: If True, allows exact cropping (ignores mod-2 restrictions). Default: False height: Output height (default: 480) width: Output width (default: 640) x_offset: Top-left X coordinate of crop (default: 0) y_offset: Top-left Y coordinate of crop (default: 0)
Returns: str: Path to the cropped video.
Inputs: input_video_path (required), safe_crop, height, width, +2 more.
extract_audioB
Function to extract audio from the given input video.
Params: input_video_path (str): Path to the input video.
Returns: audio_file_path (str): Path to the audio file.
Inputs: input_video_path (required).
extract_framesA
Extract frames from a video file and save each frame with a unique UUID filename.
Behavior:
- If number_of_frames is provided, extracts that many frames evenly across the video.
If requested frames exceed total frames available, caps at total frames.
- If timestamp_offset is provided (and number_of_frames is None), extracts frames
at every given second interval.
- If neither is provided, defaults to extracting one frame per second.
- number_of_frames takes priority if both are provided.
Params: input_video_path (str): Path to the input video file. number_of_frames (Optional[int]): Total number of frames to extract evenly across the video. timestamp_offset (Optional[int]): Time interval in seconds between frames.
Returns: List[str]: List of file paths for the extracted frames with UUID-based filenames.
Inputs: input_video_path (required), number_of_frames, timestamp_offset. Returns: result
get_normalized_clipsA
Normalize multiple video clips in parallel by adjusting resolution, frame rate, codec, and compression parameters.
Parameters: input_video_clips (list[str]): should give input video clips in the form of string resolution (tuple, optional): Target resolution as (width, height). Defaults to (1280, 720). frame_rate (int, optional): Target frame rate. Defaults to 30. crf (int, optional): Constant Rate Factor for quality control (lower = better quality). Defaults to 23. audio_bitrate (str, optional): Target audio bitrate. Defaults to '128k'. preset (str, optional): Encoding speed vs. compression efficiency preset. Defaults to 'fast'. max_workers (int, optional): Number of parallel worker threads. If None, uses os.cpu_count().
Returns: list: Sorted list of file paths to the successfully normalized video clips.
Notes: - Runs normalization tasks in parallel using ThreadPoolExecutor. - Includes a progress bar (tqdm) to track processing status. - Automatically determines the number of workers based on CPU cores if not specified. - Skips clips that encounter errors but continues processing the rest.
Inputs: input_video_clips (required), resolution, frame_rate, crf, +2 more.
get_video_metadataC
Function to extract metadata of the given input video.
Params: input_video_path (str): Path to the input video.
Returns: JSON of the video metadata.
Inputs: input_video_path (required).
make_gifB
Make gif using video path provided by user.
Args: input_video_path (str): Path to the source video file. start_timestamp (float, optional): Start time in seconds. Defaults to 0.0. duration (float, optional): Clip length in seconds. Defaults to 4.0.
Returns: str: Path to the generated clip, or an exception message string on failure.
Inputs: input_video_path (required), start_timestamp, duration.
overlay_imageA
Overlay an image on top of a video with timing control.
Args: input_video_path (str): Path to background video. overlay_image_path (str): Path to image file. output_filename (str): Output video filename (saved inside VIDEO_OVERLAY_PATH). positioning (Literal): Where to place overlay. scale (tuple | None): (width, height) to resize image before placing. keep_audio (bool): Whether to keep background audio. opacity (float | None): Transparency level (0–1). None = no alpha applied. start_time (float): When to start showing overlay (seconds). duration (float | None): How long to show overlay (seconds). None = until end of video.
Returns: str: Path to generated video.
Inputs: input_video_path (required), overlay_image_path (required), output_filename, positioning, +5 more. Returns: result
overlays_videoA
Overlay a video on top of another with simple positioning. Loops the overlay video until the background video ends, trimming any extra frames.
Args: input_video_path (str): Path to background video. overlay_video_path (str): Path to overlay video. output_filename (str): Name of the output video file (saved inside VIDEO_OVERLAY_PATH). positioning (Literal): Where to place overlay. scale (tuple): (width, height) to resize overlay video before placing. keep_audio (bool): Whether to keep background audio.
Returns: str: Path to the generated video.
Inputs: input_video_path (required), overlay_video_path (required), output_filename, positioning, +2 more. Returns: result
scale_videoA
Upscales a video to 1080p, 2K, or 4K using FFmpeg while preserving aspect ratio and color accuracy.
Args: input_video_path (str): Path to the input video file. resolution (str, optional): Target resolution for upscaling. Acceptable values are '1080p', '2k', or '4k'. Defaults to '1080p'.
Returns: str: Path to the upscaled video if successful.
Inputs: input_video_path (required), resolution. Returns: result
trim_and_concat_operationA
Trim and concatenate multiple videos (portrait orientation, normalize format).
Args: inputs (list[dict]): Each dict must have: - 'path' (str): path to the video file - 'start_time' (str, optional): start time in seconds - 'end_time' (str, optional): end time in seconds width (int): Width to scale each video (portrait). height (int): Height to scale each video (portrait). x (int): X position for overlay (default 0). y (int): Y position for overlay (default 0).
Returns: str: Path to the output video if successful. None: If an error occurs.
Inputs: inputs (required), width, height, x, +1 more. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 12 tools
Most tools have distinct purposes like clipping, cropping, extracting, and overlaying, but some overlap exists: 'clip_video' and 'trim_and_concat_operation' both involve trimming video segments, which could cause confusion. However, their descriptions clarify that 'clip_video' is for single clips while 'trim_and_concat_operation' handles multiple videos with concatenation, mitigating ambiguity.
The naming is mixed with no clear pattern: some tools use verb_noun (e.g., 'clip_video', 'crop_video'), others use noun_verb (e.g., 'get_video_metadata'), and there are inconsistencies like 'overlay_image' vs. 'overlays_video'. While readable, the lack of a consistent convention across all tools reduces predictability.
With 12 tools, the count is well-scoped for a video processing server, covering essential operations like editing, conversion, and metadata extraction. Each tool serves a specific function without redundancy, making the set comprehensive yet manageable for typical video manipulation tasks.
The toolset covers core video processing needs including clipping, cropping, scaling, overlaying, and format conversion, with good lifecycle coverage. Minor gaps exist, such as no direct tool for adding subtitles or advanced audio editing beyond extraction, but agents can likely work around these with the provided tools.
Maintenance
Related MCP Connectors
FFmpeg processing for video, audio and images via MCP with OAuth and shared account allowance.
Hosted MCP tools for FFmpeg-style video and audio processing through FFMPEG API.
FFmpeg Micro - The FFmpeg Api - www.ffmpeg-micro.com Transcode videos from n8n or Make using FFmpeg in the cloud. MCP Server: https://github.com/ffmpeg-micro/ffmpeg-micro-mcp/
MCP server for the FFmpeg Micro video transcoding API — create, monitor, download transcodes.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables comprehensive video/audio processing, analysis, and streaming via natural language by exposing 40+ FFmpeg tools as MCP tools.22-
- AlicenseAqualityDmaintenanceEnables LLMs to perform FFmpeg operations like clipping, merging, extracting audio, adding subtitles, and transcoding videos via a set of tools exposed as an MCP server.58MIT
- AlicenseAqualityDmaintenanceProvides 30+ FFmpeg video and audio editing tools via MCP, enabling AI assistants to perform operations like trimming, transcoding, overlays, and composition directly.274MIT
- AlicenseNot gradedqualityDmaintenanceMCP server exposing headless ffmpeg operations for video, audio, and image processing via auto-generated typed tools, enabling agentic media file manipulation.GPL 3.0