ffmpeg-mcp-video-editor
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| FFMPEG_MCP_LOG_LEVEL | No | Log level: DEBUG, INFO, WARNING, ERROR. | INFO |
| FFMPEG_MCP_WORKSPACE | No | Outputs, job store, cached binaries and models. | ~/.ffmpeg-mcp/workspace |
| FFMPEG_MCP_FFMPEG_PATH | No | Use specific ffmpeg binary instead of resolving one. | |
| FFMPEG_MCP_FFPROBE_PATH | No | Use specific ffprobe binary instead of resolving one. | |
| FFMPEG_MCP_ALLOWED_ROOTS | No | Roots that inputs and outputs must sit under. | $HOME |
| FFMPEG_MCP_AUTO_DOWNLOAD | No | Allow downloading a static ffmpeg build. | 1 |
| FFMPEG_MCP_WHISPER_MODEL | No | Whisper model size: tiny, base, small, medium, large-v3, turbo. | base |
| FFMPEG_MCP_MAX_INPUT_BYTES | No | Rejects oversized inputs up front. | 16 GiB |
| FFMPEG_MCP_MAX_JOB_SECONDS | No | Wall-clock cap per job. | 10800 |
| FFMPEG_MCP_RETENTION_HOURS | No | How long finished jobs and their files are kept. | 24 |
| FFMPEG_MCP_WORKER_CONCURRENCY | No | Jobs 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
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| 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:
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
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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