MCP SDK'larını kullanarak Developer Knowledge MCP sunucusuna bağlanma

Resmi Model Context Protocol (MCP) SDK'ları, kendi uygulamalarınızın ve yapay zeka aracılarının Developer Knowledge MCP sunucusuna programatik olarak bağlanmasına olanak tanır. Mevcut bir IDE'yi veya kod yazma desteğini yapılandırmak yerine resmi Google Developers geliştirici belgelerini arayıp alması gereken özel bir temsilci, arka uç hizmeti veya kendi MCP sunucunuzu oluştururken MCP SDK'sı kullanın.

Bu kılavuzda şunları nasıl yapacağınızı öğreneceksiniz:

  • Python veya TypeScript için MCP istemci SDK'sını yükleyin.
  • API anahtarı veya Uygulama Varsayılan Kimlik Bilgileri (ADC) ile Developer Knowledge MCP sunucusuna bağlanın.
  • search_documents, get_documents ve answer_query araçlarını çağırın.
  • Kimlik doğrulama, kota ve araç hatalarını işleme

Başlamadan önce

Başlamadan önce aşağıdaki bölümleri tamamlayın.

API'yi etkinleştirme ve kimlik bilgileri oluşturma

Google Cloud projenizde Developer Knowledge API'yi etkinleştirin ve kimlik doğrulama yönteminiz için kimlik bilgilerini oluşturun. Adım adım talimatlar için Kimlik doğrulama yönteminizi seçme başlıklı makaleyi inceleyin.

Bu kılavuzdaki örneklerde API anahtarı kullanılmaktadır. Bunun yerine ADC'yi kullanmak için Uygulama Varsayılan Kimlik Bilgileri ile kimlik doğrulama başlıklı makaleyi inceleyin.

MCP SDK'sını yükleme

MCP istemci SDK'sını yüklemek için programlama dilinizi seçin:

Python

Bu kılavuzda, Python 3.10 veya sonraki sürümlerin gerekli olduğu MCP Python SDK'nın 2. sürümü kullanılmaktadır. SDK'nın 1.x sürümü farklı sınıf ve işlev adları kullandığından bu örnekler bu sürümle çalışmaz:

pip install --upgrade "mcp>=2"

TypeScript

Bu kılavuzda, Node.js 18 veya sonraki sürümlerle MCP TypeScript SDK'sı kullanılır:

npm install @modelcontextprotocol/sdk

API anahtarınızı ayarlama

API anahtarınızı kaynak koduna sabit kodlamamak için bir ortam değişkeninde saklayın. YOUR_API_KEY kısmını API anahtarınızla değiştirin:

export DEVELOPERKNOWLEDGE_API_KEY="YOUR_API_KEY"

Sunucuya bağlanma

Developer Knowledge MCP sunucusu, aşağıdaki uç noktada Streamable HTTP transport'u kullanır:

https://developerknowledge.googleapis.com/mcp

Kimlik doğrulamak için her istekte X-Goog-Api-Key HTTP başlığında API anahtarınızı iletin. API anahtarını URL sorgu parametresi olarak iletmeyin.

Aşağıdaki örnekte sunucuya bağlanılır ve kullanılabilir araçlar listelenir:

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();

Bağlantı başarılı olursa çıkışta üç araç listelenir:

Available tools: search_documents, answer_query, get_documents

Bu kılavuzun geri kalanındaki örnekler, bu bölümdeki bağlı istemci içinde çalıştırılır. TypeScript örneklerinde üst düzey await kullanıldığından bunları ES modülleri olarak (örneğin, npx tsx index.ts ile) çalıştırın.

Araçları çağırma

Her araç, sonucunu aracın çıkış şemasına uygun yapılandırılmış içerik olarak döndürür. Böylece, metni ayrıştırmak yerine alanları doğrudan okuyabilirsiniz. Giriş ve çıkış şemalarının tamamı için MCP referansına bakın.

Belgelerde arama yapma

En alakalı doküman parçalarını almak için search_documents işlevini query dizesiyle çağırın. Her sonuçta content parçası ve geldiği belgenin parent kaynak adı bulunur:

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`);
}

Tam belgeleri alma

Bir parça yeterli bağlam içermiyorsa her sayfanın tam Markdown içeriğini almak için get_documents işlevine bir veya daha fazla parent değeri iletin. Tek bir görüşmede en fazla 20 belge isteğinde bulunabilirsiniz. Aynı dokümandan birden fazla parça gelebileceğinden, önce yinelenen parent değerlerini kaldırın:

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);
}

Tam belgeler büyük olabilir. Bu nedenle, yalnızca arama parçaları yeterli olmadığında get_documents işlevini çağırın. Daha fazla bilgi edinmek için Bağlam penceresini ve jeton kullanımını optimize etme başlıklı makaleyi inceleyin.

Yanıt oluşturma

answer_query işlevini çağırarak Developer Knowledge corpus'a dayalı bir yanıt oluşturun. Sonuç, answerText ve bunu oluşturmak için kullanılan references içerir:

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 alanı, get_documents yöntemine iletebileceğiniz doküman kaynağı adlarını içerir. Aynı belge birden fazla kez görünebilir. Bu nedenle, belgeleri almadan önce yinelenenleri kaldırın. answer_query aracının kotası diğer araçlara göre daha düşüktür. Daha fazla bilgi için Kota ve sınırlar başlıklı makaleyi inceleyin.

Uygulama Varsayılan Kimlik Bilgileri ile kimlik doğrulama

API anahtarı yerine Uygulama Varsayılan Kimlik Bilgileri (ADC) ile kimlik doğrulayabilirsiniz. ADC, yerel geliştirme sırasında kullanıcı kimlik bilgilerinizle, kodunuz Google Cloud'da çalışırken ise hizmet hesaplarıyla çalışır.

ADC'yi kullanırken her istekte aşağıdaki üstbilgileri gönderin:

  • Authorization: https://www.googleapis.com/auth/cloud-platform kapsamına sahip bir Bearer OAuth 2.0 erişim jetonu.
  • X-Goog-User-Project: Developer Knowledge API'nin etkinleştirildiği ve kota için faturalandırılan projenin kimliği. Hesabınızın bu projede serviceusage.services.use iznine sahip olması gerekir.

Erişim jetonlarının süresi dolduğundan uzun süre çalışan istemcilerin bu jetonları yenilemesi gerekir. Aşağıdaki örneklerde, her isteğe geçerli bir jeton eklemek için Google kimlik doğrulama kitaplıkları kullanılmaktadır.

  1. OAuth kimlik bilgisi türünüzü seçin bölümündeki ADC sekmesinde yer alan adımları uygulayarak yerel geliştirme için ADC'yi ayarlayın.

  2. GOOGLE_CLOUD_PROJECT ortam değişkenini, Developer Knowledge API'nin etkin olduğu projeye ayarlayın. Örnekler, bu proje kimliğini X-Goog-User-Project üstbilgisinde gönderir:

    export GOOGLE_CLOUD_PROJECT="PROJECT_ID"
    
  3. Diliniz için Google kimlik doğrulama kitaplığını yükleyin:

    Python

    pip install --upgrade google-auth requests
    

    TypeScript

    npm install google-auth-library
    
  4. ADC ile istemciyi oluşturun:

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

Hataları işleme

Geliştirici Bilgisi MCP sunucusundan gelen hatalar kodunuza iki şekilde ulaşır:

  • İstek hataları: Kimlik doğrulama, izin ve kota hataları 400, 403 veya 429 gibi bir HTTP hata durumuyla döndürülür. SDK'lar bunları istisna olarak bildirir: Python'da MCPError ve TypeScript'te StreamableHTTPError. Araç çağrılarınızda bu istisnaları yakalayın.
  • Araç hataları: Bir araç çalıştırıldığında ancak isteği tamamlayamadığında sonuçta is_error (Python) veya isError (TypeScript) true olarak ayarlanır ve content alanında sorunun metin açıklaması yer alır. Yapılandırılmış içeriği okumadan önce bu alanı kontrol edin.

Aşağıdaki örnekte her iki hata türü de ele alınmaktadır:

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, kota hatası (429 RESOURCE_EXHAUSTED) döndürürse daha yüksek kotaya sahip olan search_documents'ye geri dönün. Eksponansiyel geri yükleme dahil olmak üzere yeniden deneme stratejileri için Hata işleme ve kota yönetimi başlıklı makaleyi inceleyin. Kimlik doğrulama hatalarının yaygın nedenleri için API anahtarı hataları ve OAuth ve ADC hataları bölümlerine bakın.

Sırada ne var?