TL;DR: Instale cinco servidores MCP no mesmo chat do Cursor: Whapi.Cloud para enviar, ler e checar health no WhatsApp; PostgreSQL para as linhas do CRM; GitHub para o handler do webhook; Sentry para o caminho da requisição; e Playwright para a UI de staging. Prove cada fluxo sozinho. Só junte num único prompt depois que todos os cards funcionarem. Pule wrappers da Cloud API que só enviam e nunca leem CRM, repositório, erros ou o browser.
Cinco servidores MCP dão a um desenvolvedor Python um único agente de IA com WhatsApp, dados de CRM, código-fonte, erros de produção e a UI do CRM. O trabalho de integração com o WhatsApp sai de um único chat, em vez de cinco clientes REST. A Whapi.Cloud é o MCP da API do WhatsApp nesse fluxo. PostgreSQL, GitHub, Sentry e Playwright são as camadas companheiras.
Já vimos times ligarem um MCP de WhatsApp só com Graph e ainda manterem psql, GitHub e Sentry em outras janelas. Um chat inbound que nunca cria um lead no CRM é o cenário que mostra o buraco.
O Model Context Protocol padroniza o acesso a ferramentas numa única sessão do agente. Conecte o canal, pule o copy-paste do mcp.json e rode os cinco fluxos.
O que a busca por 'melhores servidores MCP para API do WhatsApp' realmente pede
A busca no SERP descreve cinco camadas de stack no mesmo chat do agente, não cinco APIs do WhatsApp. Um MCP da Cloud API que só envia ainda deixa CRM, GitHub, Sentry e o browser em outras janelas.
Os resultados do SERP para "top mcp servers whatsapp api integration" são wrappers de envio via Graph. Chamam a Meta Cloud API e param: sem linha de lead, sem handler, sem issue no Sentry, sem screenshot do CRM. O primeiro erro é instalar um único MCP de WhatsApp vindo da busca e depois se perguntar por que o Cursor não fecha uma tarefa de integração em Python.
Chame isso de stack de cinco MCP num único chat. A Whapi.Cloud é a camada voltada ao WhatsApp. Os outros quatro servidores ficam na mesma sessão do Cursor. Você copia cinco fluxos de um único chat.
Cada linha é um trabalho diferente. Os servidores companheiros não substituem o canal do WhatsApp.
| Servidor MCP | Papel no stack | Exemplo de tarefa do agente |
|---|---|---|
| Whapi MCP (Whapi.Cloud) | Camada da API do WhatsApp | Enviar uma resposta, listar mensagens inbound, checar se o número existe, GET de health do canal |
| PostgreSQL MCP | Dados do CRM | Encontrar um cliente pelo telefone, listar tickets e deals, inserir um lead depois da aprovação |
GitHub MCP (github/github-mcp-server) |
Código-fonte | Abrir o handler do webhook, inspecionar issues e pull requests |
Sentry MCP (@sentry/mcp-server) |
Erros de produção | Rastrear o webhook até o handler e o CRM numa única requisição |
Playwright MCP (@playwright/mcp) |
UI do CRM | No staging, criar um contato e validar o fio da conversa |
Um MCP pessoal do WhatsApp Web não entra em nenhuma dessas linhas como CRM de produção. Trate como sessão de desktop. Os cinco cards abaixo são os trabalhos com formato de produção.
O Whapi MCP é a camada da API do WhatsApp, não o stack inteiro
Um MCP da Cloud API que só envia não é a camada de WhatsApp deste stack. O Whapi MCP cobre envio, leitura e health ao vivo no mesmo chat do agente; depois entram CRM, GitHub, Sentry e o browser.
Um wrapper MCP da Cloud API chama Graph para enviar/receber e para. Escolha essa via só se você já vive na Meta Cloud API. Escolha o Whapi MCP quando o agente precisa operar um número de WhatsApp já conectado e depois passar o bastão para os outros quatro servidores.
| Dimensão | Wrapper MCP da Cloud API | MCP gateway QR/sessão da Whapi |
|---|---|---|
| Credenciais | Token do app Meta + WABA | Token do canal Whapi.Cloud depois do scan do QR |
| Review da Meta | Verificação de negócio e aprovação de template | Não é exigida para conectar um número |
| Modelo inbound | Só webhooks; sem consulta direta ao canal | Webhooks mais consultas ao vivo de mensagem, contato e chat |
| Templates / janela de 24 horas | Obrigatório para a maior parte do outbound fora da janela | Sem trava de template em conversas regulares |
| Grupos / canais | Limitado ou indisponível | Acesso completo via API a grupos, comunidades, canais e statuses |
| Quem hospeda os webhooks | Seu endpoint HTTPS, acessível publicamente | Seu endpoint HTTPS; o estado do canal continua consultável mesmo se um webhook se perder |
| Adequação ao fluxo do agente | Baixo: só envio/recebimento via Graph | Alto: camada de WhatsApp que encadeia com servidores de DB, código, erro e UI |
Na API oficial do WhatsApp Business, a verificação de negócio da Meta e a aprovação de templates ficam na frente da maior parte do outbound. Na Whapi.Cloud esses gates não são exigidos para conectar um número, e conversas regulares não têm trava de template, porque o canal roda em sockets de sessão web.
Você também compra um gateway gerenciado, em vez de hospedar um wrapper Graph por conta própria. Grupos, canais, statuses e checagem de número continuam nessa superfície do WhatsApp. Um MCP da Cloud API só de templates nunca expõe isso.
Não cole o mcp.json aqui. Ligue o Whapi MCP com o guia de setup do Cursor, VS Code e GitHub Copilot, depois rode as leituras HTTP abaixo.
Envio, leitura e health do canal ao vivo
A Whapi.Cloud expõe essas checagens via HTTP em https://gate.whapi.cloud/. Escreva REST em Python contra esse host. GET /messages/list devolve as mensagens recentes. GET /messages/list/{ChatID} restringe a uma conversa. GET /messages/{MessageID} devolve o objeto completo. HEAD /contacts/{ContactID} é só existência: use HEAD, não GET, quando você só precisa de sim/não. GET devolve metadados do contato. HEAD responde se o número está no WhatsApp.
GET /health informa o status do canal. POST /messages/text envia um body para um chat id; os campos obrigatórios são to e body. Um messages vazio na janela alvo significa que o número nunca chegou a este canal. Culpe o CRM depois.
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)
O Whapi MCP gera essa superfície a partir do OpenAPI, então o agente usa os mesmos nomes da documentação HTTP. A URL do webhook continua sendo sua. O MCP inspeciona o estado do canal quando um webhook se perde. Ele não hospeda esse endpoint por você.
O PostgreSQL MCP encontra clientes, tickets e deals — e grava leads
Com o canal do WhatsApp consultável, o PostgreSQL MCP encontra clientes pelo telefone, abre tickets, checa deals, grava leads e pega linhas duplicadas.
Dê a este card o mesmo peso do card de WhatsApp. Peça um cliente pelo telefone E.164, depois tickets, deals abertos, um upsert de lead e, por fim, duplicatas antes de qualquer write. Enviar WhatsApp é trivial. Receber com confiabilidade e fazer deduplicação no retry é a parte difícil: um webhook reenviado insere a mesma pessoa duas vezes se você chaveia só no telefone e ignora o message id.
Na prática, times que pulam essa checagem inserem o mesmo lead duas vezes. Deixe o PostgreSQL MCP somente leitura em leads e contatos de produção por padrão. Proponha o INSERT. Espere um humano. Writes do primeiro dia pertencem a tabelas de lookup que o operador controla.
Um loop útil é WhatsApp para IA para PostgreSQL de volta para WhatsApp: chat inbound, ação no CRM, resposta outbound no mesmo número. Busca por telefone e status do deal continuam úteis mesmo nos dias calmos. O framework de decisão para integração WhatsApp–CRM trata campos perdidos como problema de sync de dados — e esse é o trabalho deste card.
A query de inbound sem lead nas últimas 24 horas fica aninhada aqui de propósito. Ela filtra a tabela de mensagens por received_at. Na API oficial do WhatsApp Business, uma janela de mensagens de 24 horas trava a maior parte do outbound fora de templates. Na Whapi.Cloud este SQL é só higiene de CRM em received_at, porque conversas regulares não têm janela de template.
-- 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;
Nomeie o Postgres MCP que você de fato roda. Não existe uma identidade npm canônica para copiar. Aponte para uma réplica quando puder. O agente deve devolver id, phone_e164, created_at e uma flag de duplicata — e parar.
O GitHub MCP liga o JSON do webhook ao handler do conector de CRM
Quando os leads no CRM parecem errados, o GitHub MCP mapeia o JSON do webhook da Whapi no handler do conector que deveria ter persistido essas linhas.
A Whapi.Cloud entrega o JSON do webhook no seu endpoint HTTPS. Seu servidor decide quais campos viram colunas do CRM: isso é JSON de webhook sob controle do desenvolvedor. O GitHub MCP (github/github-mcp-server) abre esse servidor sem sair do Cursor. Busque no repositório, nas issues e nos pull requests. O Sentry não vai escrever o handler.
Pontos típicos:
-
Busca no repo: encontre o módulo do conector de CRM e a função que lê o body do webhook.
-
Issues e PRs: procure mudanças recentes de mapeamento. Um campo do payload renomeado costuma cair numa PR de sexta sem teste de CRM. Leia o diff e pare.
-
Exemplo aninhado: se o conector trata
messages.poste nunca gravacontact_id, a linha do lead fica vazia enquanto o canal parece saudável. Corrija o mapeamento e rode de novo o card do PostgreSQL.
O formato dos webhooks de entrada documenta arrays como messages[], statuses[], chats[] e contacts[]. Mantenha o GitHub MCP somente leitura até um humano abrir a PR. Peça o caminho do arquivo, o nome da função e a chave JSON exata que o conector lê. Se dois handlers batem com o mesmo nome de evento, abra os dois arquivos e compare a gravação da coluna.
Handlers Python que já ingerem webhooks da Whapi podem começar pelo tutorial de bot WhatsApp em Python. O card do GitHub responde qual arquivo e qual campo.
O Sentry MCP rastreia o webhook do handler até o CRM
Depois que o GitHub mostra o handler, o Sentry MCP rastreia aquele webhook pelo handler e pelo CRM até o stack trace nomear a linha que falhou.
Use este card para investigação em produção. Ele não escreve código do handler. O @sentry/mcp-server puxa a issue, o stack, as tags e os breadcrumbs para você parar de discutir que o cliente nunca mandou mensagem. O movimento útil é um rastreio do caminho da requisição: o webhook chegou, o handler rodou, a chamada ao CRM devolveu 4xx ou deu timeout, a resposta outbound nunca saiu. Isso segue o mesmo caminho de evento-reação que o seu webhook deveria percorrer.
Projetos que pulam a tag de telefone ou o message id nos eventos do Sentry passam o incidente comparando screenshots. Correlacione no timestamp mais o mesmo E.164 que você usou no PostgreSQL. Procure um erro de validação do CRM, uma unique constraint em duplicatas ou um contact_id vazio depois de um rename de payload que você já viu no GitHub.
Mantenha a busca de issues somente leitura. Não deixe o agente resolver ou apagar issues do Sentry. Depois do fix, um humano marca a issue como concluída. Comece o agente pela issue completa: snippets colados escondem breadcrumbs. Se o trace está limpo e o canal tinha a mensagem inbound, o bug restante é mapeamento ou UI. Passe isso para o GitHub ou o Playwright. Se o canal se comportar de forma inesperada, fale com o time de suporte da Whapi.Cloud pelo widget de chat em whapi.cloud.
O Playwright MCP cria um contato no CRM e valida a conversa
Depois que o Sentry nomeia a linha que falhou, o Playwright MCP ainda cria um contato no CRM de staging e valida a conversa que o time de suporte de fato vê.
O Postman só prova o caminho HTTP. Um 200 de POST /messages/text não significa que o painel de conversa do CRM renderizou o fio. O @playwright/mcp abre o staging, cria um contato, dispara um envio (ou espera o webhook) e valida o texto que o operador mandaria de screenshot para o suporte. A coleção Postman da Whapi.Cloud é a checagem HTTP. O Playwright é a checagem do painel.
Telas de SPA mentem de um jeito que clientes REST não enxergam. A API de lead devolve 201, e a view de conversa ainda amarra num contact_id antigo e mostra um fio em branco. Capture a árvore de acessibilidade: nome visível, E.164, último body. Se esse nó estiver faltando, recheque o mapeamento do webhook antes de mexer em seletores CSS.
- Abra o formulário de contato do CRM de staging e crie um contato com o E.164 de teste.
- Envie ou receba uma mensagem de WhatsApp pelo canal Whapi que você já verificou.
- Reprove a execução se o fio estiver ausente, mesmo com HTTP 200. Confirme a linha no Postgres só depois que o card do PostgreSQL já rodou.
Cadastre o número de teste no staging. Deixe o browser lá: uma sessão de produção que consegue apagar um deal é o runtime errado. Se o Playwright está verde e o PostgreSQL está vazio, você tem um bug de sync. Se os dois estão verdes e o Sentry está quieto, pare de procurar falha de entrega.
Só junte as cinco ferramentas MCP depois que cada fluxo funcionar sozinho
Junte as cinco ferramentas MCP num único prompt só depois que a validação de conversa no Playwright e os outros fluxos isolados já funcionarem.
Trate a cadeia como uma demo do MCP da API do WhatsApp ao lado de quatro servidores companheiros. Ela não substitui os cinco cards.
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.
Se uma camada falhar, fique nesse card. Não pule para o Playwright para "ver se parece ok".
Writes do agente, escopo do Sentry e browsers de staging ainda pedem trava
Aquele prompt de composição ainda precisa de travas: Postgres de produção somente leitura, escopo de org no Sentry, browsers de staging e nenhum MCP pessoal de WhatsApp Web como CRM.
Mantenha leads e contatos de produção somente leitura. Restrinja writes a tabelas de lookup do operador depois que um humano confirmar. Aponte o Playwright para o staging. Limite o Sentry MCP à org e ao projeto que você pretende expor. Recuse um MCP pessoal de WhatsApp Web como CRM de produção: é uma sessão de desktop. Chats de WhatsApp que nunca sincronizam com o CRM nunca entram no pipeline de vendas — é assim que mesas de imobiliária perdem os leads que entram pelo WhatsApp.
Cinco servidores MCP ainda dão a um desenvolvedor Python WhatsApp, dados de CRM, código, erros e UI a partir de um único chat, com a Whapi.Cloud como o MCP da API do WhatsApp nesse fluxo. Instale os cinco cards isolados e só depois junte.









