6.6 KiB
Design — MCP Server nativo no n8n para o Z-PRO
Data: 2026-08-10 Status: Aprovado pelo usuário, aguardando plano de implementação.
Objetivo
Reconstruir o "MCP Server" do Z-PRO dentro do n8n, usando nodes oficiais
(MCP Server Trigger + Call n8n Sub-Workflow Tool), em vez de um processo
Node.js externo (gti-scheduling-mcp) conectado via node comunitário stdio.
Motivação: o node comunitário (n8n-nodes-mcp) exigiu um dia inteiro de
depuração (ver docs/n8n-agendamento-runbook.md) — campo de credencial
quebrado, caminho absoluto de binário, mecanismo toolParameters/$fromAI
não documentado. Um MCP Server nativo do n8n elimina essa camada inteira:
usa só nodes oficiais dos dois lados (servidor e cliente), tudo editável
visualmente, sem deploy de processo separado, sem SSH para manutenção.
Relação com o trabalho anterior
Este design substitui, para o Z-PRO, o plano de monorepo
TypeScript (packages/zpro-mcp, packages/klingo-mcp, etc.) discutido
horas antes nesta mesma sessão. Aquele plano fica pausado — se a
abordagem nativa do n8n se confirmar boa na prática, o mesmo padrão é
replicado para Klingo/ClinicAll/SysLife depois; o monorepo TypeScript só
volta a fazer sentido se algo aqui não funcionar bem.
O gti-scheduling-mcp (TypeScript, testado, com ZProAdapter e
KlingoAdapter funcionando) não é apagado — fica como referência da
lógica de negócio já validada (mapeamento de request/response, classificação
de erro HTTP, proteção contra duplicidade) a ser replicada nos nodes do
n8n. Este design é, na prática, uma porta dessa lógica já testada para
nodes n8n — não um redesenho da regra de negócio em si.
Contexto verificado (nodes reais, confirmados via n8n-mcp)
MCP Server Trigger(@n8n/n8n-nodes-langchain.mcpTrigger, v2) — trigger baseado em webhook, expõe umpathcomo endpoint MCP. Nó oficial, não comunitário.Call n8n Sub-Workflow Tool(@n8n/n8n-nodes-langchain.toolWorkflow, v2.2) — empacota outro workflow inteiro como uma tool exposta ao MCP, comname,description, eworkflowInputs(schema dos parâmetros que a tool aceita). O sub-workflow chamado precisa começar com umExecute Workflow Trigger.- Do lado cliente (o workflow de agendamento existente), o node oficial
MCP Client Tool(@n8n/n8n-nodes-langchain.mcpClientTool) suporta conexão via HTTP Streamable/SSE — exatamente o transporte que oMCP Server Triggerexpõe. Não precisa de nenhum pacote comunitário.
Arquitetura
[MCP Server Trigger] ──Tools──┬── [Call Sub-Workflow Tool: "agendar"] ──▶ "MCP Server - ZPRO - agendar"
(workflow "MCP Server - ZPRO") │
└── [Call Sub-Workflow Tool: "consultar_horarios"] ──▶ "MCP Server - ZPRO - consultar_horarios"
Três workflows no total. O workflow de agendamento existente (AI Agent +
prompt + memória) não muda nada, exceto o node MCP: sai o comunitário
(stdio), entra o MCP Client Tool oficial (HTTP), apontando pra URL do
MCP Server Trigger.
Componentes
Workflow "MCP Server - ZPRO" (o servidor)
MCP Server Trigger— define opathdo endpoint (ex.:mcp-server-zpro-clinica-exemplo).- Dois nodes
Call n8n Sub-Workflow Tool, um por tool:agendar→ aponta pro sub-workflow "MCP Server - ZPRO - agendar".consultar_horarios→ aponta pro sub-workflow "MCP Server - ZPRO - consultar_horarios".
Sub-workflow "MCP Server - ZPRO - agendar"
[Execute Workflow Trigger] → [Config ZPRO] → [Montar corpo] → [HTTP Request] → [Classificar resultado]
- Execute Workflow Trigger: recebe os parâmetros da tool —
clinicId,startAt,endAt,patient(nome obrigatório; telefone, id, documento opcionais),titleopcional. Mesmo contrato de hoje (CreateAppointmentInput/agendarInputSchema), definido noworkflowInputsdo node pai. - Config ZPRO (
Set):baseUrleapiIdfixos desta clínica — ajustar ao duplicar pra outra clínica (mesmo espírito doclinicIdfixo no "Normalizar entrada" do workflow de agendamento). - Montar corpo (
Code): porta dezpro.mapper.ts—titledefault ("Consulta - {nome}"se não informado pelo cliente), incluicontactId/contactPhonesó quando existirem no input,status: "pending"fixo. - HTTP Request:
POST {baseUrl}/v2/api/external/{apiId}/appointment/create, Bearer token vindo de uma Credential do n8n. Resposta completa/"Never Error" habilitado — por padrão o n8n trata 4xx/5xx como falha e aborta o workflow; a classificação de erro precisa ser feita manualmente no próximo node, replicando exatamente o comportamento já validado. - Classificar resultado (
Code): porta dezpro.adapter.ts+zpro.errors.ts:- Qualquer HTTP 2xx é sucesso operacional, sem exceção — mesma
proteção contra duplicidade já validada em produção. Tenta mapear o
envelope real conhecido (
{success:true, data:{id,startAt,endAt,status}}, verdocs/zpro-api-mapping.md); se o corpo não bater com esse formato, devolve um resultado "aceito, mapeamento pendente" construído só com os dados do input (nunca inventa campos do corpo). - Fora do intervalo 2xx: classifica em
AUTHENTICATION_ERROR(401/403),NOT_FOUND(404),VALIDATION_ERROR(400/422), ou um erro genérico para o resto — mesmos códigos já usados hoje.
- Qualquer HTTP 2xx é sucesso operacional, sem exceção — mesma
proteção contra duplicidade já validada em produção. Tenta mapear o
envelope real conhecido (
Sub-workflow "MCP Server - ZPRO - consultar_horarios"
[Execute Workflow Trigger] → [Code: retorna NOT_SUPPORTED]
Sem chamada HTTP — mesma decisão de produto de hoje (o Z-PRO não expõe endpoint de disponibilidade de horários).
Credenciais
Uma Credential HTTP (Bearer/Header Auth) no n8n, só com o
ZPRO_API_TOKEN. baseUrl/apiId ficam no node Config ZPRO — não são
segredo, precisam só ficar visíveis/editáveis por clínica ao duplicar o
conjunto de workflows.
Fora de escopo (adiado)
- Klingo, ClinicAll, SysLife via este mesmo padrão — replicar depois que o Z-PRO nativo estiver validado.
- O monorepo TypeScript (
packages/*-mcp) fica pausado, não descartado. consultar_horarioscontinua não suportado pro Z-PRO (mesma decisão de produto já tomada, sem mudança).
Testes
Sem testes automatizados (workflows do n8n, não código com framework de teste). Validação manual, seguindo a mesma disciplina já usada no projeto inteiro: dado fictício, execução única por vez, conferência visual no Z-PRO antes de qualquer nova tentativa — evitar duplicar agendamento durante os testes desta migração.