在 Cloud Run 上建構及部署遠端 MCP 伺服器

本教學課程說明如何使用可串流的 HTTP 傳輸,在 Cloud Run 上建構及部署遠端模型內容通訊協定 (MCP) 伺服器。透過可串流的 HTTP 傳輸,MCP 伺服器會以獨立程序運作,可處理多個用戶端連線。

事前準備

  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. Make sure 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. Make sure that billing is enabled for your Google Cloud project.

  6. 在 Google Cloud 專案中設定 Cloud Run 開發環境
  7. 請確認您擁有部署服務的適當權限,且帳戶已獲授「Cloud Run 管理員」 (roles/run.admin) 和「服務帳戶使用者」 (roles/iam.serviceAccountUser) 角色。
  8. Cloud Run 調用者 (roles/run.invoker) 角色授予您的帳戶。這個角色可讓遠端 MCP 伺服器存取 Cloud Run 服務。
  9. 瞭解如何授予角色

    控制台

    1. 前往 Google Cloud 控制台的「IAM」IAM頁面。

      前往 IAM
    2. 選取專案。
    3. 按一下「授予存取權」
    4. 在「New principals」(新增主體) 欄位中輸入使用者 ID。這通常是部署 Cloud Run 服務時使用的 Google 帳戶電子郵件地址。

    5. 在「Select a role」(選取角色) 清單中,選取角色。
    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:您要新增至部署者帳戶的角色。
  10. 如果您受到網域限制組織政策限制,專案無法進行未經驗證的呼叫,則必須按照「測試私人服務」一節的說明存取已部署的服務。

  11. 安裝 Python 套件和專案管理員 Uv
  12. 準備 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. 在 Dockerfile 中加入下列程式碼,即可使用 uv 工具執行 server.py 檔案:

      # 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:

      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) 角色授予服務帳戶。這項身分與存取權管理政策繫結可確保使用強大的安全機制,驗證本機 MCP 用戶端。

    2. 執行 Cloud Run Proxy,在本機電腦上建立通過驗證的通道,連線至遠端 MCP 伺服器:

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

      如果尚未安裝 Cloud Run Proxy,這項指令會提示您下載 Proxy。按照提示下載並安裝 Proxy。

    Cloud Run 會驗證所有傳送至 http://127.0.0.1:8080 的流量,並將要求轉送至遠端 MCP 伺服器。

    測試遠端 MCP 伺服器

    您可以使用 FastMCP 用戶端測試及連線至遠端 MCP 伺服器,並存取網址 http://127.0.0.1:8080/mcp

    如要測試及叫用加減機制,請按照下列步驟操作:

    1. 執行測試伺服器前,請執行 Cloud Run Proxy

    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
      

    後續步驟