From 786a97083eb5015ef6763fb7000d43581cc8bff0 Mon Sep 17 00:00:00 2001 From: Gustavo Date: Mon, 10 Aug 2026 23:27:09 -0300 Subject: [PATCH] =?UTF-8?q?Docs:=20migra=C3=A7=C3=A3o=20MCP=20Server=20nat?= =?UTF-8?q?ivo=20n8n=20(Z-PRO)=20validada=20em=20produ=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Seção 13 do runbook: arquitetura nova (MCP Server Trigger + Call n8n Sub-Workflow Tool, sem node comunitário/processo externo pro Z-PRO) - Documenta os 2 gotchas reais de ativação e a causa raiz do 403 em produção (ApiID e token vêm de integrações diferentes no Z-PRO, não é bug de formato de header nem token expirado) - Teste real de ponta a ponta confirmado (webhook -> AI Agent -> MCP nativo -> Z-PRO), agendamento fictício criado e apagado - Status final atualizado: workflow + 3 sub-workflows do MCP nativo ativos em produção Co-Authored-By: Claude Sonnet 5 --- docs/n8n-agendamento-runbook.md | 118 ++++++++++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 6 deletions(-) diff --git a/docs/n8n-agendamento-runbook.md b/docs/n8n-agendamento-runbook.md index aefeb30..bf1bba0 100644 --- a/docs/n8n-agendamento-runbook.md +++ b/docs/n8n-agendamento-runbook.md @@ -254,10 +254,116 @@ explícita no `systemMessage`. certo para fuso de Brasília. Se uma clínica futura estiver em outro fuso, ajustar o offset (e o `$now.setZone(...)` do prompt) de acordo. -## Status final (10/08/2026) +## 13. Migração — MCP Server nativo no n8n (substitui o node comunitário, só Z-PRO) -Testado de ponta a ponta com sucesso, com a chave real da OpenAI -(`gpt-4o-mini`): telefone correto, data correta, um único agendamento por -teste, confirmado visualmente no Z-PRO. Workflow deixado **desativado** -propositalmente — só ativar quando o Z-PRO de uma clínica real for -configurado para apontar pra esse webhook. +**Data:** 11/08/2026. Ver design completo em +`docs/superpowers/specs/2026-08-10-mcp-server-nativo-n8n-zpro-design.md` e +plano em `docs/superpowers/plans/2026-08-10-mcp-server-nativo-n8n-zpro.md`. + +**Motivação**: o node comunitário (`n8n-nodes-mcp`, seções 1–2 acima) exigiu +depuração pesada (bug de credencial STDIO, variável de ambiente do processo, +`toolParameters`/`$fromAI` não documentado) e não é editável visualmente — +qualquer manutenção de memória/prompt/tool exige mexer em processo externo. +A alternativa: reconstruir o mesmo "MCP Server" **inteiramente dentro do +n8n**, com nodes **oficiais** (`MCP Server Trigger` + `Call n8n Sub-Workflow +Tool` do lado servidor, `MCP Client Tool` oficial via HTTP Streamable do +lado cliente) — sem processo Node.js externo, sem pacote comunitário. + +**Arquitetura nova** (3 workflows adicionais, o workflow de agendamento +existente só trocou o node MCP): + +- `MCP Server - ZPRO` (`qjSaKllvneBIZ7mC`) — `MCP Server Trigger` + (`path: mcp-server-zpro-clinica-exemplo`) + 2 `Call n8n Sub-Workflow Tool` + (`agendar`, `consultar_horarios`). +- `MCP Server - ZPRO - agendar` (`5ZEOqTOk4Xex6jUQ`) — porta fiel da lógica + já testada em `gti-scheduling-mcp` (`zpro.mapper.ts`/`zpro.adapter.ts`/ + `zpro.errors.ts`) para nodes `Set`/`Code`/`HTTP Request`: monta o corpo, + chama `POST /v2/api/external/{apiId}/appointment/create` com + `neverError: true` + `fullResponse: true` (captura manual de status/body, + nunca deixa o n8n abortar em 4xx/5xx), classifica o resultado (qualquer + 2xx é sucesso operacional — mesma proteção contra duplicidade de sempre). +- `MCP Server - ZPRO - consultar_horarios` (`yfKkhSTDZaIYCPqP`) — sempre + retorna `NOT_SUPPORTED` (mesma decisão de produto de sempre, Z-PRO não + expõe esse endpoint). +- No workflow de agendamento (`yG2mi6ECBpPv4Hmn`): saiu o node comunitário + `MCP - gti-scheduling-mcp` (`n8n-nodes-mcp.mcpClientTool`, stdio), entrou + `MCP - ZPRO (nativo n8n)` (`@n8n/n8n-nodes-langchain.mcpClientTool`, + `serverTransport: httpStreamable`, apontando pra URL do `MCP Server + Trigger` acima). Nada mais no workflow mudou (prompt, memória, fallback de + erro). + +**Gotcha 1 — todos os workflows envolvidos precisam estar `active: true`**, +inclusive os dois sub-workflows (`agendar`/`consultar_horarios`) chamados +via `Call n8n Sub-Workflow Tool` — não só o servidor MCP e o workflow de +agendamento. O erro sintoma é `"Workflow is not active and cannot be +executed."` no node `MCP Client Tool` do lado do AI Agent. + +**Gotcha 2 — diagnóstico via chamada MCP crua (`curl`), sem depender do AI +Agent**: pra isolar se o problema está na cadeia de sub-workflows ou no +transporte/roteamento do AI Agent, dá pra chamar o endpoint MCP diretamente: + +```bash +# 1. Handshake — captura o mcp-session-id no header da resposta +curl -s -i "https://devn8n.gtigrupo.com.br/mcp/mcp-server-zpro-clinica-exemplo" -X POST \ + -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \ + -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl-test","version":"1.0"}}}' + +# 2. tools/call — usa o mcp-session-id do passo 1 +curl -s "https://devn8n.gtigrupo.com.br/mcp/mcp-server-zpro-clinica-exemplo" -X POST \ + -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \ + -H "mcp-session-id: " \ + -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"agendar","arguments":{"startAt":"...","endAt":"...","patientName":"...","patientPhone":"..."}}}' +``` + +Isso foi o que revelou que a cadeia de sub-workflows já funcionava (chegava +até o Z-PRO de verdade) enquanto o caminho via AI Agent ainda reportava +"not active" — depois de reativar os 3 workflows envolvidos e aguardar um +pouco, o caminho via AI Agent voltou a funcionar igual ao teste direto +(não ficou claro se foi só o tempo/cache do n8n resolvendo, ou a +reativação — mas o sintoma não voltou a aparecer depois disso). + +**Gotcha 3 — causa raiz real do primeiro `403` em produção**: não foi +formato de header nem token expirado — foi **ApiID e token de integrações +diferentes**. A clínica tem mais de uma integração externa cadastrada no +Z-PRO (ex.: uma pro canal de WhatsApp "Canal QR", outra pro agendamento), +cada uma com seu próprio `ApiID` (segmento da URL, +`/v2/api/external/{ApiID}/...`) **e** seu próprio Bearer token — não são +intercambiáveis. O node `Config ZPRO` precisa ter o `apiId` da **mesma** +integração de onde veio o token salvo na credencial `httpHeaderAuth`. Os +sintomas por tipo de descasamento, na ordem em que apareceram: + +| Corpo de erro do Z-PRO (403) | Causa | +| --- | --- | +| `{"error": "ERR_SESSION_NOT_AUTH_TOKEN"}` | token nunca usado/nunca válido pra nenhuma integração | +| `{"error": "Invalid token."}` | token de uma integração, `apiId` de outra (ou vice-versa) | +| (sucesso, `200`) | `apiId` e token da **mesma** integração | + +Ao duplicar este padrão pra uma nova clínica: sempre confirmar, na tela de +integrações do Z-PRO daquela clínica, que o `ApiID` copiado pra URL e o +Bearer token copiado pra credencial vêm da **mesma linha/integração**. + +**Teste real de validação (11/08/2026)**: um agendamento fictício foi +criado de ponta a ponta pelo caminho de produção completo (webhook → +Normalizar entrada → AI Agent → `MCP - ZPRO (nativo n8n)` → `MCP Server - +ZPRO` → sub-workflow `agendar` → Z-PRO), com `startAt` local correto +(`2026-08-12T11:00:00-03:00`, sem bug de timezone), retorno `200` do +Z-PRO, `id` de agendamento real mapeado, e resposta final coerente pro +cliente. Conferido visualmente no Z-PRO e apagado logo em seguida. + +**Resultado**: o node comunitário `n8n-nodes-mcp` não é mais necessário +pro Z-PRO (segue instalado no servidor, mas sem uso nesse workflow). As +seções 1–2 deste runbook (instalação do node comunitário, bugs da +credencial STDIO) ficam como **referência histórica** — não se aplicam +mais a este workflow, mas continuam relevantes se algum dia o padrão nativo +não for suficiente e for necessário voltar ao processo externo +(`gti-scheduling-mcp`, monorepo TypeScript pausado). + +## Status final (11/08/2026) + +Testado de ponta a ponta com sucesso, tanto com a chave real da OpenAI +(`gpt-4o-mini`) quanto com o MCP Server nativo do n8n (seção 13): telefone +correto, data correta, um único agendamento por teste, confirmado +visualmente no Z-PRO. Workflow **ativo em produção** (`yG2mi6ECBpPv4Hmn`), +junto com os 3 workflows do MCP Server nativo (`qjSaKllvneBIZ7mC`, +`5ZEOqTOk4Xex6jUQ`, `yfKkhSTDZaIYCPqP`) — todos precisam permanecer +`active: true`.