Oficjalne pakiety SDK Model Context Protocol (MCP) umożliwiają aplikacjom i agentom AI programowe łączenie się z serwerem Developer Knowledge MCP. Użyj pakietu SDK MCP, gdy tworzysz niestandardowego agenta, usługę backendu lub własny serwer MCP, który musi wyszukiwać i pobierać oficjalną dokumentację dla deweloperów Google Developers, zamiast konfigurować istniejące IDE lub wspomaganie kodowania.
Z tego przewodnika dowiesz się, jak:
- zainstalować pakiet SDK klienta MCP dla Pythona lub TypeScripta;
- połączyć się z serwerem Developer Knowledge MCP za pomocą klucza interfejsu API lub domyślnego uwierzytelniania aplikacji (ADC);
- wywoływać narzędzia
search_documents,get_documentsianswer_query; - obsługiwać błędy uwierzytelniania, limity i błędy narzędzi.
Zanim zaczniesz
Zanim zaczniesz, wykonaj czynności opisane w tych sekcjach.
Włączanie interfejsu API i tworzenie danych logowania
Włącz Developer Knowledge API w projekcie w chmurze Google Cloud i utwórz dane logowania dla metody uwierzytelniania. Szczegółowe instrukcje znajdziesz w artykule refer to Wybieranie metody uwierzytelniania.
Przykłady w tym przewodniku używają klucza interfejsu API. Aby zamiast tego użyć ADC, zapoznaj się z artykułem Uwierzytelnianie za pomocą domyślnego uwierzytelniania aplikacji.
Instalowanie pakietu SDK MCP
Aby zainstalować pakiet SDK klienta MCP, wybierz język programowania:
Python
W tym przewodniku używamy pakietu SDK MCP dla Pythona w wersji 2, która wymaga Pythona w wersji 3.10 lub nowszej. Wersja 1.x pakietu SDK używa innych nazw klas i funkcji, więc te przykłady nie będą z nią działać:
pip install --upgrade "mcp>=2"
TypeScript
W tym przewodniku używamy pakietu SDK MCP dla TypeScripta z Node.js w wersji 18 lub nowszej:
npm install @modelcontextprotocol/sdk
Ustawianie klucza interfejsu API
Aby uniknąć zakodowania klucza interfejsu API w kodzie źródłowym, zapisz go w zmiennej środowiskowej. Zastąp YOUR_API_KEY swoim kluczem interfejsu API:
export DEVELOPERKNOWLEDGE_API_KEY="YOUR_API_KEY"
Nawiązywanie połączenia z serwerem
Serwer Developer Knowledge MCP używa transportu HTTP z możliwością przesyłania strumieniowego pod tym adresem:
https://developerknowledge.googleapis.com/mcp
Aby się uwierzytelnić, przekaż klucz interfejsu API w nagłówku HTTP X-Goog-Api-Key w każdym żądaniu. Nie przekazuj klucza interfejsu API jako parametru zapytania URL.
Ten przykład łączy się z serwerem i wyświetla listę dostępnych narzędzi:
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();
Jeśli połączenie się powiedzie, w danych wyjściowych zostaną wyświetlone 3 narzędzia:
Available tools: search_documents, answer_query, get_documents
Pozostałe przykłady w tym przewodniku są uruchamiane w połączonym kliencie z tej sekcji. Przykłady w TypeScriptcie używają await najwyższego poziomu, więc uruchamiaj je jako moduły ES (np. za pomocą npx tsx index.ts).
Wywoływanie narzędzi
Każde narzędzie zwraca wynik jako uporządkowaną treść zgodną ze schematem wyjściowym narzędzia, dzięki czemu możesz odczytywać pola bezpośrednio, zamiast analizować tekst. Pełne schematy wejściowe i wyjściowe znajdziesz w dokumentacji MCP.
Wyszukiwanie dokumentacji
Wywołaj search_documents z ciągiem znaków query, aby pobrać najbardziej odpowiednie fragmenty dokumentacji. Każdy wynik zawiera fragment content i nazwę zasobu parent dokumentu, z którego pochodzi:
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`);
}
Pobieranie pełnych dokumentów
Jeśli fragment nie zawiera wystarczającej ilości kontekstu, przekaż jedną lub więcej wartości parent do get_documents, aby pobrać pełną treść Markdown każdej strony. W jednym wywołaniu możesz poprosić o maksymalnie 20 dokumentów. Ponieważ kilka fragmentów może pochodzić z tego samego dokumentu, najpierw usuń duplikaty wartości 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);
}
Pełne dokumenty mogą być duże, dlatego wywołuj get_documents tylko wtedy, gdy fragmenty wyszukiwania nie są wystarczające. Więcej informacji znajdziesz w artykule
Optymalizowanie okna kontekstu i wykorzystania tokenów.
Generowanie odpowiedzi
Wywołaj answer_query, aby wygenerować odpowiedź na podstawie
korpusu Developer Knowledge. Wynik zawiera answerText i references użyte do jego wygenerowania:
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'));
Pole references zawiera nazwy zasobów dokumentów, które możesz przekazać do get_documents. Ten sam dokument może pojawić się więcej niż raz, więc przed pobraniem dokumentów usuń duplikaty. Narzędzie answer_query ma niższy limit niż inne narzędzia. Więcej informacji znajdziesz w artykule
Limity.
Uwierzytelnianie za pomocą domyślnego uwierzytelniania aplikacji
Zamiast klucza interfejsu API możesz uwierzytelniać się za pomocą domyślnego uwierzytelniania aplikacji (ADC). ADC działa z danymi logowania użytkownika podczas lokalnego programowania oraz z kontami usług, gdy kod jest uruchamiany w Google Cloud.
Gdy używasz ADC, wysyłaj te nagłówki w każdym żądaniu:
Authorization: token dostępu OAuth 2.0Bearerz zakresemhttps://www.googleapis.com/auth/cloud-platform.X-Goog-User-Project: identyfikator projektu, w którym jest włączony Developer Knowledge API i który jest obciążany za limit. Twoje konto musi mieć w tym projekcie uprawnienieserviceusage.services.use.
Tokeny dostępu wygasają, więc klienci działający przez dłuższy czas muszą je odświeżać. Poniższe przykłady używają bibliotek uwierzytelniania Google, aby dodać bieżący token do każdego żądania.
Skonfiguruj ADC na potrzeby lokalnego programowania, wykonując czynności opisane na karcie ADC w artykule Wybieranie typu danych logowania OAuth.
Ustaw zmienną środowiskową
GOOGLE_CLOUD_PROJECTna projekt, w którym jest włączony Developer Knowledge API. Przykłady wysyłają ten identyfikator projektu w nagłówkuX-Goog-User-Project:export GOOGLE_CLOUD_PROJECT="PROJECT_ID"Zainstaluj bibliotekę uwierzytelniania Google w swoim języku:
Python
pip install --upgrade google-auth requestsTypeScript
npm install google-auth-libraryUtwórz klienta za pomocą 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);
Obsługiwanie błędów
Błędy z serwera Developer Knowledge MCP docierają do Twojego kodu na 2 sposoby:
- Błędy żądań: błędy uwierzytelniania, uprawnień i limitów są
zwracane ze stanem błędu HTTP, takim jak
400,403, lub429. Pakiety SDK zgłaszają je jako wyjątki:MCPErrorw Pythonie iStreamableHTTPErrorw TypeScriptcie. Przechwytuj te wyjątki wokół wywołań narzędzi. - Błędy narzędzi: gdy narzędzie działa, ale nie może zrealizować żądania,
wynik ma ustawioną wartość
truew poluis_error(Python) lubisError(TypeScript), a polecontentzawiera tekstowy opis problemu. Przed odczytaniem uporządkowanej treści sprawdź to pole.
Ten przykład obsługuje oba typy błędów:
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;
}
}
Jeśli answer_query zwróci błąd limitu (429 RESOURCE_EXHAUSTED), wróć do search_documents, które ma wyższy limit. Informacje o strategiach ponawiania, w tym o wzrastającym czasie do ponowienia, znajdziesz w artykule Obsługa błędów i zarządzanie limitami.
Typowe przyczyny błędów uwierzytelniania znajdziesz w artykułach
Błędy klucza interfejsu API oraz
Błędy OAuth i ADC.
Co dalej?
- Zapoznaj się z pełnymi schematami narzędzi w dokumentacji MCP.
- Dowiedz się, które usługi są indeksowane w dokumentacji korpusu.
- Wywołuj Developer Knowledge API bezpośrednio za pomocą bibliotek klienta.