SDK Giao thức ngữ cảnh mô hình (MCP) chính thức cho phép các ứng dụng và tác nhân AI của riêng bạn kết nối với chương trình máy chủ MCP Kiến thức của nhà phát triển theo cách có lập trình. Sử dụng SDK MCP khi bạn đang xây dựng một tác nhân tuỳ chỉnh, một dịch vụ phụ trợ hoặc máy chủ MCP của riêng bạn cần tìm kiếm và truy xuất tài liệu chính thức dành cho nhà phát triển của Google, thay vì định cấu hình một IDE hoặc trợ lý lập trình hiện có.
Trong hướng dẫn này, bạn sẽ tìm hiểu cách:
- Cài đặt SDK ứng dụng MCP cho Python hoặc TypeScript.
- Kết nối với máy chủ MCP Kiến thức cho nhà phát triển bằng khoá API hoặc Thông tin xác thực mặc định của ứng dụng (ADC).
- Gọi các công cụ
search_documents,get_documentsvàanswer_query. - Xử lý lỗi xác thực, hạn mức và công cụ.
Trước khi bắt đầu
Trước khi bắt đầu, hãy hoàn tất các phần sau.
Bật API và tạo thông tin xác thực
Bật Developer Knowledge API trong dự án trên đám mây của bạn và tạo thông tin xác thực cho phương pháp xác thực của bạn. Để xem hướng dẫn từng bước, hãy tham khảo bài viết Chọn phương pháp xác thực.
Các ví dụ trong hướng dẫn này sử dụng khoá API. Để sử dụng ADC, hãy tham khảo bài viết Xác thực bằng Thông tin xác thực mặc định của ứng dụng.
Cài đặt SDK MCP
Chọn ngôn ngữ lập trình để cài đặt SDK ứng dụng MCP:
Python
Hướng dẫn này sử dụng phiên bản 2 của MCP Python SDK, yêu cầu Python 3.10 trở lên. SDK phiên bản 1.x sử dụng các tên lớp và hàm khác nhau, vì vậy, những ví dụ này không hoạt động với phiên bản đó:
pip install --upgrade "mcp>=2"
TypeScript
Hướng dẫn này sử dụng MCP TypeScript SDK với Node.js 18 trở lên:
npm install @modelcontextprotocol/sdk
Đặt khoá API
Để tránh mã hoá cứng khoá API trong mã nguồn, hãy lưu trữ khoá đó trong một biến môi trường. Thay thế YOUR_API_KEY bằng khoá API của bạn:
export DEVELOPERKNOWLEDGE_API_KEY="YOUR_API_KEY"
Kết nối với máy chủ
Máy chủ MCP Kiến thức cho nhà phát triển sử dụng giao thức truyền tải HTTP có thể truyền trực tuyến tại điểm cuối sau:
https://developerknowledge.googleapis.com/mcp
Để xác thực, hãy truyền khoá API của bạn trong tiêu đề HTTP X-Goog-Api-Key trên mọi yêu cầu. Không truyền khoá API dưới dạng tham số truy vấn URL.
Ví dụ sau đây kết nối với máy chủ và liệt kê các công cụ có sẵn:
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();
Nếu kết nối thành công, kết quả sẽ liệt kê 3 công cụ:
Available tools: search_documents, answer_query, get_documents
Các ví dụ còn lại trong hướng dẫn này chạy bên trong ứng dụng đã kết nối từ phần này. Các ví dụ về TypeScript sử dụng await cấp cao nhất, vì vậy, hãy chạy các ví dụ đó dưới dạng mô-đun ES (ví dụ: bằng npx tsx index.ts).
Gọi công cụ
Mỗi công cụ trả về kết quả dưới dạng nội dung có cấu trúc khớp với giản đồ đầu ra của công cụ, vì vậy, bạn có thể đọc trực tiếp các trường thay vì phân tích cú pháp văn bản. Để biết giản đồ đầu vào và đầu ra đầy đủ, hãy tham khảo tài liệu tham khảo về MCP.
Tìm tài liệu
Gọi search_documents bằng chuỗi query để truy xuất các đoạn tài liệu phù hợp nhất. Mỗi kết quả chứa đoạn content và tên tài nguyên parent của tài liệu chứa đoạn đó:
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`);
}
Truy xuất toàn bộ tài liệu
Nếu một đoạn không chứa đủ ngữ cảnh, hãy truyền một hoặc nhiều giá trị parent đến get_documents để truy xuất toàn bộ nội dung Markdown của mỗi trang. Bạn có thể yêu cầu tối đa 20 tài liệu trong một lệnh gọi. Vì một số đoạn có thể đến từ cùng một tài liệu, nên trước tiên, hãy xoá các giá trị parent trùng lặp:
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);
}
Tài liệu đầy đủ có thể có kích thước lớn, vì vậy, chỉ gọi get_documents khi các khối tìm kiếm không đủ. Để tìm hiểu thêm, hãy tham khảo bài viết
Tối ưu hoá cửa sổ ngữ cảnh và mức sử dụng mã thông báo.
Tạo câu trả lời
Gọi answer_query để tạo câu trả lời dựa trên Kho kiến thức dành cho nhà phát triển. Kết quả chứa answerText và references được dùng để tạo kết quả đó:
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'));
Trường references chứa tên tài nguyên tài liệu mà bạn có thể truyền đến get_documents. Cùng một tài liệu có thể xuất hiện nhiều lần, vì vậy, hãy xoá các bản sao trước khi truy xuất tài liệu. Công cụ answer_query có hạn mức thấp hơn các công cụ khác. Để tìm hiểu thêm, hãy tham khảo bài viết Hạn mức và giới hạn.
Xác thực bằng Thông tin xác thực mặc định của ứng dụng
Thay vì khoá API, bạn có thể xác thực bằng Thông tin xác thực mặc định của ứng dụng (ADC). ADC hoạt động với thông tin xác thực người dùng trong quá trình phát triển cục bộ và với tài khoản dịch vụ khi mã của bạn chạy trên Google Cloud.
Khi bạn sử dụng ADC, hãy gửi các tiêu đề sau trong mọi yêu cầu:
Authorization: mã truy cập OAuth 2.0Bearercó phạm vihttps://www.googleapis.com/auth/cloud-platform.X-Goog-User-Project: mã nhận dạng của dự án đã bật Developer Knowledge API và được tính phí theo hạn mức. Tài khoản của bạn cần có quyềnserviceusage.services.useđối với dự án này.
Mã truy cập sẽ hết hạn, vì vậy, các ứng dụng chạy trong thời gian dài phải làm mới mã truy cập. Các ví dụ sau đây sử dụng thư viện xác thực của Google để thêm mã thông báo hiện tại vào mỗi yêu cầu.
Thiết lập ADC cho hoạt động phát triển tại máy bằng cách làm theo các bước trên thẻ ADC trong phần Chọn loại thông tin xác thực OAuth.
Đặt biến môi trường
GOOGLE_CLOUD_PROJECTthành dự án đã bật Developer Knowledge API. Các ví dụ này gửi mã dự án này trong tiêu đềX-Goog-User-Project:export GOOGLE_CLOUD_PROJECT="PROJECT_ID"Cài đặt thư viện xác thực của Google cho ngôn ngữ của bạn:
Python
pip install --upgrade google-auth requestsTypeScript
npm install google-auth-libraryTạo ứng dụng bằng 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);
Xử lý lỗi
Các lỗi từ máy chủ MCP của Developer Knowledge sẽ đến mã của bạn theo hai cách:
- Lỗi yêu cầu: lỗi xác thực, lỗi về quyền và lỗi hạn mức được trả về bằng trạng thái lỗi HTTP, chẳng hạn như
400,403hoặc429. SDK sẽ đưa ra các trường hợp ngoại lệ sau:MCPErrortrong Python vàStreamableHTTPErrortrong TypeScript. Nắm bắt những trường hợp ngoại lệ này trong các lệnh gọi công cụ. - Lỗi công cụ: khi một công cụ chạy nhưng không thể hoàn tất yêu cầu, kết quả sẽ có
is_error(Python) hoặcisError(TypeScript) được đặt thànhtruevà trườngcontentchứa nội dung mô tả bằng văn bản về vấn đề. Hãy kiểm tra trường này trước khi đọc nội dung có cấu trúc.
Ví dụ sau đây xử lý cả hai loại lỗi:
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;
}
}
Nếu answer_query trả về lỗi hạn mức (429 RESOURCE_EXHAUSTED), hãy quay lại search_documents vì phương thức này có hạn mức cao hơn. Đối với các chiến lược thử lại, bao gồm cả thuật toán thời gian đợi luỹ thừa, hãy tham khảo phần Xử lý lỗi và quản lý hạn mức.
Để biết các nguyên nhân phổ biến gây ra lỗi xác thực, hãy tham khảo bài viết
Lỗi khoá API và
Lỗi OAuth và ADC.
Bước tiếp theo
- Khám phá toàn bộ giản đồ công cụ trong tài liệu tham khảo MCP.
- Tìm hiểu những sản phẩm được lập chỉ mục trong Tài liệu tham khảo về Corpus.
- Gọi trực tiếp Developer Knowledge API bằng thư viện ứng dụng.