Terhubung ke server MCP Pengetahuan Developer menggunakan MCP SDK

SDK Model Context Protocol (MCP) resmi memungkinkan aplikasi dan agen AI Anda sendiri terhubung ke server MCP Developer Knowledge secara terprogram. Gunakan MCP SDK saat Anda membuat agen kustom, layanan backend, atau server MCP Anda sendiri yang perlu menelusuri dan mengambil dokumentasi developer Google resmi, bukan mengonfigurasi IDE atau asisten coding yang ada.

Dalam panduan ini, Anda akan mempelajari cara:

  • Menginstal SDK klien MCP untuk Python atau TypeScript.
  • Terhubung ke server MCP Pengetahuan Developer dengan kunci API atau Kredensial Default Aplikasi (ADC).
  • Panggil alat search_documents, get_documents, dan answer_query.
  • Menangani error autentikasi, kuota, dan alat.

Sebelum memulai

Sebelum memulai, selesaikan bagian berikut.

Mengaktifkan API dan membuat kredensial

Aktifkan Developer Knowledge API di project Google Cloud Anda dan buat kredensial untuk metode autentikasi Anda. Untuk mengetahui petunjuk langkah demi langkah, lihat Memilih metode autentikasi Anda.

Contoh dalam panduan ini menggunakan kunci API. Untuk menggunakan ADC, lihat Melakukan autentikasi dengan Kredensial Default Aplikasi.

Menginstal MCP SDK

Pilih bahasa pemrograman Anda untuk menginstal SDK klien MCP:

Python

Panduan ini menggunakan versi 2 MCP Python SDK, yang memerlukan Python 3.10 atau yang lebih baru. SDK versi 1.x menggunakan nama class dan fungsi yang berbeda, sehingga contoh ini tidak berfungsi dengannya:

pip install --upgrade "mcp>=2"

TypeScript

Panduan ini menggunakan MCP TypeScript SDK dengan Node.js 18 atau yang lebih baru:

npm install @modelcontextprotocol/sdk

Tetapkan kunci API Anda

Untuk menghindari hardcoding kunci API dalam kode sumber, simpan kunci API dalam variabel lingkungan. Ganti YOUR_API_KEY dengan kunci API Anda:

export DEVELOPERKNOWLEDGE_API_KEY="YOUR_API_KEY"

Hubungkan ke server

Server MCP Pengetahuan Developer menggunakan Transpor HTTP yang dapat di-streaming di endpoint berikut:

https://developerknowledge.googleapis.com/mcp

Untuk melakukan autentikasi, teruskan kunci API Anda di header HTTP X-Goog-Api-Key pada setiap permintaan. Jangan meneruskan kunci API sebagai parameter kueri URL.

Contoh berikut terhubung ke server dan mencantumkan alat yang tersedia:

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

Jika koneksi berhasil, output akan mencantumkan tiga alat:

Available tools: search_documents, answer_query, get_documents

Contoh lainnya dalam panduan ini berjalan di dalam klien yang terhubung dari bagian ini. Contoh TypeScript menggunakan await tingkat atas, jadi jalankan sebagai modul ES (misalnya, dengan npx tsx index.ts).

Memanggil alat

Setiap alat menampilkan hasilnya sebagai konten terstruktur yang cocok dengan skema output alat, sehingga Anda dapat membaca kolom secara langsung, bukan mengurai teks. Untuk skema input dan output lengkap, lihat referensi MCP.

Menelusuri dokumentasi

Panggil search_documents dengan string query untuk mengambil potongan dokumentasi yang paling relevan. Setiap hasil berisi chunk content dan nama resource parent dari dokumen asalnya:

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

Mengambil dokumen lengkap

Jika sebuah potongan tidak berisi konteks yang cukup, teruskan satu atau beberapa nilai parent ke get_documents untuk mengambil konten Markdown lengkap dari setiap halaman. Anda dapat meminta hingga 20 dokumen dalam satu panggilan. Karena beberapa potongan dapat berasal dari dokumen yang sama, hapus nilai parent duplikat terlebih dahulu:

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

Dokumen lengkap bisa berukuran besar, jadi panggil get_documents hanya jika potongan penelusuran tidak mencukupi. Untuk mempelajari lebih lanjut, lihat Mengoptimalkan penggunaan token dan jendela konteks.

Membuat jawaban

Panggil answer_query untuk menghasilkan jawaban yang didasarkan pada korpus Developer Knowledge. Hasilnya berisi answerText dan references yang digunakan untuk membuatnya:

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

Kolom references berisi nama resource dokumen yang dapat Anda teruskan ke get_documents. Dokumen yang sama dapat muncul lebih dari sekali, jadi hapus duplikat sebelum Anda mengambil dokumen. Alat answer_query memiliki kuota yang lebih rendah daripada alat lainnya. Untuk mempelajari lebih lanjut, lihat Kuota dan batas.

Melakukan autentikasi dengan Kredensial Default Aplikasi

Sebagai pengganti kunci API, Anda dapat melakukan autentikasi dengan Kredensial Default Aplikasi (ADC). ADC berfungsi dengan kredensial pengguna Anda selama pengembangan lokal dan dengan akun layanan saat kode Anda berjalan di Google Cloud.

Saat Anda menggunakan ADC, kirim header berikut pada setiap permintaan:

  • Authorization: token akses OAuth 2.0 Bearer dengan cakupan https://www.googleapis.com/auth/cloud-platform.
  • X-Goog-User-Project: ID project yang mengaktifkan Developer Knowledge API dan ditagih untuk kuota. Akun Anda memerlukan izin serviceusage.services.use di project ini.

Masa berlaku token akses akan berakhir, sehingga klien yang berjalan lama harus memperbaruinya. Contoh berikut menggunakan library autentikasi Google untuk menambahkan token saat ini ke setiap permintaan.

  1. Siapkan ADC untuk pengembangan lokal dengan mengikuti langkah-langkah di tab ADC di Pilih jenis kredensial OAuth Anda.

  2. Tetapkan variabel lingkungan GOOGLE_CLOUD_PROJECT ke project yang telah mengaktifkan Developer Knowledge API. Contoh mengirimkan project ID ini di header X-Goog-User-Project:

    export GOOGLE_CLOUD_PROJECT="PROJECT_ID"
    
  3. Instal library autentikasi Google untuk bahasa Anda:

    Python

    pip install --upgrade google-auth requests
    

    TypeScript

    npm install google-auth-library
    
  4. Buat klien dengan 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);
    

Menangani error

Error dari server MCP Pengetahuan Developer menjangkau kode Anda dengan dua cara:

  • Error permintaan: error autentikasi, izin, dan kuota ditampilkan dengan status error HTTP, seperti 400, 403, atau 429. SDK memunculkan ini sebagai pengecualian: MCPError di Python dan StreamableHTTPError di TypeScript. Tangkap pengecualian ini di sekitar panggilan alat Anda.
  • Error alat: saat alat berjalan tetapi tidak dapat menyelesaikan permintaan, hasilnya memiliki is_error (Python) atau isError (TypeScript) yang ditetapkan ke true, dan kolom content berisi deskripsi teks tentang masalah tersebut. Periksa kolom ini sebelum membaca konten terstruktur.

Contoh berikut menangani kedua jenis error:

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

Jika answer_query menampilkan error kuota (429 RESOURCE_EXHAUSTED), lakukan penggantian ke search_documents, yang memiliki kuota lebih tinggi. Untuk strategi percobaan ulang, termasuk backoff eksponensial, lihat Penanganan error dan pengelolaan kuota. Untuk mengetahui penyebab umum error autentikasi, lihat Error kunci API dan Error OAuth dan ADC.

Langkah berikutnya