🚀 media-gen-mcp
Media Gen MCPは、OpenAI Images(gpt-image-1.5、gpt-image-1)、OpenAI Videos(Sora)、Google GenAI Videos(Veo)用の厳格なTypeScriptベースのModel Context Protocol(MCP)サーバーです。画像の生成や編集、ビデオジョブの作成やリミックス、URLまたはディスクからのメディアの取得を行うことができ、スマートなresource_linkとインラインのimage出力、オプションのsharp処理をサポートします。本番環境を念頭に設計されており(完全な厳格な型チェック、ESLint + Vitest CI)、fast-agent、Claude Desktop、ChatGPT、Cursor、VS Code、Windsurf、およびMCP互換のクライアントと互換性があります。
設計原則:仕様先行、型安全な画像ツール。厳格なOpenAI Images APIとMCP準拠で、完全に静的なTypeScript型を持ち、異なるクライアントに対応した柔軟な結果配置とレスポンス形式を提供します。
🚀 クイックスタート
fast-agent
fast-agentでは、MCPサーバーはfastagent.config.yamlのmcp.serversセクションで設定されます(fast-agentのドキュメントを参照)。
GitHubからnpxを使ってmedia-gen-mcpをMCPサーバーとして追加するには、以下のように設定します。
mcp:
servers:
media-gen-mcp:
command: "npx"
args: ["-y", "github:strato-space/media-gen-mcp", "--env-file", "/path/to/media-gen.env"]
OPENAI_API_KEYやその他の設定はmedia-gen.envに記述します(このリポジトリの.env.sampleを参照)。
Windsurf
GitHubからnpxを使ってmedia-gen-mcpを実行するMCPサーバーを追加するには、以下のJSON形式を使用します(Claude Desktop / VS Codeと同様)。
{
"mcpServers": {
"media-gen-mcp": {
"command": "npx",
"args": ["-y", "github:strato-space/media-gen-mcp", "--env-file", "/path/to/media-gen.env"]
}
}
}
✨ 主な機能
- 厳格なMCP仕様サポート
ツールの出力は、最新のMCPスキーマに基づくCallToolResultオブジェクトです。具体的には、content項目(text、image、resource_link、resource)、オプションのstructuredContent、オプションのトップレベルのfiles、および失敗時のisErrorフラグを含みます。
- 完全なgpt-image-1.5およびsora-2/sora-2-proパラメーターのカバレッジ(生成と編集)
- は、OpenAI Imagesの
create APIをgpt-image-1.5(およびgpt-image-1)に対して模倣しています(背景、モデレーション、サイズ、品質、出力形式、出力圧縮、n、userなど)。
- は、OpenAI Imagesの
createEdit APIをgpt-image-1.5(およびgpt-image-1)に対して模倣しています(画像、マスク、n、品質、サイズ、user)。
- OpenAI Videos(Sora)ジョブツール(作成 / リミックス / リスト / 取得 / 削除 / コンテンツ)
- Google GenAI(Veo)操作 + ダウンロード(生成 / 操作の取得 / コンテンツの取得)
- は、長時間実行される操作(
ai.models.generateVideos)を開始し、完了を待ち、.mp4出力をダウンロードするオプションがあります。Veoモデルリファレンス
- は、既存の操作をポーリングします。
- は、完了した操作から
.mp4をダウンロードし、MCPのresource_link(デフォルト)または埋め込みresourceブロック(tool_result経由)を返します。
- URLまたはファイルからの画像の取得と処理
ツールは、HTTP(S) URLまたはローカルファイルパスから画像を読み込み、オプションでユーザーが制御できる圧縮を適用します(デフォルトでは無効)。最大20枚の画像を並列処理できます。
- URLまたはファイルからのビデオの取得
ツールは、ローカルビデオをリストしたり、リモートビデオURLをディスクにダウンロードし、MCPのresource_link(デフォルト)または埋め込みresourceブロック(tool_result経由)を返します。
- 最大16枚の画像の混合と編集
は、imageを単一の文字列または1 - 16個のファイルパス/Base64文字列の配列として受け取り、GPT Imageモデル(gpt-image-1.5、gpt-image-1)の画像編集に関するOpenAI仕様に合致します。
- スマートな画像圧縮
sharpを使用した組み込みの圧縮機能があり、視覚的な品質を維持しながら、MCPペイロードの制限に収まるように品質と寸法を反復的に削減します。
resource_linkを使用したリソース認識型のファイル出力
- 総応答サイズが安全なしきい値を超えると、自動的にインラインのBase64から
fileに切り替わります。
- 出力は
output_<time_t>_media-gen__<tool>_<id>.<ext>というファイル名でディスクに書き込まれ(画像は生成されたUUIDを使用し、ビデオはOpenAIのvideo_idを使用)、tool_resultに応じてcontent[]を介してMCPクライアントに公開されます(画像はresource_link/image、ビデオダウンロードはresource_link/resource)。
- MCPクライアントのデバッグ用の組み込みtest-imagesツール
は、設定されたディレクトリからサンプル画像を読み取り、本番ツールと同じ結果構築ロジックを使用して返します。tool_resultとresponse_formatパラメーターを使用して、異なるMCPクライアントがcontent[]とstructuredContentをどのように処理するかをテストできます。
- 構造化されたMCPエラーハンドリング
すべてのツールエラー(検証、OpenAI APIの失敗、I/Oなど)は、MCPエラーとして返され、isError: trueとcontent: [{ type: "text", text: <エラーメッセージ> }]が設定されます。これにより、MCPクライアントでエラーを容易に解析して表示できます。
📦 インストール
git clone https://github.com/strato-space/media-gen-mcp.git
cd media-gen-mcp
npm install
npm run build
ビルドモード:
npm run build – すべての厳格なフラグが有効になった厳格なTypeScriptビルドです。skipLibCheck: falseを含みます。.tsbuildinfoを介したインクリメンタルビルド(ウォームキャッシュで約2 - 3秒)。
npm run esbuild – esbuildを使用した高速バンドル(型チェックなし、迅速な反復に便利)。
開発モード(ビルド不要)
開発時や、メモリ制限のためにTypeScriptのコンパイルが失敗する場合は、以下のコマンドを使用します。
npm run dev
品質チェック
npm run lint
npm run typecheck
npm run test
npm run test:watch
npm run ci
単体テスト
このプロジェクトはvitestを使用して単体テストを行っています。テストはtest/ディレクトリに配置されています。
テスト対象モジュール:
| モジュール |
テスト数 |
説明 |
compression |
12 |
画像形式の検出、バッファ処理、ファイルI/O |
helpers |
31 |
URL/パスの検証、出力解決、結果配置、リソースリンク |
env |
19 |
設定の解析、環境の検証、デフォルト値 |
logger |
10 |
構造化ロギング + トランケーションの安全性 |
pricing |
5 |
Soraの料金見積もりヘルパー |
schemas |
69 |
すべてのツールのZodスキーマ検証、型推論 |
fetch-images (統合) |
3 |
エンドツーエンドのMCPツール呼び出し動作 |
fetch-videos (統合) |
3 |
エンドツーエンドのMCPツール呼び出し動作 |
テストカテゴリー:
- compression —
isCompressionAvailable、detectImageFormat、processBufferWithCompression、readAndProcessImage
- helpers —
isHttpUrl、isAbsolutePath、isBase64Image、ensureDirectoryWritable、resolveOutputPath、getResultPlacement、buildResourceLinks
- env —
MEDIA_GEN_* / MEDIA_GEN_MCP_*設定の構成ロードと検証
- logger — トランケーションとエラー形式の動作
- schemas —
openai-images-*、openai-videos-*、fetch-images、fetch-videos、test-images入力の検証、境界テスト(プロンプト長、画像数制限、パス検証)
npm run test
npxを介して直接実行(ローカルクローン不要)
npxを使用して、リモートリポジトリから直接サーバーを実行することもできます。
npx -y github:strato-space/media-gen-mcp --env-file /path/to/media-gen.env
--env-file引数は、サーバーに読み込む環境ファイルを指定します(例えば、シークレットをクローンしたディレクトリの外に保存している場合)。このファイルにはOPENAI_API_KEY、オプションのAzure変数、および任意のMEDIA_GEN_MCP_*設定を含める必要があります。
secrets.yaml (オプション)
APIキー(およびオプションのGoogle Vertex AI設定)をsecrets.yamlファイルに保存することができます(fast-agentのシークレットテンプレートと互換性があります)。
openai:
api_key: <your-api-key-here>
anthropic:
api_key: <your-api-key-here>
google:
api_key: <your-api-key-here>
vertex_ai:
enabled: true
project_id: your-gcp-project-id
location: europe-west4
media-gen-mcpは、カレントワーキングディレクトリからsecrets.yamlを読み込み(または--secrets-file /path/to/secrets.yamlから)、環境変数に適用します。secrets.yamlの値は環境変数を上書きし、<your-api-key-here>のプレースホルダーは無視されます。
🔑 設定
MCPクライアントの設定(fast-agent、Windsurf、Claude Desktop、Cursor、VS Code)に以下を追加します。
{
"mcpServers": {
"media-gen-mcp": {
"command": "npx",
"args": ["-y", "github:strato-space/media-gen-mcp"],
"env": { "OPENAI_API_KEY": "sk-..." }
}
}
}
Azureデプロイもサポートしています。
{
"mcpServers": {
"media-gen-mcp": {
"command": "npx",
"args": ["-y", "github:strato-space/media-gen-mcp"],
"env": {
"OPENAI_API_VERSION": "2024-12-01-preview"
}
}
}
}
環境変数:
OPENAI_API_KEY(およびオプションでAZURE_OPENAI_API_KEY、AZURE_OPENAI_ENDPOINT、OPENAI_API_VERSION)を、node dist/index.jsを実行するプロセスの環境に設定します(シェル、systemdユニット、Docker環境など)。
- サーバーは、作業ディレクトリにローカルの
.envファイルが存在する場合、オプションでそれを読み込みます(すでに設定されている環境変数を上書きしません)。
- サーバーを起動するときに
--env-file /path/to/envを渡すこともできます(npxを介しても)。このファイルは、ツールが実行される前にdotenvを介して読み込まれ、やはりすでに設定されている変数を上書きしません。
ロギングとBase64のトランケーション
巨大な画像ペイロードでログが溢れないように、組み込みのロガーはlog.debug/info/warn/errorに渡される構造化されたdataに対して、ログ専用のサニタイザーを適用します。
- 構成された文字列フィールド(例:
b64_json、base64、文字列data、image_url)を、LOG_TRUNCATE_DATA_MAXで制御される短いプレビュー(デフォルト: 64文字)にトランケートします。キーのリストはsrc/lib/logger.ts内のLOG_SANITIZE_KEYSがデフォルトで、MEDIA_GEN_MCP_LOG_SANITIZE_KEYS(カンマ区切りのフィールド名のリスト)で上書きできます。
- サニタイゼーションはログのシリアライゼーションにのみ適用され、MCPクライアントに返されるツールの結果は決して変更されません。
環境で制御するには:
MEDIA_GEN_MCP_LOG_SANITIZE_IMAGES(デフォルト: true)
1、true、yes、on – トランケーションを有効にする(デフォルトの動作)。
0、false、no、off – トランケーションを無効にし、完全なペイロードをログに記録する。
フィールドリストと制限は、src/lib/logger.tsのLOG_SANITIZE_KEYSとLOG_TRUNCATE_DATA_MAXで構成されています。
セキュリティとローカルファイルアクセス
- 許可されたディレクトリ: すべてのツールは
MEDIA_GEN_DIRSに一致するパスに制限されます。設定されていない場合は、デフォルトで/tmp/media-gen-mcp(Windowsでは%TEMP%/media-gen-mcp)になります。
- テストサンプル:
MEDIA_GEN_MCP_TEST_SAMPLE_DIRは、許可リストにディレクトリを追加し、test-imagesツールを有効にします。
- ローカル読み取り:
fetch-imagesはファイルパス(絶対パスまたは相対パス)を受け取ります。相対パスはMEDIA_GEN_DIRSの最初のエントリを基準に解決され、許可されたパターンに一致する必要があります。
- リモート読み取り: HTTP(S)フェッチは
MEDIA_GEN_URLSパターンでフィルタリングされます。空の場合はすべて許可されます。
- 書き込み:
openai-images-generate、openai-images-edit、fetch-images、およびfetch-videosは、MEDIA_GEN_DIRSの最初のエントリの下に書き込みます。test-imagesは読み取り専用で、新しいファイルを作成しません。
グロブパターン
MEDIA_GEN_DIRSとMEDIA_GEN_URLSの両方がグロブワイルドカードをサポートしています。
| パターン |
一致するもの |
例 |
* |
任意の単一セグメント(/なし) |
/home/*/media/は/home/user1/media/に一致 |
** |
任意の数のセグメント |
/data/**/images/は/data/a/b/images/に一致 |
URLの例:
MEDIA_GEN_URLS=https://*.cdn.example.com/,https://storage.example.com/**/assets/
パスの例:
MEDIA_GEN_DIRS=/home/*/media-gen/output/,/data/**/images/
⚠️ 警告: 区切り文字なしの末尾のワイルドカード(例: /home/user/*またはhttps://cdn.com/**)は、サブツリー全体を公開し、起動時にコンソールに警告が表示されます。
推奨される対策
- 許可されたディレクトリにのみアクセスできる専用のOSユーザーで実行します。
- 許可リストを最小限に抑えます。ホームディレクトリやシステムパスで
*を使用しないでください。
- リモートフェッチには明示的な
MEDIA_GEN_URLSプレフィックスを使用します。
- OSのACLまたはバックアップを介して許可されたディレクトリを監視します。
ツール結果パラメーター: tool_resultとresponse_format
画像ツール(openai-images-*、fetch-images、test-images)は、MCPツール結果の形状を制御する2つのパラメーターをサポートしています。
| パラメーター |
値 |
デフォルト |
説明 |
tool_result |
resource_link、image |
resource_link |
content[]の形状を制御 |
response_format |
url、b64_json |
url |
structuredContentの形状を制御(OpenAI ImagesResponse形式) |
ビデオダウンロードツール(openai-videos-create / openai-videos-remixのダウンロード時、openai-videos-retrieve-content、google-videos-generateのダウンロード時、google-videos-retrieve-content、fetch-videos)は以下をサポートしています。
| パラメーター |
値 |
デフォルト |
説明 |
tool_result |
resource_link、resource |
resource_link |
content[]の形状を制御 |
Googleビデオツール(google-videos-*)も以下をサポートしています。
| パラメーター |
値 |
デフォルト |
説明 |
response_format |
url、b64_json |
url |
structuredContent.response.generatedVideos[].videoの形状を制御(uri vs videoBytes) |
tool_result — content[]を制御
- 画像 (
openai-images-*、fetch-images、test-images)
resource_link (デフォルト): file://またはhttps://のURIを持つResourceLink項目を出力します。
image: Base64のImageContentブロックを出力します。
- ビデオ (ビデオデータをダウンロードするツール)
resource_link (デフォルト): file://またはhttps://のURIを持つResourceLink項目を出力します。
resource: Base64のresource.blobを持つEmbeddedResourceブロックを出力します。
response_format — structuredContentを制御
OpenAIの画像の場合、structuredContentは常にOpenAI ImagesResponse形式のオブジェクトを含んでいます。
{
"created": 1234567890,
"data": [
{ "url": "https://..." }
]
}
url (デフォルト): data[].urlにはファイルURLが含まれます。
b64_json: data[].b64_jsonにはBase64エンコードされた画像データが含まれます。
Googleのビデオの場合、response_formatはstructuredContent.response.generatedVideos[].videoが以下のどちらを優先するかを制御します。
url (デフォルト): video.uri(video.videoBytesは削除)
b64_json: video.videoBytes(video.uriは削除)
下位互換性 (MCP 5.2.6)
MCP仕様5.2.6に従い、structuredContentをサポートしていないクライアントとの下位互換性のために、シリアライズされたJSONを含むTextContentブロック(常にdata[]にURLを使用)もcontent[]に含まれます。
ツール結果の構造の例:
{
"content": [
{ "type": "resource_link", "uri": "https://...", "name": "image.png", "mimeType": "image/png" },
{ "type": "text", "text": "{ \"created\": 1234567890, \"data\": [{ \"url\": \"https://...\" }] }" }
],
"structuredContent": {
"created": 1234567890,
"data": [{ "url": "https://..." }]
}
}
ChatGPT MCPクライアントの動作 (chatgpt.com、2025 - 12 - 01現在):
- ChatGPTは現在、
content[]の画像データを無視し、structuredContentを優先します。
- ChatGPTの場合は、
response_format: "url"を使用し、MEDIA_GEN_MCP_URL_PREFIXESの最初のエントリを公開されたHTTPSプレフィックス(例: MEDIA_GEN_MCP_URL_PREFIXES=https://media-gen.example.com/media)として設定してください。
Anthropicクライアント(Claude Desktopなど)の場合は、デフォルトの設定でうまく動作します。
mcp-proxyを介したネットワークアクセス (SSE)
ネットワーク上のSSEアクセスのために、media-gen-mcpの前にmcp-proxyまたはそれに相当するものを配置することができます。この設定は、TypeScriptのSSEプロキシ実装punkpeye/mcp-proxyでテストされています。
例えば、1行のコマンドは以下のようになります。
mcp-proxy --host=0.0.0.0 --port=99 --server=sse --sseEndpoint=/ --shell 'npx -y github:strato-space/media-gen-mcp --env-file /path/to/media-gen.env'
本番環境では、通常、PORT/SHELL_CMDをEnvironmentFile=から読み込むsystemdテンプレートユニットを介してこれを設定します(server/mcp/mcp@.serviceスタイルの設定を参照)。
🛠 ツールのシグネチャ
openai-images-generate
引数(入力スキーマ):
prompt (文字列、必須)
- 目的の画像を説明するテキストプロンプト。
- 最大長: 32,000文字。
background ("transparent" | "opaque" | "auto", オプション)
- 背景の処理モード。
backgroundが"transparent"の場合、output_formatは"png"または"webp"でなければなりません。
model ("gpt-image-1.5" | "gpt-image-1", オプション、デフォルト: "gpt-image-1.5")
moderation ("auto" | "low", オプション)
- コンテンツのモデレーション動作、Images APIに渡されます。
n (整数、オプション)
output_compression (整数、オプション)
- 圧縮レベル(0 - 100)。
output_formatが"jpeg"または"webp"の場合のみ適用されます。
output_format ("png" | "jpeg" | "webp", オプション)
- 出力画像の形式。
- 省略された場合、サーバーは出力をPNGセマンティクスとして扱います。
quality ("auto" | "high" | "medium" | "low", デフォルト: "high")
size ("1024x1024" | "1536x1024" | "1024x1536" | "auto", デフォルト: "1024x1536")
user (文字列、オプション)
- OpenAIに転送されるユーザー識別子(監視用)。
response_format ("url" | "b64_json", デフォルト: "url")
- レスポンス形式(OpenAI Images APIに合わせた形式):
"url": ファイル/URLベースの出力(resource_link項目、image_urlフィールド、api配置のdata[].url)。
"b64_json": インラインのBase64画像データ(画像コンテンツ、api配置のdata[].b64_json)。
tool_result ("resource_link" | "image", デフォルト: "resource_link")
content[]の形状を制御:
"resource_link"はResourceLink項目(ファイル/URLベース)を出力。
"image"はBase64のImageContentブロックを出力。
動作に関する注意:
- サーバーはデフォルトでOpenAIの
gpt-image-1.5を使用します(レガシー動作にはmodel: "gpt-image-1"を設定)。
- すべてのBase64画像の合計サイズが構成されたペイロードのしきい値(デフォルトでは
MCP_MAX_CONTENT_BYTESを介して約50MB)を超える場合、サーバーは自動的に実効的な出力モードをファイル/URLベースに切り替え、画像をMEDIA_GEN_DIRSの最初のエントリ(デフォルト: /tmp/media-gen-mcp)に保存します。
- 明示的に
response_format: "b64_json"を要求した場合でも、サーバーはファイルをディスクに書き込みます(静的ホスティング、キャッシュ、または後で再利用するため)。ツール結果でのファイルパス/URLの公開は、MEDIA_GEN_MCP_RESULT_PLACEMENTと呼び出しごとのresult_placementに依存します(以下のセクションを参照)。
出力(MCP CallToolResult、result_placementに"content"が含まれる場合):
- 実効的な
outputモードが"base64"の場合:
contentは以下を含む配列になります。
- 画像項目:
{ type: "image", data: <Base64文字列>, mimeType: <"image/png" | "image/jpeg" | "image/webp"> }
- オプションのテキスト項目(Images APIから返される修正されたプロンプト、DALL·E 3などのサポートするモデルの場合):
{ type: "text", text: <修正されたプロンプト文字列> }
- 実効的な
outputモードが"file"の場合:
contentには、各ファイルに1つのresource_link項目が含まれ、同じオプションの修正されたプロンプトのtext項目も含まれます。
{ type: "resource_link", uri: "file:///absolute-path-1.png", name: "absolute-path-1.png", mimeType: <画像のMIMEタイプ> }
gpt-image-1.5およびgpt-image-1の場合、追加のtext行に料金見積もり(structuredContent.usageに基づく)が含まれ、structuredContent.pricingには完全な料金内訳が含まれます。
result_placementに"api"が含まれる場合、openai-images-generateは代わりにMCPラッパーなしのOpenAI Images APIに似たオブジェクトを返します。
{
"created": 1764599500,
"data": [
{ "b64_json": "..." }
],
"background": "opaque",
"output_format": "png",
"size": "1024x1024",
"quality": "high"
}
openai-images-edit
引数(入力スキーマ):
image (文字列または文字列配列、必須)
- 画像ファイル(
.png、.jpg、.jpeg、.webp)の単一の絶対パス、Base64エンコードされた画像文字列(オプションでdata:image/...;base64,... URL)、または公開アクセス可能な画像を指すHTTP(S) URL、または このような文字列の配列(最大16個、複数画像編集用)。
- HTTP(S) URLが提供された場合、サーバーは画像を取得し、OpenAIに送信する前にBase64に変換します。
prompt (文字列、必須)
- 目的の編集を説明するテキスト。
- 最大長: 32,000文字。
mask (文字列、オプション)
- マスク画像の絶対パス、Base64文字列、またはHTTP(S) URL(PNG < 4MB、ソース画像と同じ寸法)。透明な領域は編集する領域を示します。
model ("gpt-image-1.5" | "gpt-image-1", オプション、デフォルト: "gpt-image-1.5")
n (整数、オプション)
quality ("auto" | "high" | "medium" | "low", デフォルト: "high")
size ("1024x1024" | "1536x1024" | "1024x1536" | "auto", デフォルト: "1024x1536")
user (文字列、オプション)
- OpenAIに転送されるユーザー識別子(監視用)。
response_format ("url" | "b64_json", デフォルト: "url")
- レスポンス形式(OpenAI Images APIに合わせた形式):
"url": ファイル/URLベースの出力(resource_link項目、image_urlフィールド、api配置のdata[].url)。
"b64_json": インラインのBase64画像データ(画像コンテンツ、api配置のdata[].b64_json)。
tool_result ("resource_link" | "image", デフォルト: "resource_link")
content[]の形状を制御:
"resource_link"はResourceLink項目(ファイル/URLベース)を出力。
"image"はBase64のImageContentブロックを出力。
動作に関する注意:
- サーバーは
imageとmaskを絶対パス、Base64/data URL、またはHTTP(S) URLとして受け取ります。
- HTTP(S) URLが提供された場合、サーバーは画像を取得し、OpenAIを呼び出す前にBase64データURLに変換します。
- 編集の場合は、サーバーは画像を出力する際に常にPNGセマンティクス(MIMEタイプ
image/png)を返します。
出力(MCP CallToolResult):
- 実効的な
outputモードが"base64"の場合:
contentは以下を含む配列になります。
- 画像項目:
{ type: "image", data: <Base64文字列>, mimeType: "image/png" }