MCP SDK ব্যবহার করে Developer Knowledge MCP সার্ভারে কানেক্ট করা

অফিসিয়াল মডেল কন্টেক্সট প্রোটোকল (MCP) SDK আপনার নিজস্ব অ্যাপ্লিকেশন ও AI এজেন্টকে প্রোগ্রাম্যাটিক উপায়ে Developer Knowledge MCP সার্ভারের সাথে কানেক্ট করতে দেয়। আপনি যখন কোনও কাস্টম এজেন্ট, ব্যাকএন্ড পরিষেবা বা আপনার নিজস্ব MCP সার্ভার তৈরি করছেন, তখন একটি MCP SDK ব্যবহার করুন। এটি অফিসিয়াল Google ডেভেলপার ডকুমেন্টেশন সার্চ এবং রিট্রিভ করার জন্য প্রয়োজন, যা আগে থেকে থাকা IDE বা কোডিং অ্যাসিস্ট্যান্ট কনফিগার করার চেয়ে বেশি কার্যকর।

এই নির্দেশিকা থেকে আপনি এগুলি সম্পর্কে জানতে পারবেন:

  • Python বা TypeScript-এর জন্য MCP ক্লায়েন্ট SDK ইনস্টল করুন।
  • API কী বা অ্যাপ্লিকেশন ডিফল্ট ক্রেডেনশিয়াল (ADC) ব্যবহার করে ডেভেলপার নলেজ MCP সার্ভারে কানেক্ট করুন।
  • search_documents, get_documents ও answer_query টুল কল করুন।
  • যাচাইকরণ, কোটা ও টুল সংক্রান্ত সমস্যা সমাধান করা।

শুরু করার আগে

শুরু করার আগে, নিম্নলিখিত বিভাগগুলি সম্পূর্ণ করুন।

API চালু করুন এবং ক্রেডেনশিয়াল তৈরি করুন

আপনার Google Cloud প্রোজেক্টে Developer Knowledge API চালু করুন এবং আপনার যাচাইকরণ পদ্ধতির জন্য ক্রেডেনশিয়াল তৈরি করুন। ধাপে-ধাপে দেওয়া নির্দেশাবলীর জন্য, আপনার যাচাইকরণ পদ্ধতি বেছে নিন দেখুন।

এই গাইডের উদাহরণে API key ব্যবহার করা হয়েছে। পরিবর্তে ADC ব্যবহার করতে, অ্যাপ্লিকেশন ডিফল্ট ক্রেডেনশিয়ালের মাধ্যমে যাচাই করুন দেখুন।

MCP SDK ইনস্টল করুন

MCP ক্লায়েন্ট SDK ইনস্টল করতে আপনার প্রোগ্রামিং ভাষা বেছে নিন:

Python

এই গাইডে MCP Python SDK-এর ভার্সন ২ ব্যবহার করা হয়, যার জন্য Python 3.10 বা তার পরের ভার্সন প্রয়োজন। SDK-এর 1.x ভার্সন আলাদা ক্লাস ও ফাংশনের নাম ব্যবহার করে, তাই এইসব উদাহরণ এর সাথে কাজ করে না:

pip install --upgrade "mcp>=2"

TypeScript

এই নির্দেশিকা Node.js 18 বা তার পরবর্তী ভার্সনের সাথে MCP TypeScript SDK ব্যবহার করে:

npm install @modelcontextprotocol/sdk

আপনার API key সেট করুন

সোর্স কোডে API কী হার্ডকোড করা এড়াতে, এটি একটি এনভায়রনমেন্ট ভেরিয়েবলে স্টোর করুন। আপনার API key দিয়ে YOUR_API_KEY পরিবর্তন করুন:

export DEVELOPERKNOWLEDGE_API_KEY="YOUR_API_KEY"

সার্ভারে কানেক্ট করুন

Developer Knowledge MCP সার্ভার নিম্নলিখিত এন্ডপয়েন্টে স্ট্রিমেবল HTTP ট্রান্সপোর্ট ব্যবহার করে:

https://developerknowledge.googleapis.com/mcp

যাচাইকরণ করতে, প্রতিটি অনুরোধে X-Goog-Api-Key HTTP হেডারে আপনার API কী পাস করুন। URL কোয়েরি প্যারামিটার হিসেবে API key পাস করবেন না।

নিচে দেওয়া উদাহরণটি সার্ভারের সাথে কানেক্ট করে এবং উপলভ্য টুলের তালিকা দেখায়:

Python

import asyncio
import os

from mcp import Client
from mcp.client.streamable_http import (
    create_mcp_http_client,
    streamable_http_client,
)

MCP_URL = "https://developerknowledge.googleapis.com/mcp"

async def main() -> None:
    headers = {"X-Goog-Api-Key": os.environ["DEVELOPERKNOWLEDGE_API_KEY"]}

    async with create_mcp_http_client(headers=headers) as http_client:
        transport = streamable_http_client(MCP_URL, http_client=http_client)
        async with Client(transport) as client:
            tools = await client.list_tools()
            names = ", ".join(tool.name for tool in tools.tools)
            print("Available tools:", names)

if __name__ == "__main__":
    asyncio.run(main())

TypeScript

import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import {
  StreamableHTTPClientTransport,
} from '@modelcontextprotocol/sdk/client/streamableHttp.js';

const apiKey = process.env.DEVELOPERKNOWLEDGE_API_KEY;
if (!apiKey) {
  throw new Error('Set the DEVELOPERKNOWLEDGE_API_KEY variable.');
}

const transport = new StreamableHTTPClientTransport(
  new URL('https://developerknowledge.googleapis.com/mcp'),
  { requestInit: { headers: { 'X-Goog-Api-Key': apiKey } } },
);

const client = new Client({ name: 'my-docs-agent', version: '1.0.0' });
await client.connect(transport);

const { tools } = await client.listTools();
console.log('Available tools:', tools.map((tool) => tool.name).join(', '));

await client.close();

কানেকশন সফল হলে, আউটপুটে তিনটি টুলের তালিকা দেখানো হবে:

Available tools: search_documents, answer_query, get_documents

এই নির্দেশিকায় বাকি উদাহরণগুলি এই বিভাগ থেকে কানেক্ট করা ক্লায়েন্টের মধ্যে রান করে। TypeScript উদাহরণে টপ-লেভেল await ব্যবহার করা হয়, তাই সেগুলি ES মডিউল হিসেবে রান করান (যেমন, npx tsx index.ts-এর মাধ্যমে)।

টুল কল করুন

প্রতিটি টুল তার ফলাফলকে স্ট্রাকচার্ড কন্টেন্ট হিসেবে রিটার্ন করে যা টুলের আউটপুট স্কিমার সাথে ম্যাচ করে, তাই আপনি টেক্সট পার্স না করেই সরাসরি ফিল্ড পড়তে পারবেন। সম্পূর্ণ ইনপুট ও আউটপুট স্কিমার জন্য, MCP রেফারেন্স দেখুন।

ডকুমেন্টেশন সার্চ করুন

সবচেয়ে প্রাসঙ্গিক ডকুমেন্টেশন চ্যাঙ্ক রিট্রিভ করতে query স্ট্রিং সহ search_documents-এ কল করুন। প্রতিটি ফলাফলে চাঙ্ক content এবং যে ডকুমেন্ট থেকে এটি এসেছে তার parent রিসোর্সের নাম থাকে:

Python

search = await client.call_tool(
    "search_documents",
    {"query": "How do I create a Cloud Storage bucket?"},
)
results = search.structured_content["results"]
for chunk in results[:3]:
    print(f"{chunk['parent']}\n{chunk['content'][:200]}...\n")

TypeScript

const search = await client.callTool({
  name: 'search_documents',
  arguments: { query: 'How do I create a Cloud Storage bucket?' },
});
const { results } = search.structuredContent as {
  results: { parent: string; id: string; content: string }[];
};
for (const chunk of results.slice(0, 3)) {
  console.log(`${chunk.parent}\n${chunk.content.slice(0, 200)}...\n`);
}

সম্পূর্ণ ডকুমেন্ট ফিরিয়ে আনুন

কোনও চঙ্কে পর্যাপ্ত প্রসঙ্গ না থাকলে, প্রতিটি পৃষ্ঠার সম্পূর্ণ মার্কডাউন কন্টেন্ট পেতে, এক বা একাধিক parent ভ্যালু get_documents-এ পাস করুন। আপনি একটি কলে সর্বাধিক ২০টি ডকুমেন্টের জন্য অনুরোধ করতে পারবেন। কারণ একই ডকুমেন্ট থেকে একাধিক চ্যাঙ্ক আসতে পারে, তাই প্রথমে ডুপ্লিকেট parent ভ্যালু সরিয়ে দিন:

Python

names = list(dict.fromkeys(chunk["parent"] for chunk in results[:3]))
get = await client.call_tool("get_documents", {"names": names})
for document in get.structured_content["documents"]:
    print(f"{document['title']} ({document['uri']})")
    print(document["content"])

TypeScript

const names = [...new Set(results.slice(0, 3).map((c) => c.parent))];
const get = await client.callTool({
  name: 'get_documents',
  arguments: { names },
});
const { documents } = get.structuredContent as {
  documents: {
    name: string;
    uri: string;
    title: string;
    content: string;
  }[];
};
for (const document of documents) {
  console.log(`${document.title} (${document.uri})`);
  console.log(document.content);
}

সম্পূর্ণ ডকুমেন্ট বড় হতে পারে, তাই সার্চ চাঙ্ক যথেষ্ট না হলে তবেই get_documents কল করুন। আরও জানতে, কন্টেক্সট উইন্ডো ও টোকেন ব্যবহার অপ্টিমাইজ করুন নিবন্ধটি দেখুন।

উত্তর জেনারেট করা

ডেভেলপার নলেজ কর্পাস-এ গ্রাউন্ডেড উত্তর জেনারেট করতে answer_query কল করুন। ফলাফলে এটি জেনারেট করতে ব্যবহৃত answerText ও references রয়েছে:

Python

answer = await client.call_tool(
    "answer_query",
    {"query": "How do I create a Cloud Storage bucket?"},
)
print(answer.structured_content["answerText"])
for reference in answer.structured_content["references"]:
    print(reference)

TypeScript

const answer = await client.callTool({
  name: 'answer_query',
  arguments: { query: 'How do I create a Cloud Storage bucket?' },
});
const { answerText, references } = answer.structuredContent as {
  answerText: string;
  references: string[];
};
console.log(answerText);
console.log(references.join('\n'));

references ফিল্ডে ডকুমেন্ট রিসোর্সের নাম থাকে যা আপনি get_documents-এ পাস করতে পারেন। একই ডকুমেন্ট একাধিকবার দেখা যেতে পারে, তাই ডকুমেন্ট ফিরিয়ে আনার আগে ডুপ্লিকেট ডকুমেন্ট সরিয়ে দিন। answer_query টুলের কোটা অন্যান্য টুলের থেকে কম। আরও জানতে, কোটা ও সীমা দেখুন।

অ্যাপ্লিকেশন ডিফল্ট ক্রেডেনশিয়ালের মাধ্যমে যাচাই করুন

API key-এর পরিবর্তে, আপনি অ্যাপ্লিকেশন ডিফল্ট ক্রেডেনশিয়াল (ADC)-এর মাধ্যমে যাচাই করতে পারবেন। লোকাল ডেভেলপমেন্টের সময় ADC আপনার ব্যবহারকারীর ক্রেডেনশিয়াল এবং Google Cloud-এ আপনার কোড রান করার সময় পরিষেবা অ্যাকাউন্টের সাথে কাজ করে।

ADC ব্যবহার করার সময়, প্রতিটি অনুরোধে নিম্নলিখিত হেডার পাঠান:

  • Authorization: https://www.googleapis.com/auth/cloud-platform স্কোপ সহ Bearer OAuth 2.0 অ্যাক্সেস টোকেন।
  • X-Goog-User-Project: Developer Knowledge API চালু আছে এবং কোটার জন্য বিল করা হয় এমন প্রোজেক্টের আইডি এই প্রোজেক্টে আপনার অ্যাকাউন্টের serviceusage.services.use অনুমতি প্রয়োজন।

অ্যাক্সেস টোকেনের মেয়াদ শেষ হয়ে যায়, তাই দীর্ঘ সময় ধরে চলা ক্লায়েন্টকে অবশ্যই সেগুলি রিফ্রেশ করতে হবে। নিম্নলিখিত উদাহরণগুলি প্রতিটি অনুরোধে একটি বর্তমান টোকেন যোগ করতে Google প্রমাণীকরণ লাইব্রেরি ব্যবহার করে।

  1. আপনার OAuth ক্রেডেনশিয়ালের ধরন বেছে নিন-এ ADC ট্যাবের ধাপগুলি অনুসরণ করে লোকাল ডেভেলপমেন্টের জন্য ADC সেট-আপ করুন।

  2. যে প্রোজেক্টে Developer Knowledge API চালু করা আছে, সেটির জন্য GOOGLE_CLOUD_PROJECT এনভায়রনমেন্ট ভেরিয়েবল সেট করুন। উদাহরণে এই প্রোজেক্ট আইডিটি X-Goog-User-Project হেডার হিসেবে পাঠানো হয়েছে:

    export GOOGLE_CLOUD_PROJECT="PROJECT_ID"
    
  3. আপনার ভাষার জন্য Google যাচাইকরণ লাইব্রেরি ইনস্টল করুন:

    Python

    pip install --upgrade google-auth requests
    

    TypeScript

    npm install google-auth-library
    
  4. ADC-এর সাহায্যে ক্লায়েন্ট তৈরি করুন:

    Python

    import os
    
    import google.auth
    import google.auth.transport.requests
    import httpx2  # Installed automatically with mcp>=2
    from mcp import Client
    from mcp.client.streamable_http import (
        create_mcp_http_client,
        streamable_http_client,
    )
    
    MCP_URL = "https://developerknowledge.googleapis.com/mcp"
    
    class GoogleCredentialsAuth(httpx2.Auth):
        """Adds a current ADC access token and quota project to requests."""
    
        def __init__(self, project_id: str) -> None:
            self.credentials, _ = google.auth.default(
                scopes=["https://www.googleapis.com/auth/cloud-platform"]
            )
            self.project_id = project_id
    
        def auth_flow(self, request):
            if not self.credentials.valid:
                self.credentials.refresh(
                    google.auth.transport.requests.Request()
                )
            request.headers["Authorization"] = (
                f"Bearer {self.credentials.token}"
            )
            request.headers["X-Goog-User-Project"] = self.project_id
            yield request
    
    async def main() -> None:
        auth = GoogleCredentialsAuth(os.environ["GOOGLE_CLOUD_PROJECT"])
        async with create_mcp_http_client(auth=auth) as http_client:
            transport = streamable_http_client(
                MCP_URL, http_client=http_client
            )
            async with Client(transport) as client:
                ...
    

    TypeScript

    import { GoogleAuth } from 'google-auth-library';
    import { Client } from '@modelcontextprotocol/sdk/client/index.js';
    import {
      StreamableHTTPClientTransport,
    } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
    
    const auth = new GoogleAuth({
      scopes: 'https://www.googleapis.com/auth/cloud-platform',
    });
    const projectId = process.env.GOOGLE_CLOUD_PROJECT;
    if (!projectId) {
      throw new Error('Set the GOOGLE_CLOUD_PROJECT variable.');
    }
    
    const transport = new StreamableHTTPClientTransport(
      new URL('https://developerknowledge.googleapis.com/mcp'),
      {
        // Add a current access token and the quota project to each request.
        fetch: async (url, init) => {
          const headers = new Headers(init?.headers);
          for (const [name, value] of await auth.getRequestHeaders()) {
            headers.set(name, value);
          }
          headers.set('X-Goog-User-Project', projectId);
          return fetch(url, { ...init, headers });
        },
      },
    );
    
    const client = new Client({ name: 'my-docs-agent', version: '1.0.0' });
    await client.connect(transport);
    

সমস্যা ম্যানেজ করা

Developer Knowledge MCP সার্ভার থেকে আপনার কোডে দুইভাবে সমস্যা পৌঁছায়:

  • অনুরোধ সংক্রান্ত সমস্যা: যাচাইকরণ, অনুমতি ও কোটা সংক্রান্ত সমস্যা HTTP সংক্রান্ত সমস্যার স্ট্যাটাস সহ ফেরত দেওয়া হয়, যেমন 400, 403 বা 429। SDK এগুলিকে ব্যতিক্রম হিসেবে দেখায়: Python-এ MCPError এবং TypeScript-এ StreamableHTTPError। আপনার টুল কলের আশেপাশে এইসব ব্যতিক্রমী ঘটনা লক্ষ্য করুন।
  • টুল সংক্রান্ত সমস্যা: কোনও টুল রান করলেও অনুরোধ সম্পূর্ণ করতে না পারলে, ফলাফলে is_error (Python) বা isError (TypeScript) true-এ সেট করা থাকে এবং content ফিল্ডে সমস্যার টেক্সট বিবরণ থাকে। স্ট্রাকচার্ড কন্টেন্ট পড়ার আগে এই ফিল্ড চেক করে নিন।

নিচের উদাহরণে দুই ধরনের সমস্যার সমাধান করা হয়েছে:

Python

from mcp import MCPError

try:
    result = await client.call_tool(
        "search_documents", {"query": "Cloud Storage buckets"}
    )
except MCPError as error:
    print(f"Request failed ({error.code}): {error.message}")
else:
    if result.is_error:
        print("Tool error:", result.content)
    else:
        results = result.structured_content["results"]

TypeScript

import {
  StreamableHTTPError,
} from '@modelcontextprotocol/sdk/client/streamableHttp.js';

try {
  const result = await client.callTool({
    name: 'search_documents',
    arguments: { query: 'Cloud Storage buckets' },
  });
  if (result.isError) {
    console.error('Tool error:', result.content);
  } else {
    const { results } = result.structuredContent as {
      results: { parent: string; id: string; content: string }[];
    };
  }
} catch (error) {
  if (error instanceof StreamableHTTPError) {
    console.error(`Request failed (${error.code}): ${error.message}`);
  } else {
    throw error;
  }
}

answer_query কোটা সংক্রান্ত সমস্যা (429 RESOURCE_EXHAUSTED) দেখালে, search_documents-এ ফিরে যান, যেখানে কোটা বেশি আছে। এক্সপোনেনশিয়াল ব্যাকঅফ সহ আবার চেষ্টা করার কৌশল সম্পর্কে জানতে, সমস্যার সমাধান ও কোটা ম্যানেজমেন্ট দেখুন। যাচাইকরণ সংক্রান্ত সমস্যার সাধারণ কারণের জন্য, API কী সংক্রান্ত সমস্যা এবং OAuth ও ADC সংক্রান্ত সমস্যা দেখুন।

এর পরে কী করতে হবে