Skip to main content
Glama

ffmpeg-mcp

ffmpeg / ffprobe を安全な引数渡しで LLM から叩く MCP サーバー

TypeScript Node.js FFmpeg MCP License: MIT

シェル文字列を組み立てずに ffmpeg を駆動する。probe は構造化 JSON で返す。


概要

LLM に ffmpeg -i ... -c:v libx264 ... を文字列として書かせると、エスケープ事故・シェルインジェクション・クォート漏れが起きる。このサーバーは全ての引数を配列で渡し、spawn でシェルを経由せずに起動する。ffprobe は常に -print_format json で叩いて、LLM に渡す前に構造化する。

要素

実装

トランスポート

stdio MCP

子プロセス

spawn(ffmpeg|ffprobe, args[]) — シェル不使用

出力制御

stderr 末尾 16 KB だけ残す (ffmpeg は verbose)

タイムアウト

既定 600 s、FFMPEG_TIMEOUT または timeout 引数で上書き

特徴

アクション

用途

probe

ffprobe を JSON で叩き、format / streams / chapters を間引いて返す(未知ファイルへの第一手)

convert

再エンコード。video_codec / audio_codec / crf / preset / video_bitrate / audio_bitrate / fps / resolution=[w,h] / オプションの startduration / extra_args

trim

既定で -c copy による無劣化カット(再エンコードなし、ほぼ瞬時)。copy: false で再エンコード可。精度注意: copy モードは I-frame 単位で seek する為、start が最大数秒ズレる事がある(ffmpeg の仕様)。フレーム精度が必要なら copy: false

concat

concat デマクサで input_paths: string[] を無劣化結合(全入力が同コーデック/同パラメータ前提)

extract_audio

-vn + オプションで audio_codec / audio_bitrate。拡張子でコーデック自動選択

thumbnail

指定時刻(既定 00:00:01)の 1 フレームを画像として書き出し、size=[w,h] で縮小可

run

生 args の escape hatch。use_ffprobe: true で ffprobe を叩く

version

ffmpeg -version / ffprobe -version の先頭行

watermark

ロゴ画像を動画にオーバーレイ。position (top-left / top-right / bottom-left / bottom-right / center), margin, watermark_scale (メイン動画幅に対する比, デフォルト 0.15), opacity

loudnorm

EBU R128 2-pass ラウドネス正規化。1 パス目で measured_I / TP / LRA / thresh / offset を取得、2 パス目で linear モードで再エンコード。target_i (-16), target_tp (-1.5), target_lra (11) がデフォルト

speed

再生速度変更。setpts=PTS/speed + atempo チェーン (0.5〜2.0 超える倍率も自動チェーン化)。video_only / audio_only で片方だけ

batch

jobs[] を sequential 実行。stop_on_error で中断制御、各ジョブの ok/exit_code/duration/stderr テイルを個別レポート

処理フロー

sequenceDiagram
    participant LLM
    participant MCP as ffmpeg-mcp (stdio)
    participant FF as ffmpeg / ffprobe

    LLM->>MCP: {action: "probe", input: "in.mp4"}
    MCP->>FF: spawn(ffprobe, [-v error, -print_format json, -show_format, -show_streams, ...])
    FF-->>MCP: stdout (JSON)
    MCP->>MCP: JSON.parse + 間引き
    MCP-->>LLM: {format, streams[], chapters[]}

    LLM->>MCP: {action: "convert", input, output, crf: 23, preset: "medium"}
    MCP->>FF: spawn(ffmpeg, [-n, -i, in.mp4, -crf, 23, -preset, medium, out.mp4])
    FF-->>MCP: exit_code / stdout / stderr(tail) / duration_ms
    MCP-->>LLM: JSON

インストール

git clone https://github.com/cUDGk/ffmpeg-mcp.git
cd ffmpeg-mcp
npm install
npm run build

ffmpeg と ffprobe が PATH にある事が前提。別パスにある場合は FFMPEG_PATH / FFPROBE_PATH で明示する。

使い方

Claude Code に登録

claude mcp add ffmpeg -- node <install-dir>/dist/index.js

環境変数

変数

デフォルト

用途

FFMPEG_PATH

ffmpeg

ffmpeg 実行ファイル

FFPROBE_PATH

ffprobe

ffprobe 実行ファイル

FFMPEG_TIMEOUT

600000

単一呼び出しのタイムアウト (ms)

FFMPEG_MCP_ALLOW_ROOTS

(未設定)

出力先のホワイトリスト(OS の path.delimiter 区切り — Windows は ;、POSIX は :)。設定すると、ここで挙げたディレクトリ配下にしか出力できない

FFMPEG_MCP_MAX_JOBS

32

batch.jobs[] の上限

FFMPEG_MCP_ALLOW_ROOTS の例:

# Windows (PowerShell): 区切りは ";"
$env:FFMPEG_MCP_ALLOW_ROOTS = "C:\Users\me\videos;D:\renders"
# Linux / macOS: 区切りは ":"
export FFMPEG_MCP_ALLOW_ROOTS="/home/me/videos:/srv/renders"

セキュリティ

  • 既定で出力ファイルは上書きしない (ffmpeg -n)。意図的に上書きしたい場合は overwrite: true を渡す(ffmpeg -y)。

  • run / convert.extra_args は無検査ではない。ffmpeg のプロトコルプレフィックス (concat:, subfile:, http:, file:, tee:, data: 等) や、ファイルを読む系のフィルタ (movie=..., subtitles=..., drawtext=...textfile=..., sendcmd=...) や、-protocol_whitelist 上書き / -f tee は拒否する。それ以外の動作については LLM 任せにせず、ホスト側でも FFMPEG_MCP_ALLOW_ROOTS を設定する事を推奨する。

  • 全ての -i 呼び出しに -protocol_whitelist file,crypto,data を強制注入する(HTTP/RTMP/RTSP 経由の任意 URL fetch を遮断する)。

呼び出し例

未知ファイルの確認 → 中央 10 秒を切り出し → H.264 に再圧縮:

{"action": "probe", "input": "C:/tmp/raw.mkv"}

{"action": "trim", "input": "C:/tmp/raw.mkv", "output": "C:/tmp/clip.mkv",
 "start": "00:01:00", "duration": 10}

{"action": "convert", "input": "C:/tmp/clip.mkv", "output": "C:/tmp/out.mp4",
 "video_codec": "libx264", "crf": 23, "preset": "medium",
 "audio_codec": "aac", "audio_bitrate": "128k"}

サムネイル 4 枚(0 / 10 / 20 / 30 秒):

{"action": "thumbnail", "input": "in.mp4", "output": "t0.jpg", "time": 0, "size": [640, 360]}
{"action": "thumbnail", "input": "in.mp4", "output": "t1.jpg", "time": 10, "size": [640, 360]}
{"action": "thumbnail", "input": "in.mp4", "output": "t2.jpg", "time": 20, "size": [640, 360]}
{"action": "thumbnail", "input": "in.mp4", "output": "t3.jpg", "time": 30, "size": [640, 360]}

ラウドネス正規化 (podcast / YouTube 公開用):

{"action": "loudnorm", "input": "raw.wav", "output": "normalized.m4a",
 "target_i": -14, "target_tp": -1.0, "target_lra": 7,
 "audio_codec": "aac", "audio_bitrate": "192k"}

ロゴ透かし (右上 10% サイズ、60% 透過):

{"action": "watermark", "input": "in.mp4", "output": "out.mp4",
 "watermark_path": "logo.png",
 "position": "top-right", "margin": 20,
 "watermark_scale": 0.1, "opacity": 0.6}

2x 早回し:

{"action": "speed", "input": "in.mp4", "output": "2x.mp4", "speed_factor": 2.0}

複数動画を一括処理 (最初の失敗で中断):

{"action": "batch", "stop_on_error": true, "jobs": [
  {"action": "trim", "input": "raw.mp4", "output": "clip.mp4", "start": 10, "duration": 30},
  {"action": "convert", "input": "clip.mp4", "output": "final.mp4", "video_codec": "libx264", "crf": 20},
  {"action": "thumbnail", "input": "final.mp4", "output": "poster.jpg", "time": 5}
]}

run で完全制御(例: フィルタ複雑グラフ):

{"action": "run", "args": [
  "-y", "-i", "in.mp4",
  "-filter_complex", "[0:v]scale=1280:720,fps=30[v]",
  "-map", "[v]", "-map", "0:a",
  "-c:v", "libx264", "-crf", "20",
  "out.mp4"
]}

設計メモ

  • 意図ベースのアクション(convert_to_mp4 等)を増やさない。増やしても結局 extra_args で逃げるだけで、LLM に覚えさせる面が増える。アクションは処理のカテゴリ単位(convert / trim / concat / thumbnail)に留める。

  • stderr は末尾 16 KB だけ残す。ffmpeg は 1 回の実行で数 MB のログを吐く事があり、LLM のコンテキストを焼き尽くす。

  • 相対パスは CWD から resolve。LLM が相対パスを渡しても意図通りの場所に書き出される。

  • タイムアウト既定 10 分。長時間エンコードは timeout で上書き。

v0.3.1 修正

バグ修正:

  • batchwatermark ジョブで watermark_pathwatermark / watermark_scalescale のフィールドマッピングが欠落していた問題を修正(ウォーターマーク画像と scale が常に無視されていた)。

  • batchspeed ジョブで speed_factorspeed のフィールドマッピングが欠落していた問題を修正(speed が undefined になり Number.isFinite チェックで必ずエラーになっていた)。

  • README の mermaid ダイアグラムで -y と表示されていたのを -n (no-clobber デフォルト) に修正。

v0.3.0 修正

セキュリティ・バグ・UX を一括で改修したリリース。

セキュリティ:

  • run / convert.extra_args の引数を assertSafeFfmpegArgs() で検査。ffmpeg プロトコルプレフィックス・ファイル読み取り系フィルタ・-protocol_whitelist 上書き・-f tee を拒否。

  • 全ての -i 呼び出しに -protocol_whitelist file,crypto,data を強制注入。

  • safeInputPath() を全アクションの入力に適用(Windows ドライブレター C:\... は許可、http: / concat: 等は拒否)。

  • 既定値を -y (force overwrite) → -n (no clobber) に変更。明示的に overwrite: true を渡した時だけ上書きする。

  • FFMPEG_MCP_ALLOW_ROOTS で出力先をディレクトリ単位でホワイトリスト可能。

  • FFMPEG_MCP_MAX_JOBSbatch.jobs[] の長さに上限。

  • concat のリストファイルに改行を含むエントリを拒否(行ベースパーサを破壊する為)。

バグ修正:

  • stdout / stderr を Buffer.concat() で組み立てる様に変更(チャンク境界で UTF-8 が壊れる問題を解消)。

  • stdout にも 8 MiB の上限を導入。

  • loudnormPass1 の stderr を切り詰めない。loudnorm の JSON ブロックが落ちる事があった。

  • loudnormPass1timeout を尊重していなかった問題を修正。

  • concat()mkdtempSync を try の中に移動。例外時の temp dir リーク防止。

  • proc.stdout / proc.stderrerror リスナを追加(Windows での EPIPE 未処理を防止)。

  • killProc を非同期化(execFileSync でイベントループを止めない)。

  • speedsetpts=Infinity*PTS を防ぐバリデーション。

  • version の戻り値が空 / 非 0 終了時に isError: true を立てる様に。

  • tsconfig.jsonnoUncheckedIndexedAccess: true

UX:

  • ツール説明に watermark / loudnorm / speed / batch を追記。

  • thumbnail のデフォルト time をドキュメント通りの 00:00:01 に。

  • batch.jobs[].action を厳密な enum に。

  • batch で 1 件でも失敗したら全体の isError を立てる。

  • extra_args が convert 専用である事を明記。

v0.2.1 修正

一部の MCP クライアント (Claude Code の LLM ツール使用パス等) が object / array 引数を JSON 文字列化してからサーバーに渡す挙動があり、extra_args / args / input_paths / resolution / size / jobs が文字列で届くと zod バリデーションで落ちるか、args.push(...p.extra_args) で文字列を spread して 1 文字ずつ ffmpeg の引数に混入する等の事故が起きていた。

修正内容:

  • extra_args / args / input_paths / resolution / size / jobs の zod schema を z.union([<本来の型>, z.string()]) に緩和

  • coerceArray() / coerceObject() ヘルパを追加し、文字列で届いた場合は JSON.parse で配列 / オブジェクトに戻してから使用

  • batch の各 job 内部のネスト配列 (extra_args / resolution / size / args / input_paths) も coerce してから dispatch

Attribution

  • FFmpeg © FFmpeg developers(LGPL/GPL)— 本 MCP はラッパーであり FFmpeg 本体のライセンスに従う

  • Model Context Protocol — 仕様・SDK

ライセンス

MIT License © 2026 cUDGk — 詳細は LICENSE を参照。

A
license - permissive license
-
quality - not tested
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

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/cUDGk/ffmpeg-mcp'

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