Los SDKs oficiales del Protocolo de contexto del modelo (MCP) permiten que tus propias aplicaciones y agentes de IA se conecten de forma programática al servidor de MCP de Developer Knowledge. Usa un SDK de MCP cuando compiles un agente personalizado, un servicio de backend o tu propio servidor de MCP que necesite buscar y recuperar documentación oficial para desarrolladores de Google, en lugar de configurar un IDE existente o un asistente de codificación.
En esta guía, aprenderás a hacer lo siguiente:
- Instalar el SDK de cliente de MCP para Python o TypeScript
- Conectarte al servidor de MCP de Developer Knowledge con una clave de API o credenciales predeterminadas de la aplicación (ADC)
- Llamar a las herramientas
search_documents,get_documentsyanswer_query - Solucionar errores de autenticación, cuota y herramientas
Antes de comenzar
Antes de comenzar, completa las siguientes secciones.
Habilita la API y crea credenciales
Habilita la API de Developer Knowledge en tu proyecto de Google Cloud y crea las credenciales para tu método de autenticación. Para obtener instrucciones paso a paso, consulta Elige tu método de autenticación.
En los ejemplos de esta guía, se usa una clave de API. Para usar ADC en su lugar, consulta Autentica con credenciales predeterminadas de la aplicación.
Instala el SDK de MCP
Selecciona tu lenguaje de programación para instalar el SDK de cliente de MCP:
Python
En esta guía, se usa la versión 2 del SDK de MCP para Python, que requiere Python 3.10 o versiones posteriores. La versión 1.x del SDK usa diferentes nombres de clase y función, por lo que estos ejemplos no funcionan con ella:
pip install --upgrade "mcp>=2"
TypeScript
En esta guía, se usa el SDK de MCP para TypeScript con Node.js 18 o versiones posteriores:
npm install @modelcontextprotocol/sdk
Establece tu clave de API
Para evitar codificar de forma rígida tu clave de API en el código fuente, almacénala en una variable de entorno. Reemplaza YOUR_API_KEY por tu clave de API:
export DEVELOPERKNOWLEDGE_API_KEY="YOUR_API_KEY"
Conéctate al servidor
El servidor de MCP de Developer Knowledge usa el transporte HTTP transmisible en el siguiente extremo:
https://developerknowledge.googleapis.com/mcp
Para autenticarte, pasa tu clave de API en el encabezado HTTP X-Goog-Api-Key en cada solicitud. No pases la clave de API como un parámetro de consulta de URL.
En el siguiente ejemplo, se conecta al servidor y se enumeran las herramientas disponibles:
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();
Si la conexión se realiza correctamente, el resultado muestra las tres herramientas:
Available tools: search_documents, answer_query, get_documents
Los ejemplos restantes de esta guía se ejecutan dentro del cliente conectado de esta sección. Los ejemplos de TypeScript usan await de nivel superior, por lo que debes ejecutarlos como módulos ES (por ejemplo, con npx tsx index.ts).
Llama a las herramientas
Cada herramienta muestra su resultado como contenido estructurado que coincide con el esquema de salida de la herramienta, por lo que puedes leer los campos directamente en lugar de analizar el texto. Para obtener los esquemas completos de entrada y salida, consulta la referencia de MCP.
Busca documentación
Llama a search_documents con una cadena query para recuperar los fragmentos de documentación más relevantes. Cada resultado contiene el fragmento content y el nombre del recurso parent del documento del que proviene:
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`);
}
Recupera documentos completos
Si un fragmento no contiene suficiente contexto, pasa uno o más valores parent a get_documents para recuperar el contenido completo de Markdown de cada página. Puedes solicitar hasta 20 documentos en una sola llamada. Debido a que varios fragmentos pueden provenir del mismo documento, primero quita los valores parent duplicados:
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);
}
Los documentos completos pueden ser grandes, por lo que debes llamar a get_documents solo cuando los fragmentos de búsqueda no sean suficientes. Para obtener más información, consulta
Optimiza la ventana de contexto y el uso de tokens.
Genera una respuesta
Llama a answer_query para generar una respuesta basada en el
corpus de Developer Knowledge. El resultado contiene el answerText y las references que se usaron para generarlo:
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'));
El campo references contiene nombres de recursos de documentos que puedes pasar a get_documents. El mismo documento puede aparecer más de una vez, por lo que debes quitar los duplicados antes de recuperar los documentos. La herramienta answer_query tiene una cuota más baja que las otras herramientas. Para obtener más información, consulta
Cuotas y límites.
Autentica con credenciales predeterminadas de la aplicación
En lugar de una clave de API, puedes autenticarte con credenciales predeterminadas de la aplicación (ADC). ADC funciona con tus credenciales de usuario durante el desarrollo local y con cuentas de servicio cuando tu código se ejecuta en Google Cloud.
Cuando usas ADC, envía los siguientes encabezados en cada solicitud:
Authorization: Un token de accesoBearerde OAuth 2.0 con el alcancehttps://www.googleapis.com/auth/cloud-platform.X-Goog-User-Project: El ID del proyecto que tiene habilitada la API de Developer Knowledge y al que se le factura la cuota. Tu cuenta necesita el permisoserviceusage.services.useen este proyecto.
Los tokens de acceso vencen, por lo que los clientes de larga duración deben actualizarlos. En los siguientes ejemplos, se usan las bibliotecas de autenticación de Google para agregar un token actual a cada solicitud.
Para configurar ADC para el desarrollo local, sigue los pasos de la pestaña ADC en Elige tu tipo de credencial de OAuth.
Establece la variable de entorno
GOOGLE_CLOUD_PROJECTen el proyecto que tiene habilitada la API de Developer Knowledge. En los ejemplos, se envía este ID del proyecto en el encabezadoX-Goog-User-Project:export GOOGLE_CLOUD_PROJECT="PROJECT_ID"Instala la biblioteca de autenticación de Google para tu lenguaje:
Python
pip install --upgrade google-auth requestsTypeScript
npm install google-auth-libraryCrea el cliente con 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);
Soluciona errores
Los errores del servidor de MCP de Developer Knowledge llegan a tu código de dos maneras:
- Errores de solicitud: Los errores de autenticación, permiso y cuota se muestran con un estado de error de HTTP, como
400,403, o429. Los SDKs los generan como excepciones:MCPErroren Python yStreamableHTTPErroren TypeScript. Detecta estas excepciones en tus llamadas a herramientas. - Errores de herramientas: cuando una herramienta se ejecuta, pero no puede completar la solicitud, el
resultado tiene
is_error(Python) oisError(TypeScript) establecido entrue, y el campocontentcontiene una descripción de texto del problema. Verifica este campo antes de leer el contenido estructurado.
En el siguiente ejemplo, se controlan ambos tipos de errores:
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;
}
}
Si answer_query muestra un error de cuota (429 RESOURCE_EXHAUSTED), vuelve a search_documents, que tiene una cuota más alta. Para obtener estrategias de reintento,
incluida la retirada exponencial, consulta
Manejo de errores y administración de cuotas.
Para conocer las causas comunes de los errores de autenticación, consulta
Errores de clave de API y
Errores de OAuth y ADC.
¿Qué sigue?
- Explora los esquemas de herramientas completos en la referencia de MCP.
- Descubre qué productos están indexados en la referencia de Corpus.
- Llama a la API de Developer Knowledge directamente con las bibliotecas cliente.