Video Frames について
Video Framesは、画像入力に対応するモデルへ動画フレームと測定可能な動画情報を提供するローカルMCPサーバー兼CLIです。タイムコード付きフレーム抽出に加え、メタデータ取得や、シーン・無音・ラウドネスの任意スキャンを行います。
主な機能
- 01タイムコード付き画像フレームの抽出
- 02動画メタデータの確認
- 03シーン・無音・ラウドネスの任意スキャン
- 04フレームとスキャン結果のキャッシュ再利用
- 05環境とMCP接続のチェック
活用シーン
- 01画像入力対応モデルで動画の指定箇所を確認
- 02処理前に動画メタデータを確認
- 03映像のシーン切り替え、無音、ラウドネスをスキャン
- 04時間範囲が重なるフレームを再利用
MCP 対応
Video Framesは、stdio経由で`view_frames`と`video_info`をMCPクライアントに提供します。ローカルへの導入とffmpegが必要で、返されたフレームの利用には画像入力対応モデルが必要です。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
2掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| end | any | いいえ | |
| start | number | いいえ | |
| video | string | はい | |
| format | any | いいえ | |
| quality | integer | いいえ | |
| interval | number | いいえ | |
| max_edge | integer | いいえ | |
| max_frames | any | いいえ |
詳細
mcp-video-frames — 動画 MCP サーバー
画像のみを扱うモデルが動画を確認できるようにする MCP サーバーです。タイムコード付きのフレームに加え、測定可能な動画のプロパティも取得できます。
利用可能なツール
このサーバーは次のツールを提供します。
view_frames- 指定した時間範囲からサンプリングし、各フレームの前にタイムコードを付けて画像として返しますvideo_info- コンテナのメタデータを返します。オプションでファイル全体のシーン/無音/ラウドネススキャンも実行できます
対話するモデルは、画像入力を受け付ける必要があります。受け付けない場合、返されたフレームは破棄されるか、テキストに変換されて劣化します。
これはローカルサーバーです。どこにもホストされておらず、クライアントから接続先として指定する必要があります。以下のセルフホストを参照してください。
PyPI からインストール
pip install mcp-video-frames # or run it without installing: uvx mcp-video-frames
これによりコンソールスクリプトが1つインストールされ、そのスクリプトがサーバーとして動作します。クライアントから接続してください。
{
"mcpServers": {
"video-frames": { "command": "mcp-video-frames" }
}
}
サブコマンドを指定せず、パイプ経由で標準入出力を使用すると MCP として動作します。ターミナルでは、ハングせずにヘルプを表示します。mcp-video-frames doctor は、実行環境を確認します。
この方法では、PATH 上に ffmpeg と ffprobe が必要です。プライベートな仮想環境にこれらをインストールし、すぐに使えるクライアント設定も用意する場合は、代わりに以下のセルフホストを利用してください。
セルフホスト
システムの Python には何もインストールせず、依存関係はプロジェクト専用の .venv/ にインストールされます。クライアント設定は、そのインタープリターを直接参照します。
- リポジトリをクローンします
git clone https://github.com/Azzy-H/mcp-video-frames.git
cd mcp-video-frames
- 仮想環境とクライアント設定を生成します
python setup_mcp.py
setup_mcp.py が行うのは次の3つだけです。
- このディレクトリに
.venv/を作成します(Python 3.10 以降の任意のインタープリターで実行できます)。 requirements.txtに記載された2つの実行時依存関係を、その.venv/にインストールします。- パスが入力済みの
mcp-config.jsonを書き込みます。
オプション:
python setup_mcp.py --max-images 12 # match your client's image limit
python setup_mcp.py --print # print the config only; write nothing
python setup_mcp.py --ffmpeg <path> # ffmpeg is not on PATH
ffmpeg が見つからない場合、スクリプトは Windows 用のビルド済みバイナリを .venv/ にダウンロードするか、インストール済みのものを指定するか、スキップするかを選べるようにします。システム全体にインストールされることはありません。
- 接続する前に環境を確認します
.venv/Scripts/python run_server.py doctor # Windows
.venv/bin/python run_server.py doctor # macOS / Linux
ffmpeg/ffprobe のパスとバージョン、必要なフィルターがあるかどうか、キャッシュディレクトリに書き込み可能かどうかを報告します。不足しているものを明示するため、推測する必要はありません。仮想環境内の ffmpeg は自動的に見つかるので、事前に何かをエクスポートする必要はありません。
test_server.py はさらに、標準入出力経由でサーバーと実際の MCP 通信を行います。そのため、クライアントを設定する前に一連の動作を検証できます。
.venv/Scripts/python test_server.py connect <video file path> # Windows
.venv/bin/python test_server.py connect <video file path> # macOS / Linux
ハンドシェイク、ツール一覧、2n + 1 のコンテンツブロックの順序、単一フレームのリクエストが PNG として返されるかどうか、上限を超えたリクエストが拒否されるかどうかを確認します。また、stdout が JSON-RPC ストリーム用にクリーンな状態に保たれていることも確認します。
- この MCP サーバーを追加します
生成された mcp-config.json をクライアントの設定にマージします。すでに mcpServers セクションがある場合は、そこに video-frames エントリーを追加するだけです。run_server.py が自動的に src/ を sys.path に追加するため、PYTHONPATH は不要で、どこにも pip install する必要はありません。
/path/to/mcp-video-frames を、システム上のこのリポジトリの実際のパスに置き換えてください。Windows では、インタープリターは .venv\Scripts\python.exe です。
アンインストール:.venv/ を削除し、設定エントリーを削除してください。それ以外には何も書き込まれていません。
要件
- Python 3.10 以降
ffmpegとffprobe。setup_mcp.pyがこれらをプロジェクト専用の.venv/にインストール(またはダウンロード)し、サーバーはまず自身のインタープリターの隣を検索し、その後PATHを検索します。そのため、仮想環境にインストールした場合はFFMPEG_PATHをエクスポートする必要はありません。ffmpegは必須です。ffprobeがない場合、メタデータは ffmpeg 自身のヘッダー出力の解析にフォールバックするため、取得できるフィールドが少なくなり、doctorがその旨を明示します- 画像入力を受け付けるクライアントモデル
ツール
view_frames
時間範囲をサンプリングし、タイムコード + 画像を交互に並べたシーケンスを返します。ひとつの時点を見るには、start と end に同じ値を設定します。
| パラメーター | 型 | デフォルト | 備考 |
|---|---|---|---|
video | string | — | 絶対パス(必須) |
start | number | 0 | 開始時刻(秒) |
end | number | start + interval | 終了時刻(秒) |
interval | number | 1.0 | サンプリング間隔、0.05~600 秒 |
max_frames | integer | 12 | この呼び出しで返すフレーム数。画像上限まで増やせます |
max_edge | integer | 768 | 長辺のピクセル数、64~4096 |
format | jpeg | png | 範囲指定の場合は jpeg、単一フレームの場合は png | |
quality | integer | 85 | jpeg の品質、1~100 |
結果は 2n + 1 個のコンテンツブロックです。
text: {"n":0,"t":0.0}
image: <frame 0>
text: {"n":1,"t":1.0}
image: <frame 1>
...
text: {"video":"...","frames":12,"range":[0.0,11.0],"interval":1.0,
"format":"jpeg","max_edge":768,"clamped":false,"cached":9,
"limits":{"max_images_per_call":20,"max_image_bytes":10485760,
"max_total_bytes":41943040}}
ブロックの順序は重要です。タイムコードのない画像からは、時間軸に沿った推論ができません。clamped は範囲が動画の長さに合わせて調整されたかどうか、cached はディスクから取得したフレーム数を示します。limits には適用中の上限が繰り返し記載されるため、拒否されて初めて上限を知る必要はありません。
範囲指定ではデフォルトで jpeg を使用します。 同じ辺の長さであれば、png よりおよそ 1 桁小さく、多くのクライアントでバイト数の上限内により多くのフレームを収められるためです。細部が重要な場合は、単一フレームを png でリクエストしてください。
上限を超える呼び出しは失敗します。切り詰めは行われず、間隔が広げられることもありません。 サンプリング間隔を暗黙に粗くすると、呼び出し元が想定する時間精度が損なわれるため、呼び出し全体が失敗します。いずれかのフレームが検証に失敗した場合、フレームは一切返されません。
video_info
動画のメタデータを返します。detail="basic" はコンテナーヘッダーのみを読み取り、すぐに返します。detail="full" は、シーンチェンジ、無音区間、EBU R128 ラウドネスを検出するためのファイル全体の網羅的なスキャンを追加します。
{
"path": "", "sha256": "", "size_bytes": 0,
"duration": 0.0, "fps": 0.0, "width": 0, "height": 0,
"video_codec": "", "pix_fmt": "",
"color_range": "", "color_space": "", "is_hdr": false,
"audio_tracks": [], "subtitle_tracks": [], "chapters": [],
"detail": "full",
"scene_cuts": [1.23, 5.67],
"silences": [{"start": 12.0, "end": 14.5, "duration": 2.5}],
"loudness": {"integrated_lufs": -23.0, "true_peak_dbfs": -1.2, "lra": 5.0},
"scan": {"ffmpeg_version": "", "computed_at": "", "cached": false}
}
detail="basic" の場合、scene_cuts/silences/loudness/scan フィールドは空ではなく、存在しません。「値がない」ことと「スキャンされていない」ことは別の意味だからです。最初の full 呼び出しではファイル全体をスキャンし、以降の呼び出しではキャッシュを再利用します。force=true を指定すると再計算します。
設定
環境変数はデフォルト値より優先されます。
| 変数 | デフォルト | 用途 |
|---|---|---|
MCP_VIDEO_MAX_IMAGES | 20 | 1 回の呼び出しで返す画像の最大数(最も重要な上限) |
MCP_VIDEO_CACHE_DIR | setup_mcp.py が生成した .cache/。それ以外の場合は <system temp>/mcp-video-frames-cache | キャッシュのルートディレクトリー |
FFMPEG_PATH / FFPROBE_PATH | 自動検出 | PATH より先に確認 |
MCP_VIDEO_MAX_IMAGE_BYTES | 10485760 | 1 フレームあたりのバイト数上限 |
MCP_VIDEO_MAX_TOTAL_BYTES | 41943040 | 結果全体のバイト数上限 |
MCP_VIDEO_MAX_IMAGE_DIM | 8192 | 1 フレームあたりの辺の長さの上限 |
MCP_VIDEO_CACHE_MAX_BYTES | 5368709120 | キャッシュサイズの上限 |
MCP_VIDEO_FRAME_MAX_AGE_DAYS | 14 | フレームの最大経過日数 |
MCP_VIDEO_SCENE_THRESHOLD | 0.3 | シーンチェンジの検出感度 |
MCP_VIDEO_MAX_IMAGES は、1 回の呼び出しで返せるフレーム数を制限します。クライアントに合わせて設定してください。 クライアントによって上限は異なり、低すぎる場合は単に控えめになるだけですが、高すぎるとバッチ全体が利用できなくなります。max_frames のデフォルトは 12 で、この上限までしか増やせません。
有効な上限はツールの説明にも記載され、すべての view_frames の結果にも繰り返し記載されるため、拒否される前に確認できます。
CLI
同じパッケージには、トラブルシューティングや一括処理に使える CLI も含まれています:
mcp-video-frames doctor # environment self-check
mcp-video-frames info video.mp4 # basic metadata
mcp-video-frames scan video.mp4 # pre-build the full scan
mcp-video-frames scan --dir ./videos # process a whole directory
mcp-video-frames frames video.mp4 --start 0 --end 5 # frames, as content-block JSON
mcp-video-frames cache --stats # cache usage
mcp-video-frames cache --prune # evict cache entries
プロジェクトをインストールせずに(上記の セルフホスト可能 を参照)、同じサブコマンドを使うにはランチャーを使用します:
.venv/Scripts/python run_server.py doctor # Windows
.venv/bin/python run_server.py info video.mp4 # macOS / Linux
引数なしで実行するとヘルプが表示されます。MCP サーバーとしては、引数を受け取りません。stdin がパイプ(MCP クライアントが提供する形式)の場合、引数なしで実行するとサーバーが起動します。このため、stdio の場合は何も設定する必要がありません。
doctor は JSON レポートを出力した後、人間向けの判定結果を 1 行で表示するため(「自己チェックに成功しました」/「自己チェックに失敗しました」)、stdout が純粋な JSON にならない唯一のサブコマンドです。CLI と MCP ツールは同じコア関数を呼び出すため、ターミナルでの動作とモデル向けの動作に食い違いが生じることはありません。
キャッシュ
場所:サーバーの起動方法によって異なります。
| デプロイ方法 | キャッシュのルートディレクトリ |
|---|---|
setup_mcp.py(推奨) | このプロジェクト内の .cache/ |
MCP_VIDEO_CACHE_DIR を設定せずに通常のパッケージをインストールした場合 | <system temp>/mcp-video-frames-cache |
セットアップスクリプトでは、cwd とともに、プロジェクト内の .cache/ が意図的に設定されています。相対パスはクライアントの作業ディレクトリを基準に解決されるため、cwd がないと、キャッシュはクライアントの起動場所によって変わります。これは一時ディレクトリの既定値より予測しにくくなります。すでに .gitignore に含まれています。
MCP_VIDEO_CACHE_DIR を設定すると、どちらの既定値も上書きされます。解決されたパスは、起動時に stderr に表示されます。
キャッシュ内のデータはすべて再生成可能です。ディレクトリを削除しても常に安全ですが、再プローブが必要になります。
エントリはコンテンツハッシュ(サイズ+mtime+先頭と末尾の各 1 MB)をキーにし、フレームは絶対タイムスタンプごとに個別に保存されます。そのため、重複する範囲の処理結果は再利用されます。0〜20 秒を見た後に 10〜30 秒を見る場合、10〜20 秒の範囲はすでにディスク上にあります。
キャッシュをシステムの一時ディレクトリに保存している場合、オペレーティングシステムによるクリーンアップを当てにしないでください。プラットフォームによる違いが大きすぎるためです。
| プラットフォーム | 一時ディレクトリのクリーンアップ |
|---|---|
| Windows | 実質的にありません。ストレージ センサーはディスク容量が逼迫したときにのみ実行され、使用中のファイルはスキップします |
| Linux | systemd-tmpfiles が /tmp の古いファイル(約 10 日)を削除します。/tmp は tmpfs であることが多く、再起動時にクリアされます |
| macOS | $TMPDIR は、時期が定められていないタイミングでシステムによってクリーンアップされます |
そのため、サーバーは自動的にクリーンアップします。MCP_VIDEO_CACHE_MAX_BYTES(既定値:5 GB)を超えると、LRU 方式で動画エントリ全体を削除します。また、フレームには 14 日間の保持期限(MCP_VIDEO_FRAME_MAX_AGE_DAYS)を適用します。
階層は再計算コストに基づいています。フレームは再生成が容易なため最初に削除され、動画全体のスキャン結果(video_info(detail="full"))は再生成にコストがかかるため、優先的に保持されます。
削除処理はツール呼び出しの応答後に非同期で実行されるため、応答がブロックされることはなく、起動時に全件スキャンすることもありません。
複数のクライアントで 1 つのキャッシュを共有します。読み書きはファイルロックで保護され、書き込みは一時ファイルと os.replace を経由して行われます。一覧表示後、読み取り前に削除されたフレームは、エラーとして報告されるのではなく再生成されます。
ライセンス
MIT — LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。