Skip to main content
Glama
AbyAbyss

ffmpeg-mcp-video-editor

by AbyAbyss

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
FFMPEG_MCP_LOG_LEVELNoLog level: DEBUG, INFO, WARNING, ERROR.INFO
FFMPEG_MCP_WORKSPACENoOutputs, job store, cached binaries and models.~/.ffmpeg-mcp/workspace
FFMPEG_MCP_FFMPEG_PATHNoUse specific ffmpeg binary instead of resolving one.
FFMPEG_MCP_FFPROBE_PATHNoUse specific ffprobe binary instead of resolving one.
FFMPEG_MCP_ALLOWED_ROOTSNoRoots that inputs and outputs must sit under.$HOME
FFMPEG_MCP_AUTO_DOWNLOADNoAllow downloading a static ffmpeg build.1
FFMPEG_MCP_WHISPER_MODELNoWhisper model size: tiny, base, small, medium, large-v3, turbo.base
FFMPEG_MCP_MAX_INPUT_BYTESNoRejects oversized inputs up front.16 GiB
FFMPEG_MCP_MAX_JOB_SECONDSNoWall-clock cap per job.10800
FFMPEG_MCP_RETENTION_HOURSNoHow long finished jobs and their files are kept.24
FFMPEG_MCP_WORKER_CONCURRENCYNoJobs running at once, per process.2

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
cancel_jobA

Stop a queued or running job.

A queued job is cancelled immediately. A running one is asked to stop: the worker that owns it terminates the ffmpeg subprocess within a second or so, which works even when the job was started by a different process such as the local UI. Jobs that already finished are left alone.

concatA

Join two or more clips end to end into a single file.

When every clip already shares a codec, resolution and frame rate, this remuxes with no re-encoding. Otherwise the clips are normalised first — scaled and padded to a common resolution, resampled to a common frame rate and audio layout — and then concatenated, which requires a re-encode.

convert_formatA

Transcode a file to a different container or codec.

Sensible codec defaults are chosen per container (H.264/AAC for mp4 and mov, VP9/Opus for webm, MP3 or AAC for audio-only targets); override them through 'encode'. Set audio_only to extract the audio track.

job_resultA

Fetch the output paths of a completed job.

Errors if the job has not finished yet — poll job_status first. For a failed job this raises with the structured failure reason; for a successful one the 'result' field carries the output path and a probe of the rendered file.

job_statusA

Check how a queued job is progressing.

Returns one of queued, running, done, failed or cancelled, with a progress percentage parsed from ffmpeg's own output. Poll this after queueing work, then call job_result once the status is 'done'.

list_capabilitiesA

Report the resolved ffmpeg build and which encoders and filters it has.

Use this before assuming something is available — hardware encoding (videotoolbox, nvenc, qsv), newer filters like xfade, or this server's optional Whisper and vision extras. Answers immediately.

list_jobsA

List jobs newest first, scoped to a project and returned a page at a time.

Defaults to the active project, so a long-running server shared by several sessions does not bury your work in everyone else's. Pass project='all' to see everything, and use offset with limit to page through a busy queue — 'total' and 'has_more' say whether there is another page.

list_projectsA

List every project in the job store, with how much work each holds.

Shows which one this session is currently working in, and how many jobs each project has queued, running, done and failed — a quick way to find the name of work started earlier, or in another session.

probe_mediaA

Read a media file's technical metadata.

Returns container format, duration in seconds, per-stream codec, resolution, frame rate, bit rate, audio channels and sample rate, and subtitle streams.

This answers immediately rather than returning a job id. Call it before any edit that depends on the source dimensions or duration, and call it again on an output to verify a render.

set_projectA

Work under a named project, so parallel sessions do not mix together.

Everything queued afterwards is filed under this name, and outputs without an explicit path land in the project's own directory. list_jobs then shows only this project by default, which keeps a busy shared queue readable.

Two sessions editing different videos should each set their own project. The name is created on first use — there is nothing to set up beforehand.

speed_rampA

Speed a clip up or slow it down, video and audio independently.

By default the audio is time-stretched so pitch is preserved, chained through as many atempo stages as the factor needs. Set keep_pitch false for a tape speed-up sound, or drop_audio to discard the track. Set audio_speed to hold audio at a different rate from the video.

transformA

Apply geometric transforms — crop, scale, rotate, flip — in one pass.

Operations compose into a single filter chain in the order crop, scale, pad, rotate, flip, so the whole change costs one re-encode. Give only one of scale_width/scale_height to preserve the aspect ratio; give both with pad_to_fit to letterbox rather than stretch.

trimA

Cut a segment out of a video or audio file.

Stream-copies when the source codecs allow it, which is near-instant but snaps the cut to the nearest keyframe; pass mode='reencode' when the in and out points must be frame-accurate. The finished job reports the output's actual duration so you can confirm what you got.

apply_curvesA

Apply a tone curve, either a named preset or your own control points.

Points are given in 0..1 input/output coordinates and may be listed in any order; they are sorted and validated before the job runs, because ffmpeg silently ignores a malformed curve rather than reporting an error. Give a preset or points, not both.

apply_lutA

Apply a .cube colour lookup table.

The LUT is parsed and validated before the job is queued — declared size, row count and numeric content — because ffmpeg reports a malformed cube with an error that gives no hint what is wrong. Use 'strength' below 1.0 to blend the graded result back against the original.

build_srtA

Turn a list of timed text segments into a valid SRT subtitle file.

Pure text handling — no ffmpeg call, so this answers immediately. Segments are sorted, empty ones dropped, and overlapping cues truncated so they do not fight each other on screen. Long lines are word-wrapped. Feed the result to burn_captions, or edit it first.

burn_captionsA

Burn an SRT or ASS subtitle file permanently into the video.

Font, size, fill and outline colour, position and margins are all controllable. Colours are given as hex (#RRGGBB) and converted to ASS's inverted BGR form internally. The subtitle file is handed to ffmpeg by path, so caption text containing colons, commas or brackets cannot corrupt the filter graph.

For styling of an .ass file's own embedded styles, note that these overrides replace them.

color_gradeA

Adjust brightness, contrast, saturation, gamma and colour temperature.

All five are applied in one filter chain, so the whole grade costs a single re-encode. Stages left at their neutral value are omitted entirely. Temperature is a relative artistic warm/cool control, not an absolute white balance in Kelvin.

text_overlayA

Draw titles and lower-thirds over the video, with timing and animation.

Each item has its own in and out point, named position (or explicit x/y), font size and colour, optional outline or background box, and an animation: fade, or a slide from any direction. Everything renders in one pass.

The text itself is written to a sidecar file and referenced by path rather than embedded in the filter graph, so any characters are safe — including colons, commas, brackets, quotes and %{...} sequences, which are drawn literally.

auto_captionA

Transcribe a video and burn the captions in, as one job.

Chains transcription, SRT generation and caption burning so you do not have to orchestrate three jobs. The generated SRT is kept alongside the video, so you can correct the text and re-burn it with burn_captions if Whisper mishears something.

Set translate_to_english to caption foreign-language speech in English.

transcribe_audioA

Transcribe speech in an audio or video file using Whisper.

Returns timed segments and, if word_timestamps is set, per-word timings. The spoken language is auto-detected unless you name one. Pass srt_path to have the transcript written straight out as a subtitle file.

This can take a while — roughly real-time on CPU with the 'base' model, and several times that with 'large-v3' — so poll job_status. The first run with a given model also downloads its weights.

translate_transcriptA

Transcribe non-English speech and translate it into English.

This uses Whisper's built-in translate mode, which only ever outputs English — Whisper cannot translate into any other target language. To reach a different language you would need a separate translation step applied to the transcript this returns.

blur_facesA

Blur every face in a clip, following each one as it moves.

Each tracked face gets its own blurred region whose position is driven over time, so the blur stays on the person rather than covering a fixed rectangle. Boxes are expanded past the detected face by default so hair and chin are covered too.

Set exclude_primary to keep the main subject sharp and blur everyone else — the usual requirement for street interviews. Because a missed detection means an unblurred face, review the output before publishing it.

detect_facesA

Find faces in a video, sampled over time.

Returns per-timestamp bounding boxes with confidence, in both source pixels and 0..1 normalised coordinates, plus 'tracks' — detections linked across frames into one entry per person, with the likely main subject flagged.

Sampling at 2 fps is usually enough to follow a talking head; raise sample_fps for fast movement. Needs the 'vision' extra; the small detection model is downloaded and cached on first use.

detect_scenesA

Find hard cuts in a video and report the shots between them.

Useful for chopping raw footage into clips: feed the returned scene start and end times straight into trim. Uses ffmpeg's own scene-change score, so unlike the other phase 4 tools this needs no vision dependency.

Lower the threshold to catch softer cuts, raise it if handheld camera motion is being reported as cuts.

track_and_cropA

Reframe a clip to a new aspect ratio, following a face across the timeline.

The classic use is turning a horizontal interview into a vertical clip that keeps the speaker in frame. The crop path is smoothed before rendering — a crop that snaps frame to frame looks worse than a slightly imperfect one that glides — and clamped so it never runs off the edge of the source.

Call detect_faces first if you want to choose which person to follow, then pass its track_id. With no face found, this falls back to a centre crop unless fallback is 'fail'.

add_transitionA

Join two clips with a cross-fade or wipe-style transition.

The clips overlap by 'duration' seconds, so the result is shorter than the two clips added together by exactly that much. The second clip is conformed to the first one's resolution and frame rate first, since xfade requires both sides to match.

Available transitions include fade, fadeblack, dissolve, the wipe family (wipeleft/right/up/down), the slide family, and circleopen/circleclose.

fade_audioA

Fade a file's audio in at the start, out at the end, or both.

The fade-out is positioned from the file's measured duration, so you give its length rather than working out its start time yourself. Video is stream- copied, so only the audio is re-encoded.

list_resolution_presetsA

List the named resolution presets, fit modes and focus points resize_video accepts.

Answers immediately. Use it when you want to name a target platform rather than work out its pixel dimensions.

mix_audioA

Mix background music or effects under a primary voice track.

Set 'duck' on a track to have it automatically drop in level whenever the voice track is loud, which is what makes music sit under narration without manual level automation. Per-track gain and start offsets are applied before the mix.

If the primary input is a video, its picture is carried through untouched.

normalize_audioA

Normalise a file's loudness to a target level (EBU R128).

By default this runs two passes: the first measures the actual loudness, the second corrects to the target using those measurements. That is noticeably more accurate than the single streaming pass, which has to guess as it goes.

-16 LUFS suits online video, -23 LUFS is the broadcast standard.

overlay_mediaA

Composite an image or video on top of another — picture-in-picture, watermark, or a chroma-keyed composite.

Position with a named corner or explicit x/y, scale with 'width', and fade it in and out of existence with 'start'/'end'. Set chroma_key to a hex colour to key out a green or blue screen from the overlay before compositing.

render_timelineA

Render a complete edit — clips, transitions, overlays, captions, audio — in one pass.

This is the entry point for driving the server from a script rather than calling tools one at a time, and it is exactly the structure the local UI's timeline editor produces.

The timeline declares an output width, height and frame rate; every clip is scaled and padded to fit, so sources may differ. Each clip has in and out points into its source, an optional speed, and an optional transition into the next one. Text overlays, media overlays (picture-in-picture or watermarks), a burned-in subtitle file, and extra audio tracks with optional ducking all layer on top.

resize_videoA

Convert a video to a different resolution or aspect ratio.

Use a named preset for the common targets — 'reel', 'tiktok', 'youtube_short' and 'story' are all 1080x1920; 'youtube_1080p', 'youtube_4k', 'instagram_square' and 'instagram_portrait' do what they say — or give an explicit width and height, or an aspect_ratio such as '9:16'.

'fit' decides what happens to the picture that no longer fits when the shape changes:

  • cover (default) zooms and crops to fill; nothing is letterboxed but the edges are lost. Use 'focus' to choose which part survives.

  • contain fits the whole picture inside and pads with solid bars.

  • blur fits the whole picture inside over a blurred, zoomed copy of itself — the usual look for turning landscape footage vertical.

  • stretch distorts the picture to fit exactly.

For a talking-head video where the subject must stay in frame, prefer track_and_crop, which follows the face instead of cropping to a fixed point.

analyze_videoA

Measure brightness and colourfulness across sampled frames.

This is how a grade gets checked rather than guessed at: whether contrast crushed the shadows, whether a highlight is clipping, whether a clip is genuinely greyscale, and how evenly exposed a cut is across its shots.

Answers immediately; each sample is a separate fast seek.

extract_filmstripA

Tile several frames into one contact sheet, to survey footage at a glance.

The fastest way to find out what is actually in a clip — where the good moments are, where the camera settles, which shots are worth cutting to. Answers immediately: each frame is a separate fast seek, so the cost tracks the number of frames, not the length of the video.

extract_frameA

Save a single frame as an image so it can actually be looked at.

Answers immediately. Seeking is done before decoding, so grabbing a frame from an hour-long file costs the same as from a short one.

Use it to check what is in footage before cutting, and to confirm a render looks the way it was meant to.

measure_audioA

Measure a file's loudness: mean and peak level, and EBU R128 LUFS.

Use it to decide whether audio is worth keeping — room tone and handling noise measure very differently from speech — and to check what a mix or a normalisation actually did.

This one is a job rather than an instant answer: integrated loudness is defined over the whole file, so it cannot be sampled.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AbyAbyss/ffmpeg-mcp-video-editor'

If you have feedback or need assistance with the MCP directory API, please join our Discord server