TL;DR
- Claude Code自体には画像生成機能がない
- ローカルのComfyUIを自作の薄いMCPサーバー経由でClaude Codeに繋いだ
- 「〇〇な画像を生成して」とチャットで頼むだけで、ローカルGPU(RTX 3060 Ti / VRAM 8GB)でSDXL画像が生成できるようになった
- API従量課金なしでコストゼロ、かつ生成物の商用利用ライセンスも自分で確認・管理できる
モチベーション
個人開発しているアプリ(NovelCraft)で、背景イラストなどの画像素材が必要になった。Midjourney等の外部APIを都度叩く運用は、
- 試行回数が多くなりがちな用途(プロンプトを何十回も微調整する)には従量課金が地味に効いてくる
- Claude Codeとの会話の中で「あ、この構図もう1パターン欲しい」を即座にできない(外部サービスに切り替えて操作する手間が発生する)
という2点がネックだった。そこで「手元のGPUでStable Diffusionを動かし、Claude Codeからそのままチャットで呼び出せるようにする」方向にした。
全体構成
ポイントは3つ。
1. コミュニティ製MCPサーバーではなく自作にした
ComfyUI用のMCPサーバーはOSSでいくつか公開されているが、出所不明なコードを常駐プロセスとして動かすことに抵抗があった。ComfyUIのHTTP API(/promptでジョブ投入、/historyで結果取得)を直接叩くだけなら数十行で書けるので、動作を完全に把握できる自作の薄いラッパーにした。
2. オンデマンド起動 + アイドルタイムアウト
ComfyUIをアイドル状態で常駐させるだけでも、Python + PyTorch + CUDAコンテキストで1〜2GB程度のメモリを常時消費する。システムRAMに余裕がない環境だったため、
- 生成リクエストが来たら自動起動
- 生成完了から一定時間(例: 5分)操作がなければ自動停止
という設計にした。初回起動込みで生成完了まで約70〜80秒、起動済み状態なら数秒〜数十秒(ステップ数次第)。
3. MCP登録スコープは user(グローバル)
最初 local スコープ(プロジェクト直下限定)で登録してしまい、別のリポジトリのセッションから呼び出せないことに気づいた。
claude mcp add comfyui -s user -- python D:\path\to\ComfyUI-MCP\server.py
-s user にすることで、どのプロジェクトディレクトリのセッションからでも同じMCPツールが使えるようになる。
使い方
セットアップ後は、Claude Codeのチャットで
廃墟になった近未来都市を、夕暮れの逆光で、低いアングルから描いた背景イラストを生成して
のように頼むだけ。裏側で generate_image(プロンプト・チェックポイント・サイズ等を指定)と list_checkpoints(利用可能なモデル一覧)というMCPツールが呼ばれ、生成された画像はローカルの ComfyUI/output/ に保存される。Claude Code自身が画像を読み取ってレビューし、「もう少し光を強く」といったフィードバックをそのままプロンプト調整に反映できるのが、チャット駆動ならではの利点だった。
チェックポイント選定でハマった点: ライセンス
初期状態はSDXL Base 1.0(Stability AI公式、商用利用も明確に許可)にしていたが、アニメ調のイラストを狙うにはBaseモデルでは物足りず、アニメ特化のファインチューン済みチェックポイントを追加することにした。
ここで重要なのは、Civitai等で配布されているアニメ系チェックポイントはモデルごとにライセンスがバラバラという点。商用サービスの素材として使う前提だったので、
- Illustrious-XL系: Fair AI Public License 1.0-SDで、"The output of this software is not covered by this license, and no contributor claims any rights to it." と明記 → 生成物の商用利用・販売は自由、クレジット表記も不要
- NoobAI-XL系(やそれをマージした派生モデル): ライセンスによっては生成物自体の商用利用を明示的に禁止しているケースがある
同じ「アニメ調SDXLチェックポイント」でも、ライセンスの条文まで読まないと商用利用可否が分からない。ダウンロード前にライセンスページを直接確認するステップを必ず挟むようにしている。
実際に同じ構図・同じテーマのプロンプトで、Baseモデルとアニメ特化モデルを比較するとこれくらい印象が変わる(どちらも本記事用に新規生成したサンプルで、実際の販売素材そのものではない)。
Before: SDXL Base 1.0
After: アニメ特化モデル(Illustrious-XL-v2.0)
プロンプトで分かった、モデル固有の癖
Illustrious-XL-v2.0でアニメ背景イラストを詰めていく過程で分かったこと。
-
線より先に光と色を詰める。
cel shadingやanime styleを強めるとディテールと荒廃感が抜け落ちやすい。逆にbacklighting, contre-jour, strong sun flare, high contrast lighting, dramatic chiaroscuroのような逆光・強コントラスト系タグの方が、狙った市販アニメ背景っぽさに近づいた。 - CFGは6.5〜7が安定。 5まで下げると光は柔らかくなるが、同時に構図の密度・ディテールも失われて別物になりやすい。
-
特定の語句が「実体」として描かれてしまうことがある。 例えば「collapsed monorail track(倒壊したモノレールの線路)」と書くと、高確率でモノレールの車両やバスそのものが具現化してしまう。橋や高架を出したいだけなら
elevated highway bridgeのように構造物であることを明示し、乗り物系の単語(train, monorail vehicleなど)はnegative側に入れておくと安定する。 - 「コントラストだけ」をプロンプトで動かそうとすると副作用が出やすい。 色相が変わる、構図が崩れるなどが起きがちなので、構図・ディテールが気に入った1枚が出たら、それ以上プロンプトはいじらず画像編集側(Pythonの Pillow)でコントラストやブルーム、靄を後処理として足し込む方が確実だった。
後処理は概ね以下のような処理を組み合わせている。
# S字カーブでコントラストを持ち上げる
arr = arr + 0.18 * (arr - 0.5) * (1 - np.abs(2 * arr - 1))
# ハイライト抽出 → ぼかし → スクリーン合成でブルームを足す
mask = np.clip((gray - 0.65) / (1 - 0.65), 0, 1) ** 1.2
bloom = highlight_img.filter(ImageFilter.GaussianBlur(radius=w * 0.035))
screened = 1 - (1 - soft) * (1 - bloom_arr * 0.55)
# 上部ほど白く霞ませる大気遠近法グラデーション
y_grad = np.linspace(0.30, 0.04, h).astype(np.float32)
foggy = screened * (1 - fog_alpha[..., None]) + white * fog_alpha[..., None]
プロンプトのガチャを回し続けるより、狙った構図が出た時点で編集に切り替えた方が収束が早い、というのが今回一番の学びだった。上記の後処理コードを先ほどの生成結果に適用すると、以下のようにハイライトがふわっと滲み、奥行きが出る。
まとめ
- Claude Code + 自作MCP + ComfyUIで、チャットのままローカル画像生成ができる
- オンデマンド起動でメモリ負担を抑えつつ、API課金なしで何十回でも試行できる
- 商用利用するならチェックポイントのライセンス条文を必ず個別確認する
- プロンプトで完璧を狙うより、「良い構図が出たら後処理で追い込む」方が安定する


