Cách triển khai một máy chủ MCP bảo mật trên Cloud Run

1. Giới thiệu

Tổng quan

Trong phòng thí nghiệm này, bạn sẽ tạo và triển khai một máy chủ Giao thức ngữ cảnh mô hình (MCP). Máy chủ MCP rất hữu ích trong việc cung cấp cho các mô hình ngôn ngữ lớn (LLM) quyền truy cập vào các công cụ và dịch vụ bên ngoài. Bạn sẽ định cấu hình máy chủ này dưới dạng một dịch vụ an toàn, sẵn sàng cho hoạt động sản xuất trên Cloud Run mà nhiều ứng dụng có thể truy cập. Sau đó, bạn sẽ kết nối với máy chủ MCP từ xa bằng Gemini CLI.

Bạn sẽ thực hiện

Chúng ta sẽ sử dụng FastMCP để tạo một máy chủ MCP cho vườn thú có 2 công cụ: get_animals_by_speciesget_animal_details. FastMCP cung cấp một cách nhanh chóng, theo kiểu Python để tạo máy chủ và ứng dụng MCP.

Hình ảnh máy chủ MCP của Zoo

Kiến thức bạn sẽ học được

  • Triển khai máy chủ MCP lên Cloud Run.
  • Bảo mật điểm cuối của máy chủ bằng cách yêu cầu xác thực cho tất cả các yêu cầu, đảm bảo chỉ những ứng dụng và tác nhân được uỷ quyền mới có thể giao tiếp với máy chủ.
  • Kết nối với điểm cuối máy chủ MCP an toàn bằng Gemini CLI

2. Thiết lập dự án

  1. Nếu chưa có, bạn phải tạo một Tài khoản Google.
    • Sử dụng tài khoản cá nhân thay vì tài khoản công việc hoặc trường học. Tài khoản công việc và trường học có thể có các hạn chế khiến bạn không thể bật các API cần thiết cho phòng thí nghiệm này.
  2. Đăng nhập vào Google Cloud Console.
  3. Tạo một dự án mới hoặc chọn sử dụng lại một dự án hiện có.
    • Nếu bạn thấy lỗi về hạn mức dự án, hãy sử dụng lại một dự án hiện có hoặc xoá một dự án hiện có để tạo một dự án mới.

3. Mở Trình chỉnh sửa Cloud Shell

  1. Nhấp vào đường liên kết này để chuyển trực tiếp đến Trình chỉnh sửa Cloud Shell
  2. Nếu được nhắc uỷ quyền vào bất kỳ thời điểm nào trong ngày hôm nay, hãy nhấp vào Uỷ quyền để tiếp tục. Nhấp để uỷ quyền cho Cloud Shell
  3. Nếu thiết bị đầu cuối không xuất hiện ở cuối màn hình, hãy mở thiết bị đầu cuối:
    • Nhấp vào Xem
    • Nhấp vào Thiết bị đầu cuốiMở cửa sổ dòng lệnh mới trong Trình chỉnh sửa Cloud Shell
  4. Trong thiết bị đầu cuối, hãy đặt dự án bằng lệnh này:
    • Định dạng:
      gcloud config set project [PROJECT_ID]
      
    • Ví dụ:
      gcloud config set project lab-project-id-example
      
    • Nếu bạn không nhớ mã dự án:
      • Bạn có thể liệt kê tất cả mã dự án bằng:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      Đặt mã dự án trong thiết bị đầu cuối Cloud Shell Editor
  5. Bạn sẽ thấy thông báo này:
    Updated property [core/project].
    
    Nếu bạn thấy một WARNING và được hỏi Do you want to continue (Y/n)? (Bạn có muốn tiếp tục (Y/n)?), thì có thể bạn đã nhập sai mã dự án. Nhấn n, nhấn Enter rồi thử chạy lại lệnh gcloud config set project.

4. Bật API

Trong thiết bị đầu cuối, hãy bật các API:

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

Nếu được nhắc uỷ quyền, hãy nhấp vào Uỷ quyền để tiếp tục. Nhấp để uỷ quyền cho Cloud Shell

Lệnh này có thể mất vài phút để hoàn tất, nhưng cuối cùng sẽ tạo ra một thông báo thành công tương tự như thông báo này:

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

5. Chuẩn bị dự án Python

  1. Tạo một thư mục có tên là mcp-on-cloudrun để lưu trữ mã nguồn cho quá trình triển khai:
    mkdir mcp-on-cloudrun && cd mcp-on-cloudrun
    
  2. Tạo một dự án Python bằng công cụ uv để tạo tệp pyproject.toml:
    uv init --description "Example of deploying an MCP server on Cloud Run" --bare --python 3.13
    
    Lệnh uv init tạo một tệp pyproject.toml cho dự án của bạn.Để xem nội dung của tệp, hãy chạy lệnh sau:
    cat pyproject.toml
    
    Đầu ra sẽ có dạng như sau:
    [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. Tạo máy chủ MCP cho vườn thú

Để cung cấp ngữ cảnh có giá trị nhằm cải thiện việc sử dụng các mô hình ngôn ngữ lớn (LLM) với MCP, hãy thiết lập một máy chủ MCP cho vườn thú bằng FastMCP – một khung tiêu chuẩn để làm việc với Giao thức ngữ cảnh mô hình. FastMCP cung cấp một cách nhanh chóng để tạo máy chủ và ứng dụng MCP bằng Python. Máy chủ MCP này cung cấp dữ liệu về các loài động vật tại một vườn thú hư cấu. Để đơn giản, chúng ta sẽ lưu trữ dữ liệu trong bộ nhớ. Đối với máy chủ MCP sản xuất, có thể bạn sẽ muốn cung cấp dữ liệu từ các nguồn như cơ sở dữ liệu hoặc API.

  1. Chạy lệnh sau để thêm FastMCP làm phần phụ thuộc trong tệp pyproject.toml:
    uv add fastmcp==2.12.4 --no-sync
    
    Lệnh này sẽ thêm một tệp uv.lock vào dự án của bạn.
  2. Tạo và mở một tệp server.py mới cho mã nguồn máy chủ MCP:
    cloudshell edit ~/mcp-on-cloudrun/server.py
    
    Lệnh cloudshell edit sẽ mở tệp server.py trong trình chỉnh sửa phía trên thiết bị đầu cuối.
  3. Thêm mã nguồn máy chủ MCP cho vườn thú sau đây vào tệp server.py:
    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,
            )
        )
    

Mã của bạn đã hoàn tất! Đã đến lúc triển khai máy chủ MCP lên Cloud Run.

7. Đang triển khai lên Cloud Run

Bây giờ, hãy triển khai một máy chủ MCP lên Cloud Run trực tiếp từ mã nguồn.

  1. Tạo và mở một Dockerfile mới để triển khai lên Cloud Run:
    cloudshell edit ~/mcp-on-cloudrun/Dockerfile
    
  2. Đưa mã sau vào Dockerfile để sử dụng công cụ uv cho việc chạy tệp 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. Tạo một tài khoản dịch vụ có tên là mcp-server-sa:
    gcloud iam service-accounts create mcp-server-sa --display-name="MCP Server Service Account"
    
  4. Chạy lệnh gcloud để triển khai ứng dụng lên 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
    
    Sử dụng cờ --no-allow-unauthenticated để yêu cầu xác thực. Điều này rất quan trọng vì lý do bảo mật. Nếu bạn không yêu cầu xác thực, thì bất kỳ ai cũng có thể gọi máy chủ MCP và có khả năng gây hại cho hệ thống của bạn.
  5. Xác nhận việc tạo một kho lưu trữ Artifact Registry mới Vì đây là lần đầu tiên bạn triển khai lên Cloud Run từ mã nguồn, nên bạn sẽ thấy:
    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)?
    
    Nhập Y rồi nhấn Enter. Lệnh này sẽ tạo một kho lưu trữ Artifact Registry cho quá trình triển khai của bạn. Bạn cần phải thực hiện việc này để lưu trữ vùng chứa Docker của máy chủ MCP cho dịch vụ Cloud Run.
  6. Sau vài phút, bạn sẽ thấy một thông báo như sau:
    Service [zoo-mcp-server] revision [zoo-mcp-server-12345-abc] has been deployed and is serving 100 percent of traffic.
    

Bạn đã triển khai máy chủ MCP. Bây giờ, bạn có thể sử dụng máy chủ này.

8. Thêm máy chủ MCP từ xa vào Gemini CLI

Giờ đây, bạn đã triển khai thành công một máy chủ MCP từ xa, bạn có thể kết nối với máy chủ đó bằng nhiều ứng dụng như Google Code Assist hoặc Gemini CLI. Trong phần này, chúng ta sẽ thiết lập kết nối với máy chủ MCP từ xa mới bằng Gemini CLI.

  1. Cấp cho tài khoản người dùng của bạn quyền gọi máy chủ MCP từ xa
    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member=user:$(gcloud config get-value account) \
        --role='roles/run.invoker'
    
  2. Lưu thông tin xác thực và số dự án của Google Cloud vào các biến môi trường để sử dụng trong tệp Cài đặt Gemini:
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    export ID_TOKEN=$(gcloud auth print-identity-token)
    
  3. Tạo một thư mục .gemini nếu thư mục này chưa được tạo
    mkdir -p ~/.gemini
    
  4. Mở tệp Cài đặt Gemini CLI
    cloudshell edit ~/.gemini/settings.json
    
  5. Thay thế tệp cài đặt Gemini CLI để thêm máy chủ MCP Cloud Run
    {
        "ide": {
            "hasSeenNudge": true
        },
        "mcpServers": {
            "zoo-remote": {
                "httpUrl": "https://zoo-mcp-server-$PROJECT_NUMBER.us-west1.run.app/mcp",
                "headers": {
                    "Authorization": "Bearer $ID_TOKEN"
                }
            }
        },
        "security": {
            "auth": {
                "selectedType": "cloud-shell"
            }
        }
    }
    
  6. Khởi động Gemini CLI trong Cloud Shell
    gemini
    
    Bạn có thể cần nhấn Enter để chấp nhận một số chế độ cài đặt mặc định.Chế độ xem ban đầu của Gemini CLI
  7. Yêu cầu Gemini liệt kê các công cụ MCP có sẵn trong ngữ cảnh của công cụ này
    /mcp
    
  8. Yêu cầu Gemini tìm một nội dung nào đó trong vườn thú
    Where can I find penguins?
    
    Gemini CLI sẽ biết cách sử dụng Máy chủ MCP zoo-remote và sẽ hỏi xem bạn có muốn cho phép thực thi MCP hay không.
  9. Sử dụng mũi tên xuống, sau đó nhấn Enter để chọn
    Yes, always allow all tools from server "zoo-remote"
    
    Gemini CLI cho phép các công cụ từ xa của zoo

Đầu ra sẽ hiển thị câu trả lời chính xác và một hộp hiển thị cho biết máy chủ MCP đã được sử dụng.

Kết quả máy chủ MCP của sở thú hiển thị trên Gemini CLI

Bạn đã hoàn tất! Bạn đã triển khai thành công một máy chủ MCP từ xa lên Cloud Run và kiểm thử máy chủ đó bằng Gemini CLI.

Khi bạn đã sẵn sàng kết thúc phiên, hãy nhập /quit rồi nhấn Enter để thoát khỏi Gemini CLI.

Gỡ lỗi

Nếu bạn thấy một lỗi như sau:

🔍 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.

Có thể là Mã thông báo nhận dạng đã hết thời gian chờ và bạn cần đặt lại ID_TOKEN.

  1. Nhập /quit rồi nhấn Enter để thoát khỏi Gemini CLI.
  2. Đặt dự án trong thiết bị đầu cuối
    gcloud config set project [PROJECT_ID]
    
  3. Chạy lại lệnh thông tin xác thực của Google Cloud để nhận ID_TOKEN mới vì mã thông báo của bạn có thể đã hết hạn.
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    export ID_TOKEN=$(gcloud auth print-identity-token)
    

9. (Không bắt buộc) Xác minh các lệnh gọi công cụ trong nhật ký máy chủ

Để xác minh rằng máy chủ MCP Cloud Run của bạn đã được gọi, hãy kiểm tra nhật ký dịch vụ.

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

Bạn sẽ thấy một nhật ký đầu ra xác nhận rằng một lệnh gọi công cụ đã được thực hiện. 🛠️

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. (Không bắt buộc) Thêm lời nhắc MCP vào Máy chủ

Lời nhắc MCP có thể giúp tăng tốc quy trình làm việc cho những lời nhắc mà bạn thường chạy bằng cách tạo một lối tắt cho lời nhắc dài hơn.

Gemini CLI tự động chuyển đổi lời nhắc MCP thành các lệnh dấu gạch chéo tuỳ chỉnh để bạn có thể gọi lời nhắc MCP bằng cách nhập /prompt_name, trong đó prompt_name là tên của lời nhắc MCP.

Tạo một lời nhắc MCP để bạn có thể nhanh chóng tìm thấy một loài động vật trong vườn thú bằng cách nhập /find animal vào Gemini CLI.

  1. Thêm mã này vào tệp server.py phía trên trình bảo vệ chính (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. Triển khai lại ứng dụng lên Cloud Run
    gcloud run deploy zoo-mcp-server \
        --region=us-west1 \
        --source=. \
        --labels=dev-tutorial=codelab-mcp
    
  3. Làm mới ID_TOKEN cho máy chủ MCP từ xa
    export ID_TOKEN=$(gcloud auth print-identity-token)
    
  4. Sau khi triển khai phiên bản mới của ứng dụng, hãy khởi động Gemini CLI.
    gemini
    
  5. Trong lời nhắc, hãy sử dụng lệnh tuỳ chỉnh mới mà bạn đã tạo:
    /find lions
    

Bạn sẽ thấy rằng Gemini CLI gọi công cụ get_animals_by_species và định dạng phản hồi theo hướng dẫn của lời nhắc 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. (Không bắt buộc) Sử dụng Gemini Flash Lite để có phản hồi nhanh hơn

Gemini CLI cho phép bạn chọn mô hình mà bạn đang sử dụng.

  • Gemini 2.5 Pro là mô hình tư duy hiện đại của Google, có khả năng suy luận về các vấn đề phức tạp trong mã, toán học và STEM, cũng như phân tích các tập dữ liệu, cơ sở mã và tài liệu lớn bằng ngữ cảnh dài.
  • Gemini 2.5 Flash là mô hình tốt nhất của Google về hiệu suất giá, mang đến các khả năng toàn diện. 2.5 Flash là lựa chọn tốt nhất cho các tác vụ xử lý quy mô lớn, độ trễ thấp, khối lượng lớn đòi hỏi khả năng tư duy và các trường hợp sử dụng dựa trên tác nhân.
  • Gemini 2.5 Flash Lite là mô hình flash nhanh nhất của Google, được tối ưu hoá để mang lại hiệu quả chi phí và thông lượng cao.

Vì các yêu cầu liên quan đến việc tìm kiếm các loài động vật trong vườn thú không đòi hỏi khả năng tư duy hoặc suy luận, nên hãy thử tăng tốc bằng cách sử dụng một mô hình nhanh hơn.

Trong phần trước, bạn đã tạo một lời nhắc MCP để có thể nhanh chóng tìm thấy một loài động vật trong vườn thú bằng cách nhập /find animal vào Gemini CLI.

  1. Sau khi triển khai phiên bản mới của ứng dụng, hãy khởi động Gemini CLI.
    gemini --model=gemini-2.5-flash-lite
    
  2. Trong lời nhắc, hãy sử dụng lệnh tuỳ chỉnh mới mà bạn đã tạo:
    /find lions
    

Bạn vẫn sẽ thấy rằng Gemini CLI gọi công cụ get_animals_by_species và định dạng phản hồi theo hướng dẫn của lời nhắc MCP, nhưng câu trả lời sẽ xuất hiện nhanh hơn nhiều!

╭───────────────────────────╮
│  > /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.

Gỡ lỗi

Nếu bạn thấy một lỗi như sau:

✕ Unknown command: /find lions

Hãy thử chạy /mcp và nếu lệnh này xuất ra zoo-remote - Disconnected, thì có thể bạn phải triển khai lại hoặc chạy lại các lệnh sau:

 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)

12. Kết luận

Xin chúc mừng! Bạn đã triển khai và kết nối thành công với một máy chủ MCP từ xa an toàn.

Tiếp tục đến phòng thí nghiệm tiếp theo

Phòng thí nghiệm này là phòng thí nghiệm đầu tiên trong một loạt 3 phần. Trong phòng thí nghiệm thứ hai, bạn sẽ sử dụng máy chủ MCP mà bạn đã tạo bằng một Tác nhân ADK.

Sử dụng máy chủ MCP trên Cloud Run với một Tác nhân ADK

(Không bắt buộc) Dọn dẹp

Nếu không tiếp tục đến phòng thí nghiệm tiếp theo và muốn dọn dẹp những nội dung bạn đã tạo, bạn có thể xoá dự án trên đám mây để tránh phát sinh thêm phí.

Mặc dù Cloud Run không tính phí khi dịch vụ không được sử dụng, nhưng bạn vẫn có thể bị tính phí khi lưu trữ hình ảnh vùng chứa trong Artifact Registry. Việc xoá dự án trên đám mây sẽ dừng tính phí cho tất cả các tài nguyên được sử dụng trong dự án đó.

Nếu muốn, hãy xoá dự án:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

Bạn cũng có thể muốn xoá các tài nguyên không cần thiết khỏi đĩa cloudshell. Bạn có thể:

  1. Xoá thư mục dự án lớp học lập trình:
    rm -rf ~/mcp-on-cloudrun
    
  2. Cảnh báo! Bạn không thể hoàn tác hành động tiếp theo này! Nếu muốn xoá mọi thứ trên Cloud Shell để giải phóng dung lượng, bạn có thể xoá toàn bộ thư mục chính. Hãy cẩn thận để đảm bảo rằng mọi thứ bạn muốn giữ lại đều được lưu ở nơi khác.
    sudo rm -rf $HOME