こんにちは、かがわ(@shinpr_p)です。
最近、個人開発で複数の画像を扱うサービスを作っていて、画像生成のワークフローをもっとスムーズにしたいと思っていました。いちいち別のツールで画像を生成して、ダウンロードして、コードに組み込んで…という作業は面倒ですよね。
そんな中、Googleが先日(2025年8月26日)正式発表したGemini 2.5 Flash Imageが目に留まりました!nano-banana
というコードネームで呼ばれていた・いるやつです。
実際使ってみるとプロンプトの工夫は必要なものの、わたしの利用シーンに合っている画像がそれなりに高い精度で生成されることが分かってきました。
そこで、これを開発環境(Claude Code)に組み込むと捗りそうだぞということで、MCPを作ることにしました。今回は、このGemini 2.5 Flash Imageを使ったMCPサーバーを実装した話を書いていきます。
なぜnano-bananaが気になったのか
私の個人開発では、同じキャラクターのシチュエーションの異なる画像や、複数の画像素材を組み合わせた画像をサンプルとして定期的に作る必要がありました。従来の画像生成AIだと、プロンプトごとにキャラクターの見た目が微妙に変わってしまったり、画像の編集が思うようにいかなかったりしていました。サンプルなのでいいっちゃいいのですが、ものづくりの観点でいうとサンプルの時点で一定のクオリティがあった方がいいのは間違いないです。
nano-bananaをXで見かけたときに気になったのは、キャラクター一貫性(Character Consistency)機能でした。同じキャラクターを異なる環境や表情で生成しても、そのアイデンティティを保持できる。それも特別な工夫の必要なく。というのはとてもよさそうに見えました。
Geminiの持つ現実世界の知識を活用した画像生成という要素も良さそうです。こちらはまだ恩恵を実感できるところまで使えていないですが、より文脈に沿った画像を生成できるというのはクオリティに寄与するはずです。
MCPサーバーとして実装することにした理由
今更感はありますが、MCPはModel Context Protocolの略称で、ホストアプリケーション(今回の場合はClaude Code)がサーバー(データソースやツール)と通信するための標準化されたプロトコルです。以前MCPを作っていたので勝手がわかっているし、Claude Codeから直接使えた方が明らかに取り回しがいいので、MCPを作ることにしました。
使ってみよう!
Claude CodeでのMCP設定を例として記載します。Claude Codeに限らずCursorなどMCPに対応しているツールであれば利用することが可能です。
Claude Codeの場合、以下のようにMCPを追加します。
% cd /path/to/project
% claude mcp add mcp-image --env GEMINI_API_KEY=new-key --env IMAGE_OUTPUT_DIR=/path/to/project -- npx -y https://github.com/shinpr/mcp-image
CursorなどGUI系ツールの場合はMCPの設定を登録するjsonファイルがあるので、そこに以下の内容を追加します(”など”と書きましたが、色々試した結果画像データはファイルでの入出力でなければトークン制限に引っかかったりする都合で、GUI系ツールはCursorがターゲットになりそうです)。
{
"mcpServers": {
"mcp-image": {
"command": "npx",
"args": ["-y", "https://github.com/shinpr/mcp-image"],
"env": {
"GEMINI_API_KEY": "your-api-key",
"IMAGE_OUTPUT_DIR": "/path/to/project/images"
}
}
}
}
IMAGE_OUTPUT_DIR
には、生成した画像を出力したいディレクトリの絶対パスを指定します。
設定値の補足(API Keyの発行)
Google AI Studioから、API Keyを発行します。
ここからAPI Keyを発行できます。Google Cloudと紐づけることも可能です。
取得したAPI KeyをGEMINI_API_KEY
に設定してください。
実際の成果物
Canva AIに生成してもらったこの元画像を、再生成してもらいます。
生成の過程
生成された画像
トーンを維持したまま左を向いてます!(こちらからみたら右向きなので、まぁいいでしょう)
nano-bananaの魅力
1画像あたり$0.039(約6円)と品質を考えるとかなりリーズナブルなことはやはり魅力的です。
また、画像生成に特化しているが故に、適切なプロンプトを与え、APIで提供されている機能を活用させれば、想定した画像が生成されやすいと感じています。現時点でまだプレビューであるため、これからさらに精度が向上し、機能が拡充されていくとより活用の幅が広がっていきそうなポテンシャルを感じます。
API実装における新機能の活用具体例
本MCPでは以下の機能を活用しています。
- maintainCharacterConsistency -> 同一キャラクターを異なるシーンで生成する際の一貫性を保証することで微妙な見た目の変化を防ぐ
- blendImages -> 入力画像とプロンプトから生成される画像を自然にブレンドする
- useWorldKnowledge -> Geminiの持つ現実世界の知識を活用し、より文脈に沿った画像を生成する
これらをtoolのパラメータに定義しており、descriptionも記載しています。つまり、呼び出し元のLLMが、画像加工の意図を解釈してフラグを指定したうえで、MCPをコールしてくれます。
フラグに応じて、Gemini APIに渡すプロンプトに構造化された補足情報を付与することで、解釈の精度を向上させています。
MCPツール定義(generate_image)に3つのパラメータを追加
{
blendImages: {
type: 'boolean',
description: 'Enable multi-image blending for combining multiple visual elements naturally. Use when prompt mentions multiple subjects or composite scenes'
},
maintainCharacterConsistency: {
type: 'boolean',
description: 'Maintain character appearance consistency. Enable when generating same character in different poses/scenes'
},
useWorldKnowledge: {
type: 'boolean',
description: 'Use real-world knowledge for accurate context. Enable for historical figures, landmarks, or factual scenarios'
}
}
プロンプトへの補足情報注入
if (params.maintainCharacterConsistency) {
enhancedPrompt += ' [INSTRUCTION: Maintain exact character appearance, including facial features, hairstyle, clothing, and all physical characteristics consistent throughout the image]'
}
if (params.blendImages) {
enhancedPrompt += ' [INSTRUCTION: Seamlessly blend multiple visual elements into a natural, cohesive composition with smooth transitions]'
}
if (params.useWorldKnowledge) {
enhancedPrompt += ' [INSTRUCTION: Apply accurate real-world knowledge including historical facts, geographical accuracy, cultural contexts, and realistic depictions]'
}
実装のポイントや苦労話
わたしはAgentic Codingの環境をここ数ヶ月整備してきました。
直近で結合時にEnd-To-Endで想定しない挙動をすることを抑止するための改善を入れていたので、実装もすんなり終わり、動作確認時も大きな期待値のズレなく動いてくれていました。
もちろん実利用を経たフィードバックや実装の微調整は必要でしたが、日に日に実装の負担が軽減されていくのはいい体験だなと改めて感じます。
苦労したことがなかったわけではありません。今回の開発では大きく2つの課題がありました。
1つ目は、インテグレーションテストです。結合時に期待された挙動を担保するために、Design Docに記載されたAC(Acceptance Criteria つまり受け入れ条件)からE2Eテストを生成する仕組み(サブエージェント)を導入しました。これにより、結合時の挙動は大幅に安定したものの、ACの日本語を複数の観点(要件、依存関係、制約・前提条件、成功指標)で分析しテストケースを生成するため、flakyなテストが一定数発生してしまいました。
今回は、一連の実装が終わるまではflakyさを許容し、実装完了かつ全テストパスしたタイミングで、flakyなテストを除去することで対処しました。
理想と現実のバランスは、今後向き合っていく必要のある課題になりそうです。
2つ目は、「LLMは最新の技術要素を知らない」問題です。このMCPでは、@google/genai
SDKを利用しています。設計書の生成時は最新の情報をWeb検索するようにしていたのですが、実装時には「設計書に記載があるのだから大丈夫だろう」ということで、Web検索を行うことを明示していません。結果的に、「設計書に記載されたSDKは間違えている。正しくは@google/generative-ai
だ!」と解釈され、誤った実装が行われてしまいました。流石にタスクの実行時までWeb検索させるのはコンテキスト的に重すぎるので、ここだけは私が介入し、修正をするという対応をしています。
どうしようかまだ思案中ですが、別途仕組みへのフィードバックは考えていきたいです。
まとめ
nano-banana(Gemini 2.5 Flash Image)を使った画像生成MCPサーバーの実装はスムーズに完了させられました。MCPもGemini APIを活用したアプリケーションも実装経験があったので、大外しせずでした。
キャラクター一貫性や自然言語編集など、実用的な機能が揃っているので、画像生成を含むプロジェクトを進めている方にはぜひ試してみてほしいです。現時点ではmodelがプレビュー版なので、アップデートには定期的に追従していくつもりです。
実際のコードも公開しているので、興味がある方は参照してみてください!
Views: 0