SDK อย่างเป็นทางการ ของ Model Context Protocol (MCP) ช่วยให้แอปพลิเคชันและ AI Agent ของคุณเองเชื่อมต่อกับเซิร์ฟเวอร์ MCP ของ Developer Knowledge ได้โดยใช้โปรแกรม ใช้ MCP SDK เมื่อสร้าง Agent ที่กำหนดเอง, บริการแบ็กเอนด์ หรือเซิร์ฟเวอร์ MCP ของคุณเองที่ต้องค้นหาและดึงข้อมูลเอกสารประกอบสำหรับนักพัฒนาแอปอย่างเป็นทางการของ Google แทนที่จะกำหนดค่า IDE หรือเครื่องมือช่วยเขียนโค้ดที่มีอยู่
ในคู่มือนี้ คุณจะได้เรียนรู้วิธีการทำสิ่งต่อไปนี้
- ติดตั้ง MCP Client SDK สำหรับ Python หรือ TypeScript
- เชื่อมต่อกับเซิร์ฟเวอร์ MCP ของ Developer Knowledge ด้วยคีย์ API หรือข้อมูลรับรองเริ่มต้นของแอปพลิเคชัน (ADC)
- เรียกใช้เครื่องมือ
search_documents,get_documentsและanswer_query - จัดการการตรวจสอบสิทธิ์ โควต้า และข้อผิดพลาดของเครื่องมือ
ก่อนเริ่มต้น
ก่อนเริ่มต้น ให้ทำตามขั้นตอนในส่วนต่อไปนี้
เปิดใช้ API และสร้างข้อมูลเข้าสู่ระบบ
เปิดใช้ Developer Knowledge API ในโปรเจ็กต์ที่อยู่ในระบบคลาวด์ของ Google และสร้างข้อมูลเข้าสู่ระบบสำหรับวิธีการตรวจสอบสิทธิ์ ดูวิธีการทีละขั้นตอนได้ที่ หัวข้อ เลือกวิธีการตรวจสอบสิทธิ์
ตัวอย่างในคู่มือนี้ใช้คีย์ API หากต้องการใช้ ADC แทน โปรดดูหัวข้อ ตรวจสอบสิทธิ์ด้วยข้อมูลรับรองเริ่มต้นของแอปพลิเคชัน
ติดตั้ง MCP SDK
เลือกภาษาโปรแกรมเพื่อติดตั้ง MCP Client SDK
Python
คู่มือนี้ใช้ MCP Python SDK เวอร์ชัน 2 ซึ่ง ต้องใช้ Python 3.10 ขึ้นไป SDK เวอร์ชัน 1.x ใช้ชื่อคลาสและฟังก์ชันที่แตกต่างกัน ดังนั้นตัวอย่างเหล่านี้จึงใช้ไม่ได้กับ SDK เวอร์ชันดังกล่าว
pip install --upgrade "mcp>=2"
TypeScript
คู่มือนี้ใช้ MCP TypeScript SDK กับ Node.js 18 ขึ้นไป
npm install @modelcontextprotocol/sdk
ตั้งค่าคีย์ API
เก็บคีย์ API ไว้ในตัวแปรสภาพแวดล้อมเพื่อหลีกเลี่ยงการฮาร์ดโค้ดคีย์ API ในซอร์สโค้ด แทนที่ YOUR_API_KEY ด้วยคีย์ API ของคุณ
export DEVELOPERKNOWLEDGE_API_KEY="YOUR_API_KEY"
เชื่อมต่อกับเซิร์ฟเวอร์
เซิร์ฟเวอร์ MCP ของ Developer Knowledge ใช้ การรับส่งข้อมูล HTTP ที่สตรีมได้ ที่ปลายทางต่อไปนี้
https://developerknowledge.googleapis.com/mcp
หากต้องการตรวจสอบสิทธิ์ ให้ส่งคีย์ API ในส่วนหัว HTTP X-Goog-Api-Key ในทุกคำขอ อย่าส่งคีย์ API เป็นพารามิเตอร์การค้นหาของ URL
ตัวอย่างต่อไปนี้แสดงวิธีเชื่อมต่อกับเซิร์ฟเวอร์และแสดงรายการเครื่องมือที่พร้อมใช้งาน
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();
หากเชื่อมต่อสำเร็จ เอาต์พุตจะแสดงรายการเครื่องมือ 3 รายการ
Available tools: search_documents, answer_query, get_documents
ตัวอย่างที่เหลือในคู่มือนี้จะทำงานภายในไคลเอ็นต์ที่เชื่อมต่อจากส่วนนี้ ตัวอย่าง TypeScript ใช้ await ระดับบนสุด ดังนั้นให้เรียกใช้เป็นโมดูล ES (เช่น ใช้ npx tsx index.ts)
เรียกใช้เครื่องมือ
เครื่องมือแต่ละรายการจะแสดงผลลัพธ์เป็นเนื้อหาที่มีโครงสร้างซึ่งตรงกับสคีมาเอาต์พุตของเครื่องมือ คุณจึงอ่านฟิลด์ได้โดยตรงแทนที่จะแยกวิเคราะห์ข้อความ ดูสคีมาอินพุตและเอาต์พุตทั้งหมดได้ในข้อมูลอ้างอิง MCP
ค้นหาเอกสารประกอบ
เรียกใช้ search_documents ด้วยสตริง query เพื่อดึงข้อมูลเอกสารประกอบที่เกี่ยวข้องมากที่สุด ผลลัพธ์แต่ละรายการจะมี 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 อย่างน้อย 1 ค่าไปยัง get_documents เพื่อดึงข้อมูลเนื้อหา Markdown ฉบับเต็มของแต่ละหน้า คุณขอเอกสารได้สูงสุด 20 รายการในการเรียกใช้ครั้งเดียว เนื่องจากข้อมูลหลายรายการอาจมาจากเอกสารเดียวกัน ให้ลบค่า 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 เพื่อสร้างคำตอบที่อิงตาม
คลังข้อมูล Developer Knowledge ผลลัพธ์จะมี 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 ได้ เอกสารเดียวกันอาจปรากฏมากกว่า 1 ครั้ง ดังนั้นให้ลบรายการที่ซ้ำกันออกก่อนที่จะดึงข้อมูลเอกสาร เครื่องมือ answer_query มีโควต้าต่ำกว่าเครื่องมืออื่นๆ ดูข้อมูลเพิ่มเติมได้ที่หัวข้อ
โควต้าและขีดจำกัด
ตรวจสอบสิทธิ์ด้วยข้อมูลรับรองเริ่มต้นของแอปพลิเคชัน
คุณสามารถตรวจสอบสิทธิ์ด้วย ข้อมูลรับรองเริ่มต้นของแอปพลิเคชัน (ADC)แทนคีย์ API ADC ทำงานร่วมกับข้อมูลเข้าสู่ระบบของผู้ใช้ในระหว่างการพัฒนาในเครื่อง และทำงานร่วมกับบัญชีบริการเมื่อโค้ดทำงานบน Google Cloud
เมื่อใช้ ADC ให้ส่งส่วนหัวต่อไปนี้ในทุกคำขอ
Authorization: โทเค็นเพื่อการเข้าถึง OAuth 2.0Bearerที่มีขอบเขตhttps://www.googleapis.com/auth/cloud-platformX-Goog-User-Project: รหัสของโปรเจ็กต์ที่เปิดใช้ Developer Knowledge API และมีการเรียกเก็บเงินสำหรับโควต้า บัญชีของคุณต้องมีสิทธิ์serviceusage.services.useในโปรเจ็กต์นี้
โทเค็นเพื่อการเข้าถึงจะหมดอายุ ดังนั้นไคลเอ็นต์ที่ทำงานเป็นเวลานานจึงต้องรีเฟรชโทเค็น ตัวอย่างต่อไปนี้ใช้ไลบรารีการตรวจสอบสิทธิ์ของ Google เพื่อเพิ่มโทเค็นปัจจุบันลงในแต่ละคำขอ
ตั้งค่า ADC สำหรับการพัฒนาในเครื่องโดยทำตามขั้นตอนในแท็บ ADC ในหัวข้อ เลือกประเภทข้อมูลเข้าสู่ระบบ OAuth
ตั้งค่าตัวแปรสภาพแวดล้อม
GOOGLE_CLOUD_PROJECTเป็นโปรเจ็กต์ที่เปิดใช้ Developer Knowledge API ตัวอย่างจะส่งรหัสโปรเจ็กต์นี้ในส่วนหัวX-Goog-User-Projectดังนี้export GOOGLE_CLOUD_PROJECT="PROJECT_ID"ติดตั้งไลบรารี Google Authenticator สำหรับภาษาของคุณ
Python
pip install --upgrade google-auth requestsTypeScript
npm install google-auth-libraryสร้างไคลเอ็นต์ด้วย 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);
จัดการข้อผิดพลาด
ข้อผิดพลาดจากเซิร์ฟเวอร์ MCP ของ Developer Knowledge จะไปถึงโค้ดของคุณได้ 2 วิธี
- ข้อผิดพลาดของคำขอ: ระบบจะแสดงข้อผิดพลาดในการตรวจสอบสิทธิ์ สิทธิ์ และโควต้า พร้อมสถานะข้อผิดพลาดของ HTTP เช่น
400,403, หรือ429SDK จะแสดงข้อผิดพลาดเหล่านี้เป็นข้อยกเว้น ได้แก่MCPErrorใน Python และStreamableHTTPErrorใน TypeScript ดักจับข้อยกเว้นเหล่านี้รอบๆ การเรียกใช้เครื่องมือ - ข้อผิดพลาดของเครื่องมือ: เมื่อเครื่องมือทำงานแต่ไม่สามารถดำเนินการตามคำขอให้เสร็จสมบูรณ์
ผลลัพธ์จะมี
is_error(Python) หรือisError(TypeScript) ตั้งค่าเป็นtrueและ ฟิลด์contentจะมีคำอธิบายข้อความของปัญหา ตรวจสอบฟิลด์นี้ก่อนอ่านเนื้อหาที่มีโครงสร้าง
ตัวอย่างต่อไปนี้แสดงวิธีจัดการข้อผิดพลาดทั้ง 2 ประเภท
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 ซึ่งมีโควต้าสูงกว่า ดูกลยุทธ์การลองอีกครั้ง
รวมถึง Exponential Backoff ได้ที่
หัวข้อการจัดการข้อผิดพลาดและการจัดการโควต้า
ดูสาเหตุที่พบบ่อยของข้อผิดพลาดในการตรวจสอบสิทธิ์ได้ที่หัวข้อ
ข้อผิดพลาดเกี่ยวกับคีย์ API และ
ข้อผิดพลาดเกี่ยวกับ OAuth และ ADC
ขั้นตอนถัดไป
- สำรวจสคีมาเครื่องมือทั้งหมดใน ข้อมูลอ้างอิง MCP
- ดูว่าผลิตภัณฑ์ใดบ้างที่จัดทำดัชนีใน ข้อมูลอ้างอิงคลังข้อมูล
- เรียกใช้ Developer Knowledge API โดยตรงด้วย ไลบรารีของไคลเอ็นต์