mcpField
M
media-gen-mcp

media-gen-mcp

ローカル
github.com/strato-spaceメディア・デザイン939 週間前に更新

media-gen-mcp について

media-gen-mcp は、OpenAI と Google GenAI による画像の生成・編集や動画生成を提供する TypeScript 製 MCP サーバーです。URL やローカルファイルからメディアと文書を取得し、MCP クライアント向けに出力を調整できます。

主な機能

  1. 01OpenAI モデルによる画像生成・編集
  2. 02Sora 動画ジョブの作成と管理
  3. 03Veo 動画の生成と結果取得
  4. 04URL やファイルからの画像取得・圧縮
  5. 05メディアと文書を MCP リソースとして返却

活用シーン

  1. 01テキストプロンプトから画像を作成・編集
  2. 02Sora 動画ジョブの作成・リミックス・確認
  3. 03Veo 動画の生成と完成動画のダウンロード
  4. 04MCP クライアント向け画像ファイルの読み込みと最適化

MCP 対応

画像、動画、ファイル取得のツールを MCP クライアントに公開します。メディアはインラインコンテンツまたはリソースリンクとして返せ、構造化結果と MCP エラー処理にも対応します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"strato-space-media-gen": {
"command": "npx",
"args": [
"-y",
"@strato-space/media-gen-mcp"
],
"env": {
"OPENAI_API_KEY": "<OPENAI_API_KEY>",
"GEMINI_API_KEY": "<GEMINI_API_KEY>",
"GOOGLE_API_KEY": "<GOOGLE_API_KEY>",
"GOOGLE_GENAI_USE_VERTEXAI": "<GOOGLE_GENAI_USE_VERTEXAI>",
"GOOGLE_CLOUD_PROJECT": "<GOOGLE_CLOUD_PROJECT>",
"GOOGLE_CLOUD_LOCATION": "<GOOGLE_CLOUD_LOCATION>",
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>",
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
"OPENAI_API_VERSION": "<OPENAI_API_VERSION>",
"AZURE_OPENAI_DEPLOYMENT": "<AZURE_OPENAI_DEPLOYMENT>",
"MEDIA_GEN_DIRS": "<MEDIA_GEN_DIRS>",
"MEDIA_GEN_URLS": "<MEDIA_GEN_URLS>",
"MEDIA_GEN_MCP_URL_PREFIXES": "<MEDIA_GEN_MCP_URL_PREFIXES>",
"MEDIA_GEN_MCP_TEST_SAMPLE_DIR": "<MEDIA_GEN_MCP_TEST_SAMPLE_DIR>"
}
}
}
}
起動コマンドnpx -y @strato-space/media-gen-mcp
設定が必要な環境変数
OPENAI_API_KEYシークレットOpenAI API key (required for OpenAI image/video tools).
GEMINI_API_KEYシークレットGemini API key (alternative to GOOGLE_API_KEY).
GOOGLE_API_KEYシークレットGoogle GenAI API key for Veo video tools.
GOOGLE_GENAI_USE_VERTEXAISet to true to use Vertex AI for Google GenAI.
GOOGLE_CLOUD_PROJECTGCP project id for Vertex AI.
GOOGLE_CLOUD_LOCATIONGCP region for Vertex AI (e.g. us-central1).
AZURE_OPENAI_API_KEYシークレットAzure OpenAI API key (optional).
AZURE_OPENAI_ENDPOINTAzure OpenAI endpoint hostname.
OPENAI_API_VERSIONAzure OpenAI API version.
AZURE_OPENAI_DEPLOYMENTAzure OpenAI deployment name.
MEDIA_GEN_DIRSComma-separated output directories for media files.
MEDIA_GEN_URLSComma-separated URL prefixes allowed for fetch tools.
MEDIA_GEN_MCP_URL_PREFIXESPublic URL prefixes for mapping local output files.
MEDIA_GEN_MCP_TEST_SAMPLE_DIRPath to sample images for the test-images tool.

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npm@strato-space/media-gen-mcp1.0.4

ツール

13

掲載時のツール一覧 · 2 週間前に更新

パラメーター型必須説明
nintegerいいえ
sizeenumいいえ1024x1024 | 1536x1024 | 1024x1536 | auto
userstringいいえ
modelenumいいえgpt-image-1.5 | gpt-image-1
promptstringはい
qualityenumいいえauto | high | medium | low
backgroundenumいいえtransparent | opaque | auto
moderationenumいいえauto | low
tool_resultenumいいえcontent[] の形式を制御します:'resource_link'(デフォルト)は ResourceLink 項目を出力し、'image' は base64 ImageContent ブロックを出力します。resource_link | image
output_formatenumいいえpng | jpeg | webp
response_formatenumいいえstructuredContent の形式を制御します:'url'(デフォルト)は data[].url を出力し、'b64_json' は data[].b64_json を出力します。url | b64_json
output_compressionintegerいいえ

詳細

media-gen-mcp

media-gen-mcp MCP SDK OpenAI SDK mcp-proxy fast-mcp License GitHub stars Build Status


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 の静的型を完全に活用するとともに、クライアントごとに柔軟な結果の配置とレスポンス形式を選べます。

  • OpenAI の gpt-image-1.5 モデルを使用して、テキストプロンプトから画像を生成します(gpt-image-1 との互換性があり、今後のバージョンで DALL·E のサポートも予定しています)。
  • 画像を編集します(インペインティング、アウトペインティング、合成)。1~16 枚の画像を一度に処理でき、高度なプロンプト制御に対応しています。
  • OpenAI Videos(sora-2、sora-2-pro)を使用して動画を生成します。ジョブの作成・リミックス・一覧表示・取得・削除、およびアセットのダウンロードに対応しています。
  • Google GenAI(Veo)を使用して動画を生成します。オペレーションのポーリングと、ファイルを優先したダウンロードに対応しています。
  • HTTP(S) URL またはローカルファイルパスから画像を取得して圧縮します。サイズと品質を適切に最適化します。
  • HTTP(S) URL またはローカルファイルパスからドキュメントを取得し、resource_link/resource 形式で出力します。
  • 本番環境での結果の配置(content、structuredContent、toplevel)を再現する test-images ツールを使って、MCP の出力形式をデバッグできます。
  • 以下と連携します: fast-agent、Windsurf、Claude Desktop、Cursor、VS Code、および MCP 対応クライアント。

✨ 特長

  • 厳密な MCP 仕様への対応
    ツールの出力は、最新の MCP スキーマに基づく第一級の CallToolResult オブジェクトです。以下を含みます。 content 項目(text、image、resource_link、resource)、オプションの structuredContent、オプションのトップレベル files、および失敗時に設定される isError フラグ。

  • gpt-image-1.5 および sora-2/sora-2-pro の全パラメーターに対応(生成と編集)

    • openai-images-generate は、gpt-image-1.5(および gpt-image-1)の OpenAI Images create API を反映しています(background、moderation、size、quality、output_format、output_compression、n、user など)。
    • openai-images-edit は、gpt-image-1.5(および gpt-image-1)の OpenAI Images createEdit API を反映しています(image、mask、n、quality、size、user)。
  • OpenAI Videos(Sora)のジョブツール(作成/リミックス/一覧表示/取得/削除/コンテンツ取得)

  • Google GenAI(Veo)の操作とダウンロード(生成/オペレーション取得/コンテンツ取得)

  • URL またはファイルから画像を取得して処理
    fetch-images ツールは、HTTP(S) URL またはローカルファイルパスから画像を読み込みます。圧縮は任意で、ユーザーが制御でき、デフォルトでは無効です。最大 20 枚の画像を並行して処理できます。

  • URL またはファイルから動画を取得
    fetch-videos ツールは、ローカル動画を一覧表示するか、リモートの動画 URL から動画をディスクにダウンロードし、MCP resource_link(デフォルト)または埋め込み resource ブロック(tool_result 経由)を返します。

  • URL またはファイルからドキュメントを取得
    fetch-document ツールは、リモートファイルをダウンロードするか、ローカルパスを再利用し、MCP resource_link(デフォルト)または埋め込み resource ブロック(tool_result 経由)を返します。

  • 最大 16 枚の画像を組み合わせて編集
    openai-images-edit は、GPT Image モデル(gpt-image-1.5、gpt-image-1)の画像編集に関する OpenAI の仕様に合わせて、image に単一の文字列、または 1~16 個のファイルパス/base64 文字列の配列を指定できます。

  • スマート画像圧縮
    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 エラーとして返されるため、MCP クライアントで簡単に解析し、表示できます。 isError: true および content: [{ type: "text", text: <error message> }]


🚀 インストール

git clone https://github.com/strato-space/media-gen-mcp.git
cd media-gen-mcp

npm install
npm run build

ビルドモード:

  • npm run build – .tsbuildinfo を使用したインクリメンタルビルド(キャッシュが温まっている状態で約 2~3 秒)を行う、すべての厳格フラグ(skipLibCheck: false を含む)を有効にした厳格な TypeScript ビルドです。
  • npm run esbuild – esbuild による高速バンドル(型チェックなし。迅速な反復に便利です)。
開発モード(ビルド不要)

開発時、またはメモリ制約によって TypeScript のコンパイルに失敗する場合:

npm run dev  # Uses tsx to run TypeScript directly
品質チェック
npm run lint        # ESLint with typescript-eslint
npm run typecheck   # Strict tsc --noEmit
npm run test        # Unit tests (vitest)
npm run test:watch  # Watch mode for TDD
npm run ci          # lint + typecheck + test
ユニットテスト

このプロジェクトでは、ユニットテストに vitest を使用しています。テストは test/ にあります。

対象モジュール:

モジュールテスト数説明
compression12画像形式の検出、バッファー処理、ファイル I/O
helpers31URL/パスの検証、出力先の解決、結果の配置、リソースリンク
env19設定の解析、環境変数の検証、デフォルト値
logger10構造化ロギングと切り詰め時の安全性
pricing5Sora の価格見積もりヘルパー
schemas69すべてのツールの Zod スキーマ検証、型推論
fetch-images(統合)3MCP ツール呼び出しのエンドツーエンドの動作
fetch-videos(統合)3MCP ツール呼び出しのエンドツーエンドの動作

テストカテゴリー:

  • 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
# ✓ test/compression.test.ts (12 tests)
# ✓ test/helpers.test.ts (31 tests)
# ✓ test/env.test.ts (19 tests)
# ✓ test/logger.test.ts (10 tests)
# ✓ test/pricing.test.ts (5 tests)
# ✓ test/schemas.test.ts (69 tests)
# ✓ test/fetch-images.integration.test.ts (3 tests)
# ✓ test/fetch-videos.integration.test.ts (3 tests)
# Tests: 152 passed
ローカルにクローンせず 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> のプレースホルダーは無視されます。


⚡ クイックスタート(fast-agent と Windsurf)

fast-agent

fast-agent では、MCP サーバーは fastagent.config.yaml の mcp.servers セクションで設定します(fast-agent のドキュメントを参照)。

GitHub から npx 経由で media-gen-mcp を MCP サーバーとして追加するには、次のようにします。

# fastagent.config.yaml

mcp:
  servers:
    # your existing servers (e.g. fetch, filesystem, huggingface, ...)
    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

以下の JSON 形式を使って、GitHub から npx 経由で media-gen-mcp を実行する MCP サーバーを追加します(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 クライアントの設定に追加します(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": {
        // "AZURE_OPENAI_API_KEY": "sk-...",
        // "AZURE_OPENAI_ENDPOINT": "my.endpoint.com",
        "OPENAI_API_VERSION": "2024-12-01-preview"
      }
    }
  }
}

環境変数:

  • node dist/index.js を実行するプロセスの環境(シェル、systemd ユニット、Docker 環境変数など)に OPENAI_API_KEY を設定します(必要に応じて AZURE_OPENAI_API_KEY、AZURE_OPENAI_ENDPOINT、OPENAI_API_VERSION も設定します)。
  • サーバーは、作業ディレクトリにローカルの .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 と fetch-document は、ファイルパス(絶対パスまたは相対パス)を受け付けます。相対パスは MEDIA_GEN_DIRS の最初のエントリを基準に解決され、許可パターンに一致する必要があります。
  • リモート読み込み:HTTP(S) の取得は、MEDIA_GEN_URLS のパターンでフィルタリングされます。空の場合はすべて許可されます。
  • 書き込み:openai-images-generate、openai-images-edit、fetch-images、fetch-videos、fetch-document は、MEDIA_GEN_DIRS の最初のエントリ配下に書き込みます。test-images は読み取り専用で、新しいファイルは作成しません。
Glob パターン

MEDIA_GEN_DIRS と MEDIA_GEN_URLS は、どちらも glob ワイルドカードに対応しています。

パターン一致対象例
*任意の単一セグメント(/ を含まない)/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/**)は、サブツリー全体を公開し、起動時にコンソール警告が表示されます。

推奨される緩和策
  1. 許可されたディレクトリのみにアクセスできる専用の OS ユーザーで実行します。
  2. 許可リストは最小限に保ちます。ホームディレクトリやシステムパスで * を使わないでください。
  3. リモート取得には、明示的な MEDIA_GEN_URLS のプレフィックスを使用します。
  4. OS の ACL またはバックアップを使って、許可ディレクトリを監視します。
ツールの結果パラメーター:tool_result と response_format

画像ツール(openai-images-*、fetch-images、test-images)は、MCP ツールの結果の形式を制御する 2 つのパラメーターをサポートしています。

パラメーター値デフォルト説明
tool_resultresource_link、imageresource_linkcontent[] の形式を制御します
response_formaturl、path、b64_jsonurlstructuredContent の形式を制御します(OpenAI ImagesResponse 形式)

動画/ドキュメントのダウンロードツール(ダウンロード時の openai-videos-create / openai-videos-remix、openai-videos-retrieve-content、ダウンロード時の google-videos-generate、google-videos-retrieve-content、fetch-videos、fetch-document)は、次のパラメーターをサポートしています。

パラメーター値デフォルト説明
tool_resultresource_link、resourceresource_linkcontent[] の形式を制御します

Google の動画ツール(google-videos-*)は、次のパラメーターもサポートしています。

パラメーター値デフォルト説明
response_formaturl、b64_jsonurlstructuredContent.response.generatedVideos[].video の形式を制御します(uri と 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 ブロックを出力します
  • ドキュメント(fetch-document)
    • resource_link(デフォルト):file:// または https:// の URI を持つ ResourceLink アイテムを出力します
    • resource:Base64 の resource.blob を持つ EmbeddedResource ブロックを出力します
response_format — structuredContent を制御します

OpenAI 画像の場合、structuredContent には常に OpenAI ImagesResponse 形式のオブジェクトが含まれます。

{
  "created": 1234567890,
  "data": [
    { "url": "https://..." } // or { "path": "/abs/path.png" } / { "b64_json": "..." } depending on response_format
  ]
}
  • url(デフォルト):data[].url にファイル URL が含まれます
  • path:data[].path にローカルファイルシステムのパスが含まれます
  • 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(data[] では常に URL を使用)を含む TextContent ブロックも content[] に含まれます。

ツール結果の構造例:

{
  "content": [
    // ResourceLink or ImageContent based on tool_result
    { "type": "resource_link", "uri": "https://...", "name": "image.png", "mimeType": "image/png" },
    // Serialized JSON for backward compatibility (MCP 5.2.6)
    { "type": "text", "text": "{ \"created\": 1234567890, \"data\": [{ \"url\": \"https://...\" }] }" }
  ],
  "structuredContent": {
    "created": 1234567890,
    "data": [{ "url": "https://..." }]
  }
}

ChatGPT MCP クライアントの動作(chatgpt.com、2025-12-01 時点):

  • ChatGPT は現在、structuredContent を優先し、content[] の画像データを無視します。
  • 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 にアクセスする場合は、mcp-proxy または同等のものを media-gen-mcp の前段に配置できます。この構成は、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'

本番環境では通常、EnvironmentFile= から PORT / SHELL_CMD を読み込む systemd テンプレートユニットを使って設定します(server/mcp/[email protected] 形式の設定を参照)。


🛠 ツールのシグネチャ

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(整数、任意)
    • 生成する画像の数です。
    • 最小:1、最大:10。
  • 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" | "path" | "b64_json"、デフォルト:"url")
    • 応答形式です(OpenAI Images API に準拠)。
      • "url":ファイル/URL ベースの出力(resource_link アイテム、image_url フィールド、api 配置での data[].url)。
      • "path":data[].path にローカルファイルシステムのパスを返します(ローカルのスキルワークフロー用)。
      • "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 によって決まります(下のセクションを参照)。

出力(配置に "content" が含まれる場合の MCP CallToolResult):

  • 実効 output モードが "base64" の場合:
    • content は、以下を含む可能性がある配列です。
      • 画像アイテム:
        • { type: "image", data: <base64 string>, mimeType: <"image/png" | "image/jpeg" | "image/webp"> }
      • Images API が返す改訂プロンプトを含む任意のテキストアイテム(DALL·E 3 など、対応するモデルの場合):
        • { type: "text", text: <revised_prompt string> }
  • 実効 output モードが "file" の場合:
    • content には、ファイルごとに 1 つの resource_link アイテムと、改訂プロンプトを含む同じ任意の text アイテムが含まれます。
      • { type: "resource_link", uri: "file:///absolute-path-1.png", name: "absolute-path-1.png", mimeType: <image mime> }
    • gpt-image-1.5 と gpt-image-1 では、価格の推定値(structuredContent.usage に基づく)を示す text 行も追加で含まれ、structuredContent.pricing には価格の内訳全体が含まれます。

result_placement に "api" が含まれる場合、openai-images-generate は代わりに、MCP のラッパーを含まないOpenAI Images API に類似したオブジェクトを返します。

{
  "created": 1764599500,
  "data": [
    { "b64_json": "..." } // or { "url": "https://.../media/file.png" } when output: "file"
  ],
  "background": "opaque",
  "output_format": "png",
  "size": "1024x1024",
  "quality": "high"
}
openai-images-edit

引数(入力スキーマ):

  • image(string または string[]、必須)
    • 画像ファイル(.png、.jpg、.jpeg、.webp)への単一の絶対パス、 base64 エンコードされた画像文字列(data:image/...;base64,... 形式の URL も指定可能)、 または一般にアクセス可能な画像を指す HTTP(S) URL を指定します。 またはこれらの文字列を 1~16 個含む配列を指定できます(複数画像の編集用)。
    • HTTP(S) URL を指定すると、サーバーは画像を取得し、OpenAI に送信する前に base64 に変換します。
  • prompt(string、必須)
    • 希望する編集内容のテキスト説明です。
    • 最大長:32,000 文字。
  • mask(string、任意)
    • マスク画像(PNG、4MB 未満。元画像と同じ寸法)の絶対パス、base64 文字列、または HTTP(S) URL です。透明な領域が編集対象範囲を示します。
  • model("gpt-image-1.5" | "gpt-image-1"、任意、デフォルト:"gpt-image-1.5")
  • n(integer、任意)
    • 生成する画像の数です。
    • 最小:1、最大:10。
  • quality("auto" | "high" | "medium" | "low"、デフォルト:"high")
  • size("1024x1024" | "1536x1024" | "1024x1536" | "auto"、デフォルト:"1024x1536")
  • user(string、任意)
    • モニタリングのために OpenAI に転送するユーザー識別子です。
  • response_format("url" | "path" | "b64_json"、デフォルト:"url")
    • レスポンス形式(OpenAI Images API に準拠):
      • "url":ファイル/URL ベースの出力(resource_link アイテム、image_url フィールド、api 配置の data[].url)。
      • "path":data[].path にローカルファイルシステムのパスを指定します(ローカルスキルのワークフロー用)。
      • "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 data URL に変換します。
  • 編集では、画像を出力する際、サーバーは常に PNG セマンティクス(MIME タイプ image/png)を返します。

出力(MCP CallToolResult):

  • 有効な output モードが "base64" の場合:
    • content は次の内容を含む配列です。
      • 画像アイテム:
        • { type: "image", data: <base64 string>, mimeType: "image/png" }
      • 改訂されたプロンプトを含むテキストアイテム(基盤モデルが返す場合は任意):
        • { type: "text", text: <revised_prompt string> }
  • 有効な output モードが "file" の場合:
    • content にはファイルごとに 1 つの resource_link アイテムが含まれ、改訂されたプロンプトを含む同じ任意の text アイテムも含まれます。
      • { type: "resource_link", uri: "file:///absolute-path-1.png", name: "absolute-path-1.png", mimeType: "image/png" }
    • gpt-image-1.5 と gpt-image-1 では、料金の見積もり(structuredContent.usage に基づく)を示す text 行も追加され、structuredContent.pricing に料金の内訳全体が含まれます。

result_placement に "api" が含まれる場合、openai-images-edit は openai-images-generate と同じ未加工の API 形式(トップレベルの created、data[]、background、output_format、size、quality。base64 出力では b64_json、ファイル出力では url)に従います。

エラー処理(両方のツール):

  • ツールハンドラー内でエラー(検証、OpenAI API の失敗、I/O など)が発生すると、サーバーはエラーとしてマークされた CallToolResult を返します。
    • isError: true
    • content: [{ type: "text", text: <error message string> }]
  • エラーメッセージのテキストには、サーバーからの補足説明を加えず、基盤となる例外メッセージをそのまま使用します。詳細情報はすべてサーバーのコンソールに記録されます。
openai-videos-create

OpenAI Videos API(videos.create)を使用して、動画生成ジョブを作成します。

引数(入力スキーマ):

  • prompt(string、必須)— 動画を説明するテキストプロンプト(最大 32K 文字)。
  • input_reference(string、任意)— 任意の画像参照(HTTP(S) URL、base64/data URL、またはファイルパス)。
  • input_reference_fit("match" | "cover" | "contain" | "stretch"、デフォルト:"contain")
    • input_reference を指定された動画の size に合わせる方法:
      • match:寸法が完全に一致することを要求します(一致しない場合は即座に失敗します)
      • cover:拡大縮小し、中央を切り抜いて埋めます
      • contain:拡大縮小し、余白を追加して収めます(デフォルト)
      • stretch:歪みを許容して拡大縮小します
  • input_reference_background("blur" | "black" | "white" | "#RRGGBB" | "#RRGGBBAA"、デフォルト:"blur")
    • input_reference_fit="contain" の場合に使用する余白の背景色です。
  • model("sora-2" | "sora-2-pro"、デフォルト:"sora-2-pro")
  • seconds("4" | "8" | "12"、任意)
  • size("720x1280" | "1280x720" | "1024x1792" | "1792x1024"、任意)
    • 1024x1792 と 1792x1024 には sora-2-pro が必要です。
    • input_reference と size の両方を省略した場合、API のデフォルトが使用されます。
  • wait_for_completion(boolean、デフォルト:true)
    • true の場合、サーバーは completed または failed(あるいはタイムアウト)になるまで openai-videos-retrieve をポーリングし、その後アセットをダウンロードします。
  • timeout_ms(integer、デフォルト:900000)
  • poll_interval_ms(integer、デフォルト:2000)
  • download_variants(string[]、デフォルト:["video"])
    • 使用できる値:"video" | "thumbnail" | "spritesheet"。
  • tool_result("resource_link" | "resource"、デフォルト:"resource_link")
    • ダウンロードしたアセットの content[] の形式を指定します。
      • "resource_link" は ResourceLink アイテム(ファイル/URL ベース)を出力します
      • "resource" は base64 の resource.blob を含む EmbeddedResource ブロックを出力します

出力(MCP CallToolResult):

  • structuredContent:OpenAI Video オブジェクト(ジョブのメタデータ。wait_for_completion=true の場合は最終状態)。
  • content:ダウンロードしたアセットの resource_link(デフォルト)または埋め込み resource ブロック(リクエスト時)と、JSON を含むテキストブロックが含まれます。
    • 概要 JSON ブロックを含みます:{ "video_id": "...", "pricing": { "currency": "USD", "model": "...", "size": "...", "seconds": 4, "price": 0.1, "cost": 0.4 } | null }(待機する場合:{ "video_id": "...", "assets": [...], "pricing": ... })
openai-videos-remix

既存の video_id からリミックスジョブを作成します(videos.remix)。

引数(入力スキーマ):

  • video_id(string、必須)
  • prompt(string、必須)
  • wait_for_completion、timeout_ms、poll_interval_ms、download_variants、tool_result — openai-videos-create と同じセマンティクスです(デフォルトでは待機します)。
openai-videos-list

動画ジョブを一覧表示します(videos.list)。

引数(入力スキーマ):

  • after(string、任意)— この位置より後の項目を一覧表示するためのカーソル(動画 ID)。
  • limit(integer、任意)
  • order("asc" | "desc"、任意)

出力:

  • structuredContent:OpenAI のリスト応答形式 { data, has_more, last_id }。
  • content:シリアライズされた JSON を含むテキストブロック。
openai-videos-retrieve

ジョブのステータスを取得します(videos.retrieve)。

  • video_id(string、必須)
openai-videos-delete

動画ジョブを削除します(videos.delete)。

  • video_id(string、必須)
openai-videos-retrieve-content

完了したジョブのアセットを取得し(videos.downloadContent、REST GET /videos/{video_id}/content)、許可された MEDIA_GEN_DIRS の下に書き込み、MCP resource_link(デフォルト)または埋め込み resource ブロック(tool_result 経由)を返します。

引数(入力スキーマ):

  • video_id(string、必須)
  • variant("video" | "thumbnail" | "spritesheet"、デフォルト:"video")
  • tool_result("resource_link" | "resource"、デフォルト:"resource_link")

出力(MCP CallToolResult):

  • structuredContent:OpenAI Video オブジェクト。
  • content:resource_link(または埋め込み resource)、概要 JSON ブロック { video_id, variant, uri, pricing }、および完全な動画 JSON が含まれます。
google-videos-generate

Google GenAI SDK(@google/genai)の ai.models.generateVideos を使用して、Google 動画生成オペレーションを作成します。

引数(入力スキーマ):

  • prompt(文字列、任意)
  • input_reference(文字列、任意)— 画像から動画を生成する際の入力(HTTP(S) URL、base64/data URL、または MEDIA_GEN_DIRS 配下のファイルパス)
  • input_reference_mime_type(文字列、任意)— input_reference の MIME タイプの上書き指定(image/* である必要があります)
  • input_video_reference(文字列、任意)— 動画拡張入力(HTTP(S) URL または MEDIA_GEN_DIRS 配下のファイルパス。input_reference とは同時に指定できません)
  • model(文字列、デフォルト:"veo-3.1-generate-001")
  • number_of_videos(整数、デフォルト:1)
  • aspect_ratio("16:9" | "9:16"、任意)
  • duration_seconds(整数、任意)
    • Veo 2 モデル:5~8 秒(デフォルト:8)
    • Veo 3 モデル:4、6、または 8 秒(デフォルト:8)
    • referenceImages の使用時:8 秒
  • person_generation("DONT_ALLOW" | "ALLOW_ADULT" | "ALLOW_ALL"、任意)
  • wait_for_completion(ブール値、デフォルト:true)
  • timeout_ms(整数、デフォルト:900000)
  • poll_interval_ms(整数、デフォルト:10000)
  • download_when_done(ブール値、任意。待機する場合のデフォルトは true)
  • tool_result("resource_link" | "resource"、デフォルト:"resource_link")
    • ダウンロードした動画の content[] の形式を指定します。
  • response_format("url" | "b64_json"、デフォルト:"url")
    • structuredContent.response.generatedVideos[].video のフィールドを指定します。
      • "url" は video.uri を優先します(video.videoBytes は除去されます)。
      • "b64_json" は video.videoBytes を優先します(video.uri は除去されます)。

要件:

  • Gemini Developer API:GEMINI_API_KEY(または GOOGLE_API_KEY)を設定するか、secrets.yaml で google.api_key を設定します。
  • Vertex AI:GOOGLE_GENAI_USE_VERTEXAI=true、GOOGLE_CLOUD_PROJECT、GOOGLE_CLOUD_LOCATION を設定するか、secrets.yaml で google.vertex_ai.* を設定します。

出力:

  • structuredContent:Google オペレーションオブジェクト(利用可能な場合は name、done、response.generatedVideos[] を含みます)。
  • content:ステータステキスト、任意の .mp4 resource_link(デフォルト)、またはダウンロード時の埋め込み resource ブロック、および互換性のための JSON テキストブロック。
google-videos-retrieve-operation

既存の Google 動画オペレーション(ai.operations.getVideosOperation)を取得/ポーリングします。

  • operation_name(文字列、必須)
  • response_format("url" | "b64_json"、デフォルト:"url")

出力:

  • structuredContent:Google オペレーションオブジェクト。
  • content:短い概要とオペレーション全体を含む JSON テキストブロック。
google-videos-retrieve-content

完了したオペレーションの .mp4 コンテンツをダウンロードし、ファイル優先の MCP resource_link(デフォルト)または埋め込み resource ブロック(tool_result で指定)を返します。

  • operation_name(文字列、必須)
  • index(整数、デフォルト:0)— response.generatedVideos[index] を選択します。
  • tool_result("resource_link" | "resource"、デフォルト:"resource_link")
  • response_format("url" | "b64_json"、デフォルト:"url")

推奨ワークフロー:

  1. google-videos-generate を wait_for_completion=true(デフォルト)で呼び出し、完了したオペレーションとダウンロードを取得します。オペレーション ID がすぐに必要な場合に限り、false に設定します。
  2. done=true になるまで google-videos-retrieve-operation をポーリングします。
  3. google-videos-retrieve-content を呼び出して .mp4 をダウンロードし、resource_link(または埋め込み resource)を受け取ります。
fetch-images

URL またはローカルファイルパスから画像を取得し、オプションで圧縮して処理します。

引数(入力スキーマ):

  • sources (string[], optional)
    • 画像ソースの配列:HTTP(S) URL、またはファイルパス(絶対パス、もしくは最初の MEDIA_GEN_DIRS エントリからの相対パス)。
    • 最小:1、最大:20 枚の画像。
    • ids および n とは相互に排他的です。
  • ids (string[], optional)
    • プライマリの MEDIA_GEN_DIRS[0] ディレクトリ内で、ローカルファイル名に一致する画像 ID の配列。
    • ID は安全な文字のみで構成する必要があります([A-Za-z0-9_-] のみ。..、*、?、スラッシュは不可)。
    • _{id}_ または _{id}. を含むファイル名に一致します(単一の出力と、_1.png のような複数出力のサフィックスの両方に対応)。
    • ids を使用する場合、compression と file はサポートされません(新しいファイルは作成されません)。
    • sources および n とは相互に排他的です。
  • n (integer, optional)
    • 設定すると、プライマリの MEDIA_GEN_DIRS[0] ディレクトリから最後の N 個の画像ファイルを返します。
    • ファイルは更新日時順(最も新しく更新されたものが先)に並べ替えられます。
    • sources および ids とは相互に排他的です。
  • compression (object, optional)
    • max_size (integer, optional):最大寸法(ピクセル単位)。これを超えるサイズの画像はリサイズされます。
    • max_bytes (integer, optional):目標とする最大ファイルサイズ(バイト単位)。デフォルト:819200(800KB)。
    • quality (integer, optional):JPEG/WebP の品質(1~100)。デフォルト:85。
    • format ("jpeg" | "png" | "webp", optional):出力形式。デフォルト:jpeg。
  • response_format ("url" | "path" | "b64_json", default: "url")
    • レスポンス形式:ファイル/URL ベース(url)、ローカルパス(path)、またはインラインの base64(b64_json)。
  • tool_result ("resource_link" | "image", default: "resource_link")
    • content[] の形式を指定します:
      • "resource_link" は ResourceLink アイテム(ファイル/URL ベース)を出力します
      • "image" は base64 の ImageContent ブロックを出力します
  • file (string, optional)
    • 出力ファイルのベースパス。画像が複数ある場合は、インデックスのサフィックスが追加されます。

動作に関する注意:

  • 最大スループットを実現するため、画像は並列処理されます。
  • 圧縮は、compression オプションが指定された場合にのみ適用されます。
  • 圧縮を有効にすると、sharp を使用して、品質やサイズを段階的に下げます。
  • 部分的な成功:一部のソースでエラーが発生しても、取得に成功した画像は返され、エラーはレスポンスに記載されます。
  • n が指定されている場合でも、MEDIA_GEN_MCP_ALLOW_FETCH_LAST_N_IMAGES 環境変数が true に設定されている場合にのみ適用されます。設定されていない場合、呼び出しは検証エラーで失敗します。
  • タイムアウトにより、MCP クライアント(ChargeGPT など)が media-gen-mcp からのレスポンスを待たないことがあります。openai-images-generate/openai-images-edit の最新の出力をすぐに取得する必要があるクリエイティブな環境では、n 引数を指定して fetch-images を使用できます。MEDIA_GEN_MCP_ALLOW_FETCH_LAST_N_IMAGES=true 環境変数が設定されている場合、元の生成または編集操作が MCP クライアント側でタイムアウトしていても、fetch-images は MEDIA_GEN_DIRS[0] から最後の N 個のファイルを返します。
fetch-videos

HTTP(S) URL またはローカルファイルパスから動画を取得します。

引数(入力スキーマ):

  • sources(string[]、任意)
    • 動画ソースの配列:HTTP(S) URL またはファイルパス(絶対パス、または最初の MEDIA_GEN_DIRS エントリからの相対パス)。
    • 最小:1 件、最大:20 件の動画。
    • ids および n とは相互に排他的です。
  • ids(string[]、任意)
    • プライマリ MEDIA_GEN_DIRS[0] ディレクトリ内でローカルファイル名に一致する動画 ID の配列。
    • ID は安全な文字列である必要があります([A-Za-z0-9_-] のみ。..、*、?、スラッシュは使用できません)。
    • _{id}_ または _{id}. を含むファイル名に一致します(単一出力と、_thumbnail.webp のような複数アセットのサフィックスの両方に対応します)。
    • ids を使用する場合、file はサポートされません(ダウンロードは行わず、既存のファイルを返します)。
    • sources および n とは相互に排他的です。
  • n(integer、任意)
    • 指定すると、プライマリ MEDIA_GEN_DIRS[0] ディレクトリから最新 N 件の動画ファイルを返します。
    • ファイルは更新日時順(更新日時が新しい順)に並べ替えられます。
    • sources および ids とは相互に排他的です。
  • tool_result("resource_link" | "resource"、デフォルト:"resource_link")
    • content[] の形式を指定します:
      • "resource_link" は ResourceLink アイテム(ファイル/URL ベース)を出力します
      • "resource" は base64 の resource.blob を含む EmbeddedResource ブロックを出力します
  • file(string、任意)
    • 出力ファイルのベースパス(URL からダウンロードする場合に使用します)。複数の動画をダウンロードする場合は、インデックスのサフィックスが追加されます。

出力:

  • content:解決された動画ごとに 1 つの resource_link(デフォルト)または埋め込み resource ブロックを返し、任意でエラー概要のテキストブロックも返します。
  • structuredContent:{ data: [{ source, uri, file, mimeType, name, downloaded }], errors?: string[] }。

動作に関する注意事項:

  • URL のダウンロードが許可されるのは、URL が MEDIA_GEN_URLS に一致する場合のみです(設定されている場合)。
  • n を指定した場合、環境変数 MEDIA_GEN_MCP_ALLOW_FETCH_LAST_N_VIDEOS が true に設定されている場合にのみ適用されます。それ以外の場合、呼び出しは検証エラーで失敗します。
fetch-document

HTTP(S) URL またはローカルファイルパスからドキュメントを取得します。

引数(入力スキーマ):

  • sources(string[])
    • ドキュメントソースの配列:HTTP(S) URL またはファイルパス(絶対パス、または最初の MEDIA_GEN_DIRS エントリからの相対パス)。
    • 最小:1 件、最大:20 件のドキュメント。
  • tool_result("resource_link" | "resource"、デフォルト:"resource_link")
    • content[] の形式を指定します:
      • "resource_link" は ResourceLink アイテム(ファイル/URL ベース)を出力します
      • "resource" は base64 の resource.blob を含む EmbeddedResource ブロックを出力します
  • file(string、任意)
    • 出力ファイルのベースパス(URL からダウンロードする場合に使用します)。複数のドキュメントをダウンロードする場合は、インデックスのサフィックスが追加されます。

出力:

  • content:解決されたドキュメントごとに 1 つの resource_link(デフォルト)または埋め込み resource ブロックを返し、任意でエラー概要のテキストブロックも返します。
  • structuredContent:{ data: [{ source, uri, file, mimeType, name, downloaded }], errors?: string[] }。

動作に関する注意事項:

  • URL のダウンロードが許可されるのは、URL が MEDIA_GEN_URLS に一致する場合のみです(設定されている場合)。
  • ローカルパスは MEDIA_GEN_DIRS に対して検証され、file:// URL として指定できます。
  • file を省略した場合、デフォルトのファイル名は output_<time_t>_media-gen__fetch-document_<uuid>.<ext> になります。
test-images

OpenAI API を呼び出さずに MCP の結果の配置をテストするデバッグツールです。

MEDIA_GEN_MCP_TEST_SAMPLE_DIR が設定されている場合にのみ有効です。このツールは、このディレクトリ内にある既存の画像を読み込み、新しいファイルは作成しません。

引数(入力スキーマ):

  • response_format("url" | "path" | "b64_json"、デフォルト:"url")
  • result_placement("content" | "api" | "structured" | "toplevel" またはこれらの配列、省略可)
    • この呼び出しに限り、MEDIA_GEN_MCP_RESULT_PLACEMENT を上書きします。
  • compression(オブジェクト、省略可)
    • fetch-images と同じ調整項目ですが、キーには camelCase を使用します:
  • tool_result("resource_link" | "image"、デフォルト:"resource_link")
    • content[] の形式を制御します:
      • "resource_link" は ResourceLink 項目(ファイル/URL ベース)を出力します
      • "image" は base64 の ImageContent ブロックを出力します
      • maxSize(整数、省略可):ピクセル単位の最大寸法です。
      • maxBytes(整数、省略可):バイト単位の目標最大ファイルサイズです。
      • quality(整数、省略可):JPEG/WebP の品質(1~100)です。
      • format("jpeg" | "png" | "webp"、省略可):出力形式です。

動作に関する注意:

  • サンプルディレクトリから最大 10 枚の画像を読み込みます(並べ替えは行わず、ファイルシステムの順序に従います)。

  • openai-images-generate および openai-images-edit と同じ結果構築ロジックを使用します(result_placement による上書きも含みます)。

  • output == "base64" で compression が指定されている場合、サンプルファイルを読み込み、sharp を使用してメモリ上で圧縮します。ディスク上の元ファイルは変更されません。

  • さまざまな結果構造を異なる MCP クライアントがどのように処理するかのテストに便利です。

  • result_placement に "api" が含まれる場合、ツールは OpenAI Images API 形式のモックオブジェクトを返します:

    • トップレベル:created、data[]、background、output_format、size、quality。
    • response_format: "b64_json" の場合、各 data[i] に b64_json が含まれます。
    • response_format: "path" の場合、各 data[i] に path が含まれます。
    • response_format: "url" の場合、各 data[i] に b64_json ではなく url が含まれます。
test-images 用デバッグ CLI ヘルパー

ローカルでデバッグするために、test-images を直接呼び出すヘルパースクリプトが 2 つあります:

  • npm run test-images – debug/debug-call.ts を使用し、MCP SDK クライアントから見た検証済みの CallToolResult を出力します。使用方法:

    npm run test-images -- [placement] [--response_format url|path|b64_json]
    # examples:
    # npm run test-images -- structured --response_format b64_json
    # npm run test-images -- structured --response_format path
    # npm run test-images -- structured --response_format url
    
  • npm run test-images:raw – debug/debug-call-raw.ts を使用し、未加工の JSON-RPC result(追加のラップ処理がない、基になる CallToolResult)を出力します。上記と同じ CLI フラグを使用します。

どちらのスクリプトも、読みやすくするため、大きなフィールドを切り詰めます:

  • image_url → 先頭 80 文字の後に ...(N chars);
  • b64_json および data(base64 文字列の場合)→ 先頭 25 文字の後に ...(N chars)。

🧩 バージョンポリシー

セマンティック バージョニング(SemVer)

このパッケージは SemVer に従います:MAJOR.MINOR.PATCH(x.y.z)。

  • MAJOR — 破壊的変更(ツール名、入力スキーマ、出力形式)。
  • MINOR — 新しいツール、または後方互換性のある追加(新しい任意パラメーター、レスポンス内の新しいフィールド)。
  • PATCH — 意図的な動作変更を伴わないバグ修正と内部リファクタリング。

1.0.0 以降、このプロジェクトは 標準的な SemVer のルールに従います:破壊的変更では MAJOR を上げます(npm の ^1.0.0 は 1.x を許容しますが、2.0.0 は許容しません)。

依存関係の方針

このリポジトリは、最新の安定版リリースに緊密に追随することを目指しています。

  • MCP SDK:最新の安定版 @modelcontextprotocol/sdk とスキーマを対象にしています。
  • OpenAI SDK:最新の安定版 openai パッケージに定期的に更新しています。
  • Zod:Zod 4.x 系(現在は ^4.1.3)を使用しています。このプロジェクトでは以前 Zod 3.x を使用していましたが、MCP TypeScript SDK の型定義と組み合わせた際に、.shape を inputSchema に渡すと、TypeScript のエラーが多数発生しました。特に TS2589("type instantiation is excessively deep and possibly infinite")と TS2322(schema shape not assignable to AnySchema | ZodRawShapeCompat)が発生しました。上流での議論は modelcontextprotocol/typescript-sdk#494、関連する Zod の型定義に関する作業は colinhacks/zod#5222 で追跡しており、完全な strict コンパイルを安定して通過できる組み合わせを使用しています。
  • ツールチェーン(Node.js、TypeScript など):最近の LTS 版/現行リリースを使用して開発・テストしています。また、すべての TypeScript strict チェック(strict、noUnusedLocals、noUnusedParameters、exactOptionalPropertyTypes、noUncheckedIndexedAccess、noPropertyAccessFromIndexSignature など)を有効にする専用の tsconfig-strict.json を用意しています。

環境の要件に応じて、Node.js、TypeScript、OpenAI SDK、Zod、またはスタック内のその他の要素を特定のバージョンに固定したり、ダウングレードしたりしてもかまいません。ただし、次の点にご留意ください。

  • 主に最新のスタックを対象にテストと調整を行っています。
  • 古いランタイム/SDK バージョンでのみ再現する問題は、調査やサポートが難しい場合があります。
  • 上流との互換性は、まず最新の MCP 仕様と OpenAI Images API を基準に検証しています。

このプロジェクトは、意図的に少し未来志向です。MCP と OpenAI のツールに新機能が登場するたびに対応しようとしています(特に、MCP 経由での堅牢なマルチモーダル/画像サポートと、ChatGPT の UI における画像サポート)。ChatGPT での MCP 画像レンダリングに関する、実環境での詳細なバグ報告と分析を、事例として参考資料のセクションに掲載しています。

長期的に安定したスタックが必要な場合は、ご自身のフォークでバージョンを正確に固定し、環境内で慎重に検証してください。


🧩 型付きツールコールバック

すべてのツールハンドラーでは、Zod スキーマから z.input<typeof schema> を使って導出した、厳密に型付けされたコールバックパラメーターを使用しています。

// Schema definition
const openaiImagesGenerateBaseSchema = z.object({
  prompt: z.string().max(32000),
  background: z.enum(["transparent", "opaque", "auto"]).optional(),
  // ... more fields
});

// Type alias
type OpenAIImagesGenerateArgs = z.input<typeof openaiImagesGenerateBaseSchema>;

// Strictly typed callback
server.registerTool(
  "openai-images-generate",
  { inputSchema: openaiImagesGenerateBaseSchema.shape, ... },
  async (args: OpenAIImagesGenerateArgs, _extra: unknown) => {
    const validated = openaiImagesGenerateSchema.parse(args);
    // ... handler logic
  },
);

このパターンには、次の利点があります。

  • 静的な型安全性 — すべての入力フィールドで、IDE の自動補完とコンパイル時チェックが利用できます。
  • 実行時の検証 — Zod の .parse() により、処理前にすべての入力がスキーマに一致することを確認できます。
  • MCP SDK との互換性 — inputSchema: schema.shape によって、ツール登録用の JSON Schema を提供します。

すべてのツール(openai-images-*、openai-videos-*、fetch-images、fetch-videos、fetch-document、test-images)がこのパターンに従っています。


🧩 ツールのアノテーション

この MCP サーバーでは、以下のツールにアノテーションのヒントを設定しています。

ツールreadOnlyHintdestructiveHintidempotentHintopenWorldHint
openai-images-generatetruefalsefalsetrue
openai-images-edittruefalsefalsetrue
openai-videos-createtruefalsefalsetrue
openai-videos-remixtruefalsefalsetrue
openai-videos-listtruefalsefalsetrue
openai-videos-retrievetruefalsefalsetrue
openai-videos-deletetruefalsefalsetrue
openai-videos-retrieve-contenttruefalsefalsetrue
fetch-imagestruefalsefalsefalse
fetch-videostruefalsefalsefalse
fetch-documenttruefalsefalsefalse
test-imagestruefalsefalsefalse

これらのヒントにより、MCP クライアントは次のことを理解できます。

  • 外部 API を呼び出したり、外部リソースを読み取ったりする場合があります(オープンワールド)。
  • 既存のプロジェクトファイルやユーザーデータは変更せず、設定された出力ディレクトリに新しいメディアファイル(画像/動画/ドキュメント)のみを作成します。
  • 入力が同じでも、呼び出しごとに異なる出力が生成される場合があります。

ほとんどのツールで readOnlyHint が true に設定されているため、MCP プラットフォーム(chatgpt.com を含む)では、このサーバーを論理的に読み取り専用として扱うことができ、通常は「このツールはファイルを変更できます」という警告は表示されません。


📁 プロジェクト構成

media-gen-mcp/
├── src/
│   ├── index.ts              # MCP server entry point
│   └── lib/
│       ├── compression.ts    # Image compression (sharp)
│       ├── env.ts            # Env parsing + allowlists (+ glob support)
│       ├── helpers.ts        # URL/path validation, result building
│       ├── logger.ts         # Structured logging + truncation helpers
│       └── schemas.ts        # Zod schemas for all tools
├── test/
│   ├── compression.test.ts             # 12 tests
│   ├── env.test.ts                     # 19 tests
│   ├── fetch-images.integration.test.ts# 2 tests
│   ├── fetch-videos.integration.test.ts# 2 tests
│   ├── helpers.test.ts                 # 31 tests
│   ├── logger.test.ts                  # 10 tests
│   └── schemas.test.ts                 # 64 tests
├── debug/                    # Local debug helpers (MCP client scripts)
├── plan/                     # Design notes / plans
├── dist/                     # Compiled output
├── tsconfig.json
├── vitest.config.ts
├── package.json
├── CHANGELOG.md
├── README.md
└── AGENTS.md

📝 ライセンス

MIT


🩺 トラブルシューティング

  • OPENAI_API_KEY が有効で、画像 API にアクセスできることを確認してください。
  • 認証済みの OpenAI 組織が必要です。認証後、画像 API が利用可能になるまで 15~20 分かかることがあります。
  • ファイルパス[任意のパラメーター]は絶対パスで指定してください。
    • Unix/macOS/Linux:/ で始まるパス(例:/path/to/image.png)
    • Windows:ドライブ文字の後に : を付けたパス(例:C:/path/to/image.png または C:\path\to\image.png)
  • ファイルを出力する場合は、対象ディレクトリに書き込み権限があることを確認してください。
  • ファイル形式に関するエラーが表示された場合は、画像ファイルの拡張子と形式を確認してください。

🙏 インスピレーション

このサーバーは当初、 SureScaleAI/openai-gpt-image-mcp に着想を得ていましたが、現在は 公式仕様に厳密に準拠すること に重点を置いた、独立した実装になっています。

  • OpenAI Images API との整合性 – openai-images-generate と openai-images-edit の引数は、 images.create / gpt-image-1.5 に準拠しています。 prompt、n、size、quality、background、output_format、 output_compression、user、さらに response_format(url / b64_json)が含まれ、 OpenAI Images API と同じ意味で使用されます。
  • MCP ツール結果との整合性(image + resource_link) – result_placement = "content" の場合、サーバーは MCP の 5.2 ツール結果 セクション (5.2.2 画像コンテンツ、 5.2.4 リソースリンク) に準拠し、型が明確な content[] アイテムを出力します。
    • response_format = "b64_json" の場合: { "type": "image", "data": "<base64>", "mimeType": "image/png" };
    • ファイルまたは URL ベースの出力の場合: { "type": "resource_link", "uri": "file:///..." | "https://...", "name": "...", "mimeType": "image/..." }。
  • OpenAI 形式の生の API 出力 – result_placement = "api" の場合、ツール 結果自体が OpenAI Images 形式のオブジェクトになります。 { created, data: [...], background, output_format, size, quality, usage? }。 各 data[] エントリには、response_format = "b64_json" の場合は b64_json が、response_format = "url" の場合は url が含まれます。この モードでは、MCP のラッパーフィールド(content、structuredContent、files、urls)は 追加されません。

要するに、このライブラリは次のように動作します。

  • result_placement = "api" かつ response_format = "url" | "b64_json" の場合、 引数と結果の形式 は OpenAI Images API に準拠し、
  • result_placement = "content" の場合、ツール結果のコンテンツブロック (image、resource_link、text)は MCP 仕様に準拠します。
一般的なクライアント向けの推奨プリセット
  • デフォルトモード/Claude Desktop/厳密な MCP クライアント
    MCP 仕様に厳密に準拠するクライアントには、次の設定が推奨されます。

    • result_placement = content
    • response_format = b64_json

    このモードでは、サーバーは次を返します。

    • type: "image"(Base64 画像データ)と type: "resource_link"(ファイル/URL リンク)を含む content[]。MCP の第 5.2 節(画像コンテンツとリソースリンク)に準拠しています。この出力は、Claude Desktop との 直接連携 や、 2025‑11‑25 仕様を完全に実装しているあらゆるクライアントで適切に機能します。
  • chatgpt.com Developer Mode
    このサーバーを ChatGPT Developer Mode の背後で MCP バックエンドとして実行する場合、 OpenAI Images API に最も近い次の設定が実用的です。

    • result_placement = api
    • response_format = url

    このモードでは、ツール結果は images.create / gpt-image-1.5 の形式 (data[].url を含む)に一致するため、OpenAI スキーマを想定するバックエンドや ライブラリで扱いやすくなります。

    ただし、この OpenAI ネイティブ形式でも、chatgpt.com クライアントは現在、画像を表示しません。この動作については、次のレポートで詳しく説明されています。
    https://github.com/strato-space/report/issues/1


⚠️ 制限事項と大容量ファイルの処理

  • 設定可能なペイロード保護機能: このサーバーはデフォルトで、一般的な MCP クライアントの制限内に収まるよう、インラインの content に対して約 50MB(52,428,800 bytes)の上限を設定しています。このしきい値は、MCP_MAX_CONTENT_BYTES 環境変数により、より大きい値(または小さい値)に変更できます。
  • ファイル出力への自動切り替え: 画像の合計 base64 サイズが設定されたしきい値を超えると、ツールは画像を自動的にディスクに保存し、インラインの base64 の代わりに resource_link を通じてファイルパスを返します。これにより、フル解像度の画像を提供しながら、クライアント側の「ペイロードが大きすぎます」エラーを回避できます。
  • デフォルトのファイル保存先: file パスを指定しない場合、出力は MEDIA_GEN_DIRS[0](デフォルト:/tmp/media-gen-mcp)に、output_<time_t>_media-gen__<tool>_<id>.<ext> のような名前で保存されます。
  • 環境変数:
    • MEDIA_GEN_DIRS:出力の保存先を指定します。例:export MEDIA_GEN_DIRS=/your/desired/dir。このディレクトリは、ファイルを直接配信する場合、公開静的ディレクトリと同じ場所にできます。
    • MEDIA_GEN_MCP_URL_PREFIXES:公開 URL 用の、カンマ区切りの任意の HTTPS プレフィックスです。MEDIA_GEN_DIRS の各エントリに位置順で対応します。設定すると、サーバーは <prefix>/<relative_path_inside_root> の形式で公開 URL を生成し、ファイルパスとともに返します(たとえば、response_format: "url" の場合は resource_link URI や structuredContent.data[].url を通じて返します)。例:export MEDIA_GEN_MCP_URL_PREFIXES=https://media-gen.example.com/media,https://media-gen.example.com/samples
    • ベストプラクティス: 大容量または本番環境向けの画像には、必ずファイル出力を使用し、クライアントがファイルパスを処理できるように設定してください。公開ウェブサーバー(例:nginx)経由で画像を配信するには、MEDIA_GEN_DIRS と(任意で)MEDIA_GEN_MCP_URL_PREFIXES を設定します。

🌐 生成ファイルを HTTPS 経由で配信する

ChatGPT(またはその他の MCP クライアント)に、ファイルパスとともに一般公開されている URL を提示させる場合:

  1. 画像ディレクトリを HTTPS 経由で公開します。たとえば、nginx では次のように設定します。

    server {
        # listen 443 ssl http2;
        # server_name <server_name>;
    
        # ssl_certificate     <path>;
        # ssl_certificate_key <path>;
    
        location /media/ {
            alias /home/username/media-gen-mcp/media/;
            autoindex off;
            expires 7d;
            add_header Cache-Control "public, immutable";
        }
    }
    
  2. MEDIA_GEN_DIRS の最初のエントリが同じディレクトリを指すようにします(例:MEDIA_GEN_DIRS=/home/username/media-gen-mcp/media/、またはプロジェクトのルートから実行する場合は MEDIA_GEN_DIRS=media/)。

  3. MEDIA_GEN_MCP_URL_PREFIXES=https://media-gen.example.com/media を設定すると、サーバーは最上位の urls、resource_link URI、および image_url フィールドに対応する HTTPS URL を返します(response_format: "url" の場合)。

openai-images-generate と openai-images-edit は、base64 とファイルの両方のレスポンスモードで、files と urls を付加するようになりました。これにより、クライアントはローカルファイルシステムのパスと公開 HTTPS リンクのどちらも参照できます。これは、ChatGPT が MCP の画像ブロックをまだインラインで表示できない場合に特に便利です。


📚 参考資料

  • Model Context Protocol

  • OpenAI Images

  • OpenAI Videos

  • 事例

    • ChatGPT での MCP 画像レンダリング(GitHub issue)
      • 症状: ChatGPT は MCP の image コンテンツブロックを無視したり、誤って処理したりすることがよくありました。ツールの結果が空になる、生の base64 がテキストとして扱われて大量のトークンを消費する、または「画像が見えません」という一般的な応答が返される一方で、他の MCP クライアント(Cursor、Claude)では同じ画像が正しくレンダリングされていました。
      • 根本原因: MCP 仕様そのものの問題ではなく、MCP の CallToolResult 画像コンテンツブロックとメディアオブジェクトの ChatGPT における処理・シリアル化の問題です(特に UI レンダリングやネストされたコンテナーに関するものです)。
      • 状況と回避策: OpenAI は Codex/ChatGPT で MCP の画像サポートに関する修正の展開を開始していますが、動作には依然として一貫性がありません。このサーバーでは、現在および今後の MCP クライアントでツールを使用できるように、file/resource_link と URL のパターン、および仕様に準拠した image ブロックを使用しています。

🙏 謝辞

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。