วิธีทำให้เซิร์ฟเวอร์ MCP ของ Genkit ที่ปลอดภัยใช้งานได้ใน Cloud Run

1. บทนำ

ภาพรวม

ใน Lab นี้ คุณจะได้สร้างและติดตั้งใช้งานเซิร์ฟเวอร์ Model Context Protocol (MCP) เซิร์ฟเวอร์ MCP มีประโยชน์ในการให้สิทธิ์ LLM เข้าถึงเครื่องมือและบริการภายนอก คุณจะกำหนดค่าให้เป็นบริการที่ปลอดภัยและพร้อมใช้งานจริงใน Cloud Run ซึ่งเข้าถึงได้จากไคลเอ็นต์หลายราย จากนั้นคุณจะเชื่อมต่อกับเซิร์ฟเวอร์ MCP ระยะไกลจาก Gemini CLI

สิ่งที่คุณต้องดำเนินการ

เราจะใช้ Genkit เพื่อสร้างเซิร์ฟเวอร์ MCP ของสวนสัตว์ที่มีเครื่องมือ 2 อย่าง ได้แก่ get_animals_by_species และ get_animal_details Genkit มีวิธีที่รวดเร็วในการสร้างเซิร์ฟเวอร์และไคลเอ็นต์ MCP ด้วย Node.js

กราฟิกเซิร์ฟเวอร์ MCP ของสวนสัตว์

สิ่งที่คุณจะได้เรียนรู้

  • ติดตั้งใช้งานเซิร์ฟเวอร์ MCP ใน Cloud Run
  • รักษาความปลอดภัยให้กับปลายทางของเซิร์ฟเวอร์โดยกำหนดให้มีการตรวจสอบสิทธิ์สำหรับคำขอทั้งหมด เพื่อให้มั่นใจว่าเฉพาะไคลเอ็นต์และตัวแทนที่ได้รับอนุญาตเท่านั้นที่จะสื่อสารกับเซิร์ฟเวอร์ได้
  • เชื่อมต่อกับอุปกรณ์ปลายทางของเซิร์ฟเวอร์ MCP ที่ปลอดภัยจาก Gemini CLI

2. การตั้งค่าโปรเจ็กต์

  1. หากยังไม่มีบัญชี Google คุณต้องสร้างบัญชี Google
    • ใช้บัญชีส่วนตัวแทนบัญชีงานหรือบัญชีโรงเรียน บัญชีงานและบัญชีโรงเรียนอาจมีข้อจำกัดที่ทำให้คุณเปิดใช้ API ที่จำเป็นสำหรับ Lab นี้ไม่ได้
  2. ลงชื่อเข้าใช้ Google Cloud Console
  3. เปิดใช้การเรียกเก็บเงินใน Cloud Console
    • การทำ Lab นี้ควรมีค่าใช้จ่ายน้อยกว่า $1 USD ในทรัพยากรระบบคลาวด์
    • คุณสามารถทำตามขั้นตอนที่ส่วนท้ายของแล็บนี้เพื่อลบทรัพยากรเพื่อหลีกเลี่ยงการเรียกเก็บเงินเพิ่มเติม
    • ผู้ใช้ใหม่มีสิทธิ์ใช้ช่วงทดลองใช้ฟรีมูลค่า$300 USD
  4. สร้างโปรเจ็กต์ใหม่หรือเลือกใช้โปรเจ็กต์ที่มีอยู่ซ้ำ
    • หากเห็นข้อผิดพลาดเกี่ยวกับโควต้าโปรเจ็กต์ ให้ใช้โปรเจ็กต์ที่มีอยู่ซ้ำหรือลบโปรเจ็กต์ที่มีอยู่เพื่อสร้างโปรเจ็กต์ใหม่

3. เปิดเครื่องมือแก้ไข Cloud Shell

  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. เตรียมโปรเจ็กต์ 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 ของสวนสัตว์

หากต้องการให้บริบทที่มีประโยชน์ในการปรับปรุงการใช้ LLM กับ MCP ให้ตั้งค่าเซิร์ฟเวอร์ MCP ของสวนสัตว์ด้วย Genkit ซึ่งเป็นเฟรมเวิร์กมาตรฐานสำหรับการทำงานกับ Model Context Protocol Genkit มีวิธีที่รวดเร็วในการสร้างเซิร์ฟเวอร์และไคลเอ็นต์ MCP ด้วย Node.js เซิร์ฟเวอร์ MCP นี้ให้ข้อมูลเกี่ยวกับสัตว์ในสวนสัตว์สมมติ เราจัดเก็บข้อมูลไว้ในหน่วยความจำเพื่อให้ง่ายต่อการใช้งาน สำหรับเซิร์ฟเวอร์ MCP ที่ใช้งานจริง คุณอาจต้องการระบุข้อมูลจากแหล่งที่มา เช่น ฐานข้อมูลหรือ API

  1. เรียกใช้คำสั่งต่อไปนี้เพื่อเพิ่ม Genkit เป็นทรัพยากร Dependency ในไฟล์ package.json
    npm install genkit
    
    ซึ่งจะเป็นการเพิ่มไฟล์ package-lock.json ลงในโปรเจ็กต์
  2. เรียกใช้คำสั่งต่อไปนี้เพื่อเพิ่มไลบรารี MCP ของ Genkit AI ในไฟล์ 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 เพื่อเพิ่มเซิร์ฟเวอร์ MCP ของ Cloud Run
    {
        "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 Server และจะถามว่าคุณต้องการอนุญาตให้ดำเนินการ MCP หรือไม่
  4. ใช้ลูกศรลง แล้วกด Enter เพื่อเลือก
    Yes, always allow all tools from server "zoo-remote"
    
    Gemini CLI อนุญาตเครื่องมือระยะไกลของ Zoo

เอาต์พุตควรแสดงคำตอบที่ถูกต้องและกล่องแสดงที่ระบุว่าใช้เซิร์ฟเวอร์ MCP

Gemini CLI แสดงผลเซิร์ฟเวอร์ MCP ของสวนสัตว์

คุณทำสำเร็จแล้ว คุณติดตั้งใช้งานเซิร์ฟเวอร์ 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ใหม่ เนื่องจาก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 เป็นคําสั่ง Slash ที่กําหนดเองโดยอัตโนมัติเพื่อให้คุณเรียกใช้พรอมต์ 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 ที่สามารถให้เหตุผลเกี่ยวกับปัญหาที่ซับซ้อนในโค้ด คณิตศาสตร์ และ STEM รวมถึงวิเคราะห์ชุดข้อมูล ฐานของโค้ด และเอกสารขนาดใหญ่โดยใช้บริบทแบบยาว
  • Gemini 2.5 Flash เป็นโมเดลที่ดีที่สุดของ Google ในแง่ของราคาต่อประสิทธิภาพ โดยมีความสามารถที่ครอบคลุม 2.5 Flash เหมาะที่สุดสำหรับการประมวลผลขนาดใหญ่ งานที่มีเวลาในการตอบสนองต่ำและมีปริมาณมากซึ่งต้องใช้ความคิด และ Use Case ของเอเจนต์
  • 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 ระยะไกลเครื่องที่ 2 จากนั้นเพิ่มลงในการตั้งค่า 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 ระยะไกลที่ปลอดภัยเรียบร้อยแล้ว

ไปยัง Lab ถัดไป

ห้องทดลองนี้เป็นห้องทดลองแรกในชุด 3 ตอน ใน Lab ที่ 2 คุณจะได้ใช้เซิร์ฟเวอร์ MCP ที่สร้างด้วย ADK Agent

ใช้เซิร์ฟเวอร์ MCP ใน Cloud Run กับ Agent ประเภท 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