ক্লাউড রানে কীভাবে একটি নিরাপদ জেনকিট এমসিপি সার্ভার স্থাপন করবেন

১. ভূমিকা

সংক্ষিপ্ত বিবরণ

এই ল্যাবে, আপনি একটি মডেল কনটেক্সট প্রোটোকল (MCP) সার্ভার তৈরি এবং ডেপ্লয় করবেন। LLM-দেরকে বাহ্যিক টুল ও পরিষেবাগুলিতে অ্যাক্সেস দেওয়ার জন্য MCP সার্ভারগুলি উপযোগী। আপনি এটিকে ক্লাউড রান-এ একটি সুরক্ষিত, প্রোডাকশন-রেডি পরিষেবা হিসাবে কনফিগার করবেন, যা একাধিক ক্লায়েন্ট থেকে অ্যাক্সেস করা যাবে। তারপর আপনি Gemini CLI থেকে রিমোট MCP সার্ভারটির সাথে সংযোগ স্থাপন করবেন।

আপনি যা করবেন

আমরা Genkit ব্যবহার করে একটি চিড়িয়াখানার MCP সার্ভার তৈরি করব, যেটিতে get_animals_by_species এবং get_animal_details এই দুটি টুল থাকবে। Genkit, Node.js দিয়ে দ্রুত MCP সার্ভার এবং ক্লায়েন্ট তৈরি করার একটি উপায় প্রদান করে।

চিড়িয়াখানা এমসিপি সার্ভার গ্রাফিক

আপনি যা শিখবেন

  • ক্লাউড রান-এ এমসিপি সার্ভারটি স্থাপন করুন।
  • সমস্ত অনুরোধের জন্য প্রমাণীকরণ বাধ্যতামূলক করে আপনার সার্ভারের এন্ডপয়েন্ট সুরক্ষিত করুন, যাতে শুধুমাত্র অনুমোদিত ক্লায়েন্ট এবং এজেন্টরাই এর সাথে যোগাযোগ করতে পারে।
  • Gemini CLI থেকে আপনার সুরক্ষিত MCP সার্ভার এন্ডপয়েন্টে সংযোগ করুন

২. প্রকল্প স্থাপন

  1. যদি আপনার আগে থেকে কোনো গুগল অ্যাকাউন্ট না থাকে, তাহলে আপনাকে অবশ্যই একটি গুগল অ্যাকাউন্ট তৈরি করতে হবে।
    • কর্মক্ষেত্র বা শিক্ষা প্রতিষ্ঠানের অ্যাকাউন্টের পরিবর্তে ব্যক্তিগত অ্যাকাউন্ট ব্যবহার করুন। কর্মক্ষেত্র এবং শিক্ষা প্রতিষ্ঠানে এমন কিছু সীমাবদ্ধতা থাকতে পারে, যার ফলে আপনি এই ল্যাবের জন্য প্রয়োজনীয় এপিআই (API) সক্রিয় করতে পারবেন না।
  2. গুগল ক্লাউড কনসোলে সাইন-ইন করুন।
  3. ক্লাউড কনসোলে বিলিং চালু করুন
    • এই ল্যাবটি সম্পন্ন করতে ক্লাউড রিসোর্সে ১ মার্কিন ডলারেরও কম খরচ হওয়া উচিত।
    • পরবর্তী চার্জ এড়াতে, এই ল্যাবের শেষে দেওয়া ধাপগুলো অনুসরণ করে আপনি রিসোর্সগুলো মুছে ফেলতে পারেন।
    • নতুন ব্যবহারকারীরা ৩০০ মার্কিন ডলারের ফ্রি ট্রায়ালের জন্য যোগ্য।
  4. একটি নতুন প্রজেক্ট তৈরি করুন অথবা বিদ্যমান কোনো প্রজেক্ট পুনরায় ব্যবহার করুন।
    • প্রজেক্ট কোটা সংক্রান্ত কোনো ত্রুটি দেখলে, একটি নতুন প্রজেক্ট তৈরি করার জন্য বিদ্যমান কোনো প্রজেক্ট পুনরায় ব্যবহার করুন অথবা আগের প্রজেক্টটি মুছে ফেলুন।

৩. ক্লাউড শেল এডিটর খুলুন

  1. সরাসরি ক্লাউড শেল এডিটর- এ যেতে এই লিঙ্কে ক্লিক করুন।
  2. আজ যেকোনো সময়ে অনুমোদনের জন্য অনুরোধ করা হলে, চালিয়ে যাওয়ার জন্য 'অনুমোদন করুন' (Authorize) বোতামে ক্লিক করুন। ক্লাউড শেল অনুমোদন করতে ক্লিক করুন
  3. যদি স্ক্রিনের নিচে টার্মিনালটি দেখা না যায়, তাহলে এটি খুলুন:
    • ভিউ ক্লিক করুন
    • টার্মিনালে ক্লিক করুন ক্লাউড শেল এডিটরে নতুন টার্মিনাল খুলুন
  4. টার্মিনালে এই কমান্ডটি দিয়ে আপনার প্রজেক্ট সেট করুন:
    • বিন্যাস:
      gcloud config set project [PROJECT_ID]
      
    • উদাহরণ:
      gcloud config set project lab-project-id-example
      
    • যদি আপনি আপনার প্রজেক্ট আইডি মনে করতে না পারেন:
      • আপনি আপনার সমস্ত প্রজেক্ট আইডি তালিকাভুক্ত করতে পারেন:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      ক্লাউড শেল এডিটর টার্মিনালে প্রজেক্ট আইডি সেট করুন
  5. আপনি এই বার্তাটি দেখতে পাবেন:
    Updated property [core/project].
    
    যদি আপনি একটি WARNING দেখতে পান এবং আপনাকে Do you want to continue (Y/n)? জিজ্ঞাসা করা হয়, তাহলে সম্ভবত আপনি প্রজেক্ট আইডি ভুলভাবে প্রবেশ করিয়েছেন। n চাপুন, Enter চাপুন এবং gcloud config set project কমান্ডটি আবার চালানোর চেষ্টা করুন।

৪. এপিআই সক্রিয় করুন

টার্মিনালে, এপিআইগুলো সক্রিয় করুন:

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

অনুমোদন করতে বলা হলে, চালিয়ে যাওয়ার জন্য 'Authorize'-এ ক্লিক করুন। ক্লাউড শেল অনুমোদন করতে ক্লিক করুন

এই কমান্ডটি সম্পন্ন হতে কয়েক মিনিট সময় লাগতে পারে, কিন্তু অবশেষে এটি এইটির মতো একটি সফলতার বার্তা দেবে:

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

৫. আপনার জাভাস্ক্রিপ্ট প্রজেক্ট প্রস্তুত করুন।

  1. ডিপ্লয়মেন্টের জন্য সোর্স কোড সংরক্ষণ করতে mcp-on-cloudrun নামে একটি ফোল্ডার তৈরি করুন:
    mkdir mcp-on-cloudrun && cd mcp-on-cloudrun
    
  2. package.json ফাইল তৈরি করার জন্য npm টুল ব্যবহার করে একটি Node.js প্রজেক্ট তৈরি করুন:
    npm init es6 -y
    
    npm init কমান্ডটি আপনার প্রোজেক্টের জন্য একটি package.json ফাইল তৈরি করে।
  3. @modelcontextprotocol/sdk , express , এবং zod ডিপেন্ডেন্সিগুলো ইনস্টল করুন:
    npm install @modelcontextprotocol/sdk express zod
    

৬. চিড়িয়াখানার এমসিপি সার্ভার তৈরি করুন

MCP-এর সাথে LLM-এর ব্যবহার উন্নত করার জন্য মূল্যবান প্রেক্ষাপট প্রদানের উদ্দেশ্যে, Genkit ব্যবহার করে একটি চিড়িয়াখানার MCP সার্ভার সেট আপ করুন — এটি মডেল কনটেক্সট প্রোটোকল (Model Context Protocol) নিয়ে কাজ করার একটি স্ট্যান্ডার্ড ফ্রেমওয়ার্ক। Genkit, Node.js ব্যবহার করে দ্রুত MCP সার্ভার এবং ক্লায়েন্ট তৈরি করার একটি উপায় প্রদান করে। এই MCP সার্ভারটি একটি কাল্পনিক চিড়িয়াখানার প্রাণীদের সম্পর্কে ডেটা সরবরাহ করে। সরলতার জন্য, আমরা ডেটা মেমরিতে সংরক্ষণ করি। একটি প্রোডাকশন MCP সার্ভারের জন্য, আপনি সম্ভবত ডেটাবেস বা API-এর মতো উৎস থেকে ডেটা সরবরাহ করতে চাইবেন।

  1. package.json ফাইলে Genkit-কে ডিপেন্ডেন্সি হিসেবে যোগ করতে নিম্নলিখিত কমান্ডটি চালান:
    npm install genkit
    
    এটি আপনার প্রজেক্টে একটি package-lock.json ফাইল যুক্ত করবে।
  2. package.json ফাইলে Genkit AI MCP লাইব্রেরি যোগ করতে নিম্নলিখিত কমান্ডটি চালান:
    npm install @genkit-ai/mcp
    
  3. MCP সার্ভার সোর্স কোডের জন্য একটি নতুন index.js ফাইল তৈরি করে খুলুন:
    cloudshell edit index.js
    
    cloudshell edit কমান্ডটি টার্মিনালের উপরের এডিটরে index.js ফাইলটি খুলবে।
  4. index.js ফাইলে নিম্নলিখিত zoo MCP সার্ভার সোর্স কোডটি যোগ করুন:
    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}`);
    });
    

আপনার কোড সম্পূর্ণ হয়েছে! এখন ক্লাউড রান-এ এমসিপি সার্ভারটি ডেপ্লয় করার সময় হয়েছে।

৭. ক্লাউড রান-এ ডেপ্লয় করা

এখন সরাসরি সোর্স কোড থেকে ক্লাউড রান-এ একটি এমসিপি সার্ভার ডেপ্লয় করুন।

  1. mcp-server-sa নামে একটি পরিষেবা অ্যাকাউন্ট তৈরি করুন:
    gcloud iam service-accounts create mcp-server-sa --display-name="MCP Server Service Account"
    
  2. অ্যাপ্লিকেশনটি ক্লাউড রানে ডেপ্লয় করতে gcloud কমান্ডটি চালান।
    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. একটি নতুন আর্টিফ্যাক্ট রেজিস্ট্রি রিপোজিটরি তৈরির বিষয়টি নিশ্চিত করুন। যেহেতু আপনি প্রথমবারের মতো সোর্স কোড থেকে ক্লাউড রান-এ ডিপ্লয় করছেন, আপনি দেখতে পাবেন:
    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 চাপুন, এটি আপনার ডেপ্লয়মেন্টের জন্য একটি আর্টিফ্যাক্ট রেজিস্ট্রি রিপোজিটরি তৈরি করবে। ক্লাউড রান সার্ভিসের জন্য এমসিপি সার্ভার ডকার কন্টেইনার সংরক্ষণের জন্য এটি প্রয়োজন।
  4. কয়েক মিনিট পর আপনি এইরকম একটি বার্তা দেখতে পাবেন:
    Service [zoo-mcp-server] revision [zoo-mcp-server-12345-abc] has been deployed and is serving 100 percent of traffic.
    

আপনি আপনার এমসিপি সার্ভারটি স্থাপন করেছেন। এখন আপনি এটি ব্যবহার করতে পারেন।

৮. জেমিনি সিএলআই-তে রিমোট এমসিপি সার্ভারটি যুক্ত করুন।

এখন যেহেতু আপনি সফলভাবে একটি রিমোট এমসিপি সার্ভার স্থাপন করেছেন, আপনি গুগল কোড অ্যাসিস্ট বা জেমিনি সিএলআই-এর মতো বিভিন্ন অ্যাপ্লিকেশন ব্যবহার করে এটির সাথে সংযোগ করতে পারেন। এই অংশে, আমরা জেমিনি সিএলআই ব্যবহার করে আপনার নতুন রিমোট এমসিপি সার্ভারের সাথে একটি সংযোগ স্থাপন করব।

  1. আপনার ব্যবহারকারী অ্যাকাউন্টকে রিমোট এমসিপি সার্ভার কল করার অনুমতি দিন।
    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member=user:$(gcloud config get-value account) \
        --role='roles/run.invoker'
    
  2. জেমিনি সেটিংস ফাইলে ব্যবহারের জন্য আপনার গুগল ক্লাউড ক্রেডেনশিয়াল এবং প্রজেক্ট নম্বর এনভায়রনমেন্ট ভেরিয়েবলে সংরক্ষণ করুন:
    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. Cloud Run MCP সার্ভার যোগ করতে আপনার Gemini CLI সেটিংস ফাইলটি প্রতিস্থাপন করুন।
    {
        "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
    
    কিছু ডিফল্ট সেটিংস গ্রহণ করার জন্য আপনাকে Enter চাপতে হতে পারে। জেমিনি সিএলআই প্রাথমিক দৃশ্য
  2. জেমিনিকে তার প্রেক্ষাপটের মধ্যে উপলব্ধ এমসিপি টুলগুলির একটি তালিকা তৈরি করতে বলুন।
    /mcp
    
  3. চিড়িয়াখানায় কিছু খুঁজে বের করতে মিথুন রাশিকে বলুন।
    Where can I find penguins?
    
    Gemini CLI-কে zoo-remote MCP সার্ভারটি ব্যবহার করতে জানতে হবে এবং এটি আপনাকে জিজ্ঞাসা করবে যে আপনি MCP চালানোর অনুমতি দিতে চান কিনা।
  4. নির্বাচন করতে ডাউন অ্যারো ব্যবহার করুন, তারপর Enter চাপুন।
    Yes, always allow all tools from server "zoo-remote"
    
    জেমিনি সিএলআই চিড়িয়াখানার রিমোট টুলগুলিকে অনুমতি দেয়

আউটপুটে সঠিক উত্তর এবং একটি ডিসপ্লে বক্স দেখানো উচিত, যা থেকে বোঝা যাবে যে এমসিপি সার্ভারটি ব্যবহার করা হয়েছে।

Gemini CLI show zoo mcp server result

আপনি পেরেছেন! আপনি সফলভাবে ক্লাউড রান-এ একটি রিমোট এমসিপি সার্ভার ডেপ্লয় করেছেন এবং জেমিনি সিএলআই ব্যবহার করে এটি পরীক্ষা করেছেন।

আপনার সেশন শেষ করার জন্য, /quit টাইপ করুন এবং তারপর Gemini CLI থেকে বের হতে Enter চাপুন।

ডিবাগিং

আপনি যদি এই ধরনের কোনো ত্রুটি দেখতে পান:

🔍 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. Gemini CLI থেকে বের হতে /quit টাইপ করুন এবং তারপরে Enter চাপুন।
  2. আপনার টার্মিনালে আপনার প্রজেক্টটি সেট করুন।
    gcloud config set project [PROJECT_ID]
    
  3. যেহেতু আপনার ID_TOKEN-টির মেয়াদ শেষ হয়ে গিয়ে থাকতে পারে, তাই একটি নতুন ID_TOKEN পেতে Google Cloud credentials কমান্ডটি পুনরায় চালান।
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    export ID_TOKEN=$(gcloud auth print-identity-token)
    

৯. (ঐচ্ছিক) সার্ভার লগ-এ টুল কলগুলো যাচাই করুন

আপনার ক্লাউড রান এমসিপি সার্ভারটি কল করা হয়েছিল কিনা তা যাচাই করতে, পরিষেবা লগগুলি পরীক্ষা করুন।

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'

১০. (ঐচ্ছিক) সার্ভারে এমসিপি প্রম্পট যোগ করুন

একটি এমসিপি প্রম্পট দীর্ঘ প্রম্পটের সংক্ষিপ্ত রূপ তৈরি করার মাধ্যমে, আপনার প্রায়শই চালানো প্রম্পটগুলোর কর্মপ্রবাহকে দ্রুততর করতে পারে।

Gemini CLI স্বয়ংক্রিয়ভাবে MCP প্রম্পটগুলিকে কাস্টম স্ল্যাশ কমান্ডে রূপান্তর করে, যাতে আপনি /prompt_name টাইপ করে একটি MCP প্রম্পট চালু করতে পারেন, যেখানে prompt_name হলো আপনার MCP প্রম্পটের নাম।

একটি MCP প্রম্পট তৈরি করুন, যাতে Gemini CLI-তে /find animal টাইপ করে আপনি চিড়িয়াখানার কোনো প্রাণী দ্রুত খুঁজে নিতে পারেন।

  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. আপনার অ্যাপ্লিকেশনটি ক্লাউড রানে পুনরায় স্থাপন করুন
    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 রিফ্রেশ করুন।
    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.

১১. (ঐচ্ছিক) দ্রুত প্রতিক্রিয়ার জন্য জেমিনি ফ্ল্যাশ লাইট ব্যবহার করুন।

Gemini CLI আপনাকে আপনার ব্যবহৃত মডেলটি বেছে নিতে দেয়।

  • জেমিনি ২.৫ প্রো হলো গুগলের একটি অত্যাধুনিক চিন্তন মডেল, যা কোড, গণিত এবং STEM-এর জটিল সমস্যা নিয়ে যুক্তি-তর্ক করতে সক্ষম, পাশাপাশি দীর্ঘ প্রেক্ষাপট ব্যবহার করে বিশাল ডেটাসেট, কোডবেস এবং ডকুমেন্ট বিশ্লেষণ করতে পারে।
  • মূল্য ও কার্যক্ষমতার দিক থেকে জেমিনি ২.৫ ফ্ল্যাশ হলো গুগলের সেরা মডেল, যা বহুমুখী সক্ষমতা প্রদান করে। বৃহৎ পরিসরের প্রসেসিং, স্বল্প-লেটেন্সি, চিন্তাভাবনার প্রয়োজন হয় এমন বিপুল পরিমাণ কাজ এবং এজেন্টিক ব্যবহারের ক্ষেত্রে ২.৫ ফ্ল্যাশ সবচেয়ে উপযুক্ত।
  • জেমিনি ২.৫ ফ্ল্যাশ লাইট হলো গুগলের দ্রুততম ফ্ল্যাশ মডেল, যা ব্যয়-সাশ্রয় এবং উচ্চ কার্যক্ষমতার জন্য বিশেষভাবে তৈরি।

যেহেতু চিড়িয়াখানার প্রাণী খোঁজার অনুরোধগুলোর জন্য চিন্তা বা যুক্তির প্রয়োজন হয় না, তাই একটি দ্রুততর মডেল ব্যবহার করে কাজটি দ্রুত করার চেষ্টা করুন।

একটি MCP প্রম্পট তৈরি করুন, যাতে Gemini CLI-তে /find animal টাইপ করে আপনি চিড়িয়াখানার কোনো প্রাণী দ্রুত খুঁজে নিতে পারেন।

  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.

নিজেকে যাচাই করার জন্য উচ্চাকাঙ্ক্ষী লক্ষ্য

বাড়তি চ্যালেঞ্জ হিসেবে, চিড়িয়াখানার নির্দিষ্ট প্রাণী প্রজাতি সম্পর্কে মজার তথ্য বলার জন্য একই ধাপগুলো অনুসরণ করে একটি নির্দেশিকা তৈরি করার চেষ্টা করুন।

অথবা, আপনি যা শিখেছেন তা পরীক্ষা করার জন্য আরও বড় একটি পদক্ষেপ হিসেবে, এমন একটি টুলের ধারণা নিয়ে আসুন যা আপনি প্রায়শই ব্যবহার করবেন এবং একটি দ্বিতীয় রিমোট এমসিপি সার্ভার স্থাপন করুন। তারপর এটি কাজ করে কিনা তা দেখতে আপনার জেমিনি সিএলআই সেটিংসে এটি যোগ করুন।

ডিবাগিং

আপনি যদি এই ধরনের কোনো ত্রুটি দেখতে পান:

✕ 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)

১২. উপসংহার

অভিনন্দন! আপনি সফলভাবে একটি সুরক্ষিত রিমোট এমসিপি সার্ভার স্থাপন এবং এর সাথে সংযুক্ত হয়েছেন।

পরবর্তী ল্যাবে যান

এই ল্যাবটি তিন পর্বের একটি সিরিজের প্রথম ল্যাব। দ্বিতীয় ল্যাবে, আপনি একটি ADK এজেন্টের সাথে আপনার তৈরি করা MCP সার্ভারটি ব্যবহার করবেন।

ক্লাউড রানে একটি ADK এজেন্টের সাথে একটি MCP সার্ভার ব্যবহার করুন

(ঐচ্ছিক) পরিষ্কার করা

আপনি যদি পরবর্তী ল্যাবে অগ্রসর না হন এবং আপনার তৈরি করা কাজগুলো গুছিয়ে নিতে চান, তাহলে অতিরিক্ত চার্জ এড়ানোর জন্য আপনার ক্লাউড প্রজেক্টটি ডিলিট করে দিতে পারেন।

পরিষেবাটি ব্যবহার না করা হলে ক্লাউড রান কোনো চার্জ না করলেও, আর্টিফ্যাক্ট রেজিস্ট্রি-তে কন্টেইনার ইমেজ সংরক্ষণের জন্য আপনাকে চার্জ করা হতে পারে। আপনার ক্লাউড প্রজেক্টটি ডিলিট করে দিলে সেই প্রজেক্টের মধ্যে ব্যবহৃত সমস্ত রিসোর্সের বিলিং বন্ধ হয়ে যায়।

আপনি চাইলে প্রজেক্টটি মুছে ফেলতে পারেন:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

আপনি আপনার ক্লাউডশেল ডিস্ক থেকে অপ্রয়োজনীয় রিসোর্সগুলো মুছে ফেলতে চাইতে পারেন। আপনি তা করতে পারেন:

  1. কোডল্যাব প্রজেক্ট ডিরেক্টরিটি মুছে ফেলুন:
    rm -rf ~/mcp-on-cloudrun
    
  2. সতর্কীকরণ! এই পরবর্তী কাজটি পূর্বাবস্থায় ফেরানো যাবে না! জায়গা খালি করার জন্য আপনি যদি আপনার ক্লাউড শেলের সবকিছু মুছে ফেলতে চান, তাহলে আপনি আপনার সম্পূর্ণ হোম ডিরেক্টরিটি ডিলিট করে দিতে পারেন। খেয়াল রাখবেন, আপনি যা কিছু রাখতে চান তা যেন অন্য কোথাও সেভ করা থাকে।
    sudo rm -rf $HOME