Cloud Run にリモート MCP サーバーをビルドしてデプロイする


このチュートリアルでは、ストリーミング可能な HTTP トランスポートを使用して、Cloud Run にリモート Model Context Protocol(MCP)サーバーを構築してデプロイする方法について説明します。ストリーミング可能な HTTP トランスポートを使用すると、MCP サーバーは複数のクライアント接続を処理できる独立したプロセスとして動作します。

目標

このチュートリアルの内容は次のとおりです。

  1. uv パッケージ マネージャーを使用して Python プロジェクトを準備します
  2. 算術演算用の MCP サーバーを作成します
  3. Cloud Run にデプロイする
  4. MCP クライアントを認証する
  5. リモート MCP サーバーをテストする

費用

このドキュメントでは、課金対象である次の Google Cloudコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。

新規の Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

始める前に

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Verify that billing is enabled for your Google Cloud project.

  6. Enable the Artifact Registry, Cloud Run Admin API, and Cloud Build APIs.

    Enable the APIs

  7. Google Cloud プロジェクトで Cloud Run 開発環境を設定します。
  8. 適切なサービス デプロイ権限を持ち、ご利用のアカウントに Cloud Run 管理者roles/run.admin)とサービス アカウント ユーザーroles/iam.serviceAccountUser)のロールが付与されていることを確認します。
  9. アカウントに Cloud Run 起動元(roles/run.invokerロールを付与します。このロールにより、リモート MCP サーバーは Cloud Run サービスにアクセスできます。
  10. ロールの付与方法を確認する

    コンソール

    1. Google Cloud コンソールで、[IAM] ページに移動します。

      IAM に移動
    2. プロジェクトを選択します。
    3. [ アクセスを許可] をクリックします。
    4. [新しいプリンシパル] フィールドに、ユーザー ID を入力します。これは通常、Cloud Run サービスのデプロイに使用される Google アカウントのメールアドレスです。

    5. [ロールを選択] リストでロールを選択します。
    6. 追加のロールを付与するには、[ 別のロールを追加] をクリックして各ロールを追加します。
    7. [保存] をクリックします。

    gcloud

    プロジェクトで自分のアカウントに必要な IAM ロールを付与するには:

       gcloud projects add-iam-policy-binding PROJECT_ID \
           --member=PRINCIPAL \
           --role=ROLE
       

    次のように置き換えます。

    • PROJECT_NUMBER: Google Cloud プロジェクトの番号。
    • PROJECT_ID: 実際の Google Cloud プロジェクト ID。
    • PRINCIPAL: ロールを付与するアカウントのメールアドレス。
    • ROLE: デプロイするアカウントに追加するロール。
  11. ドメイン制限の組織のポリシーでプロジェクトの未認証呼び出しが制限されている場合は、限定公開サービスのテストの説明に従って、デプロイされたサービスにアクセスする必要があります。

  12. Python パッケージとプロジェクト マネージャーである Uv をインストールします。

Python プロジェクトを準備する

次の手順では、uv パッケージ マネージャーを使用して Python プロジェクトを設定する方法について説明します。

  1. mcp-on-cloudrun という名前のフォルダを作成して、デプロイ用のソースコードを保存します。

      mkdir mcp-on-cloudrun
      cd mcp-on-cloudrun
    
  2. uv ツールを使用して Python プロジェクトを作成し、pyproject.toml ファイルを生成します。

      uv init --name "mcp-on-cloudrun" --description "Example of deploying an MCP server on Cloud Run" --bare --python 3.10
    

    uv init コマンドにより、次の pyproject.toml ファイルが作成されます。

    [project]
    name = "mcp-server"
    version = "0.1.0"
    description = "Example of deploying an MCP server on Cloud Run"
    readme = "README.md"
    requires-python = ">=3.10"
    dependencies = []
    
  3. 次の新しいファイルを追加で作成します。

    • MCP サーバーのソースコードの server.py
    • test_server.py: リモート サーバーをテストします。
    • Cloud Run にデプロイするための Dockerfile
    touch server.py test_server.py Dockerfile
    

    プロジェクト ディレクトリには次の構造が含まれている必要があります。

    ├── mcp-on-cloudrun
    │   ├── pyproject.toml
    │   ├── server.py
    │   ├── test_server.py
    │   └── Dockerfile
    

算術演算用の MCP サーバーを作成する

MCP で LLM の使用を改善するための重要なコンテキストを提供するには、FastMCP を使用して数学 MCP サーバーを設定します。FastMCP は、Python で MCP サーバーとクライアントを迅速に構築するためのツールです。

加算や減算などの数学演算用の MCP サーバーを作成する手順は次のとおりです。

  1. 次のコマンドを実行して、pyproject.toml ファイルに FastMCP を依存関係として追加します。

    uv add fastmcp==2.8.0 --no-sync
    
  2. server.py ファイルに次の数学 MCP サーバーのソースコードを追加します。

    import asyncio
    import logging
    import os
    
    from fastmcp import FastMCP 
    
    logger = logging.getLogger(__name__)
    logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
    
    mcp = FastMCP("MCP Server on Cloud Run")
    
    @mcp.tool()
    def add(a: int, b: int) -> int:
        """Use this to add two numbers together.
    
        Args:
            a: The first number.
            b: The second number.
    
        Returns:
            The sum of the two numbers.
        """
        logger.info(f">>> 🛠️ Tool: 'add' called with numbers '{a}' and '{b}'")
        return a + b
    
    @mcp.tool()
    def subtract(a: int, b: int) -> int:
        """Use this to subtract two numbers.
    
        Args:
            a: The first number.
            b: The second number.
    
        Returns:
            The difference of the two numbers.
        """
        logger.info(f">>> 🛠️ Tool: 'subtract' called with numbers '{a}' and '{b}'")
        return a - b
    
    if __name__ == "__main__":
        logger.info(f"🚀 MCP server started on port {os.getenv('PORT', 8080)}")
        # Could also use 'sse' transport, host="0.0.0.0" required for Cloud Run.
        asyncio.run(
            mcp.run_async(
                transport="streamable-http",
                host="0.0.0.0",
                port=os.getenv("PORT", 8080),
            )
        )
    
  3. uv ツールを使用して server.py ファイルを実行するには、Dockerfile に次のコードを追加します。

    # Use the official Python image
    FROM python:3.13-slim
    
    # Install uv
    COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
    
    # Install the project into /app
    COPY . /app
    WORKDIR /app
    
    # Allow statements and log messages to immediately appear in the logs
    ENV PYTHONUNBUFFERED=1
    
    # Install dependencies
    RUN uv sync
    
    EXPOSE $PORT
    
    # Run the FastMCP server
    CMD ["uv", "run", "server.py"]
    

Cloud Run へのデプロイ

MCP サーバーは、コンテナ イメージまたはソースコードとしてデプロイできます。

コンテナ イメージ

コンテナ イメージとしてパッケージ化された MCP サーバーをデプロイするには、次の手順を行います。

  1. コンテナ イメージを保存する Artifact Registry リポジトリを作成します。

    gcloud artifacts repositories create remote-mcp-servers \
    --repository-format=docker \
    --location=us-central1 \
    --description="Repository for remote MCP servers" \
    --project=PROJECT_ID
    
  2. Cloud Build を使用してコンテナ イメージをビルドし、Artifact Registry に push します。

    gcloud builds submit --region=us-central1 --tag us-central1-docker.pkg.dev/PROJECT_ID/remote-mcp-servers/mcp-server:latest
    
  3. MCP サーバーのコンテナ イメージを Cloud Run にデプロイします。

    gcloud run deploy mcp-server \
    --image us-central1-docker.pkg.dev/PROJECT_ID/remote-mcp-servers/mcp-server:latest \
    --region=us-central1 \
    --no-allow-unauthenticated
    

ソース

リモート MCP サーバーは、ソースから Cloud Run にデプロイできます。

次のコマンドを実行して、ソースからデプロイします。

gcloud run deploy mcp-server --no-allow-unauthenticated --region=us-central1 --source .

MCP クライアントを認証する

--no-allow-unauthenticated フラグを使用してサービスをデプロイした場合、リモート MCP サーバーに接続する MCP クライアントは認証を受ける必要があります。

  1. サービス アカウントに Cloud Run 起動元roles/run.invoker)ロールを付与します。この Identity and Access Management ポリシー バインディングにより、ローカル MCP クライアントの認証に強力なセキュリティ メカニズムが使用されます。

  2. Cloud Run プロキシを実行して、ローカルマシンでリモート MCP サーバーへの認証済みトンネルを作成します。

    gcloud run services proxy mcp-server --region=us-central1
    

    Cloud Run プロキシがまだインストールされていない場合、このコマンドを実行すると、プロキシのダウンロードを求めるプロンプトが表示されます。プロンプトに沿ってプロキシをダウンロードしてインストールします。

Cloud Run は http://127.0.0.1:8080 へのすべてのトラフィックを認証し、リクエストをリモート MCP サーバーに転送します。

リモート MCP サーバーをテストする

FastMCP クライアントを使用して http://127.0.0.1:8080/mcp の URL にアクセスし、リモート MCP サーバーをテストして接続します。

加算と減算のメカニズムをテストして呼び出す手順は次のとおりです。

  1. テストサーバーを実行する前に、Cloud Run プロキシを実行します。

  2. test_server.py というテストファイルを作成し、次のコードを追加します。

    import asyncio
    
    from fastmcp import Client
    
    async def test_server():
        # Test the MCP server using streamable-http transport.
        # Use "/sse" endpoint if using sse transport.
        async with Client("http://localhost:8080/mcp") as client:
            # List available tools
            tools = await client.list_tools()
            for tool in tools:
                print(f">>> 🛠️  Tool found: {tool.name}")
            # Call add tool
            print(">>> 🪛  Calling add tool for 1 + 2")
            result = await client.call_tool("add", {"a": 1, "b": 2})
            print(f"<<< ✅ Result: {result[0].text}")
            # Call subtract tool
            print(">>> 🪛  Calling subtract tool for 10 - 3")
            result = await client.call_tool("subtract", {"a": 10, "b": 3})
            print(f"<<< ✅ Result: {result[0].text}")
    
    if __name__ == "__main__":
        asyncio.run(test_server())
  3. 新しいターミナルで、テストサーバーを実行します。

    uv run test_server.py
    

    次の出力が表示されます。

     🛠️ Tool found: add
     🛠️ Tool found: subtract
     🪛 Calling add tool for 1 + 2
     ✅ Result: 3
     🪛 Calling subtract tool for 10 - 3
     ✅ Result: 7
    

クリーンアップ

Google Cloud アカウントに追加料金が発生しないようにするには、このチュートリアルでデプロイしたリソースをすべて削除します。

プロジェクトの削除

このチュートリアル用に新しいプロジェクトを作成した場合は、そのプロジェクトを削除します。既存のプロジェクトを使用し、このチュートリアルで追加した変更を加えずに残す場合は、チュートリアル用に作成したリソースを削除します。

課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。

プロジェクトを削除するには:

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

チュートリアル リソースの削除

  1. このチュートリアルでデプロイした Cloud Run サービスを削除します。Cloud Run サービスは、リクエストを受信するまで費用が発生しません。

    Cloud Run サービスを削除するには、次のコマンドを実行します。

    gcloud run services delete SERVICE-NAME

    SERVICE-NAME は、実際のサービス名に置き換えます。

    Cloud Run サービスは Google Cloud コンソールで削除することもできます。

  2. チュートリアルの設定時に追加した gcloud のデフォルト リージョン構成を削除します。

     gcloud config unset run/region
    
  3. プロジェクト構成を削除します。

     gcloud config unset project