IA

Servidor MCP de WhatsApp: cómo armarlo y usarlo en Claude y Cursor

Un servidor MCP de WhatsApp es un programa que expone acciones de la API (enviar texto, verificar un número, ver el estado de la instancia, leer mensajes) como herramientas que Claude, Cursor y otros clientes MCP pueden llamar. Aviso de honestidad: ZapZap todavía no publica un servidor MCP propio. Esta guía es un ejemplo de cómo armar el tuyo en unas 80 líneas de TypeScript sobre la API que ya existe, y no describe un producto lanzado.

Publicado el · 6 min de lectura

Este artículo también está disponible en: Português · English

Qué es MCP y por qué conectar WhatsApp a un asistente de IA

MCP (Model Context Protocol) es un protocolo abierto que define cómo un cliente de IA (una app de chat, un editor de código, un agente) descubre y llama a herramientas expuestas por un servidor. En vez de que cada integración se haga a medida, el servidor declara las herramientas, los parámetros y las descripciones, y el cliente decide cuándo llamarlas durante la conversación.

Para WhatsApp esto abre usos concretos: pedirle al asistente que confirme si una lista de números tiene WhatsApp, que resuma los últimos mensajes de un cliente, que verifique si la instancia está conectada antes de una campaña o que redacte y, con tu aprobación, envíe un mensaje. La parte difícil no es técnica, es de control: un asistente con acceso de envío necesita candados.

Qué existe hoy y qué no existe

Estado al 27/10/2026. Existe: la API REST de ZapZap, con referencia por endpoint y archivo OpenAPI publicado en OpenAPI; el paquete n8n-nodes-zapzap 0.1.3 en npm, para quien usa n8n; y el SDK oficial de MCP en TypeScript (@modelcontextprotocol/sdk, versión 1.32.2 en npm a esta fecha), que usaremos en el ejemplo. No existe: un servidor MCP de ZapZap publicado y mantenido por nosotros.

Por eso el código de abajo es tuyo: tú lo alojas, tú lo mantienes y tú respondes por lo que el asistente pueda hacer con él. La ventaja es el control total sobre qué herramientas existen. Si algún día hay un servidor oficial, estará anunciado en las páginas de documentación y esta guía se actualizará.

Qué herramientas exponer (empieza solo con lectura)

HerramientaEndpoint de la APIRiesgoObservación
instance_statusGET /{instanceId}/instance/statusBajoMuestra si la instancia está conectada
check_numbersPOST /{instanceId}/chat/checkBajoRecibe numbers y devuelve isInWhatsapp y jid
find_messagesPOST /{instanceId}/message/findMedioLee conversaciones; dato personal
send_textPOST /{instanceId}/send/textAltoEnvía un mensaje de verdad; exige candado

Empieza con las tres primeras y agrega send_text después de probar los candados de la sección de seguridad. Quien lee mensajes de clientes debe tratarlos como dato personal y como entrada no confiable, ya que el texto de un cliente puede intentar darle instrucciones al asistente (inyección de prompt).

Código: servidor MCP en TypeScript sobre la API de ZapZap

El servidor de abajo usa el transporte stdio, el más simple para correr localmente: el cliente inicia el proceso y conversa por la entrada y salida estándar. Cada herramienta tiene un esquema de entrada en zod y devuelve texto. Las credenciales vienen de variables de entorno del proceso, nunca del asistente.

La herramienta send_text tiene tres candados: solo envía a números de una lista permitida (ZAPZAP_ALLOWED), limita el tamaño del texto y queda apagada a menos que ZAPZAP_ENABLE_SEND sea true. Instala con npm install @modelcontextprotocol/sdk zod y compila con tsc o ejecuta con tsx.

TypeScript (server.ts)

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const BASE = "https://api.zapzapapi.com/api/v1/" + process.env.ZAPZAP_INSTANCE_ID;
const headers = {
  "Content-Type": "application/json",
  "x-api-key": process.env.ZAPZAP_API_KEY ?? "",
  "x-api-secret": process.env.ZAPZAP_API_SECRET ?? "",
};
const allowed = new Set((process.env.ZAPZAP_ALLOWED ?? "").split(",").filter(Boolean));
const sendEnabled = process.env.ZAPZAP_ENABLE_SEND === "true";

async function call(method: "GET" | "POST", path: string, body?: unknown) {
  const res = await fetch(BASE + path, { method, headers, body: body ? JSON.stringify(body) : undefined });
  const text = await res.text();
  if (!res.ok) throw new Error("ZapZap " + res.status + ": " + text.slice(0, 300));
  return text;
}
const ok = (text: string) => ({ content: [{ type: "text" as const, text }] });

const server = new McpServer({ name: "whatsapp-zapzap-exemplo", version: "0.1.0" });

server.registerTool(
  "instance_status",
  { description: "Mostra se a instancia de WhatsApp esta conectada." },
  async () => ok(await call("GET", "/instance/status")),
);

server.registerTool(
  "check_numbers",
  {
    description: "Verifica quais numeros (com DDI, so digitos) tem WhatsApp.",
    inputSchema: { numbers: z.array(z.string().regex(/^\d{10,15}$/)).min(1).max(50) },
  },
  async ({ numbers }) => ok(await call("POST", "/chat/check", { numbers })),
);

server.registerTool(
  "find_messages",
  {
    description: "Lista mensagens recentes de uma conversa (chatid, ex: 5511999999999@s.whatsapp.net).",
    inputSchema: { chatid: z.string(), limit: z.number().int().min(1).max(30).default(10) },
  },
  async ({ chatid, limit }) => ok(await call("POST", "/message/find", { chatid, limit, offset: 0 })),
);

if (sendEnabled) {
  server.registerTool(
    "send_text",
    {
      description: "Envia uma mensagem de texto. So funciona para numeros da lista permitida.",
      inputSchema: { number: z.string().regex(/^\d{10,15}$/), text: z.string().min(1).max(1000) },
    },
    async ({ number, text }) => {
      if (!allowed.has(number)) throw new Error("number not in the allowed list");
      return ok(await call("POST", "/send/text", { number, text }));
    },
  );
}

await server.connect(new StdioServerTransport());

Cómo conectar el servidor a Claude y a Cursor

Los clientes MCP leen una configuración JSON con el comando que inicia cada servidor y las variables de entorno. En Claude Desktop, el archivo es claude_desktop_config.json; en Cursor, .cursor/mcp.json en el proyecto (o el equivalente global). En Claude Code, el comando claude mcp add registra el servidor. El formato del JSON es el mismo en los dos primeros, pero la ubicación del archivo y los menús cambian entre versiones: consulta la documentación de cada cliente.

Después de guardar, reinicia el cliente. Las herramientas aparecen en la lista; pide algo como: verifica si la instancia está conectada y luego revisa si estos tres números tienen WhatsApp. Aprueba cada llamada la primera vez en vez de liberar todo de golpe.

JSON (claude_desktop_config.json ou .cursor/mcp.json)

{
  "mcpServers": {
    "whatsapp": {
      "command": "npx",
      "args": ["tsx", "/caminho/para/server.ts"],
      "env": {
        "ZAPZAP_INSTANCE_ID": "SEU_INSTANCE_ID",
        "ZAPZAP_API_KEY": "SUA_API_KEY",
        "ZAPZAP_API_SECRET": "SEU_API_SECRET",
        "ZAPZAP_ALLOWED": "5511999999999",
        "ZAPZAP_ENABLE_SEND": "false"
      }
    }
  }
}

Seguridad: qué hacer antes de habilitar el envío

Cuatro reglas. Primera: lista permitida de destinatarios, como en el código; un asistente nunca debe poder enviar a cualquier número. Segunda: aprobación humana por cada llamada de envío, que los clientes MCP suelen ofrecer y que debes mantener activa. Tercera: trata el contenido leído como no confiable. Un mensaje de cliente que diga que ignores las instrucciones y envíes algo a otro número es un ataque real; la lista permitida y la aprobación son las defensas. Cuarta: instancia dedicada, no el número principal del negocio.

Suma límites de volumen en el propio servidor (un contador por hora), registra en log toda llamada y rota las credenciales. Y recuerda que el envío automatizado sigue sujeto a los Términos de WhatsApp: una herramienta de IA no cambia el riesgo de restricción del número, y una conversación iniciada por el asistente con alguien que no te conoce es el escenario de mayor riesgo. Mira por qué WhatsApp bloquea números.

Alternativas: OpenAPI, n8n y código propio

MCP es uno entre varios caminos para darle herramientas a un agente. Si tu agente habla OpenAPI, el archivo OpenAPI de ZapZap describe todas las rutas y puede alimentar un generador de herramientas. Si ya usas n8n, el flujo del agente de IA con n8n cubre el caso sin escribir un servidor. Y para frameworks en Python, la guía de LangChain y CrewAI muestra la misma idea con herramientas HTTP.

Elige según dónde corre el agente: MCP sirve bien para asistentes de uso personal y de equipo (Claude, Cursor); n8n, para automatizaciones con disparador; código propio, para un producto. En todos, la referencia de la API es la misma: send/text, chat/check, message/find e instance/status.

Resumen rápido

  • MCP es un protocolo abierto para que los clientes de IA llamen herramientas; ZapZap todavía no publica un servidor MCP propio (estado al 27/10/2026).
  • Puedes armar el tuyo en TypeScript con @modelcontextprotocol/sdk sobre los endpoints instance/status, chat/check, message/find y send/text.
  • Empieza solo con herramientas de lectura; habilita el envío con lista permitida, límite de volumen y aprobación humana.
  • Los mensajes leídos son entrada no confiable: la inyección de prompt es un riesgo real.
  • El envío automatizado sigue sujeto a los Términos de WhatsApp, con o sin asistente de IA.

Lee también

Preguntas frecuentes

¿ZapZap tiene un servidor MCP listo?

No. Al 27/10/2026 no hay un servidor MCP publicado y mantenido por ZapZap. La guía muestra cómo armar el tuyo sobre la API REST existente. Lo que está publicado es la API, el OpenAPI y el paquete n8n-nodes-zapzap para n8n.

¿Cómo uso WhatsApp como herramienta en Claude?

Arma (o instala) un servidor MCP que llame a la API, regístralo en la configuración del cliente (claude_desktop_config.json en Claude Desktop, o claude mcp add en Claude Code) y reinicia. Las herramientas aparecen para que el asistente las llame, con tu aprobación.

¿Es seguro dejar que un asistente de IA envíe WhatsApp?

Solo con candados: lista permitida de destinatarios, aprobación humana por envío, límite de volumen, log e instancia dedicada. Empieza solo con herramientas de lectura y trata el texto leído como no confiable por la inyección de prompt.

¿Cuál es la diferencia entre MCP y llamar a la API directamente?

La API es la interfaz del servicio. MCP es una capa estandarizada que presenta acciones de la API como herramientas descubiertas por el cliente de IA. Escribes el servidor una vez y cualquier cliente MCP compatible lo usa.

¿Funciona en Cursor y en otros clientes?

Cualquier cliente que hable MCP puede usar el servidor. Cursor lee un mcp.json con el comando y las variables de entorno. Las ubicaciones de archivo y los menús cambian entre versiones, así que consulta la documentación del cliente que uses.

Empieza por la API: es la base de cualquier agente

Crea la cuenta, verifica tu teléfono y recibe el crédito de bienvenida, sin depositar (uno por teléfono, sujeto a la campaña vigente). Conecta por código QR y prueba las llamadas antes de exponerlas como herramientas.