Files
KLINGO-CLINICAL-SYSLIFE-GCHAT/docs/superpowers/specs/2026-08-10-mcp-server-nativo-n8n-zpro-design.md

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 um path como 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, com name, description, e workflowInputs (schema dos parâmetros que a tool aceita). O sub-workflow chamado precisa começar com um Execute 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 o MCP Server Trigger expõ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 o path do 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), title opcional. Mesmo contrato de hoje (CreateAppointmentInput/agendarInputSchema), definido no workflowInputs do node pai.
  • Config ZPRO (Set): baseUrl e apiId fixos desta clínica — ajustar ao duplicar pra outra clínica (mesmo espírito do clinicId fixo no "Normalizar entrada" do workflow de agendamento).
  • Montar corpo (Code): porta de zpro.mapper.ts — title default ("Consulta - {nome}" se não informado pelo cliente), inclui contactId/contactPhone só 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 de zpro.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}}, ver docs/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.

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_horarios continua 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.