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

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

準備 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 大型語言模型的使用體驗,請使用 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