Docs: migração MCP Server nativo n8n (Z-PRO) validada em produção
- 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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
8641d68f4f
commit
786a97083e
@@ -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: <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`.
|
||||
|
||||
Reference in New Issue
Block a user