# Design — Workflow n8n de Agendamento via GChat/Z-PRO + gti-scheduling-mcp **Data:** 2026-08-10 **Status:** Aprovado pelo usuário, aguardando plano de implementação. ## Objetivo Construir o primeiro workflow n8n que recebe mensagens de clientes via GChat (webhook do Z-PRO), conduz a conversa com um agente de IA para capturar os dados necessários e realiza o agendamento de fato, chamando a tool `agendar` do `gti-scheduling-mcp` (que por sua vez delega ao Adapter do sistema da clínica — Z-PRO neste MVP). Escopo do MVP: **só agendamento** (`agendar`). Consulta de disponibilidade, cancelamento e remarcação ficam fora desta etapa. ## Contexto verificado (não inventado) Estes fatos vêm de um workflow real já em produção no n8n de referência ("Enforcer - GLPI"/fluxo de suporte via Z-PRO, código do node `1 - Decide` compartilhado pelo usuário) e de consultas diretas ao n8n (`devn8n.gtigrupo.com.br`) e ao registro de nodes via `n8n-mcp`: - O Z-PRO chama o webhook do n8n **uma vez por mensagem do cliente** — não agrupa/enfileira mensagens. - O corpo da requisição (`req = $json.body`) tem os campos: `step` (esperado `"process"`), `entrada` (texto da mensagem do cliente), `number` (telefone), `contactName`, `protocol` (identificador único do **atendimento**, não do telefone — o mesmo cliente pode ter vários atendimentos/protocolos ao longo do tempo). - **Se o workflow segurar a resposta** (esperando mais mensagens antes de responder), o Z-PRO **descarta** as mensagens seguintes do cliente (confirmado em teste real: 5 mensagens em sequência → 1 execução no n8n). O workflow precisa responder a cada execução, sempre. - A resposta ao Z-PRO é **texto puro** (não JSON), via node `Respond to Webhook` em modo texto. - O node oficial `MCP Client Tool` (`@n8n/n8n-nodes-langchain`) só suporta transporte HTTP Streamable/SSE — **não** suporta rodar um comando local via stdio. - O node comunitário `n8n-nodes-mcp` (`mcpClient`/`mcpClientTool`) suporta conexão via linha de comando (stdio) — é o caminho escolhido para não precisar alterar o transporte do `gti-scheduling-mcp` (que hoje só implementa `StdioServerTransport`). - O `gti-scheduling-mcp` (`ZProAdapter`/`KlingoAdapter`) já está pronto e testado para `agendar()` — nenhuma mudança de arquitetura nele é necessária para este workflow. ## Arquitetura ``` [Cliente WhatsApp] │ ▼ [Z-PRO/GChat] ──webhook──▶ [n8n: Webhook] → [Normalizar entrada] → [AI Agent] → [Respond to Webhook] │ ▲ (tool call) │ │ (memória de sessão) ▼ │ [MCP Client Tool] [Simple Memory] (stdio, agendar) (sessionId = protocol) │ ▼ [gti-scheduling-mcp: tool "agendar"] │ ▼ [AdapterFactory → ZProAdapter/KlingoAdapter] │ ▼ [Sistema real da clínica: Z-PRO/Klingo] ``` O `gti-scheduling-mcp` não sofre nenhuma alteração de arquitetura para este workflow — o n8n é só mais um cliente MCP, como qualquer outro. ## Componentes (nós do n8n) 1. **Webhook (Z-PRO)** — `POST`, recebe `{step, entrada, number, contactName, protocol}`. 2. **Normalizar entrada** (`Set`/`Code`) — - Valida `step === "process"`; caso contrário, responde com um texto mínimo e encerra (mesma defesa do fluxo de referência). - Monta as variáveis usadas a seguir: `sessionId = protocol`, `mensagem = entrada`, `nomeContato = contactName`, `telefone = number`. - **Nó de configuração da clínica** (fixo por cópia do workflow, não dinâmico em runtime): `provider` (ex.: `"zpro"`), `clinicId`, e referência de qual Credential do n8n / config do MCP Client Tool usar para esta clínica. Cada clínica nova = uma cópia deste workflow com esses valores ajustados e seu próprio webhook cadastrado no Z-PRO — não há branching dinâmico de provider dentro de uma mesma execução. 3. **AI Agent** (`@n8n/n8n-nodes-langchain.agent`) — - Chat Model: OpenAI (credencial a configurar no n8n). - System prompt cobre: confirmar o nome completo do paciente (mesmo já tendo `contactName`), perguntar data/horário desejado, motivo (opcional), nunca chamar `agendar` mais de uma vez por atendimento, responder sempre em português, tom cordial, nunca inventar dado que o cliente não informou. - **Memória**: `Simple Memory` (`memoryBufferWindow`), `sessionId = protocol`. Trade-off aceito para o MVP: essa memória vive na RAM do processo do n8n — um restart do n8n no meio de um atendimento perde o histórico da conversa. Evolução futura, se necessário: Postgres ou Redis Chat Memory (durável, mas exige infraestrutura adicional). - **Tool**: `MCP Client Tool` (via `n8n-nodes-mcp`, transporte stdio), expondo a tool `agendar` do `gti-scheduling-mcp` (comando: `node dist/index.js`, variáveis de ambiente = credenciais da clínica, vindas de uma Credential do n8n — nunca hardcoded no node/JSON do workflow). 4. **Respond to Webhook** — modo texto simples; devolve só a resposta em linguagem natural produzida pelo AI Agent. ## Tratamento de erro Quando `agendar` falha (`VALIDATION_ERROR`, `AUTHENTICATION_ERROR`, `NOT_FOUND`, `ZPRO_API_ERROR`/`KLINGO_API_ERROR`, timeout, etc.), o MCP já devolve uma resposta estruturada (`success:false` + código/mensagem) — o AI Agent recebe isso como resultado da tool e decide, em linguagem natural, como comunicar isso ao cliente (pedir os dados de novo, avisar que vai encaminhar para um atendente humano, etc.), dentro do que o system prompt permitir. Não há tratamento hard-coded por código de erro neste workflow — isso fica deliberadamente a cargo do agente, para manter o MVP simples. ## Risco de agendamento duplicado (mitigação no nível do workflow) O `ZProAdapter`/`KlingoAdapter` já trata qualquer HTTP 2xx do provider como sucesso operacional (sem risco de duplicidade por reinterpretação de resposta ambígua — ver `docs/zpro-api-mapping.md`). O risco adicional neste workflow é de outra natureza: o **próprio agente** decidir chamar a tool `agendar` mais de uma vez na mesma conversa (ex.: o cliente confirma duas vezes, ou o agente se confunde). Mitigação adotada para o MVP: instrução explícita no system prompt para nunca chamar `agendar` mais de uma vez por atendimento (`protocol`). Isto é uma mitigação por prompt, não uma garantia determinística — se isso se mostrar insuficiente em uso real, a evolução natural é adicionar uma marcação de "já agendado" no estado da sessão, verificada por código antes de permitir uma nova chamada da tool. ## Fora de escopo (explicitamente adiado) - Consulta de disponibilidade (`consultar_horarios`) — não implementada para nenhum provider neste MVP (Z-PRO não suporta; Klingo tem lacuna de mapeamento de resposta). - Cancelamento/remarcação de agendamento. - Transferência automática de fila/atendimento humano no Z-PRO após o agendamento (padrão existente no fluxo de referência via `updateticketinfo`) — pode ser adicionado depois, não é necessário para o MVP funcionar. - Suporte a múltiplas clínicas com providers diferentes atendidas por uma única execução/webhook compartilhado — cada clínica é uma cópia dedicada do workflow. - Memória de conversa durável entre restarts do n8n (Postgres/Redis Chat Memory). ## Testes Este workflow vive no n8n, fora do repositório `gti-scheduling-mcp` — não há testes automatizados de código aqui. A validação é funcional/manual: - Testar o fluxo completo com uma conversa real (ou simulada via chamada direta ao webhook) contra o Z-PRO, com dados fictícios, seguindo a mesma disciplina de segurança contra duplicidade já usada nos testes manuais do `ZProAdapter` (execução única, verificação visual no Z-PRO antes de qualquer nova tentativa). - Confirmar que o `Respond to Webhook` devolve texto puro, sem envelope JSON, compatível com o que o Z-PRO espera exibir ao cliente.