# MCPツール仕様 ## 1. 概要 `mcp-sd15` は`stdio`または`streamable-http`トランスポートで動作し、 Stable Diffusion 1.xによる画像生成を行う次の3ツールを公開する。 | ツール | 用途 | |---|---| | `generate_image` | テキストから画像を生成する | | `generate_guided_image` | DepthまたはOpenPoseで誘導して画像を生成する | | `inpaint_image` | 元画像のmask指定領域を再生成する | 全ツールの出力は1枚のPNGである。生成パラメータ、モデル、LoRA、ControlNet強度、seedは ツール入力には公開しない。これらは設定ファイルまたはサーバ内部で管理する。 ## 2. 共通仕様 ### 2.1 Prompt | 項目 | 仕様 | |---|---| | `positive_prompt` | 必須の文字列。前後の空白を除去した結果が空の場合はエラー | | `negative_prompt` | 任意の文字列。省略または`null`の場合は空文字列 | | 最大長 | それぞれ10,000文字 | `[prompt]`設定でbase promptを指定している場合、LLMからのプロンプトと結合してから pipelineへ渡す。positiveは`base, user`の順でカンマ区切り、negativeは`base\nuser`の順で 改行区切りとなる。base promptはMCPツール入力には公開しない。 ### 2.2 Image size `size`には次の列挙値だけを指定できる。省略または`null`の場合は `generation.default_size`が使用される。 | 値 | 幅 | 高さ | |---|---:|---:| | `square_512` | 512 | 512 | | `landscape_512` | 512 | 384 | | `portrait_512` | 384 | 512 | 任意の`width`や`height`は指定できない。 ### 2.3 入力画像 `input_image`と`mask_image`は、次のいずれかの文字列で指定する。 - PNGまたはJPEGバイナリをBase64エンコードした文字列 - `data:image/png;base64,...`形式のdata URI - `data:image/jpeg;base64,...`または`data:image/jpg;base64,...`形式のdata URI 画像入力には次の制限がある。 | 項目 | 制限 | |---|---| | 画像形式 | PNG、JPEGのみ | | Base64文字列長 | 36,000,000文字以下 | | pixel数 | 40,000,000 pixel以下 | | Base64 | 改行やBase64以外の文字を含まない正規のBase64 | 入力画像は生成サイズにリサイズされる。通常画像にはLanczos、maskにはnearest-neighborが 使用される。 ### 2.4 出力 成功時はMCPの`ImageContent`を1件返す。 ```json { "type": "image", "data": "iVBORw0KGgoAAA...", "mimeType": "image/png" } ``` `data`はMCP SDKによってBase64エンコードされる。PNGには次のtext metadataが埋め込まれる。 | Key | 内容 | |---|---| | `seed` | サーバが生成したseed | | `size` | 使用したサイズID | | `mode` | `text_to_image`、`guided_image`、`inpaint_image`のいずれか | | `timestamp` | UTCのISO 8601生成日時 | | `elapsed_seconds` | キュー待ちを含む処理時間(秒) | 出力ファイルの保存が有効な場合も、MCPレスポンスには同じPNGが返される。 ## 3. `generate_image` 設定済みのbase checkpoint、VAE、LoRAを使ってText-to-Imageを実行する。 ### 入力 | 名前 | 型 | 必須 | 既定値 | |---|---|---:|---| | `positive_prompt` | string | Yes | なし | | `negative_prompt` | string \| null | No | `null`(内部では空文字列) | | `size` | size enum \| null | No | `generation.default_size` | ### 呼び出し例 ```json { "positive_prompt": "a small lighthouse on a rocky coast, sunset", "negative_prompt": "low quality, blurry", "size": "landscape_512" } ``` ### JSON Schema ```json { "type": "object", "title": "generate_imageArguments", "properties": { "positive_prompt": { "type": "string", "title": "Positive Prompt" }, "negative_prompt": { "anyOf": [{"type": "string"}, {"type": "null"}], "default": null, "title": "Negative Prompt" }, "size": { "anyOf": [ { "type": "string", "enum": ["square_512", "landscape_512", "portrait_512"] }, {"type": "null"} ], "default": null, "title": "Size" } }, "required": ["positive_prompt"] } ``` ## 4. `generate_guided_image` 入力画像を固定preprocessorに通し、対応するControlNetで画像生成を誘導する。 ### 入力 | 名前 | 型 | 必須 | 既定値 | |---|---|---:|---| | `positive_prompt` | string | Yes | なし | | `control_mode` | control mode enum | Yes | なし | | `input_image` | string | Yes | なし | | `negative_prompt` | string \| null | No | `null`(内部では空文字列) | | `size` | size enum \| null | No | `generation.default_size` | `control_mode`の意味は次のとおり。 | 値 | ControlNet設定 | 前処理 | |---|---|---| | `depth` | `controlnet.depth` | MiDaS depth | | `openpose` | `controlnet.openpose` | body pose | | `openpose_full` | `controlnet.openpose` | body、hand、face pose | 要求したControlNetが設定で無効の場合はツールエラーになる。`openpose`と `openpose_full`は同じControlNetモデルを共有する。 ### 呼び出し例 ```json { "positive_prompt": "a dancer wearing a red dress, studio lighting", "control_mode": "openpose_full", "input_image": "data:image/png;base64,iVBORw0KGgoAAA...", "negative_prompt": "deformed hands", "size": "portrait_512" } ``` ### JSON Schema ```json { "type": "object", "title": "generate_guided_imageArguments", "properties": { "positive_prompt": { "type": "string", "title": "Positive Prompt" }, "control_mode": { "type": "string", "enum": ["depth", "openpose", "openpose_full"], "title": "Control Mode" }, "input_image": { "type": "string", "title": "Input Image" }, "negative_prompt": { "anyOf": [{"type": "string"}, {"type": "null"}], "default": null, "title": "Negative Prompt" }, "size": { "anyOf": [ { "type": "string", "enum": ["square_512", "landscape_512", "portrait_512"] }, {"type": "null"} ], "default": null, "title": "Size" } }, "required": ["positive_prompt", "control_mode", "input_image"] } ``` ## 5. `inpaint_image` 元画像とmask画像を使い、白い領域をControlNet Inpaintで再生成する。 ### 入力 | 名前 | 型 | 必須 | 既定値 | |---|---|---:|---| | `positive_prompt` | string | Yes | なし | | `input_image` | string | Yes | なし | | `mask_image` | string | Yes | なし | | `negative_prompt` | string \| null | No | `null`(内部では空文字列) | | `size` | size enum \| null | No | `generation.default_size` | `mask_image`はgrayscaleに変換される。輝度が50%を超えるpixelが再生成対象で、黒い領域は 保持対象となる。 ### 呼び出し例 ```json { "positive_prompt": "a wooden table with a ceramic vase", "input_image": "data:image/png;base64,iVBORw0KGgoAAA...", "mask_image": "data:image/png;base64,iVBORw0KGgoAAA...", "negative_prompt": "artifacts", "size": "square_512" } ``` ### JSON Schema ```json { "type": "object", "title": "inpaint_imageArguments", "properties": { "positive_prompt": { "type": "string", "title": "Positive Prompt" }, "input_image": { "type": "string", "title": "Input Image" }, "mask_image": { "type": "string", "title": "Mask Image" }, "negative_prompt": { "anyOf": [{"type": "string"}, {"type": "null"}], "default": null, "title": "Negative Prompt" }, "size": { "anyOf": [ { "type": "string", "enum": ["square_512", "landscape_512", "portrait_512"] }, {"type": "null"} ], "default": null, "title": "Size" } }, "required": ["positive_prompt", "input_image", "mask_image"] } ``` ## 6. 実行制御とエラー 生成処理はサーバ内の単一lockで直列化される。同時に複数の要求を受信した場合、GPU推論は 1件ずつ実行される。 主なツールエラーは次のとおり。 | 分類 | 例 | |---|---| | 入力エラー | 空のprompt、不正なsize、不正なcontrol mode | | 画像エラー | Base64不正、未対応形式、画像破損、上限超過 | | 設定エラー | 要求したControlNetが無効、モデルをロードできない | | 推論エラー | Diffusers処理失敗、出力画像数不正 | | CUDA OOM | VRAM不足。CUDA cacheの解放を試みた後にエラーを返す | | 保存エラー | output directoryの作成またはPNG書込み失敗 | エラー時に画像は返されない。設定ファイル自体やbase modelが不正な場合は、MCPツールを 公開する前のサーバ起動処理が失敗する。