איך פורסים שרת MCP מאובטח ב-Cloud Run

1. מבוא

סקירה כללית

בשיעור ה-Lab הזה תבנו ותפרסו שרת Model Context Protocol (MCP). שרתי MCP שימושיים כדי לספק למודלים מסוג LLM גישה לכלים ולשירותים חיצוניים. תגדירו אותו כשירות מאובטח ומוכן לייצור ב-Cloud Run, שאפשר לגשת אליו מכמה לקוחות. לאחר מכן תתחברו לשרת ה-MCP המרוחק מ-Gemini CLI.

הפעולות שתבצעו:

נשתמש ב-FastMCP כדי ליצור שרת MCP של zoo עם שני כלים: get_animals_by_species ו-get_animal_details. ‫FastMCP מספק דרך מהירה ופייתונית לבניית שרתים ולקוחות של MCP.

‫Zoo MCP Server Graphic

מה תלמדו

  • פורסים את שרת ה-MCP ב-Cloud Run.
  • כדי להגן על נקודת הקצה של השרת, צריך לדרוש אימות לכל הבקשות, כדי שרק לקוחות ונציגים מורשים יוכלו לתקשר איתו.
  • התחברות לנקודת הקצה של שרת ה-MCP המאובטח מ-Gemini CLI

2. הגדרת הפרויקט

  1. אם אין לכם חשבון Google, אתם צריכים ליצור חשבון Google.
    • משתמשים בחשבון לשימוש אישי במקום בחשבון לצורכי עבודה או בחשבון בית ספרי. יכול להיות שבחשבונות לצורכי עבודה או בחשבונות בית ספריים יש הגבלות שלא מאפשרות להפעיל את ממשקי ה-API שנדרשים למעבדה הזו.
  2. נכנסים למסוף Google Cloud.
  3. מפעילים את החיוב במסוף Cloud.
    • העלות של השלמת שיעור ה-Lab הזה צריכה להיות פחות מ-1 $‎ על משאבי Cloud.
    • כדי למחוק משאבים ולמנוע חיובים נוספים, אפשר לפעול לפי השלבים בסוף שיעור ה-Lab הזה.
    • משתמשים חדשים זכאים לתקופת ניסיון בחינם בשווי 300$.
  4. יוצרים פרויקט חדש או בוחרים להשתמש בפרויקט קיים.

3. פתיחת Cloud Shell Editor

  1. כדי לעבור ישירות אל Cloud Shell Editor, לוחצים על הקישור הזה.
  2. אם תתבקשו לאשר את הפעולה בשלב כלשהו היום, תצטרכו ללחוץ על אישור כדי להמשיך. לוחצים כדי לתת הרשאה ל-Cloud Shell
  3. אם הטרמינל לא מופיע בתחתית המסך, פותחים אותו:
    • לוחצים על תצוגה.
    • לוחצים על Terminal (מסוף)פתיחת טרמינל חדש ב-Cloud Shell Editor.
  4. בטרמינל, מגדירים את הפרויקט באמצעות הפקודה הבאה:
    • פורמט:
      gcloud config set project [PROJECT_ID]
      
    • דוגמה:
      gcloud config set project lab-project-id-example
      
    • אם אתם לא זוכרים את מזהה הפרויקט:
      • כדי לראות את כל מזהי הפרויקטים, מריצים את הפקודה:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      הגדרת מזהה הפרויקט בטרמינל של Cloud Shell Editor
  5. תוצג ההודעה:
    Updated property [core/project].
    
    אם מופיע WARNING ומוצגת השאלה Do you want to continue (Y/n)?, כנראה שהזנתם את מזהה הפרויקט בצורה שגויה. לוחצים על 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. יוצרים פרויקט Python באמצעות הכלי uv כדי ליצור קובץ 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. יצירת שרת MCP של גן החיות

כדי לספק הקשר חשוב לשיפור השימוש ב-LLM באמצעות MCP, צריך להגדיר שרת MCP של zoo באמצעות FastMCP – מסגרת סטנדרטית לעבודה עם פרוטוקול הקשר של המודל. ‫FastMCP היא דרך מהירה לבנות שרתי MCP ולקוחות באמצעות Python. שרת ה-MCP הזה מספק נתונים על בעלי חיים בגן חיות פיקטיבי. לשם פשטות, אנחנו מאחסנים את הנתונים בזיכרון. בשרת MCP של סביבת ייצור, כדאי לספק נתונים ממקורות כמו מסדי נתונים או ממשקי API.

  1. מריצים את הפקודה הבאה כדי להוסיף את FastMCP כתלות בקובץ pyproject.toml:
    uv add fastmcp==2.11.1 --no-sync
    
    כך יתווסף קובץ uv.lock לפרויקט.
  2. יוצרים ופותחים קובץ server.py חדש לקוד המקור של שרת ה-MCP:
    cloudshell edit server.py
    
    הפקודה cloudshell edit תפתח את הקובץ server.py בכלי העריכה מעל הטרמינל.
  3. מוסיפים את קוד המקור הבא של שרת ה-MCP של zoo לקובץ 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__":
        logger.info(f"🚀 MCP server started on port {os.getenv('PORT', 8080)}")
        asyncio.run(
            mcp.run_async(
                transport="http",
                host="0.0.0.0",
                port=os.getenv("PORT", 8080),
            )
        )
    

הקוד שלך הושלם! הגיע הזמן לפרוס את שרת ה-MCP ב-Cloud Run.

7. פריסה ב-Cloud Run

עכשיו פורסים שרת MCP ב-Cloud Run ישירות מקוד המקור.

  1. יוצרים ופותחים קובץ Dockerfile חדש לפריסה ב-Cloud Run:
    cloudshell edit Dockerfile
    
  2. כדי להשתמש בכלי 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"]
    
  3. מריצים את הפקודה gcloud כדי לפרוס את האפליקציה ב-Cloud Run.
    gcloud run deploy zoo-mcp-server \
        --no-allow-unauthenticated \
        --region=europe-west1 \
        --source=. \
        --labels=dev-tutorial=codelab-mcp
    
    משתמשים בדגל --no-allow-unauthenticated כדי לדרוש אימות. הדבר חשוב מטעמי אבטחה. אם לא נדרש אימות, כל אחד יכול להתקשר לשרת ה-MCP שלכם ולגרום נזק למערכת.
  4. מאשרים את היצירה של מאגר חדש ב-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 [europe-west1] will be created.
    
    Do you want to continue (Y/n)?
    
    מקלידים Y ולוחצים על Enter. כך ייצור מאגר Artifact Registry לפריסה. ההרשאה הזו נדרשת כדי לאחסן את קונטיינר Docker של שרת ה-MCP בשירות Cloud Run.
  5. אחרי כמה דקות, תופיע הודעה כמו:
    Service [zoo-mcp-server] revision [zoo-mcp-server-12345-abc] has been deployed and is serving 100 percent of traffic.
    

פרסתם את שרת ה-MCP. עכשיו אפשר להשתמש בו.

8. הוספת שרת MCP מרוחק ל-Gemini CLI

אחרי שפרסתם בהצלחה שרת MCP מרוחק, אתם יכולים להתחבר אליו באמצעות אפליקציות שונות כמו Google Code Assist או Gemini CLI. בקטע הזה נסביר איך ליצור חיבור לשרת MCP המרוחק החדש באמצעות Gemini CLI.

  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 ואת מספר הפרויקט במשתני סביבה לשימוש בקובץ ההגדרות של Gemini:
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    export ID_TOKEN=$(gcloud auth print-identity-token)
    
  3. פותחים את קובץ ההגדרות של Gemini CLI.
    cloudshell edit ~/.gemini/settings.json
    
  4. החלפת קובץ ההגדרות של Gemini CLI כדי להוסיף את שרת ה-MCP של Cloud Run
    {
      "mcpServers": {
        "zoo-remote": {
          "httpUrl": "https://zoo-mcp-server-$PROJECT_NUMBER.europe-west1.run.app/mcp/",
          "headers": {
            "Authorization": "Bearer $ID_TOKEN"
          }
        }
      },
      "selectedAuthType": "cloud-shell",
      "hasSeenIdeIntegrationNudge": true
    }
    

  1. הפעלת Gemini CLI ב-Cloud Shell
    gemini
    
    יכול להיות שתצטרכו ללחוץ על Enter כדי לאשר כמה הגדרות ברירת מחדל.התצוגה הראשונית של Gemini CLI
  2. מבקשים מ-Gemini לרשום את כלי ה-MCP שזמינים לו בהקשר שלו
    /mcp
    
  3. אפשר לבקש מ-Gemini למצוא משהו בגן החיות
    Where can I find penguins?
    
    Gemini CLI אמור לדעת להשתמש בשרת zoo-remote MCP וישאל אם רוצים לאפשר את ההפעלה של MCP.
  4. משתמשים בחץ למטה ומקישים על Enter כדי לבחור.
    Yes, always allow all tools from server "zoo-remote"
    
    ‫Gemini CLI allow zoo remote tools

הפלט צריך להציג את התשובה הנכונה ותיבת תצוגה שמראה שהשתמשו בשרת MCP.

‫Gemini CLI show zoo mcp server result

הצלחתם! הצלחתם לפרוס שרת MCP מרוחק ב-Cloud Run ולבדוק אותו באמצעות Gemini CLI.

כשמוכנים לסיים את הסשן, מקלידים /quit ואז לוחצים על Enter כדי לצאת מ-Gemini 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. מקלידים /quit ואז מקישים על Enter כדי לצאת מ-Gemini CLI.
  2. הגדרת הפרויקט במסוף
    gcloud config set project [PROJECT_ID]
    
  3. מתחילים מחדש משלב 2 שלמעלה

9. (אופציונלי) אימות של קריאות לכלים ביומני השרת

כדי לוודא שהשרת של Cloud Run MCP נקרא, בודקים את יומני השירות.

gcloud run services logs read zoo-mcp-server --region europe-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 יכולה לזרז את תהליך העבודה שלכם בהנחיות שאתם מריצים לעיתים קרובות, על ידי יצירת קיצור להנחיה ארוכה יותר.

ממשק ה-CLI של Gemini ממיר באופן אוטומטי הנחיות של MCP לפקודות סלאש מותאמות אישית, כך שאפשר להפעיל הנחיה של MCP על ידי הקלדת /prompt_name, כאשר prompt_name הוא השם של ההנחיה של MCP.

יוצרים הנחיה ל-MCP כדי למצוא במהירות חיה בגן החיות על ידי הקלדת /find animal ב-Gemini CLI.

  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 \
        --no-allow-unauthenticated \
        --region=europe-west1 \
        --source=. \
        --labels=dev-tutorial=codelab-mcp
    
  3. רענון של ID_TOKEN עבור שרת MCP מרוחק
    export ID_TOKEN=$(gcloud auth print-identity-token)
    
  4. אחרי שפורסתם את הגרסה החדשה של האפליקציה, מפעילים את Gemini CLI.
    gemini
    
  5. בהנחיה, משתמשים בפקודה החדשה בהתאמה אישית שיצרתם:
    /find --animal="lions"
    

אפשר לראות ש-Gemini CLI קורא לכלי get_animals_by_species ומעצב את התשובה לפי ההוראות בהנחיה של MCP.

╭───────────────────────────╮
│  > /find --animal="lion"  │
╰───────────────────────────╯

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

יעדים שאפתניים לבדיקה עצמית

כדי להוסיף אתגר, נסו לבצע את אותם השלבים כדי ליצור הנחיה להחזרת עובדות מעניינות על מינים ספציפיים של בעלי חיים בגן החיות.

או, כדי לבחון את מה שלמדתם, אפשר להעלות רעיון לכלי שבו תשתמשו לעיתים קרובות ולפרוס שרת MCP מרוחק שני. לאחר מכן מוסיפים אותו להגדרות של Gemini CLI כדי לבדוק אם הוא פועל.

11. סיכום

מעולה! הצלחתם לפרוס ולהתחבר לשרת MCP מרוחק ומאובטח.

המשך לשיעור ה-Lab הבא

שיעור ה-Lab הזה הוא הראשון בסדרה של שלושה שיעורי Lab. בשיעור ה-Lab השני, תשתמשו בשרת ה-MCP שיצרתם באמצעות סוכן ADK.

שימוש בשרת MCP ב-Cloud Run עם סוכן ADK

(אופציונלי) ניקוי

אם אתם לא ממשיכים למעבדה הבאה ורוצים לנקות את מה שיצרתם, אתם יכולים למחוק את פרויקט Cloud כדי להימנע מחיובים נוספים.

ב-Cloud Run לא מחויבים כשלא משתמשים בשירות, אבל יכול להיות שתחויבו על אחסון קובץ האימג' של הקונטיינר ב-Artifact Registry. כשמוחקים פרויקט ב-Cloud, החיוב על כל המשאבים שנעשה בהם שימוש באותו פרויקט נפסק.

אם רוצים, מוחקים את הפרויקט:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

מומלץ גם למחוק משאבים מיותרים מהדיסק של Cloud Shell. אתם יכולים:

  1. מוחקים את ספריית הפרויקט של ה-codelab:
    rm -rf ~/mcp-on-cloudrun
    
  2. אזהרה! אי אפשר לבטל את הפעולה הבאה! אם אתם רוצים למחוק את כל מה שיש ב-Cloud Shell כדי לפנות מקום, אתם יכולים למחוק את כל ספריית הבית. חשוב לוודא שכל מה שרוצים לשמור נשמר במקום אחר.
    sudo rm -rf $HOME