Skip to main content
Glama
MoviePy MCP Server

MoviePy MCP Server

by vive1101011

MoviePy MCP Server

An LLM-friendly Model Context Protocol server for video and audio editing, built on MoviePy v2 and FastMCP. It lets MCP clients (Claude Desktop, Claude Code, Cursor, etc.) trim, merge, resize, overlay, mix audio, and render video through natural language.

Design

The server is built around a clip registry:

  1. load_video / load_audio / load_image returns a clip_id.

  2. Every editing tool takes a clip_id and returns a new clip_id — operations chain without touching disk, and source clips are never mutated, so an agent can branch or retry any step.

  3. export_clip renders a file. preset can be youtube_1080p, reels_1080x1920, or podcast_aac.

Every tool returns uniform metadata (duration_seconds, size, fps, has_audio, history), so the model always knows the state of an edit without extra probing. Errors are actionable: they name the bad argument, list known clip_ids, and suggest the fix.

Reads and writes stay inside MOVIEPY_MCP_MEDIA_ROOT (your home directory when unset) or the system temp directory. The registry is one session on stdio. HTTP (MOVIEPY_MCP_TRANSPORT=http) gives each client its own registry and requires MOVIEPY_MCP_TOKEN. Source files are written to .moviepy-mcp/ under the workspace and reopened after a restart; project_status lists edits that were not rebuilt.

The default tool list is the everyday edit path. Set MOVIEPY_MCP_ADVANCED=1 to also expose blur, chroma key, Ken Burns, and the other effects.

Code is split under src/moviepy_mcp/: config, paths, registry, presets, editing, prompts, and tools/.

Related MCP server: Video Edit MCP Server

Requirements

  • Python 3.10+

  • FFmpeg on your PATH (sudo apt install ffmpeg / brew install ffmpeg)

Installation

git clone <your-repo-url> moviepy-mcp
cd moviepy-mcp
pip install -e .
# or with uv:
uv pip install -e .

Run it directly to verify:

moviepy-mcp

Client configuration

Cursor (~/.cursor/mcp.json)

Add a moviepy entry under mcpServers (same shape as other local uv servers). Restart Cursor or reload MCP after saving:

{
  "mcpServers": {
    "moviepy": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "C:/Users/vivek/projects/moviepy-mcp",
        "moviepy-mcp"
      ],
      "env": {
        "MOVIEPY_MCP_MEDIA_ROOT": "C:/Users/vivek/Videos",
        "MOVIEPY_MCP_ADVANCED": "1"
      }
    }
  }
}

Replace the --directory path with your clone of this repo. uv run uses the project’s pyproject.toml / .venv, so you do not need a global moviepy-mcp install.

Claude Desktop / Claude Code (stdio)

If the package is installed (pip install -e . or uv pip install -e .):

{
  "mcpServers": {
    "moviepy": {
      "command": "moviepy-mcp"
    }
  }
}

Or without installing, via uv:

{
  "mcpServers": {
    "moviepy": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/path/to/moviepy-mcp",
        "moviepy-mcp"
      ]
    }
  }
}

Tools

Category

Tools

Load / create

load_video, load_audio, load_image, upload_media, download_video, create_color_clip, create_text_clip, create_slideshow

Inspect

list_clips, get_clip_info, preview_frame, delete_clip, list_fonts, project_status

Time

trim, concatenate, crossfade, change_speed, loop_clip, reverse_clip, freeze

Geometry

resize, crop, rotate, mirror, even_size, reframe

Visual FX

fade, to_grayscale, adjust_colors, chroma_key, invert_colors, gamma_correct, multiply_color, add_margin, painting, blur, sharpen, set_opacity, freeze_region, slide_in, slide_out, scroll, ken_burns

Audio

set_volume, duck_audio, normalize_audio, delay_audio, set_stereo_volume, extract_audio, remove_audio, attach_audio, mix_audio_tracks, remove_silence

Compositing

overlay_clip, grid_clips, add_subtitles

Output

save_frame, export_image, export_clip, download_media

Example agent workflow

"Take intro.mp4, keep seconds 5–20, add the title 'Q2 Review' for the first 4 seconds, fade out at the end, and save as final.mp4."

The agent will typically call:

load_video(path="intro.mp4")                          -> video_a1b2c3d4
trim(clip_id="video_a1b2c3d4", start_seconds=5, end_seconds=20)
create_text_clip(text="Q2 Review", font_size=64, duration_seconds=4)
overlay_clip(base_clip_id=..., overlay_clip_id=..., position="top")
preview_frame(clip_id=..., time_seconds=0)
export_clip(clip_id=..., output_path="final.mp4")

Notes

  • Text rendering requires a font; pass font="/path/to/font.ttf" to create_text_clip if the default is unavailable on your system.

  • GIF export uses write_gif (defaults to 12 fps); everything else goes through FFmpeg.

  • Source clips are reopened from .moviepy-mcp/*.json after a restart. Derived edits are listed by project_status and are not rebuilt. Set MOVIEPY_MCP_PERSIST=0 to keep nothing on disk.

  • MOVIEPY_MCP_MAX_CLIPS (default 48) drops the oldest clip that nothing else still uses. MOVIEPY_MCP_MAX_WIDTH, MAX_HEIGHT, and MAX_DURATION reject oversized media.

  • download_video will not read browser cookies unless MOVIEPY_MCP_ALLOW_BROWSER_COOKIES=1.

  • file_manager opens a drop zone in the chat. After upload, list_files returns each clip_id. download_media opens a player and download button for the finished clip; export_clip still writes a path you choose.

  • preview_frame returns an image to the model (downscaled to 640px by default). Use it after edits to verify before export_clip.

  • Clip metadata and a first-frame PNG are resources: clip://{clip_id}/info and clip://{clip_id}/frame.

  • crossfade dissolves overlapping clips; concatenate is still a hard cut.

  • even_size crops odd dimensions (H.264). add_subtitles accepts SRT or WebVTT via srt_text or srt_path.

  • download_video uses yt-dlp for YouTube and Instagram. Public URLs work as-is; private Instagram media may need cookies_from_browser (e.g. chrome) or a cookies_file. Respect each platform's terms of service and only download content you have rights to use.

  • reframe changes aspect ratio for Shorts/Reels-style output: mode="crop" center-crops to fill, mode="pad_blur" keeps the whole frame and fills the bars with a blurred, zoomed copy.

  • create_slideshow builds a video from a list of image paths in one call, with optional crossfade transitions and background audio (looped or trimmed to fit).

  • mix_audio_tracks layers audio clips simultaneously (voice + music + SFX) with per-track volume; concatenate still plays clips one after another.

  • remove_silence cuts near-silent gaps out of an audio or video clip (podcast/vlog jump-cut editing) based on a loudness threshold and minimum gap length.

  • save_frame and export_image take at_end=True to grab the last frame without knowing the exact duration.

License

MIT

Available Tools

27 tools
adjust_colorsC

Adjust brightness/contrast.

Inputs: clip_id (required), contrast, brightness. Returns: object

attach_audioB

Set or mix an audio track onto a video clip.

Inputs: audio_clip_id (required), video_clip_id (required), mix_with_existing. Returns: object

change_speedB

Speed a clip up or down.

Inputs: factor (required), clip_id (required). Returns: object

chroma_keyB

Mask a color in a video clip (chroma key / green screen).

Inputs: clip_id (required), color_rgb (required), stiffness, threshold. Returns: object

concatenateA

Join clips end-to-end, in the given order.

All ids must be the same kind (all video/image, or all audio).

Inputs: clip_ids (required), method. Returns: object

create_color_clipA

Create a solid-color video clip (backgrounds, spacers, title cards).

Inputs: width (required), height (required), color_rgb (required), duration_seconds (required), +1 more. Returns: object

create_text_clipA

Create a standalone text clip (titles, captions, credits).

To place text ON TOP of a video, create it here and then use overlay_clip with position and timing.

Inputs: text (required), font, color, label, +3 more. Returns: object

cropB

Crop to the rectangle (x1, y1)-(x2, y2). Origin is the top-left.

Inputs: x1 (required), x2 (required), y1 (required), y2 (required), +1 more. Returns: object

delete_clipB

Remove a clip from the registry and free its resources.

Inputs: clip_id (required). Returns: object

export_clipA

Render a clip to disk. THIS is the step that writes a file.

Inputs: clip_id (required), output_path (required), fps, codec, +1 more. Returns: object

extract_audioB

Pull the audio track out of a video as a new audio clip.

Inputs: clip_id (required). Returns: object

fadeB

Add fade-in and/or fade-out. Works for video (to black) and audio.

Inputs: clip_id (required), fade_in_seconds, fade_out_seconds. Returns: object

get_clip_infoA

Get full metadata for one clip: duration, size, fps, audio, history.

Inputs: clip_id (required). Returns: object

list_clipsA

List every clip currently in the registry with its metadata.

Inputs: no named parameters. Returns: object

load_audioA

Load an audio file (mp3, wav, aac, ogg...) into the registry.

Inputs: path (required), label. Returns: object

load_imageA

Load a still image (png, jpg...) as a video clip of fixed duration.

Useful for slideshows, intros, watermark sources, and overlays.

Inputs: path (required), label, duration_seconds. Returns: object

load_videoA

Load a video file (mp4, mov, avi, webm, mkv...) into the registry.

Inputs: path (required), label. Returns: object

loop_clipA

Repeat a clip. Give either n_times OR total_duration_seconds.

Inputs: clip_id (required), n_times, total_duration_seconds. Returns: object

mirrorB

Flip a clip. axis: 'horizontal' (left-right) or 'vertical' (up-down).

Inputs: clip_id (required), axis. Returns: object

overlay_clipA

Place one clip on top of another (text, watermark, picture-in-picture).

Inputs: base_clip_id (required), overlay_clip_id (required), x, y, +4 more. Returns: object

remove_audioA

Return a muted copy of a video clip (audio track removed).

Inputs: clip_id (required). Returns: object

resizeA

Resize a video/image clip.

Give exactly one of: scale (e.g. 0.5), width, height, or width+height. A single dimension preserves aspect ratio.

Inputs: clip_id (required), scale, width, height. Returns: object

rotateB

Rotate counter-clockwise by the given degrees (use -90 for clockwise).

Inputs: clip_id (required), degrees (required). Returns: object

save_frameA

Save a single frame of a video as an image (png/jpg).

Useful for thumbnails or letting the user preview an edit.

Inputs: clip_id (required), output_path (required), time_seconds. Returns: object

set_volumeA

Scale volume: 0.5 = half, 2.0 = double, 0 = silent.

Works on audio clips and on the audio track of video clips.

Inputs: factor (required), clip_id (required). Returns: object

to_grayscaleC

Convert a video/image clip to black and white.

Inputs: clip_id (required). Returns: object

trimB

Cut a clip to the range [start_seconds, end_seconds].

Inputs: clip_id (required), start_seconds (required), end_seconds. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.6/5.0

    Scored across 27 tools

    Disambiguation5/5

    Every tool targets a distinct operation: loading, creating, transforming, compositing, audio handling, and exporting. Even related tools like adjust_colors and to_grayscale are clearly separate, with no ambiguous overlap.

    Naming Consistency5/5

    Tool names are consistently lowercase snake_case, mostly following a verb_noun pattern (load_video, create_text_clip, export_clip). A few single-word verbs (resize, trim, fade) and to_grayscale are minor deviations but do not break the overall predictable style.

    Tool Count2/5

    With 27 tools, this server is well above the 3-15 tool sweet spot for MCP coherence. The large number increases agent selection difficulty and could be split into focused sub-servers (e.g., core editing vs. audio vs. compositing).

    Completeness5/5

    The server covers the full editing lifecycle: import (load_*), creation (create_*), inspection (list, get, delete), modification (trim, resize, rotate, etc.), compositing (overlay, attach), and export (export_clip, save_frame). No obvious gap for standard MoviePy workflows.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      A lightweight server that exposes FFmpeg's video processing capabilities to AI assistants through the Model Context Protocol (MCP), supporting operations like video format conversion, audio extraction, and adding watermarks.
      8
      53 npm
      25
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      A Model Context Protocol server that enables AI assistants to perform comprehensive video and audio editing operations including trimming, effects, overlays, audio processing, and YouTube downloads.
      35 PyPI
      30
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Enables 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.
      5
      8
      MIT