Configurar clientes MCP
Conecta un cliente con cabeceras privadas o usa el SDK oficial para verificar el protocolo completo.
Servidor 1.0 · MCP 2025-11-25 · Claves Bearer por negocio
En esta página
Transporte y negociación
Usa un SDK compatible con Streamable HTTP para initialize, notificación de inicialización y negociación de versión. Delivery utiliza @modelcontextprotocol/sdk 1.x y se verifica con el protocolo 2025-11-25; no se anuncia compatibilidad automática con revisiones posteriores.
- Endpoint único: /api/mcp. No uses /sse ni lances un servidor local de Zoy para conectarte al remoto.
- Envía Authorization: Bearer en cada petición. Las cookies del panel no autentican al MCP.
- Un cliente HTTP debe aceptar application/json y text/event-stream, y enviar la versión negociada en MCP-Protocol-Version.
- El transporte es stateless, sin un MCP-Session-Id que debas guardar. Los planes y trabajos durables viven en el servidor.
- Las peticiones de navegador de otro origen se rechazan. Conecta desde el cliente/agente o un backend; no incrustes la clave en el frontend.
VS Code: formato local con entrada secreta
Para el formato de VS Code en un perfil privado o .vscode/mcp.json, el cliente Local admite una entrada secreta. Las sesiones Copilot y los archivos portables tienen capacidades distintas: no reutilices este bloque sin comprobarlas.
{
"inputs": [
{
"type": "promptString",
"id": "zoy-token",
"description": "Clave privada del catálogo Zoy",
"password": true
}
],
"servers": {
"zoy": {
"type": "http",
"url": "https://zoydelivery.com/api/mcp",
"headers": {
"Authorization": "Bearer ${input:zoy-token}"
}
}
}
}En un archivo portable compatible con Copilot se usa mcpServers y una referencia de entorno como ${ZOY_MENU_TOKEN}; no se admiten las entradas ${input:...}. El proceso remoto o contenedor que conecta debe disponer de esa variable. Revisa la configuración vigente de tu cliente.
Node.js: ejemplo ejecutable de solo lectura
Requiere Node.js 24+ y el SDK 1.x. Ejecuta en un proceso privado con ZOY_MENU_TOKEN. ZOY_MCP_URL es opcional y permite apuntar al subdominio del negocio o a un servidor local. El ejemplo no imprime el catálogo, sus costos ni la credencial.
// Ejemplo de solo lectura. Node.js 24+ y @modelcontextprotocol/sdk 1.x.
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const token = process.env.ZOY_MENU_TOKEN;
let url;
try {
url = new URL(process.env.ZOY_MCP_URL || "https://zoydelivery.com/api/mcp");
} catch {
throw new Error("ZOY_MCP_URL debe ser una URL válida sin credenciales.");
}
const loopback =
url.hostname === "localhost" ||
url.hostname === "127.0.0.1" ||
url.hostname.endsWith(".localhost");
if (!token)
throw new Error("Define ZOY_MENU_TOKEN en el entorno privado del proceso.");
if (url.protocol !== "https:" && !(url.protocol === "http:" && loopback))
throw new Error(
"Usa HTTPS; HTTP solo está permitido para desarrollo en loopback.",
);
if (url.username || url.password || url.search || url.hash)
throw new Error(
"La URL MCP no debe contener credenciales, query ni fragmento.",
);
const client = new Client({ name: "zoy-read-example", version: "1.0.0" });
try {
await client.connect(
new StreamableHTTPClientTransport(url, {
requestInit: { headers: { Authorization: `Bearer ${token}` } },
}),
);
const { tools } = await client.listTools();
const result = await client.callTool({
name: "catalog_schema",
arguments: {},
});
if (result.isError)
throw new Error(
"catalog_schema falló; revisa la clave y el negocio autorizado.",
);
// No imprime credenciales, costos ni el catálogo privado.
console.log(
JSON.stringify({
server: client.getServerVersion()?.name,
documentation: client.getServerVersion()?.websiteUrl,
tools: tools.map((tool) => tool.name),
schemaRead: true,
}),
);
} catch {
console.error(
"No se pudo completar la consulta MCP. Revisa endpoint, clave, permisos y conectividad sin registrar el secreto.",
);
process.exitCode = 1;
} finally {
await client.close();
}