🍫

Cloud RunでAIアプリを作る。サイドカーでMCPサーバーを動かして連携する。

に公開

GW暇だったので、Cloud RunでAIチャットアプリを作ってみました。それだけだと普通すぎるのでサイドカーでMCPサーバーを動かして連携できるようにしてみました。

セキュリティ的に懸念も多いMCPサーバーですが、自社アカウントのクラウド上に閉じて構築すれば安心して使えるのではないかと思った次第です。Cloud Runならコンテナアプリを簡単にデプロイ出来ますし、生成AIはVertex AIを使えばGoogle Cloudに閉じた構築が可能です。

サイドカーとは?

こういうやつです。(この図はChatGPT製です)

つまり、サイドカーというのはメインとなるコンテナをサポートする為に付随する別のコンテナのことです。
通常、コンテナは1プロセス1コンテナで互いに疎結合に設計されます。そうすることで、開発や保守がしやすくなったり責任分離がしやすくなったりしていいことが多いです。
しかし、時には密結合にしたい機能もあります。例えばWebアプリケーションにNginxを付けて公開したり、Fluentdを付けてログを取得したりといった時です。そういう時にサイドカーが使われるというわけです。

MCPサーバーというのは、stdioやSSEでMCPクライアントと常に接続を維持する必要があります。モダンなアプリ開発でよく使用するFaaSやマネジメントサービスは疎結合を基本としているので、MCPとは相性が悪かったりします。
でも、コンテナのサイドカー構成なら密結合前提だから相性悪くないよね。という感じです。

構成図

下図のような構成です。とてもシンプルな作りですね。

主に使用した技術

以下のようなサービスやライブラリで作りました。

  • Google Cloud
  • Webアプリ
    • Flet : PythonだけでFlutterアプリを作れる。Flutterなのでwebアプリも作れる。
    • LangChain : LLMを用いたアプリケーション開発を効率的に行うためのフレームワーク
  • MCPサーバー

以下もうちょっと詳細に説明します。

Cloud Run

Cloud Runは、Google Cloudが提供するコンテナの実行環境を提供するサービスです。他のクラウドにもコンテナを実行できる環境は当然提供していますが、個人的にはCloud Runが圧倒的に使いやすいです。今回は、特に以下のような点でCloud Runを採用しました。

Cloud Runは、サイドカーの設定が楽

今回はお試しで作っているのでIaCを頑張るよりもコンソールからポチポチで簡単に作りたかったというのもありますが、Cloud Runの設定画面からコンテナを追加するだけでサイドカーを増やせるので楽です。

Cloud Runは、WebSocketが使える

Streamlitなどの多くのPythonのWebフレームワークはWebSocketで通信を必要としています。今回使用するFletもそうです。なのでFletで作ったWebアプリはWebSocketに対応しているプラットフォームでないと動かすことが出来ません。[1]
つまり、AWSのLambdaやApp Runnerでは動きません。ECSでは動かせますがECSは設定が面倒くさいのでちょっとお試しで作ってみるのには向きません。特にApp Runnerは、多数のユーザーのリクエストを無視して、WebSocketの対応をしない方針を固めています
簡単にWebSocketが使える環境を提供してくれるCloud Runは本当にありがたい存在です。

Cloud Runは、インスタンス数0までスケールインできる

Cloud Runには当然オートスケールの機能がありますが、設定すれば最小で0までスケールインしてくれます。0の時の利用量は0円です。お財布に優しいです。
0まで落とすと起動に多少時間がかかるので、0にしないほうがいいケースも普通に多いですが、今回のようにお試しで作る場合は「使わなければお金がかからない」というのは本当にありがたいです。生成AI系のサービスってコストが高いものが多いので作ったあと残しておきにくいんですよね。その点Cloud Runなら放置しても使わなければコストがかからないのがありがたいです。

Cloud Runは、簡単に認証が付けられる

これは、2025年4月のGoogle Cloud Nextで追加された新機能です。コンソールからIdentity-Aware Proxyにチェックをいれるだけで、Google認証を付けることができます。
お試しでアプリ作ったときって認証が面倒くさくて公開出来なかったりすることも多いので、これも本当に神機能だと思います。

Cloud Runは、ストレージのマウントが簡単にできる

Cloud StrageのバケットをCloud Runに簡単にマウントすることが出来ます。

MCPサーバーの場合設定をjsonで書くのが一般的なので、外部で編集した設定ファイルをCloud Strage経由で簡単にアプリに共有できるのはメリットが大きいです。
AWSだとECSにS3をマウントするのって結構面倒くさいのですよね。(出来なくはないはず)

Vertex AI (Claude)

Vertex AIについては、Cloud Runを使うことにしたので、単純に同じGoogle CloudのVertex AIを使っただけですね。深い理由はないです。
GeminiでなくてClaudeなのは、Geminiを使おうとしたらなんかエラーになってしまいまして、問題の切り分けのためにClaudeを試したら呼べたのでもうこのままClaudeでいいやとなった感じです。今回はMCPサーバーを使うことを目的にしてたので生成AIのモデルにあまりこだわりはないです。

Flet

FletはPythonでFlutterアプリを作ることができるフレームワークです。Flutterはクロスプラットフォームな開発ができるので、Webアプリも使えます。正直なところWebアプリのフレームワークは何でも良かったのですが、Fletは以前チャットアプリを作ろうとして途中で投げ出したので、今回はちゃんと使って見ようかなと思った次第です。
ですが、Fletで書いたことによる利点もちゃんとあります。それはネイティブアプリとしても動かせる点です。なんだかんだでWebだと使いにくいMCPサーバーがかなり多いので、ネイティブアプリで同じものを提供できるのは結構な強みかなと思いました。

LangChain MCP Adapters

https://github.com/langchain-ai/langchain-mcp-adapters

LangChain自体は今更説明不要だと思うので割愛して、LangChain MCP Adaptersですね。このライブラリを使うことで、MCPサーバーをLangChainやLangGraphと連携して扱うことができるようになります。つまり、このライブラリを使うことでLangChainを使ってMCPクライアントを実装できます。便利ですね。

ちなみに実装する際はこちらの記事を参考にしました。
https://qiita.com/moritalous/items/1591ab48f1ffda299719
参考にしたというか、AIエージェントにこの記事を読んで実装して欲しいと依頼しただけですが。今話題のバイブコーディングってやつですね。

Supergateway

https://github.com/supercorp-ai/supergateway

最後に紹介するのはSupergatewayです。こちらはMCPサーバー側のコンテナを作るのに使いました。何に使ったかというとstdioのMCPサーバーをSSEに変換するためです。
サイドカー構成したとはいえサーバーサイドで動かす以上stdioで接続するのは難しいです。ですので、SSEでMCPサーバーを立てることにしました。しかし、現時点(2025/05/05)で世の中の殆どのMCPサーバーはstdioで提供されています。Claude公式がSSEに対応したのもつい数日前のことですし、仕方がないですね。
しかし、ということはSSEにしか対応できないと現時点では汎用性がかなり劣るということになっていまいます。そこで使ったのがこの神ツールSupergatewayです。Supergatewayを使うことで簡単にstdioのツールをSSEに変換して提供することが出来ます。
使い方はとても簡単で、起動時のコマンドをこんな感じにするだけです。

npx -y supergateway \
    --stdio "npx -y @modelcontextprotocol/server-filesystem ./my-folder" \
    --port 8000 --baseUrl http://localhost:8000 \
    --ssePath /sse --messagePath /message

ということで、Supergatewayを使う前提でMCPサーバーのDockerfileを書き換えて、コンテナイメージをGoogle CloudのArtifact RegistryにPushすればCloud Runのサイドカーとして使えるようになるというわけです。

その他+感想

  • Cloud Runは1サービスあたり10コンテナが限界なのでサイドカーの数は9個が最大。超えたらどうしようかな。
  • Vertex AIのClaudeって529エラー多くないですか?(429エラーも多い)[2]
    • AWSのBedrockのClaudeではこんなにエラーはでないので、生成AI部分はBedrock使ったほうが安定しそう。

  • 今回は98%くらいはAIにコーディングを任せました。最近は参考になるURLを与えるとその中身を読んで実装してくれるのでとても楽になりました。
    • でも生成AIは物覚えが悪いので何度も同じミスを繰り返すのはなにか対策を考えたいです。プロンプトの調整でなんとかなるのかな?
    • FletのUIってもっとダサいイメージがあったけど、AIに「モダンでスタイリッシュにして」と頼んだら、見栄えが良くなって「こんなにカスタマイズできるんだー」と驚きました。
  • 久しぶりにCloud Runに触ったけどやっぱり使いやすいです。総合的に見るとGoogle CloudよりもAWSのほうが好きではあるのですが、AWSはコンテナ系のサービスが貧弱なのでCloud Runは非常に魅力的ですね。

まとめ

  • Cloud RunのサイドカーによりWebアプリとMCPサーバーの密な連携を構築できた。汎用性はローカル環境に劣るけど、セキュリティ面ではいい感じだと思う。
  • Flet + LangChain MCP Adaptersを使ったWebアプリをバイブコーディングすることで、短期間でMCPと統合したWebアプリを作れた。
  • SupergatewayでstdioのMCPサーバーを簡単にSSE化することが出来た。
  • Vertex AIのClaudeは安定性に欠ける。
  • Cloud Runは使いやすい。
脚注
  1. 厳密にはFletはFlutterをベースとしているので、FlutterアプリとしてビルドすればWebSocketなしでも動かなくはないです。ただし非常に面倒くさいです。 ↩︎

  2. 429はToo Many Requests、529はoverloaded_errorです。APIに負荷がかかりすぎてエラーになっているということです。分かりやすくいうとサーバーが貧弱。 ↩︎

NCDCエンジニアブログ

Discussion