TL;DR: Instala cinco MCP servers en un chat de Cursor: Whapi.Cloud para enviar, leer y revisar el health de WhatsApp, PostgreSQL para las filas del CRM, GitHub para el handler del webhook, Sentry para la ruta del request y Playwright para la UI de staging. Demuestra cada flujo por separado. Combina un prompt solo cuando cada tarjeta ya funciona. Omite wrappers de Cloud API que solo envían y nunca leen CRM, repo, errores o el navegador.
Cinco MCP servers le dan a un desarrollador Python un agente de IA con WhatsApp, datos del CRM, código fuente, errores de producción y la UI del CRM, de modo que el trabajo de integración de WhatsApp corre desde un solo chat en lugar de cinco clientes REST. Whapi.Cloud es el MCP de WhatsApp API en ese flujo. PostgreSQL, GitHub, Sentry y Playwright son las capas compañeras.
Hemos visto equipos conectar un MCP de WhatsApp solo Graph y seguir usando psql, GitHub y Sentry en otras ventanas. Un chat entrante que nunca crea un lead en el CRM es el escenario que muestra el hueco.
Model Context Protocol estandariza el acceso a herramientas en una sesión de agente. Conecta el canal, no pegues mcp.json aquí y ejecuta los cinco flujos.
Qué cubre de verdad un ranking de MCP servers para WhatsApp API
La consulta de SERP nombra cinco capas de stack en un chat de agente, no cinco WhatsApp APIs. Un MCP de Cloud API que solo envía sigue dejando el CRM, GitHub, Sentry y el navegador en otras ventanas.
Los resultados de SERP para "top mcp servers whatsapp api integration" son wrappers de envío Graph. Llaman a Meta Cloud API y se detienen: sin fila de lead, sin handler, sin issue de Sentry, sin captura del CRM. El primer error es instalar un MCP de WhatsApp que salió en la búsqueda y después preguntarse por qué Cursor no termina una tarea de integración Python.
Llámalo un stack de cinco MCP en un chat. Whapi.Cloud es la capa que mira a WhatsApp. Los otros cuatro servers viven en la misma sesión de Cursor. Copias cinco flujos desde un solo chat.
Cada fila es un trabajo distinto. Los servers compañeros no sustituyen el canal de WhatsApp.
| MCP server | Rol en el stack | Tarea de ejemplo del agente |
|---|---|---|
| Whapi MCP (Whapi.Cloud) | Capa de WhatsApp API | Enviar una respuesta, listar mensajes entrantes, comprobar si un número existe, GET health del canal |
| PostgreSQL MCP | Datos del CRM | Encontrar un cliente por teléfono, listar tickets y deals, insertar un lead después de aprobación |
GitHub MCP (github/github-mcp-server) |
Código fuente | Abrir el handler del webhook, inspeccionar issues y pull requests |
Sentry MCP (@sentry/mcp-server) |
Errores de producción | Seguir el webhook al handler y al CRM a lo largo de un request |
Playwright MCP (@playwright/mcp) |
UI del CRM | En staging, crear un contacto y verificar el hilo de la conversación |
Un MCP personal de WhatsApp Web no pertenece a ninguna de esas filas como CRM de producción. Trátalo como una sesión de escritorio. Las cinco tarjetas de abajo son los trabajos listos para producción.
Whapi MCP es la capa de WhatsApp API, no el stack completo
Un MCP de Cloud API que solo envía no es la capa de WhatsApp de este stack. Whapi MCP maneja envío, lectura y health en vivo en el mismo chat de agente; después entran CRM, GitHub, Sentry y el navegador.
Un wrapper MCP de Cloud API llama a Graph para enviar y recibir y se detiene. Elígelo solo si ya operas sobre Meta Cloud API. Elige Whapi MCP cuando el agente debe operar un número de WhatsApp conectado y luego pasar el testigo a los otros cuatro servers.
| Dimensión | Wrapper MCP de Cloud API | MCP gateway QR/sesión de Whapi |
|---|---|---|
| Credenciales | Token de app Meta + WABA | Token de canal de Whapi.Cloud después del scan QR |
| Revisión de Meta | Verificación de negocio y aprobación de plantillas | No se requiere para conectar un número |
| Modelo de entrada | Solo webhooks; sin consulta directa al canal | Webhooks más consultas en vivo de mensajes, contactos y chats |
| Plantillas / ventana de 24 horas | Obligatorias para la mayoría de los envíos fuera de la ventana | Sin bloqueo por plantilla en conversaciones regulares |
| Grupos / canales | Limitados o no disponibles | Acceso API completo a grupos, comunidades, canales y estados |
| Quién aloja los webhooks | Tu endpoint HTTPS, alcanzable públicamente | Tu endpoint HTTPS; el estado del canal se puede consultar aunque se pierda un webhook |
| Encaje con el flujo del agente | Bajo: solo envío y recepción Graph | Alto: capa de WhatsApp que se encadena con servers de DB, código, errores y UI |
En la WhatsApp Business API oficial, la verificación de negocio de Meta y la aprobación de plantillas se interponen frente a la mayoría de los envíos. En Whapi.Cloud esas barreras no son necesarias para conectar un número, y las conversaciones regulares no tienen bloqueo por plantilla, porque el canal corre sobre sockets de sesión web.
También compras un gateway administrado en lugar de hospedar tú mismo un wrapper de Graph. Grupos, canales, estados y chequeos de número se quedan en esta superficie de WhatsApp. Un MCP de Cloud API solo de plantillas nunca los expone.
No pegues mcp.json aquí. Conecta Whapi MCP con la guía de setup para Cursor, VS Code y GitHub Copilot y luego ejecuta las lecturas HTTP de abajo.
Envío, lectura y health del canal en vivo
Whapi.Cloud expone esos chequeos por HTTP en https://gate.whapi.cloud/. Escribe REST en Python contra ese host. GET /messages/list devuelve mensajes recientes. GET /messages/list/{ChatID} acota una conversación. GET /messages/{MessageID} devuelve el objeto completo. HEAD /contacts/{ContactID} es solo existencia: usa HEAD, no GET, cuando solo necesitas un sí o un no. GET devuelve metadatos del contacto. HEAD responde si el número está en WhatsApp.
GET /health reporta el estado del canal. POST /messages/text envía un body a un chat id; los campos requeridos son to y body. Un messages vacío en la ventana objetivo significa que el número nunca llegó a este canal. Culpa al CRM después.
import os
import requests
TOKEN = os.environ["WHAPI_TOKEN"]
headers = {"Authorization": f"Bearer {TOKEN}"}
# GET /health first. A dead channel makes every later MCP look like a CRM bug.
health = requests.get("https://gate.whapi.cloud/health", headers=headers)
health.raise_for_status()
# from_me=False keeps the list on inbound. An empty list here is a channel miss; look at CRM only after this returns rows.
inbound = requests.get(
"https://gate.whapi.cloud/messages/list",
headers=headers,
params={"count": 50, "from_me": False},
).json()
contact_id = "15551234567"
# HEAD 404 means this ContactID is not on WhatsApp. Do not INSERT a CRM lead from a guessed number.
# GET /contacts/{ContactID} returns metadata; existence-only is HEAD /contacts/{ContactID}.
exists = requests.head(
f"https://gate.whapi.cloud/contacts/{contact_id}",
headers=headers,
)
print(health.status_code, len(inbound.get("messages", [])), exists.status_code)
Whapi MCP genera esta superficie desde OpenAPI, así que el agente conserva los mismos nombres que la documentación HTTP. La URL del webhook sigue siendo tuya. MCP inspecciona el estado del canal cuando se perdió un webhook. No hospeda ese endpoint por ti.
Con PostgreSQL MCP buscas clientes, tickets y deals, y escribes leads
Cuando el canal de WhatsApp ya se puede consultar, PostgreSQL MCP busca clientes por teléfono, abre tickets, revisa deals, escribe leads y atrapa filas duplicadas.
Dale a esta tarjeta el mismo peso que a la de WhatsApp. Pide un cliente por teléfono E.164, luego tickets, deals abiertos, un upsert de lead y después duplicados antes de cualquier escritura. Enviar WhatsApp es trivial. Recibir con fiabilidad y la deduplicación en reintentos es lo difícil: un webhook reintentado inserta a la misma persona dos veces si indexas solo por teléfono e ignoras el message id.
En la práctica, los equipos que se saltan ese chequeo insertan el mismo lead dos veces. Mantén PostgreSQL MCP en solo lectura sobre leads y contactos de producción por defecto. Propón el INSERT. Espera a un humano. Las escrituras del día uno pertenecen a tablas de lookup que opera el operador.
Un loop útil es WhatsApp a IA a PostgreSQL y de vuelta a WhatsApp: chat entrante, acción de CRM, respuesta saliente en el mismo número. La búsqueda por teléfono y el estado del deal siguen siendo lo que importa en los días tranquilos. El framework de decisión para integrar WhatsApp con CRM trata los campos perdidos como un problema de sincronización de datos, y ese es el trabajo de esta tarjeta.
La consulta de 24 horas de inbound sin lead está anidada aquí a propósito. Filtra tu tabla de mensajes por received_at. En la WhatsApp Business API oficial, una ventana de mensajería de 24 horas bloquea la mayoría de los envíos fuera de plantillas. En Whapi.Cloud este SQL es solo higiene de CRM sobre received_at, porque las conversaciones regulares no tienen ventana de plantilla.
-- Nested hygiene query: inbound phones in the last 24 hours with no lead row.
-- Skipping the join on message_id during webhook retries duplicates the same person.
SELECT m.phone_e164, m.received_at, m.message_id
FROM inbound_messages m
LEFT JOIN leads l ON l.phone_e164 = m.phone_e164
WHERE m.received_at >= NOW() - INTERVAL '24 hours'
AND l.id IS NULL
ORDER BY m.received_at DESC;
Nombra el Postgres MCP que de verdad corres. No hay una identidad npm canónica única para copiar. Apúntalo a una réplica cuando puedas. El agente debe devolver id, phone_e164, created_at y un flag de duplicado, y detenerse.
Cómo GitHub MCP conecta el JSON del webhook con el handler del CRM
Cuando los leads se ven mal en el CRM, GitHub MCP mapea el JSON del webhook de Whapi sobre el handler del conector que debería haber persistido esas filas.
Whapi.Cloud entrega JSON de webhook a tu endpoint HTTPS. Tu servidor decide qué campos se vuelven columnas del CRM: eso es JSON de webhook de propiedad del desarrollador. GitHub MCP (github/github-mcp-server) abre ese servidor sin salir de Cursor. Busca en el repo, issues y pull requests. Sentry no va a escribir el handler.
Lo que suele importar:
-
Búsqueda en el repo: encuentra el módulo del conector CRM y la función que lee el body del webhook.
-
Issues y PRs: busca cambios recientes de mapeo. Un campo renombrado en el payload suele aterrizar en un PR del viernes sin test de CRM. Lee el diff y detente.
-
Ejemplo anidado: si el conector maneja
messages.posty nunca escribecontact_id, la fila del lead queda vacía mientras el canal se ve sano. Corrige el mapeo y vuelve a correr la tarjeta de PostgreSQL.
El formato de webhooks entrantes documenta arrays como messages[], statuses[], chats[] y contacts[]. Mantén GitHub MCP en solo lectura hasta que un humano abra el PR. Pide la ruta del archivo, el nombre de la función y la clave JSON exacta que lee el conector. Si dos handlers coinciden con el mismo nombre de evento, abre ambos archivos y compara la escritura de columna.
Los handlers Python que ya ingieren webhooks de Whapi pueden partir del tutorial de bot de WhatsApp en Python. La tarjeta de GitHub responde qué archivo y qué campo.
Sentry MCP sigue el webhook desde el handler hasta el CRM
Cuando GitHub ya mostró el handler, Sentry MCP sigue ese webhook por el handler y el CRM hasta que el stack trace nombra la línea que falla.
Usa esta tarjeta para investigación en producción. No escribe código del handler. @sentry/mcp-server trae el issue, el stack, los tags y los breadcrumbs para que dejes de discutir que el cliente nunca envió un mensaje. El movimiento útil es un trace de la ruta del request: el webhook llegó, el handler corrió, la llamada al CRM devolvió 4xx o se agotó el tiempo, la respuesta saliente nunca salió. Eso sigue la misma ruta de evento-reacción que se supone que toma tu webhook.
Los proyectos que omiten un tag de teléfono o un message id en los eventos de Sentry pasan el incidente comparando capturas. Correlaciona por timestamp más el mismo E.164 que usaste en PostgreSQL. Busca un error de validación del CRM, una restricción unique por duplicados, o un contact_id vacío después de un rename de payload que ya viste en GitHub.
Mantén la búsqueda de issues en solo lectura. No dejes que el agente resuelva o borre issues de Sentry. Después del fix, un humano marca el issue como listo. Arranca el agente desde el issue completo: los snippets pegados esconden breadcrumbs. Si el trace está limpio y el canal tenía el mensaje entrante, el bug que queda es de mapeo o de UI. Pásalo a GitHub o Playwright. Si ves comportamiento inesperado del canal, habla con el equipo de soporte de Whapi.Cloud desde el widget de chat en whapi.cloud.
Playwright MCP crea un contacto en el CRM y verifica la conversación
Cuando Sentry ya nombró la línea que falla, Playwright MCP todavía crea un contacto en el CRM de staging y verifica la conversación que el equipo de soporte realmente ve.
Postman solo prueba la ruta HTTP. Un 200 de POST /messages/text no significa que el panel de conversación del CRM renderizó el hilo. @playwright/mcp abre staging, crea un contacto, dispara un envío (o espera el webhook) y verifica el texto que el operador capturaría para soporte. La colección de Postman de Whapi.Cloud es el chequeo HTTP. Playwright es el chequeo del panel.
Los tableros SPA mienten de un modo que los clientes REST no ven. La API de lead devuelve 201 y la vista de conversación sigue ligada a un contact_id viejo y muestra un hilo en blanco. Captura el árbol de accesibilidad: nombre visible, E.164, último body. Si ese nodo falta, vuelve a revisar el mapeo del webhook antes de tocar selectores CSS.
- Abre el formulario de contacto del CRM de staging y crea un contacto con el E.164 de prueba.
- Envía o recibe un mensaje de WhatsApp por el canal de Whapi que ya verificaste.
- Falla el run si el hilo falta, incluso cuando HTTP fue 200. Confirma la fila de Postgres solo después de que la tarjeta de PostgreSQL ya corrió.
Deja el número de prueba creado en staging. Quédate con el navegador ahí: una sesión de producción que puede borrar un deal es el runtime equivocado. Si Playwright está verde y PostgreSQL está vacío, tienes un bug de sync. Si ambos están verdes y Sentry está callado, deja de buscar un fallo de entrega.
Combina las cinco herramientas MCP en un prompt solo cuando cada flujo ya funciona
Combina las cinco herramientas MCP en un prompt solo después de que el assert de conversación de Playwright y los demás flujos independientes ya funcionan.
Trata la cadena como una demo del WhatsApp API MCP sentado junto a cuatro servers compañeros. No sustituye las cinco tarjetas.
After each standalone workflow works:
1. Whapi: GET /health, GET /messages/list, HEAD /contacts/{ContactID}.
2. PostgreSQL: find client by phone; propose a lead insert and wait for approval.
3. Sentry: errors for this webhook timestamp.
4. GitHub: CRM connector that handles messages.post.
5. Playwright: staging contact plus conversation assert.
No production writes. Stop at the first broken layer.
Si una capa falla, quédate en esa tarjeta. No saltes a Playwright para «ver si se ve bien».
Las escrituras del agente, el alcance de Sentry y el navegador de staging todavía necesitan límites
Ese prompt de composición todavía necesita límites: Postgres de producción en solo lectura, alcance de org en Sentry, navegadores de staging, y ningún MCP personal de WhatsApp Web como CRM.
Mantén leads y contactos de producción en solo lectura. Restringe las escrituras a tablas de lookup del operador después del visto bueno de un humano. Apunta Playwright a staging. Limita Sentry MCP a la org y el proyecto que pretendes exponer. Rechaza un MCP personal de WhatsApp Web como CRM de producción: es una sesión de escritorio. Los chats de WhatsApp que nunca sincronizan al CRM nunca entran al pipeline de ventas, y así es como los equipos inmobiliarios pierden leads de entrada.
Cinco MCP servers siguen dando a un desarrollador Python WhatsApp, datos de CRM, código, errores y UI desde un chat, con Whapi.Cloud como el MCP de WhatsApp API en ese flujo. Instala las cinco tarjetas independientes y después combina.









