Spec: MCP Server nativo no n8n para o Z-PRO (substitui node comunitario stdio)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
257afe98c0
commit
3f10ab5efd
@@ -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.
|
||||
Reference in New Issue
Block a user