# Design — MCP Server nativo no n8n para Mensageria (Z-PRO) **Data:** 2026-08-11 **Status:** Aprovado pelo usuário, aguardando plano de implementação. ## Objetivo Um MCP Server nativo do n8n, **standalone**, dedicado só a **enviar** mensagens de WhatsApp — desacoplado de qualquer provider de agendamento (Z-PRO, Klingo, SysLife, ClinicAll). O caso de uso original que motivou isso foi a confirmação de agenda (lembrete proativo perguntando se o paciente confirma a consulta), mas o MCP em si não sabe nada sobre agendamento — é só "enviar mensagem". Qualquer workflow futuro (agente conversacional, fluxo de confirmação, campanha, etc.) pode chamar essas tools, atribuídas manualmente pelo usuário conforme a necessidade. ## Relação com o trabalho anterior Reaproveita a mesma API do Z-PRO já integrada pro agendamento (`apigchat.gtigrupo.com.br/v2/api/external/{ApiID}/...`), mas é um **endpoint diferente** (envio de mensagem, não agenda) — provavelmente uma integração/ApiID diferente da usada pro agendamento, dado o padrão já visto nesta sessão de que cada integração cadastrada no Z-PRO tem seu próprio `ApiID` + Bearer token, não intercambiáveis (ver `docs/n8n-agendamento-runbook.md`, seção 13, gotcha 3). O motivo de ser um MCP separado, não parte do `MCP Server - ZPRO` (agendamento): a expectativa do usuário é que diferentes clientes usem diferentes backends de envio (WABA oficial, não oficial, híbrido) — se essas tools morassem dentro do MCP de agendamento de um provider específico, um cliente que trocasse de sistema de agendamento perderia a reutilização das tools de envio. Mantendo separado, qualquer workflow (de qualquer provider) pode apontar pra esse MCP de mensageria. ## Escopo: 4 tools desta rodada (de 10 endpoints documentados) | Tool | Endpoint | Uso | | --- | --- | --- | | `enviar_texto` | `POST /v2/api/external/{ApiID}/` (JSON) | Texto simples — canal não oficial ou dentro da janela de 24h do WABA oficial | | `enviar_template` | `POST /v2/api/external/{ApiID}/template` | Template WABA aprovado, sem parâmetros dinâmicos | | `enviar_template_com_parametros` | `POST /v2/api/external/{ApiID}/templateBody` | Template WABA aprovado, com parâmetros dinâmicos no corpo | | `enviar_template_marketing` | `POST /v2/api/external/{ApiID}/templateMarketingBody` | Template WABA de marketing, com componentes de header (ex.: imagem) + body | **Fora de escopo desta rodada** (documentados no manual/mensagem do usuário, sem caso de uso imediato): envio de mídia via multipart form-data, envio de mídia/áudio via URL pública, envio via Base64, envio via query params GET, busca de mensagem por `wamid` (`getMessageByMessageId`). ## Autenticação — pendência real a confirmar As credenciais Z-PRO já criadas nesta sessão são específicas de integrações de **agendamento** (`e372d4f0-...`/`ab2d51db-...` como ApiID). O envio de mensagem pode usar uma integração diferente (`ApiID` + Bearer token próprios) — possivelmente a credencial `ZPRO API Token - Canal QR - MC AGENDAMENTO` (criada quando o usuário mencionou "não é a versão que tem template da Meta, permite texto simples", que bate conceitualmente com o canal não oficial de texto simples), mas isso **não foi confirmado**, só é uma hipótese razoável dado o nome. Fica como pré-requisito de confirmação/teste antes de considerar a integração validada — mesmo espírito da lição já registrada no runbook (nunca assumir que ApiID e token de integrações diferentes são intercambiáveis). ## Arquitetura ``` [MCP Server Trigger] ──Tools──┬── enviar_texto ──▶ POST /v2/api/external/{ApiID}/ ("MCP Server - ├── enviar_template ──▶ POST /v2/api/external/{ApiID}/template Mensageria ZPRO") ├── enviar_template_com_parametros ──▶ POST /v2/api/external/{ApiID}/templateBody └── enviar_template_marketing ──▶ POST /v2/api/external/{ApiID}/templateMarketingBody ``` 5 workflows no total (servidor + 4 sub-workflows), mesmo padrão arquitetural dos outros MCP Servers deste projeto. Sem workflow de agente cliente — este MCP é consumido por outros workflows (a serem atribuídos manualmente pelo usuário depois), não tem conversa própria. ## Componentes ### Sub-workflow `enviar_texto` ``` [Execute Workflow Trigger] → [Config Mensageria] → [Montar corpo] → [POST /] → [Classificar resultado] ``` - **Execute Workflow Trigger**: `number` (obrigatório, formato `5511999999999`), `body` (obrigatório, texto da mensagem), `externalKey` (obrigatório, chave única de controle — ex.: `agenda-` pra rastrear de qual contexto veio o envio), `isClosed` (opcional, boolean, fecha o ticket após envio). - **Config Mensageria** (`Set`): `baseUrl`/`apiId` desta integração (placeholder até confirmar a pendência de autenticação acima). - **Montar corpo**: `{ body, number, externalKey, isClosed }`, só com os campos documentados. - **POST `/v2/api/external/{apiId}/`**: Bearer token (credencial `httpHeaderAuth`), `neverError: true` + `fullResponse: true`. - **Classificar resultado**: 2xx → sucesso (devolve o corpo cru — sem exemplo de resposta real capturado ainda pra validar um envelope específico); fora de 2xx → taxonomia genérica já usada nos outros providers (`AUTHENTICATION_ERROR` 401/403, `NOT_FOUND` 404, `VALIDATION_ERROR` 400/422, `ZPRO_MENSAGERIA_API_ERROR` demais). ### Sub-workflows `enviar_template` / `enviar_template_com_parametros` / `enviar_template_marketing` Mesmo esqueleto do `enviar_texto`, mudando o endpoint e o corpo da requisição: - `enviar_template`: `number`, `isClosed`, `templateName`, `templateLanguageCode` (ex.: `pt_BR`) → monta `{ number, isClosed, templateData: { messaging_product: "whatsapp", to: number, type: "template", template: { name: templateName, language: { code: templateLanguageCode } } } }`. - `enviar_template_com_parametros`: os mesmos campos acima + `parametrosBody` (lista de strings, cada uma vira `{ type: "text", text: valor }` dentro de `components[0].parameters`). - `enviar_template_marketing`: os mesmos campos de `enviar_template_com_parametros` + `headerImageUrl` (opcional, monta o componente `header` com `{ type: "image", image: { link: headerImageUrl } }` quando presente). Nenhum dos três inventa campo fora do que foi documentado pelo usuário — parâmetros de template genéricos o suficiente pra cobrir os exemplos reais mostrados (`hello_world`, template com 1 parâmetro de texto, template de marketing com header de imagem), sem assumir uma estrutura mais complexa (múltiplos parâmetros, múltiplos componentes) que não foi documentada. ## Fora de escopo (adiado) - Os 6 endpoints de envio de mídia/áudio/base64/busca listados acima (seção Escopo). - Qualquer lógica de "qual canal usar por cliente" (WABA oficial vs. não oficial vs. híbrido) — decisão de negócio de quem for atribuir a tool no workflow consumidor, não deste MCP. - A feature de confirmação de agenda em si (Klingo) — motivou a criação deste MCP, mas fica como trabalho separado, a ser desenhado depois, que vai **consumir** este MCP quando estiver pronto. ## Testes Diferente dos outros MCP Servers (que não têm clínica real disponível), este reaproveita a **clínica exemplo do Z-PRO, já em produção real** — então existe a tentação de testar direto contra ela. **Cuidado real**: enviar uma mensagem de teste manda uma mensagem de WhatsApp de verdade pro número de destino — ao contrário de criar um agendamento fictício (que pode ser apagado depois de conferido), uma mensagem enviada não pode ser "desenviada". Testar só com um número de celular de teste controlado pela equipe (nunca um número de paciente real), e confirmar visualmente no celular de teste antes de considerar validado. Validação estrutural (`n8n_validate_workflow`) segue a disciplina normal; a validação de autenticação (pendência acima) precisa ser resolvida antes de qualquer teste real de envio.