Skip to main content
Glama

MCP Video Gen

セルフホスト型のMCPサーバーで、ComfyUIやBlenderなどのローカルメディア生成バックエンドを公開するとともに、ローカルメディア分析、編集、FFmpeg、HyperFrames、タイムライン、字幕、音声、およびオーディオユーティリティを提供します。

このプロジェクトはPortainer専用デプロイメント向けに設計されています。公開リポジトリには通常のマルチファイルアプリケーションが含まれていますが、単一のvideo-mcp.yml Stackが不変のGitHubリリースのブートストラップローダーとして機能します。

機能

  • ComfyUIが利用可能な場合、/object_infoによって実際に登録されているComfyUIノードを検出します。

  • マウントされている場合、読み取り専用のComfyUI models/およびcustom_nodes/ディレクトリをスキャンします。

  • 互換性のあるカスタムノードのソース/ドキュメントファイルを検査します。

  • 任意の有効なComfyUI APIワークフローJSONを送信し、キュー/履歴/出力状態を検査します。

  • オプションで、ホストにインストールされたBlenderを認証済みブリッジ経由で制御し、bpy自動化、静止画レンダリング、アニメーションレンダリング、GLBエクスポートを実行します。

  • MCPクライアント/AIから永続キャッシュにファイルをインポートします(テキスト、ワンショットbase64、またはチャンク化されたバイナリ転送を使用)。

  • 認証済みHTTPダウンロード、インラインbase64、または制限付きチャンク化base64読み取りを介して、キャッシュされたファイルをクライアント/AIに返します。

  • 1つのfile_idコントラクトを通じて、入力をアップロードし、出力をキャッシュし、生成された画像、動画、音声、3D、シーン、字幕、その他のファイルを取得します。

  • HTML/CSS/メディアを使用してローカルのHyperFramesプロジェクトを作成およびレンダリングします。

  • FFmpegを使用して、プローブ、トランスコード、連結、オーバーレイ、音声多重化、クロップ、リバース、ループ、スピードランプ、フレーム抽出を行います。

  • 無音、黒/フリーズセクション、ラウドネス、インターレース、クロップ領域、キーフレーム、および客観的なSSIM/PSNRの差異を検出します。

  • コンタクトシート/ストーリーボードを作成し、軽量なフレーム類似性、モーション、重複フレーム、およびベストフレーム分析を実行します。

  • PySceneDetectを使用してシーンを検出および分割します。

  • pysubs2 + FFmpegを使用して、字幕を作成、リタイム、変換、スタイル設定、および焼き付けます。

  • トラック、クリップ、トランジション、マーカー、並べ替え、検査、エクスポートを備えた永続的なOpenTimelineIOタイムラインを維持します。

  • aubioを使用してビート、テンポ、オンセット、ピッチを検出します。

  • RNNoiseを使用してローカルで音声をノイズ除去します。

  • 小型のSilero VAD ONNXモデルを使用して音声セグメントを検出します。

  • whisper.cppを使用してローカルでメディアを文字起こしし、字幕を生成し、単語レベルのタイムスタンプを取得します。

  • オプションで、ユーザーが提供するPiper音声を使用して音声を合成します。Piperはデフォルトで無効になっています。

  • オプションで、オリジンでCloudflare Access JWTを検証し、Cloudflare Tunnelサイドカーを実行します。

このサーバーは、意図的に固定のAI生成ワークフロー、長期記憶、またはエージェントスキルを含んでいません。実行プリミティブを公開するため、クライアントまたは別の知識/スキルMCPがワークフローの構築方法を決定できます。

ComfyUIとBlenderは外部のオプションバックエンドです。どちらかのバックエンドが無効、欠落、または一時的に到達不能な場合でも、MCP自体は正常な状態を維持します。ネットワーク依存のツールは、サーバーをダウンさせたり、バックエンド不在のツールエラーを表示したりする代わりに、モデルが読み取り可能なavailable=false結果を返します。

Related MCP server: comfyui-mcp-server-node

アーキテクチャ

MCP client / AI
   |
   |<------ generic MCP file transfer ------>
   v
MCP Video Gen + persistent file_id cache
   |
   |---------------- optional ComfyUI API
   |                    |
   |                    +-- installed models
   |                    +-- custom nodes
   |                    +-- image/video/audio generation
   |
   |---------------- optional Blender bridge on VM
   |                    |
   |                    +-- bpy scene creation/editing
   |                    +-- .blend / GLB export
   |                    +-- still / animation rendering
   |
   |---------------- HyperFrames
   |---------------- OpenTimelineIO / subtitles
   |---------------- scene / frame analysis
   |---------------- whisper.cpp / Silero VAD / RNNoise / aubio
   +---------------- FFmpeg

All execution paths exchange files through the same MCP cache.

Portainerデプロイメント

Stack定義としてvideo-mcp.ymlを使用します。

オプションのComfyUI

一般的なComfyUI接続変数は次のとおりです。

COMFYUI_HOST=host.docker.internal
COMFYUI_PORT=8188
COMFYUI_SCHEME=http

ファイルシステム検出のために、ComfyUIが存在する場合にホストパスを設定します。

COMFYUI_MODELS_PATH=/host/path/to/ComfyUI/models
COMFYUI_CUSTOM_NODES_PATH=/host/path/to/ComfyUI/custom_nodes

これらのパス変数はMCP起動時に不要になりました。Stackには汎用の空ディレクトリフォールバックがあるため、ComfyUIがインストールされる前に起動できます。ComfyUIが到達不能な場合、そのネットワークツールはモデルにそのステータスを報告し、ローカルMCPツールは引き続き動作します。

オプションのBlender

Blenderはデフォルトで無効になっています。

BLENDER_ENABLED=false
BLENDER_BRIDGE_URL=http://host.docker.internal:9876
BLENDER_BRIDGE_TOKEN=
BLENDER_BRIDGE_TIMEOUT_SEC=7200

推奨される統合方法は、専用の低権限OSアカウントとしてVM上で直接scripts/blender_bridge.pyを実行することです。コンテナは認証済みのローカルHTTPブリッジを介して通信します。Blender自体はホスト上でヘッドレスで実行されます。これにより、MCPコンテナへのホストルートファイルシステムまたはホスト実行可能ファイルのマウントを回避できます。

ブリッジがインストールされたら、Portainerでプライベートに設定します。

BLENDER_ENABLED=true
BLENDER_BRIDGE_URL=http://host.docker.internal:9876
BLENDER_BRIDGE_TOKEN=<same long random token used by the host bridge>

セットアップ、セキュリティ、systemdの強化、ファイルフロー、および例については、**docs/BLENDER_BRIDGE.md**を参照してください。

Cloudflare Tunnel

含まれているCloudflare Tunnelサイドカーを使用する場合は、以下を提供します。

CLOUDFLARED_TUNNEL_TOKEN=<set privately in Portainer>

リモートTunnelホスト名を次の場所に向けます。

http://video-mcp:8000

MCPエンドポイントは次のとおりです。

https://your-public-host.example/mcp

Cloudflare Access / Managed OAuth

アプリケーションは、オリジンでCloudflare Access JWTを検証できます。これらの値をPortainerでプライベートに設定します。

CF_ACCESS_VERIFY=true
CF_ACCESS_TEAM_DOMAIN=https://your-team.cloudflareaccess.com
CF_ACCESS_AUD=<Access application audience tag>
PUBLIC_BASE_URL=https://your-public-host.example

実際のドメイン、オーディエンス、トークン、ブリッジトークン、内部IP、または資格情報は、この公開リポジトリに属しません。

外部バックエンドの可用性

external_backends_statusは、ComfyUIとBlenderの現在の状態を報告します。inventory_summaryには、ローカル機能とともに同じバックエンドステータスが含まれます。

外部バックエンドが利用できない場合、呼び出しは次のような構造を返します。

{
  "ok": false,
  "available": false,
  "backend": "blender",
  "status": "unavailable",
  "message": "Blender integration is disabled..."
}

これはMCPサーバーの障害とは意図的に異なります。モデルは、1つのオプションの実行パスが利用できないことを学習し、別のパスで続行できます。

ファイル転送と共有キャッシュ

生成/インポートされたすべてのアーティファクトはMCPキャッシュに正規化され、file_idによって識別されます。これは、AIクライアント、ComfyUI、Blender、FFmpeg、HyperFrames、字幕、タイムライン、およびオーディオユーティリティ間の交換レイヤーです。

クライアント / AI -> MCP

小規模ファイルの場合:

cache_text_file
cache_file_base64

大規模なバイナリファイルの場合:

file_upload_begin
file_upload_chunk
file_upload_finish
file_upload_abort

チャンクアップロードでは、永続キャッシュに昇格する前に、予想されるバイト長とSHA-256を指定できます。

MCP -> クライアント / AI

メタデータ:

get_cached_file_info

既存の小規模互換パス:

get_output_inline_base64

制限付き汎用読み取り:

read_cached_file_chunk_base64

すべての通常のキャッシュメタデータオブジェクトには、/files/{file_id}と、PUBLIC_BASE_URLが設定されている場合の完全な認証済みダウンロードURLも含まれます。

これは、AIがテキストとしてBlender Pythonスクリプトを作成し、任意の参照アセットをキャッシュに配置し、それらのfile_id値をBlenderに送信し、.blend/.glb/レンダリングを新しいfile_id値として受け取り、それらのファイルをComfyUIまたはローカルの後処理スタックにフィードできることを意味します。

高度なローカルメディアユーティリティ

ランタイムは、FFmpeg/HyperFramesに加えて、いくつかの小さなローカルユーティリティを準備します。Python venvには、PySceneDetect、OpenTimelineIO、pysubs2、ONNX Runtime、NumPy、およびヘッドレスOpenCVが含まれています。Debianは、小さなaubio-tools CLIパッケージを提供します。RNNoiseとwhisper.cppは、固定された上流ソースから永続データボリュームにローカルでビルドされます。

Silero VAD、RNNoise、およびwhisper.cppのモデル/ソースアーティファクトは、永続データボリュームの下に保存されます。RNNoiseのソースとモデル、およびSilero/Whisperモデルのダウンロードでは、明示的なSHA-256検証が使用されます。デフォルトのWhisperモデルは、軽量なローカル文字起こしを目的とした小さな量子化モデルです。モデルのURL/ハッシュとソース参照は、Stack変数を通じてオーバーライドできます。

関連する変数は次のとおりです。

SILERO_VAD_ENABLED=true
SILERO_VAD_MODEL_URL=<public model URL>
SILERO_VAD_MODEL_SHA256=<expected sha256>

RNNOISE_ENABLED=true
RNNOISE_REF=<pinned upstream commit>
RNNOISE_SOURCE_URL=<public source archive URL>
RNNOISE_SOURCE_SHA256=<expected sha256>
RNNOISE_MODEL_URL=<public model URL>
RNNOISE_MODEL_SHA256=<expected sha256>

WHISPER_CPP_ENABLED=true
WHISPER_CPP_REF=v1.8.6
WHISPER_CPP_BUILD_JOBS=2
WHISPER_MODEL_AUTO_DOWNLOAD=true
WHISPER_MODEL_NAME=tiny-q5_1
WHISPER_MODEL_URL=<public model URL>
WHISPER_MODEL_SHA256=<expected sha256>

これらのユーティリティを有効にした後の最初の起動は、RNNoiseとwhisper.cppがローカルでビルドされ、選択されたアセットがダウンロードされるため、時間がかかる場合があります。結果として得られるビルドとモデルは/dataに残るため、永続ボリュームが保持されている場合、通常のコンテナ再作成ではこれらのビルドは繰り返されません。Stackは、この理由から最初の起動に拡張されたヘルスチェック猶予期間を与えます。

オプションのPiper TTS

Piperはオプションのランタイムとして実装されており、デフォルトで無効になっています。

PIPER_ENABLED=false
PIPER_PACKAGE_SPEC=piper-tts

有効にしても、音声は自動的にダウンロードされません。音声.onnxファイルとそれに対応する設定ファイルは/data/piper/voicesの下にあります。これらは、piper_import_voice_fileを使用してMCPメディアキャッシュからインポートできます。これにより、ComfyUI自体もオーディオ/TTSワークフローをホストできるため、TTSはオプションのままになります。

サードパーティのライセンスに関する注意事項については、THIRD_PARTY.mdを参照してください。

リリース選択

Stackは以下をサポートしています。

VIDEO_MCP_VERSION=latest
VIDEO_MCP_CHECK_UPDATES_ON_START=true
VIDEO_MCP_FORCE_REFRESH=false

latestは、タグがvX.Y.Zと完全に一致する、最も新しい非ドラフト、非プレリリースのGitHubリリースを意味します。これはmainを意味するものではありません。

リリースを固定することもできます。

VIDEO_MCP_VERSION=v2.4.0

またはコミットSHA:

VIDEO_MCP_VERSION=<commit-sha>

更新チェックが無効になっており、有効な/currentソースが存在する場合、起動は完全にキャッシュファーストになります。失敗したリリースルックアップ、ダウンロード、またはアーカイブ検証は、最後に確認された正常なソースが存在する場合は常にそれにフォールバックします。

永続ボリューム

Stackは3つの懸念事項を分離します。

video_mcp_code  -> /opt/video-mcp   versioned source cache + /current
video_mcp_venv  -> /opt/venv        persistent Python virtual environment
video_mcp_data  -> /data             media, timelines, models, local tooling, HyperFrames projects/cache

アプリケーションランタイムデータルートはデフォルトで/dataです。直接/非Stackデプロイメントでは、VIDEO_MCP_DATA_ROOTでオーバーライドできます。video_mcp.serverまたはvideo_mcp.entrypointをインポートしても、ディレクトリは作成されません。ランタイムディレクトリは、アプリケーションの起動時にのみ作成されます。

Python環境は、requirements.txtが変更された場合にのみ再構築されます。再構築すると、マウントされたvenvディレクトリの内容がクリアされます。Dockerマウントポイント自体は削除されません。

ソースブートストラップセキュリティ

ソースアーカイブは、GitHub codeloadからステージングディレクトリにダウンロードされ、抽出前に検証されます。ブートストラップは以下を拒否します。

  • 絶対パス。

  • ..トラバーサル。

  • シンボリックリンク。

  • ハードリンク。

  • 複数のトップレベルルートを持つアーカイブ。

リリースは、抽出とランタイムコントラクトチェックが成功した後にのみ.mcp-source-readyを受け取ります。/currentはその時点でのみ切り替えられるため、中断されたり不正な形式の更新が最後に確認された正常なソースを置き換えることはできません。

ComfyUIモデルとカスタムノードのファイルシステムマウントは読み取り専用です。AIユーティリティのソース/モデルのダウンロードでは、キャッシュされたアーティファクトを置き換える前に、一時ファイルとSHA-256検証が使用されます。オプションのBlenderブリッジはベアラートークン認証を使用し、宣言されたジョブの入力/出力のみを転送しますが、任意のBlender Pythonは強力なままであるため、ブリッジは非特権OSアカウントで分離する必要があります。

HyperFrames

HyperFramesはMCPコンテナ内でローカルに実行され、MCPメディアキャッシュと同じ永続/data領域を使用します。ブラウザアセットは/data/hyperframes-homeの下に永続的にキャッシュされます。

デフォルトのパッケージ仕様は、再現性のためにStackに固定されており、プライベートにオーバーライドできます。

HYPERFRAMES_NPM_SPEC=hyperframes@0.7.111

HyperFramesスキルは、この実行サーバーでは意図的に無効になっています(HYPERFRAMES_SKIP_SKILLS=1)。

開発

python -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt pytest PyYAML
PYTHONPATH=src python -m pytest -q
python scripts/check_public_repo.py

CIは、Pythonコンパイル、サーバー/エントリポイントのインポート、テスト、YAML解析、シェル/Pythonヘルパーの構文、Composeレンダリング、バージョン/チェンジログの一貫性、および公開リポジトリのシークレット/プライベートネットワークガードレールをチェックします。

リリースプロセス

  1. ブランチで開発し、PRを開きます。

  2. CIが成功する必要があります。

  3. VERSIONとCHANGELOG.mdを更新します。

  4. mainにマージします。

  5. CIは、まだ存在しない場合、不変のvX.Y.Zタグとそれに対応する安定したGitHubリリースを作成します。

アプリケーションのタグ/リリースは正確なvX.Y.Z名のために予約されているため、無関係なモデルまたはアセットリリースがVIDEO_MCP_VERSION=latestの解決に影響を与えることはありません。

ライセンスと帰属

Apache License 2.0の下でライセンスされています。LICENSEを参照してください。

再配布および派生物は、Apache License 2.0に従って、NOTICE内の帰属表示を保持する必要があります。サードパーティコンポーネントは独自のライセンスを保持します。THIRD_PARTY.mdを参照してください。

Related MCP Connectors

Related MCP Servers