كيفية نشر خادم MCP آمن على Cloud Run

1. مقدمة

نظرة عامة

في هذا الدرس التطبيقي، ستنشئ خادم بروتوكول سياق النموذج (MCP) وتنشره. تفيد خوادم MCP في منح النماذج اللغوية الكبيرة إمكانية الوصول إلى الأدوات والخدمات الخارجية. ستتمكّن من إعدادها كخدمة آمنة وجاهزة للإنتاج على Cloud Run يمكن الوصول إليها من أجهزة عملاء متعددة. بعد ذلك، ستتصل بخادم MCP البعيد من واجهة سطر الأوامر Antigravity.

الإجراءات التي ستنفذّها

سنستخدم FastMCP لإنشاء خادم MCP خاص بحديقة حيوانات يتضمّن أداتَين: get_animals_by_species وget_animal_details. توفّر FastMCP طريقة سريعة تستند إلى لغة Python لإنشاء خوادم وعملاء MCP.

رسم بياني لخادم MCP في حديقة الحيوانات

أهداف الدورة التعليمية

  • نشر خادم MCP على Cloud Run
  • يمكنك تأمين نقطة نهاية الخادم من خلال طلب المصادقة لجميع الطلبات، ما يضمن إمكانية تواصل العملاء والوكلاء المصرّح لهم فقط معها.
  • الاتصال بنقطة نهاية خادم MCP الآمنة من Antigravity CLI

2. إعداد المشروع

  1. إذا لم يكن لديك حساب على Google، عليك إنشاء حساب Google.
    • استخدام حساب شخصي بدلاً من حساب تديره المؤسسة التعليمية أو حساب تابع للعمل. قد تتضمّن حسابات العمل والمؤسسات التعليمية قيودًا تمنعك من تفعيل واجهات برمجة التطبيقات اللازمة لهذا الدرس التطبيقي.
  2. سجِّل الدخول إلى Google Cloud Console.
  3. أنشِئ مشروعًا جديدًا أو اختَر إعادة استخدام مشروع حالي.
    • إذا ظهر لك خطأ بشأن حصة المشروع، أعِد استخدام مشروع حالي أو احذف مشروعًا حاليًا لإنشاء مشروع جديد.

3- فتح Cloud Shell Editor

  1. انقر على هذا الرابط للانتقال مباشرةً إلى محرّر Cloud Shell
  2. إذا طُلب منك منح الإذن في أي وقت اليوم، انقر على منح الإذن للمتابعة. انقر لتفويض Cloud Shell
  3. إذا لم تظهر المحطة الطرفية في أسفل الشاشة، افتحها باتّباع الخطوات التالية:
    • انقر على عرض.
    • انقر على Terminalفتح نافذة طرفية جديدة في "محرِّر Cloud Shell"
  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. تفعيل واجهات برمجة التطبيقات

في الوحدة الطرفية، فعِّل واجهات برمجة التطبيقات:

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 الخاص بحديقة الحيوانات

لتقديم سياق قيّم لتحسين استخدام النماذج اللغوية الكبيرة مع "بروتوكول سياق النموذج"، يمكنك إعداد خادم "بروتوكول سياق النموذج" لحديقة حيوانات باستخدام FastMCP، وهو إطار عمل عادي للتعامل مع "بروتوكول سياق النموذج". توفّر FastMCP طريقة سريعة لإنشاء خوادم وعملاء MCP باستخدام Python. يوفّر خادم "بروتوكول سياق النموذج" (MCP) هذا بيانات عن الحيوانات في حديقة حيوانات وهمية. لتبسيط الأمر، نخزِّن البيانات في الذاكرة. بالنسبة إلى خادم MCP مخصّص للإنتاج، من المحتمل أنّك تريد تقديم بيانات من مصادر مثل قواعد البيانات أو واجهات برمجة التطبيقات.

  1. نفِّذ الأمر التالي لإضافة FastMCP كعنصر تابع في ملف pyproject.toml:
    uv add fastmcp==2.12.4 --no-sync
    
    سيؤدي ذلك إلى إضافة ملف uv.lock إلى مشروعك.
  2. أنشئ ملف server.py جديدًا وافتحه لرمز المصدر الخاص بخادم MCP:
    cloudshell edit ~/mcp-on-cloudrun/server.py
    
    سيفتح الأمر cloudshell edit الملف server.py في المحرِّر أعلى الوحدة الطرفية.
  3. أضِف رمز المصدر التالي لخادم MCP الخاص بحديقة الحيوانات إلى ملف 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,
            )
        )
    

اكتملت عملية إدخال الرمز. حان الوقت لنشر خادم 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 لعملية النشر. هذا الإجراء مطلوب لتخزين حاوية Docker لخادم MCP لخدمة Cloud Run.
  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. في هذا القسم، سننشئ اتصالاً بخادم MCP البعيد الجديد باستخدام Antigravity 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 ورقم المشروع في متغيّرات البيئة لاستخدامها في ملف إعدادات 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 البعيد في ملف إعداد MCP الخاص بأداة Antigravity CLI:
    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: يجب إجراء المصادقة أثناء بدء التشغيل الأوّلي. اختَر OAuth (بالضغط على Enter).شاشة مصادقة Antigravity
  2. انقر على الرابط (إذا لم يكن قابلاً للنقر، حدِّد عنوان URL في Cloud Shell لنسخه، ثم الصقه في المتصفّح).
  3. تسجيل الدخول إلى حسابك على Google
  4. نسخ الشفرة
  5. ألصِق الرمز في وحدة Cloud Shell Editor الطرفية
  6. اضغط على Enter.طلب إدخال رمز الأمان في Antigravity
  7. اضغط على Enter لقبول بعض الإعدادات التلقائية.
  8. أن تطلب من Antigravity CLI إدراج أدوات MCP المتاحة لها ضمن سياقها
    /mcp
    
    اضغط على ESC للرجوع إلى مربّع الطلب.
  9. اطلب من Antigravity CLI العثور على شيء في حديقة الحيوانات
    Where can I find penguins?
    
    يجب أن تعرف واجهة سطر الأوامر Antigravity كيفية استخدام خادم zoo-remote MCP، وسيتم سؤالك عمّا إذا كنت تريد السماح بتنفيذ MCP.
  10. استخدِم السهم المتّجه للأسفل، ثم اضغط على Enter للاختيار
    Yes, always allow all tools from server "zoo-remote"
    
    Antigravity CLI allow zoo remote tools

يجب أن تعرض النتيجة الإجابة الصحيحة ومربّع عرض يشير إلى أنّه تم استخدام خادم MCP.

Antigravity CLI show zoo mcp server result

لقد أنجزت المهمة! لقد تمكّنت من نشر خادم 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_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. (اختياري) التحقّق من استدعاءات الأدوات في سجلّات الخادم

للتأكّد من أنّه تم استدعاء خادم MCP على Cloud Run، راجِع سجلات الخدمة.

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 إلى أوامر مخصّصة تبدأ بشرطة مائلة، ما يتيح لك استدعاء طلب MCP عن طريق كتابة /prompt_name حيث prompt_name هو اسم طلب MCP.

أنشئ طلب MCP لتتمكّن من العثور بسرعة على حيوان في حديقة الحيوانات من خلال كتابة /find animal في Antigravity 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 \
        --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 حتى تتمكّن من العثور بسرعة على حيوان في حديقة الحيوانات من خلال كتابة /find animal في واجهة سطر الأوامر Antigravity.

  1. بعد نشر الإصدار الجديد من تطبيقك، ابدأ تشغيل Antigravity CLI.
    agy --model=gemini-3.6-flash --effort=low
    
  2. في الطلب، استخدِم الأمر المخصّص الجديد الذي أنشأته:
    /find lions
    

سيظل بإمكانك ملاحظة أنّ واجهة سطر الأوامر Antigravity تستدعي الأداة 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.

استخدام خادم MCP على Cloud Run مع وكيل ADK

(اختياري) إخلاء مساحة تخزين

إذا كنت لن تنتقل إلى المختبر التالي وأردت تنظيف ما أنشأته، يمكنك حذف مشروعك على السحابة الإلكترونية لتجنُّب تكبُّد رسوم إضافية.

على الرغم من أنّ Cloud Run لا يفرض رسومًا عندما لا تكون الخدمة قيد الاستخدام، قد يتم تحصيل رسوم منك مقابل تخزين صورة الحاوية في Artifact Registry. يؤدي حذف مشروعك على السحابة الإلكترونية إلى إيقاف الفوترة لجميع الموارد المستخدَمة في هذا المشروع.

إذا أردت، يمكنك حذف المشروع باتّباع الخطوات التالية:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

يمكنك أيضًا حذف الموارد غير الضرورية من قرص cloudshell. يمكنك إجراء ما يلي:

  1. احذف دليل مشروع الدرس البرمجي:
    rm -rf ~/mcp-on-cloudrun
    
  2. تحذير! لا يمكن التراجع عن الإجراء التالي. إذا أردت حذف كل المحتوى على Cloud Shell لإخلاء بعض المساحة، يمكنك حذف دليل منزلك بأكمله. يجب الحرص على حفظ كل ما تريد الاحتفاظ به في مكان آخر.
    sudo rm -rf $HOME