如何在 Cloud Run 上部署安全的 MCP 服务器

1. 简介

概览

在本实验中,您将构建和部署 Model Context Protocol (MCP) 服务器。MCP 服务器有助于为 LLM 提供对外部工具和服务的访问权限。您将 MCP 服务器配置为 Cloud Run 上安全且可用于生产用途的服务,该服务可供多个客户端访问。然后,您将从 Antigravity CLI 连接到远程 MCP 服务器。

您将执行的操作

我们将使用 FastMCP 创建一个具有两个工具的 zoo MCP 服务器get_animals_by_speciesget_animal_details。FastMCP 提供了一种使用 Python 快速构建 MCP 服务器和客户端的方法。

动物园 MCP 服务器图形

学习内容

  • 将 MCP 服务器部署到 Cloud Run。
  • 通过要求对所有请求进行身份验证来保护服务器的端点,确保只有经过授权的客户端和智能体才能与服务器通信。
  • 从 Antigravity CLI 连接到安全的 MCP 服务器端点

2. 项目设置

  1. 如果您还没有 Google 账号,则必须先创建一个 Google 账号
    • 请使用个人账号,而不是工作或学校账号。工作和学校账号可能会受到限制,导致您无法启用本实验所需的 API。
  2. 登录 Google Cloud 控制台
  3. 创建新项目,或选择重复使用现有项目。
    • 如果您看到有关项目配额的错误,请重复使用现有项目或删除现有项目以创建新项目。

3. 打开 Cloud Shell Editor

  1. 点击此链接可直接前往 Cloud Shell Editor
  2. 如果系统在今天任何时间提示您授权,请点击授权以继续。点击以授权 Cloud Shell
  3. 如果终端未显示在屏幕底部,请打开它:
    • 点击查看
    • 点击终端在 Cloud Shell 编辑器中打开新终端
  4. 在终端中,使用以下命令设置项目:
    • 格式:
      gcloud config set project [PROJECT_ID]
      
    • 示例:
      gcloud config set project lab-project-id-example
      
    • 如果您不记得项目 ID,可以执行以下操作:
      • 您可以使用以下命令列出所有项目 ID:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      在 Cloud Shell 编辑器终端中设置项目 ID
  5. 您应会看到以下消息:
    Updated property [core/project].
    
    如果您看到 WARNING 并被问到 Do you want to continue (Y/n)?,则可能是输入的项目 ID 不正确。按 n,按 Enter,然后尝试再次运行 gcloud config set project 命令。

4. 启用 API

在终端中,启用以下 API:

gcloud services enable \
  run.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com

如果系统提示您授权,请点击授权以继续。点击以授权 Cloud Shell

此命令可能需要几分钟才能完成,但最终应生成类似于以下内容的成功消息:

Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.

5. 准备 Python 项目

  1. 创建一个名为 mcp-on-cloudrun 的文件夹,用于存储要部署的源代码:
    mkdir mcp-on-cloudrun && cd mcp-on-cloudrun
    
  2. 使用 uv 工具创建一个 Python 项目,以生成 pyproject.toml 文件:
    uv init --description "Example of deploying an MCP server on Cloud Run" --bare --python 3.13
    
    uv init 命令会为您的项目创建一个 pyproject.toml 文件。如需查看该文件的内容,请运行以下命令:
    cat pyproject.toml
    
    输出应如下所示:
    [project]
    name = "mcp-on-cloudrun"
    version = "0.1.0"
    description = "Example of deploying an MCP server on Cloud Run"
    requires-python = ">=3.13"
    dependencies = []
    

6. 创建 zoo MCP 服务器

为了提供有价值的背景信息,以便改进 LLM 与 MCP 的搭配使用,请使用 FastMCP 设置 zoo MCP 服务器。FastMCP 是一个用于处理 Model Context Protocol 的标准框架。FastMCP 提供了一种使用 Python 快速构建 MCP 服务器和客户端的方法。此 MCP 服务器提供有关虚构动物园中动物的数据。为简单起见,我们将数据存储在内存中。对于生产 MCP 服务器,您可能需要提供来自数据库或 API 等来源的数据。

  1. 运行以下命令,将 FastMCP 添加为 pyproject.toml 文件中的依赖项:
    uv add fastmcp==2.12.4 --no-sync
    
    这会将 uv.lock 文件添加到您的项目中。
  2. 为 MCP 服务器源代码创建并打开新的 server.py 文件:
    cloudshell edit ~/mcp-on-cloudrun/server.py
    
    cloudshell edit 命令会在终端上方的编辑器中打开 server.py 文件。
  3. server.py 文件中添加以下 zoo MCP 服务器源代码:
    import asyncio
    import logging
    import os
    from typing import List, Dict, Any
    
    from fastmcp import FastMCP
    
    logger = logging.getLogger(__name__)
    logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
    
    mcp = FastMCP("Zoo Animal MCP Server 🦁🐧🐻")
    
    # Dictionary of animals at the zoo
    ZOO_ANIMALS = [
        {
            "species": "lion",
            "name": "Leo",
            "age": 7,
            "enclosure": "The Big Cat Plains",
            "trail": "Savannah Heights"
        },
        {
            "species": "lion",
            "name": "Nala",
            "age": 6,
            "enclosure": "The Big Cat Plains",
            "trail": "Savannah Heights"
        },
        {
            "species": "lion",
            "name": "Simba",
            "age": 3,
            "enclosure": "The Big Cat Plains",
            "trail": "Savannah Heights"
        },
        {
            "species": "lion",
            "name": "King",
            "age": 8,
            "enclosure": "The Big Cat Plains",
            "trail": "Savannah Heights"
        },
        {
            "species": "penguin",
            "name": "Waddles",
            "age": 2,
            "enclosure": "The Arctic Exhibit",
            "trail": "Polar Path"
        },
        {
            "species": "penguin",
            "name": "Pip",
            "age": 4,
            "enclosure": "The Arctic Exhibit",
            "trail": "Polar Path"
        },
        {
            "species": "penguin",
            "name": "Skipper",
            "age": 5,
            "enclosure": "The Arctic Exhibit",
            "trail": "Polar Path"
        },
        {
            "species": "penguin",
            "name": "Chilly",
            "age": 3,
            "enclosure": "The Arctic Exhibit",
            "trail": "Polar Path"
        },
        {
            "species": "penguin",
            "name": "Pingu",
            "age": 6,
            "enclosure": "The Arctic Exhibit",
            "trail": "Polar Path"
        },
        {
            "species": "penguin",
            "name": "Noot",
            "age": 1,
            "enclosure": "The Arctic Exhibit",
            "trail": "Polar Path"
        },
        {
            "species": "elephant",
            "name": "Ellie",
            "age": 15,
            "enclosure": "The Pachyderm Sanctuary",
            "trail": "Savannah Heights"
        },
        {
            "species": "elephant",
            "name": "Peanut",
            "age": 12,
            "enclosure": "The Pachyderm Sanctuary",
            "trail": "Savannah Heights"
        },
        {
            "species": "elephant",
            "name": "Dumbo",
            "age": 5,
            "enclosure": "The Pachyderm Sanctuary",
            "trail": "Savannah Heights"
        },
        {
            "species": "elephant",
            "name": "Trunkers",
            "age": 10,
            "enclosure": "The Pachyderm Sanctuary",
            "trail": "Savannah Heights"
        },
        {
            "species": "bear",
            "name": "Smokey",
            "age": 10,
            "enclosure": "The Grizzly Gulch",
            "trail": "Polar Path"
        },
        {
            "species": "bear",
            "name": "Grizzly",
            "age": 8,
            "enclosure": "The Grizzly Gulch",
            "trail": "Polar Path"
        },
        {
            "species": "bear",
            "name": "Barnaby",
            "age": 6,
            "enclosure": "The Grizzly Gulch",
            "trail": "Polar Path"
        },
        {
            "species": "bear",
            "name": "Bruin",
            "age": 12,
            "enclosure": "The Grizzly Gulch",
            "trail": "Polar Path"
        },
        {
            "species": "giraffe",
            "name": "Gerald",
            "age": 4,
            "enclosure": "The Tall Grass Plains",
            "trail": "Savannah Heights"
        },
        {
            "species": "giraffe",
            "name": "Longneck",
            "age": 5,
            "enclosure": "The Tall Grass Plains",
            "trail": "Savannah Heights"
        },
        {
            "species": "giraffe",
            "name": "Patches",
            "age": 3,
            "enclosure": "The Tall Grass Plains",
            "trail": "Savannah Heights"
        },
        {
            "species": "giraffe",
            "name": "Stretch",
            "age": 6,
            "enclosure": "The Tall Grass Plains",
            "trail": "Savannah Heights"
        },
        {
            "species": "antelope",
            "name": "Speedy",
            "age": 2,
            "enclosure": "The Tall Grass Plains",
            "trail": "Savannah Heights"
        },
        {
            "species": "antelope",
            "name": "Dash",
            "age": 3,
            "enclosure": "The Tall Grass Plains",
            "trail": "Savannah Heights"
        },
        {
            "species": "antelope",
            "name": "Gazelle",
            "age": 4,
            "enclosure": "The Tall Grass Plains",
            "trail": "Savannah Heights"
        },
        {
            "species": "antelope",
            "name": "Swift",
            "age": 5,
            "enclosure": "The Tall Grass Plains",
            "trail": "Savannah Heights"
        },
        {
            "species": "polar bear",
            "name": "Snowflake",
            "age": 7,
            "enclosure": "The Arctic Exhibit",
            "trail": "Polar Path"
        },
        {
            "species": "polar bear",
            "name": "Blizzard",
            "age": 5,
            "enclosure": "The Arctic Exhibit",
            "trail": "Polar Path"
        },
        {
            "species": "polar bear",
            "name": "Iceberg",
            "age": 9,
            "enclosure": "The Arctic Exhibit",
            "trail": "Polar Path"
        },
        {
            "species": "walrus",
            "name": "Wally",
            "age": 10,
            "enclosure": "The Walrus Cove",
            "trail": "Polar Path"
        },
        {
            "species": "walrus",
            "name": "Tusker",
            "age": 12,
            "enclosure": "The Walrus Cove",
            "trail": "Polar Path"
        },
        {
            "species": "walrus",
            "name": "Moby",
            "age": 8,
            "enclosure": "The Walrus Cove",
            "trail": "Polar Path"
        },
        {
            "species": "walrus",
            "name": "Flippers",
            "age": 9,
            "enclosure": "The Walrus Cove",
            "trail": "Polar Path"
        }
    ]
    
    @mcp.tool()
    def get_animals_by_species(species: str) -> List[Dict[str, Any]]:
        """
        Retrieves all animals of a specific species from the zoo.
        Can also be used to collect the base data for aggregate queries
        of animals of a specific species - like counting the number of penguins
        or finding the oldest lion.
    
        Args:
            species: The species of the animal (e.g., 'lion', 'penguin').
    
        Returns:
            A list of dictionaries, where each dictionary represents an animal
            and contains details like name, age, enclosure, and trail.
        """
        logger.info(f">>> 🛠️ Tool: 'get_animals_by_species' called for '{species}'")
        return [animal for animal in ZOO_ANIMALS if animal["species"].lower() == species.lower()]
    
    @mcp.tool()
    def get_animal_details(name: str) -> Dict[str, Any]:
        """
        Retrieves the details of a specific animal by its name.
    
        Args:
            name: The name of the animal.
    
        Returns:
            A dictionary with the animal's details (species, name, age, enclosure, trail)
            or an empty dictionary if the animal is not found.
        """
        logger.info(f">>> 🛠️ Tool: 'get_animal_details' called for '{name}'")
        for animal in ZOO_ANIMALS:
            if animal["name"].lower() == name.lower():
                return animal
        return {}
    
    if __name__ == "__main__":
        port = int(os.getenv("PORT", 8080))
        logger.info(f"🚀 MCP server started on port {port}")
        asyncio.run(
            mcp.run_async(
                transport="http",
                host="0.0.0.0",
                port=port,
            )
        )
    

您的代码已完成!现在可以将 MCP 服务器部署到 Cloud Run 了。

7. 部署至 Cloud Run

现在,直接从源代码将 MCP 服务器部署到 Cloud Run。

  1. 创建并打开新的 Dockerfile 以部署到 Cloud Run:
    cloudshell edit ~/mcp-on-cloudrun/Dockerfile
    
  2. 在 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"]
    
  3. 创建一个名为 mcp-server-sa 的服务账号:
    gcloud iam service-accounts create mcp-server-sa --display-name="MCP Server Service Account"
    
  4. 运行 gcloud 命令,将应用部署到 Cloud Run
    cd ~/mcp-on-cloudrun
    gcloud run deploy zoo-mcp-server \
        --service-account=mcp-server-sa@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
        --no-allow-unauthenticated \
        --region=us-west1 \
        --source=. \
        --labels=dev-tutorial=codelab-mcp
    
    使用 --no-allow-unauthenticated 标志来要求进行身份验证。这对于安全至关重要。如果您不要求进行身份验证,任何人都可以调用您的 MCP 服务器,并可能对您的系统造成损害。
  5. 确认创建新的 Artifact Registry 代码库。由于您是首次从源代码部署到 Cloud Run,因此您会看到:
    Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named
    [cloud-run-source-deploy] in region [us-west1] will be created.
    
    Do you want to continue (Y/n)?
    
    输入 Y 并按 Enter,系统会为您的部署创建一个 Artifact Registry 代码库。这是存储 Cloud Run 服务的 MCP 服务器 Docker 容器所必需的。
  6. 几分钟后,您会看到类似以下内容的消息:
    Service [zoo-mcp-server] revision [zoo-mcp-server-12345-abc] has been deployed and is serving 100 percent of traffic.
    

您已部署 MCP 服务器。现在可以使用它了。

8. 将远程 MCP 服务器添加到 Antigravity CLI

现在,您已成功部署远程 MCP 服务器,可以使用各种应用(例如 Google Code Assist 或 Antigravity CLI)连接到该服务器。在本部分中,我们将使用 Antigravity CLI 与新的远程 MCP 服务器建立连接。

  1. 向您的用户账号授予调用远程 MCP 服务器的权限
    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member=user:$(gcloud config get-value account) \
        --role='roles/run.invoker'
    
  2. 使用以下命令,将您的 Google Cloud 凭据和项目编号保存在环境变量中,以便在 Antigravity 设置文件中使用:
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    export ID_TOKEN=$(gcloud auth print-identity-token)
    
  3. 如果尚未创建 .gemini/antigravity-cli 文件夹,请创建一个
    mkdir -p ~/.gemini/antigravity-cli
    
  4. 将远程 MCP 服务器写入 Antigravity CLI MCP 配置文件:
    cat > ~/.gemini/antigravity-cli/mcp_config.json << EOF
    {
        "mcpServers": {
            "zoo-remote": {
                "serverUrl": "https://zoo-mcp-server-${PROJECT_NUMBER}.us-west1.run.app/mcp",
                "headers": {
                    "Authorization": "Bearer ${ID_TOKEN}"
                }
            }
        }
    }
    EOF
    
  5. 启动 Antigravity CLI:
    agy
    
  1. 使用 Antigravity CLI 进行身份验证:首次启动时,需要进行身份验证。选择 OAuth(按 Enter)。Antigravity 身份验证界面
  2. 点击链接(如果无法点击,请在 Cloud Shell 中突出显示网址以复制,然后将其粘贴到浏览器中)
  3. 登录您的 Google 账号
  4. 复制代码
  5. 将代码粘贴到 Cloud Shell Editor 终端中
  6. EnterAntigravity 安全码提示
  7. Enter 接受一些默认设置。
  8. 让 Antigravity CLI 列出其上下文中可用的 MCP 工具
    /mcp
    
    ESC 返回到提示框。
  9. 让 Antigravity CLI 帮忙寻找动物园中的动物
    Where can I find penguins?
    
    Antigravity CLI 应该知道要使用 zoo-remote MCP 服务器,并询问您是否允许执行 MCP。
  10. 使用向下箭头,然后按 Enter 进行选择
    Yes, always allow all tools from server "zoo-remote"
    
    Antigravity CLI 允许 zoo 远程工具

输出应显示正确答案,并显示一个框,表明使用了 MCP 服务器。

Antigravity CLI 显示动物园 MCP 服务器结果

您已完成!您已成功将远程 MCP 服务器部署到 Cloud Run,并使用 Antigravity CLI 对其进行了测试。

准备好结束会话后,输入 /exit,然后按 Enter 退出 Antigravity CLI。

调试

如果您看到类似这样的错误:

🔍 Attempting OAuth discovery for 'zoo-remote'...
❌ 'zoo-remote' requires authentication but no OAuth configuration found
Error connecting to MCP server 'zoo-remote': MCP server 'zoo-remote' requires authentication. Please configure OAuth or check server settings.

可能是 ID 令牌已超时,需要重新设置 ID_TOKEN

  1. 输入 /exit,然后按 Enter 退出 Antigravity CLI。
  2. 在终端中设置项目
    gcloud config set project [PROJECT_ID]
    
  3. 重新运行 Google Cloud 凭据命令以获取新的 ID_TOKEN(因为您的凭据可能已过期),并重写配置文件:
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    export ID_TOKEN=$(gcloud auth print-identity-token)
    
    cat > ~/.gemini/antigravity-cli/mcp_config.json << EOF
    

{ "mcpServers": { "zoo-remote": { "serverUrl": "https://zoo-mcp-server-${PROJECT_NUMBER}.us-west1.run.app/mcp", "headers": { "Authorization": "Bearer ${ID_TOKEN}" } } } } EOF ```

9. (可选)验证服务器日志中的工具调用

如需验证 Cloud Run MCP 服务器是否被调用,请检查服务日志。

gcloud run services logs read zoo-mcp-server --region us-west1 --limit=5

您应该会看到一个输出日志,确认已进行工具调用。🛠️

2025-08-05 19:50:31 INFO:     169.254.169.126:39444 - "POST /mcp HTTP/1.1" 200 OK
2025-08-05 19:50:31 [INFO]: Processing request of type CallToolRequest
2025-08-05 19:50:31 [INFO]: >>> 🛠️ Tool: 'get_animals_by_species' called for 'penguin'

10. (可选)向服务器添加 MCP 提示

MCP 提示可以为经常运行的提示创建简写,从而加快工作流程。

Antigravity CLI 会自动将 MCP 提示转换为 自定义斜杠命令,以便您可以通过输入 /prompt_name 来调用 MCP 提示,其中 prompt_name 是您的 MCP 提示的名称。

创建一个 MCP 提示,以便您可以通过在 Antigravity CLI 中输入 /find animal 来快速查找动物园中的动物。

  1. 将此代码添加到 server.py 文件中的主保护语句 (if __name__ == "__main__":) 上方
    @mcp.prompt()
    def find(animal: str) -> str:
        """
        Find which exhibit and trail a specific animal might be located.
        """
    
        return (
            f"Please find the exhibit and trail information for {animal} in the zoo. "
            f"Respond with '[animal] can be found in the [exhibit] on the [trail].'"
            f"Example: Penguins can be found in The Arctic Exhibit on the Polar Path."
        )
    
  2. 将应用重新部署到 Cloud Run
    gcloud run deploy zoo-mcp-server \
        --region=us-west1 \
        --source=. \
        --labels=dev-tutorial=codelab-mcp
    
  3. 刷新 ID_TOKEN 并重新创建配置文件:
    export ID_TOKEN=$(gcloud auth print-identity-token)
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    
    cat > ~/.gemini/antigravity-cli/mcp_config.json << EOF
    

{ "mcpServers": { "zoo-remote": { "serverUrl": "https://zoo-mcp-server-${PROJECT_NUMBER}.us-west1.run.app/mcp", "headers": { "Authorization": "Bearer ${ID_TOKEN}" } } } } EOF ```

  1. 部署应用的新版本后,启动 Antigravity CLI。
    agy
    
  2. 在提示中使用您创建的新自定义命令:
    /find lions
    

您应该会看到 Antigravity CLI 调用 get_animals_by_species 工具,并按照 MCP 提示的指示设置回答格式!

╭───────────────────────────╮
│  > /find lions            │
╰───────────────────────────╯

 ╭───────────────────────────────────────────────────────────────────────────────────────────────────╮
 │ ✔  get_animals_by_species (zoo-remote MCP Server) get_animals_by_species (zoo-remote MCP Server)  │
 │                                                                                                   │
 │    [{"species":"lion","name":"Leo","age":7,"enclosure":"The Big Cat                               │
 │    Plains","trail":"Savannah                                                                      │
 │    Heights"},{"species":"lion","name":"Nala","age":6,"enclosure":"The Big Cat                     │
 │    Plains","trail":"Savannah                                                                      │
 │    Heights"},{"species":"lion","name":"Simba","age":3,"enclosure":"The Big Cat                    │
 │    Plains","trail":"Savannah                                                                      │
 │    Heights"},{"species":"lion","name":"King","age":8,"enclosure":"The Big Cat                     │
 │    Plains","trail":"Savannah Heights"}]                                                           │
 ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ Lions can be found in The Big Cat Plains on the Savannah Heights.

11. (可选)使用 Gemini Flash Lite 获得更快的响应

Antigravity CLI 可让您选择使用的模型和工作量。

由于与查找动物园中的动物相关的请求不需要思考或推理,因此请尝试使用更快的模型来加快速度。

在上一部分中,您创建了一个 MCP 提示,以便您可以通过在 Antigravity CLI 中输入 /find animal 来快速查找动物园中的动物。

  1. 部署应用的新版本后,启动 Antigravity CLI。
    agy --model=gemini-3.6-flash --effort=low
    
  2. 在提示中使用您创建的新自定义命令:
    /find lions
    

您应该仍然会看到 Antigravity CLI 调用 get_animals_by_species 工具,并按照 MCP 提示的指示设置回答格式,但答案应该会更快显示!

╭───────────────────────────╮
│  > /find lions            │
╰───────────────────────────╯

 ╭───────────────────────────────────────────────────────────────────────────────────────────────────╮
 │ ✔  get_animals_by_species (zoo-remote MCP Server) get_animals_by_species (zoo-remote MCP Server)  │
 │                                                                                                   │
 │    [{"species":"lion","name":"Leo","age":7,"enclosure":"The Big Cat                               │
 │    Plains","trail":"Savannah                                                                      │
 │    Heights"},{"species":"lion","name":"Nala","age":6,"enclosure":"The Big Cat                     │
 │    Plains","trail":"Savannah                                                                      │
 │    Heights"},{"species":"lion","name":"Simba","age":3,"enclosure":"The Big Cat                    │
 │    Plains","trail":"Savannah                                                                      │
 │    Heights"},{"species":"lion","name":"King","age":8,"enclosure":"The Big Cat                     │
 │    Plains","trail":"Savannah Heights"}]                                                           │
 ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ Lions can be found in The Big Cat Plains on the Savannah Heights.

调试

如果您看到类似这样的错误:

✕ Unknown command: /find lions

尝试运行 /mcp,如果输出 zoo-remote - Disconnected,您可能需要重新部署,或再次运行以下命令:

 gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
   --member=user:$(gcloud config get-value account) \
   --role='roles/run.invoker'

export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
export ID_TOKEN=$(gcloud auth print-identity-token)

cat > ~/.gemini/antigravity-cli/mcp_config.json << EOF
{
   "mcpServers": {
       "zoo-remote": {
           "serverUrl": "https://zoo-mcp-server-${PROJECT_NUMBER}.us-west1.run.app/mcp",
           "headers": {
               "Authorization": "Bearer ${ID_TOKEN}"
           }
       }
   }
}
EOF

12. 总结

恭喜!您已成功部署并连接到安全的远程 MCP 服务器。

继续学习下一项实验

本实验是三部分系列实验中的第一项实验。在第二项实验中,您将使用您创建的 MCP 服务器和 ADK 智能体。

在 Cloud Run 上使用 MCP 服务器和 ADK 智能体

(可选)清理

如果您不打算继续学习下一项实验,并且想要清理已创建的内容,可以删除云项目,以免产生额外费用。

虽然 Cloud Run 不会对未在使用中的服务计费,但您可能仍然需要支付将容器映像存储在 Artifact Registry 中而产生的相关费用。删除 Cloud 项目后,系统即会停止对该项目中使用的所有资源计费。

如果您愿意,可以删除项目:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

您可能还需要从 cloudshell 磁盘中删除不必要的资源。您可以:

  1. 删除 Codelab 项目目录:
    rm -rf ~/mcp-on-cloudrun
    
  2. 警告!此操作无法撤消!如果您想删除 Cloud Shell 中的所有内容以释放空间,可以删除整个主目录。请注意,您要保留的所有内容都已保存在其他位置。
    sudo rm -rf $HOME