- gti-scheduling-mcp: MCP server com ZProAdapter e KlingoAdapter (agendar() completo pros dois) - Workflow n8n 'Agendamento - GChat - Z-PRO': webhook -> AI Agent -> MCP -> Z-PRO, testado com sucesso real - Documentacao: specs, plano, runbook de problemas reais e export do workflow Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
8.8 KiB
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 Webhookem 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 dogti-scheduling-mcp(que hoje só implementaStdioServerTransport). - O
gti-scheduling-mcp(ZProAdapter/KlingoAdapter) já está pronto e testado paraagendar()— 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)
- Webhook (Z-PRO) —
POST, recebe{step, entrada, number, contactName, protocol}. - 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.
- Valida
- 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 chamaragendarmais 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(vian8n-nodes-mcp, transporte stdio), expondo a toolagendardogti-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).
- 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 Webhookdevolve texto puro, sem envelope JSON, compatível com o que o Z-PRO espera exibir ao cliente.