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

1. مقدمة

نظرة عامة

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

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

سنستخدم Genkit لإنشاء خادم MCP لحديقة حيوانات يتضمّن أداتَين: get_animals_by_species وget_animal_details. توفّر Genkit طريقة سريعة لإنشاء خوادم وعملاء MCP باستخدام Node.js.

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

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

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

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

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

3- فتح "محرّر Cloud Shell"

  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- إعداد مشروع JavaScript

  1. أنشئ مجلدًا باسم mcp-on-cloudrun لتخزين رمز المصدر اللازم للنشر:
    mkdir mcp-on-cloudrun && cd mcp-on-cloudrun
    
  2. أنشئ مشروع Node.js باستخدام الأداة npm لإنشاء ملف package.json:
    npm init es6 -y
    
    ينشئ الأمر npm init ملف package.json لمشروعك.
  3. ثبِّت الاعتماديات @modelcontextprotocol/sdk وexpress وzod:
    npm install @modelcontextprotocol/sdk express zod
    

6. إنشاء خادم MCP الخاص بحديقة الحيوانات

لتوفير سياق قيّم لتحسين استخدام النماذج اللغوية الكبيرة مع بروتوكول سياق النموذج، يمكنك إعداد خادم بروتوكول سياق النموذج في حديقة حيوانات باستخدام Genkit، وهو إطار عمل عادي للعمل مع بروتوكول سياق النموذج. توفّر Genkit طريقة سريعة لإنشاء خوادم وعملاء MCP باستخدام Node.js. يوفّر خادم MCP هذا بيانات عن الحيوانات في حديقة حيوانات وهمية. لتبسيط الأمر، نخزّن البيانات في الذاكرة. بالنسبة إلى خادم MCP للإنتاج، من المفترض أن تقدّم بيانات من مصادر مثل قواعد البيانات أو واجهات برمجة التطبيقات.

  1. نفِّذ الأمر التالي لإضافة Genkit كعنصر تابع في ملف package.json:
    npm install genkit
    
    سيؤدي ذلك إلى إضافة ملف package-lock.json إلى مشروعك.
  2. نفِّذ الأمر التالي لإضافة مكتبة Genkit AI MCP في ملف package.json:
    npm install @genkit-ai/mcp
    
  3. أنشئ ملف index.js جديدًا وافتحه لرمز المصدر الخاص بخادم MCP:
    cloudshell edit index.js
    
    سيفتح الأمر cloudshell edit الملف index.js في المحرِّر أعلى الوحدة الطرفية.
  4. أضِف رمز المصدر التالي لخادم MCP الخاص بحديقة الحيوانات إلى ملف index.js:
    import express from 'express';
    import { genkit, z } from 'genkit';
    import { createMcpServer } from '@genkit-ai/mcp';
    import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
    
    // Dictionary of animals at the zoo
    const 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"
        }
    ];
    
    // Initialize Genkit
    const ai = genkit({});
    
    // Define tools using Genkit
    ai.defineTool(
        {
            name: 'get_animals_by_species',
            description: "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.",
            inputSchema: z.object({ species: z.string() }),
        },
        async ({ species }) => {
            console.log(`>>> 🛠️ Tool: 'get_animals_by_species' called for '${species}'`);
            const animals = ZOO_ANIMALS.filter(animal => animal.species.toLowerCase() === species.toLowerCase());
            return animals;
        }
    );
    
    ai.defineTool(
        {
            name: 'get_animal_details',
            description: "Retrieves the details of a specific animal by its name.",
            inputSchema: z.object({ name: z.string() }),
        },
        async ({ name }) => {
            console.log(`>>> 🛠️ Tool: 'get_animal_details' called for '${name}'`);
            const animal = ZOO_ANIMALS.find(a => a.name.toLowerCase() === name.toLowerCase());
            return animal;
        }
    );
    
    // Create Genkit MCP server wrapper
    const mcpWrapper = createMcpServer(ai, {
        name: 'zoo-animal-server',
        version: '1.0.0',
    });
    
    // HTTP server mode
    const app = express();
    app.use(express.json());
    
    // Initialize Genkit MCP server once
    const mcpServerPromise = mcpWrapper.setup().then(() => mcpWrapper.server);
    
    app.post('/mcp', async (req, res) => {
        console.log('/mcp Received:', req.body);
        console.log('Using HTTP transport mode.');
    
        const server = await mcpServerPromise;
    
        const transport = new StreamableHTTPServerTransport({
            sessionIdGenerator: undefined,
        });
    
        if (!server) {
            console.error('MCP Server not initialized correctly.');
            res.sendStatus(500);
            return;
        }
    
        await server.connect(transport);
        await transport.handleRequest(req, res, req.body);
    
        res.on('close', () => {
            console.log('Request closed');
            transport.close();
        });
    });
    
    app.get('/mcp', async (req, res) => {
        console.log('Received GET MCP request');
        res.sendStatus(405);
    });
    
    app.delete('/mcp', async (req, res) => {
        console.log('Received DELETE MCP request');
        res.sendStatus(405);
    });
    
    // Start the server
    const PORT = process.env.PORT || 8080;
    app.listen(PORT, () => {
        console.log(`Zoo Animal MCP server listening on port ${PORT}`);
    });
    

اكتملت عملية إدخال الرمز. حان الوقت لنشر خادم MCP على Cloud Run.

7. النشر على Cloud Run

الآن، يمكنك نشر خادم MCP على Cloud Run مباشرةً من رمز المصدر.

  1. أنشئ حساب خدمة باسم mcp-server-sa:
    gcloud iam service-accounts create mcp-server-sa --display-name="MCP Server Service Account"
    
  2. نفِّذ الأمر gcloud لنشر التطبيق على Cloud Run
    gcloud run deploy zoo-mcp-server \
        --service-account=mcp-server-sa@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
        --no-allow-unauthenticated \
        --region=europe-west1 \
        --source=. \
        --labels=dev-tutorial=codelab-mcp
    
    استخدِم العلامة --no-allow-unauthenticated لطلب المصادقة. هذا الإجراء مهم لأسباب تتعلق بالأمان. إذا لم تكن بحاجة إلى مصادقة، يمكن لأي شخص الاتصال بخادم MCP وإلحاق الضرر بنظامك.
  3. تأكيد إنشاء مستودع جديد في 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.
  4. بعد بضع دقائق، ستظهر لك رسالة مثل:
    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 لإضافة خادم Cloud Run MCP
    {
        "ide": {
            "hasSeenNudge": true
        },
        "mcpServers": {
            "zoo-remote": {
                "httpUrl": "https://zoo-mcp-server-$PROJECT_NUMBER.europe-west1.run.app/mcp",
                "headers": {
                    "Authorization": "Bearer $ID_TOKEN"
                }
            }
        },
        "security": {
            "auth": {
                "selectedType": "cloud-shell"
            }
        }
    }
    

  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.

عرض نتيجة خادم MCP الخاص بحديقة الحيوان في Gemini CLI

لقد نجحت في ذلك. لقد نشرت خادم 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_TOKEN مرة أخرى.

  1. اكتب /quit ثم اضغط على Enter للخروج من Gemini 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)
    

9- (اختياري) التحقّق من استدعاءات الأدوات في سجلّات الخادم

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

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 إلى تسريع سير عملك للطلبات التي تنفّذها غالبًا من خلال إنشاء اختصار لطلب أطول.

يحوّل Gemini CLI تلقائيًا طلبات MCP إلى أوامر مخصّصة تبدأ بشرطة مائلة، ما يتيح لك استدعاء طلب MCP عن طريق كتابة /prompt_name حيث prompt_name هو اسم طلب MCP.

أنشئ طلب MCP لتتمكّن من العثور بسرعة على حيوان في حديقة الحيوانات عن طريق كتابة /find animal في Gemini CLI.

  1. أضِف الرمز التالي إلى ملف index.js فوق السطر // Create Genkit MCP server wrapper:
    ai.definePrompt(
        {
            name: 'find',
            description: 'Find which exhibit and trail a specific animal is located.',
            inputSchema: z.object({ animal: z.string() }),
        },
        async ({ animal }) => {
            console.log(`>>> 💬 Prompt: 'find' called'`);
            return {
                messages: [
                    {
                        role: 'user',
                        content: [
                            { text: `Please find the exhibit and trail information for ${animal} in the zoo. Respond with '[animal] can be found in the [exhibit] on the [trail].' Example: Penguins can be found in The Arctic Exhibit on the Polar Path.` }
                        ]
                    }
                ]
            };
        }
    );
    
  2. إعادة نشر تطبيقك على Cloud Run
    gcloud run deploy zoo-mcp-server \
        --service-account=mcp-server-sa@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
        --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.

11. (اختياري) استخدام Gemini Flash Lite للحصول على ردود أسرع

يتيح لك Gemini CLI اختيار النموذج الذي تستخدمه.

  • Gemini 2.5 Pro هو نموذج التفكير الأكثر تطورًا من Google، وهو قادر على التفكير في المشاكل المعقّدة في الرموز البرمجية والرياضيات والعلوم والتكنولوجيا والهندسة والرياضيات، بالإضافة إلى تحليل مجموعات البيانات وقواعد الرموز البرمجية والمستندات الكبيرة باستخدام السياق الطويل.
  • Gemini 2.5 Flash هو أفضل نموذج من Google من حيث السعر والأداء، وهو يقدّم إمكانات شاملة. ‫2.5 Flash هو الخيار الأفضل للمهام التي تتطلّب التفكير ومعالجة البيانات على نطاق واسع، والمهام التي تتطلّب وقت استجابة منخفضًا، والمهام التي تتطلّب معالجة كميات كبيرة من البيانات، وحالات الاستخدام التي تستند إلى الذكاء الاصطناعي الوكيل.
  • Gemini 2.5 Flash Lite هو أسرع نموذج flash من Google، وهو مصمَّم لتحقيق فعالية عالية من حيث التكلفة ومعدّل أعلى لنقل البيانات.

بما أنّ الطلبات المتعلقة بالعثور على حيوانات الحديقة لا تتطلّب التفكير أو الاستدلال، يمكنك محاولة تسريع العملية باستخدام نموذج أسرع.

أنشئ طلب MCP لتتمكّن من العثور بسرعة على حيوان في حديقة الحيوانات عن طريق كتابة /find animal في Gemini CLI.

  1. بعد نشر الإصدار الجديد من تطبيقك، ابدأ تشغيل Gemini CLI.
    gemini --model=gemini-2.5-flash-lite
    
  2. في الطلب، استخدِم الأمر المخصّص الجديد الذي أنشأته:
    /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 لمعرفة ما إذا كانت تعمل.

تصحيح الأخطاء

إذا ظهرت لك رسالة خطأ مشابهة لما يلي:

✕ Unknown command: /find --animal="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)

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