From 3f10ab5efdf0181d6f31f8f4b49b9cba91f60f64 Mon Sep 17 00:00:00 2001 From: Gustavo Date: Mon, 10 Aug 2026 18:00:13 -0300 Subject: [PATCH] Spec: MCP Server nativo no n8n para o Z-PRO (substitui node comunitario stdio) Co-Authored-By: Claude Sonnet 5 --- ...08-10-mcp-server-nativo-n8n-zpro-design.md | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-10-mcp-server-nativo-n8n-zpro-design.md diff --git a/docs/superpowers/specs/2026-08-10-mcp-server-nativo-n8n-zpro-design.md b/docs/superpowers/specs/2026-08-10-mcp-server-nativo-n8n-zpro-design.md new file mode 100644 index 0000000..e528b41 --- /dev/null +++ b/docs/superpowers/specs/2026-08-10-mcp-server-nativo-n8n-zpro-design.md @@ -0,0 +1,139 @@ +# 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.