ffmpeg-mcp

ffmpeg-mcp

Enables LLMs to safely execute ffmpeg and ffprobe operations by passing arguments as arrays, avoiding shell injection, with support for probe, convert, trim, concat, thumbnail, watermark, speed, loudnorm, and batch processing.

Category
访问服务器

README

<div align="center">

ffmpeg-mcp

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

TypeScript Node.js FFmpeg MCP License: MIT

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


</div>

概要

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 を参照。

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选