@lionchat/mcp-server 1.15.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -74,6 +74,15 @@ Glossário completo de termos, status codes, enums e conceitos da plataforma. Us
74
74
  de WhatsApp — oficial e QR Code). A bolha mostra o selo "Encaminhada"
75
75
  - `content_attributes.frequently_forwarded`: `true` = encaminhada MUITAS vezes (o "encaminhada com
76
76
  frequência" do WhatsApp). Útil pra responder "essa mensagem foi encaminhada?" sem chutar
77
+ - `content_attributes.edited`: `true` = o CLIENTE editou a mensagem no WhatsApp (`edited_at` traz
78
+ quando). O `content` já é o texto novo; a versão anterior não fica guardada. Vale nos dois canais
79
+ de WhatsApp (QR Code desde 18/07/2026; oficial desde 21/08/2026 — entra com o próximo deploy do
80
+ app depois de 21/08/2026; antes a edição virava um balão VAZIO novo, contado como mensagem nova).
81
+ - `content_attributes.deleted`: `true` = mensagem APAGADA ("apagar para todos"), pelo cliente ou
82
+ pela empresa no celular (convivência). O `content` vira `"⛔ Esta mensagem foi excluída"` seguido
83
+ do texto original (a equipe continua vendo o que foi dito); os anexos são removidos. Ao resumir
84
+ uma conversa, trate como apagada — não cite o texto como se ainda estivesse de pé. (No canal
85
+ oficial, desde 21/08/2026 — entra com o próximo deploy do app depois de 21/08/2026.)
77
86
 
78
87
  ## Attachment (Anexo)
79
88
 
@@ -296,6 +305,18 @@ comportamento intencional.
296
305
  - `role`: `agent` (atendente) ou `administrator` (admin/dono)
297
306
  - `availability`: `online`, `busy`, `offline`
298
307
  - `permissions`: array de strings com permissões granulares
308
+ - `replacing`: `true` em `lionchat_agents_list` por até 30 min enquanto uma substituição
309
+ (`lionchat_agents_replace`) transfere a carteira desse agente pro novo — ele está SAINDO; não
310
+ atribua nada a ele
311
+
312
+ ### Agente de SUPORTE (SupportAccessGrant) — não é agente da conta
313
+
314
+ Quem entra na conta por **acesso de suporte** (operador da plataforma) aparece como administrador,
315
+ mas **não é membro da equipe**: `lionchat_agents_list` não o lista (escopo `regular_users`), ele
316
+ não ocupa vaga do plano, não pode ser substituído (`agents_replace` recusa) e, desde 17/08/2026,
317
+ a IA também o ignora — não atribui conversa a ele, não agenda mensagem no nome dele, não o menciona
318
+ em alerta nem o conta como "disponível". Exceção deliberada: se alguém o atribuir à mão como
319
+ responsável, ele segue valendo como responsável.
299
320
 
300
321
  ## AutomationRule (Regra de automação)
301
322
 
@@ -309,7 +330,11 @@ comportamento intencional.
309
330
  - `booking_event_type_id`: FK pro tipo de evento (ex: "Demo 30min")
310
331
  - `attendee_email`, `attendee_name`, `attendee_phone`
311
332
  - `start_time`, `end_time`: ISO 8601
312
- - `status`: `scheduled`, `cancelled`, `completed`
333
+ - `status`: `confirmed`, `cancelled`, `completed` — mas **só muda quando o cancelamento/conclusão
334
+ vem pelo link do paciente ou pela IA**. Quem conclui/cancela pela Agenda mexe na TAREFA
335
+ (`account_tasks.status`: `pending`/`completed`/`cancelled`/`snoozed`), e o booking fica
336
+ `confirmed`. Pra saber se um agendamento aconteceu, leia a tarefa (`lionchat_tasks_show`), não o
337
+ booking.
313
338
 
314
339
  **A IA agenda EXCLUSIVAMENTE por agenda de Booking (15/08/2026).** Não existe mais agendamento
315
340
  avulso/direto pela IA — ela consulta as agendas liberadas, respeita os dias em que a agenda não
@@ -48,6 +48,17 @@ Stages NÃO são tabela separada. São armazenadas como jsonb dentro do Funnel:
48
48
  }
49
49
  ```
50
50
 
51
+ **Etapa que não existe no funil (desde 19/08/2026):**
52
+ - `kanban_items_create`/`_update`/`_move` com `funnel_stage` que o funil não tem **não falha e não
53
+ some**: o card é REDIRECIONADO — pro destino gravado quando a etapa foi apagada, senão pra etapa
54
+ da mesma posição, senão pra primeira. **Confira o `funnel_stage` da resposta**: pode ser diferente
55
+ do que você mandou. Leia `funnels_show` antes e use o slug exato.
56
+ - `funnels_update` que tira do `stages` uma etapa com card responde **422 `STAGE_HAS_ITEMS`** com
57
+ `stages: {"<slug>": <quantos cards>}`. Primeiro mova os cards com `lionchat_funnels_create_2`
58
+ (`POST /funnels/{id}/migrate_stage`, `from_stage`, `to_stage` ou `to_funnel_id`) e só então
59
+ reenvie o funil sem a etapa. Não existe parâmetro de destino no `update` de propósito.
60
+ - Funil apagado continua sendo erro (o card não é criado).
61
+
51
62
  ### KanbanConfig (Configuração Global do Kanban) — CRÍTICO
52
63
 
53
64
  **Tabela separada do Funnel.** 1:1 com a conta. Guarda configurações que valem pra TODOS os funis. Tem 5 campos jsonb importantes:
@@ -245,6 +256,11 @@ Log automático de eventos do card:
245
256
 
246
257
  Tipos comuns: `created`, `stage_changed`, `agent_assigned`, `agent_removed`, `note_added`, `value_changed`, `priority_changed`, `archived`.
247
258
 
259
+ Quem fez: `by_user_id`/`user` traz a pessoa; ação de automação ou flow vem com o nome da regra/fluxo;
260
+ ação da IA (desde 21/08/2026 — entra com o próximo deploy do app depois de 21/08/2026) vem como
261
+ `"IA: <nome do assistente>"` com `id` nulo — antes saía sem autor. Ao explicar um histórico de card,
262
+ use esse campo pra dizer se foi gente, automação ou IA.
263
+
248
264
  ## Checklist (tarefas dentro do card)
249
265
 
250
266
  Array plano de itens. Cada item pode (opcionalmente) pertencer a um grupo via `group_id` +
@@ -580,7 +596,9 @@ Cada card pode receber atributos custom de 3 origens diferentes. **A escolha do
580
596
  ## Diagnóstico: "Card sumiu do funil"
581
597
 
582
598
  1. Está arquivado? `archived = true` em algum nível?
583
- 2. Etapa atual existe ainda? (etapa removida do funil deixa card "órfão")
599
+ 2. Etapa atual existe ainda? Desde 19/08/2026 card em etapa inexistente é redirecionado na
600
+ gravação (e os 621 antigos foram movidos pra primeira etapa) — se ainda sumiu, filtre por
601
+ `funnel_stage` com o slug que aparece em `kanban_items_show` e compare com `funnels_show`.
584
602
  3. `position` está faltando? (cards sem position vão pro fim)
585
603
  4. Está em outro funil? (mover entre funis muda `funnel_id`)
586
604
 
@@ -153,6 +153,7 @@ conversa antiga que NÃO aparece no relatório de hoje (régua antiga por criaç
153
153
  | "retrospectiva do ano" | `lionchat_reports_list_15` |
154
154
  | "satisfação", "CSAT", "nota dos clientes" | `lionchat_csat_metrics` |
155
155
  | "SLA", "cumprimento de prazo" (se a conta tiver Enterprise) | `lionchat_sla_metrics` |
156
+ | "quantos agendamentos", "taxa de comparecimento", "agendamentos por tipo/atendente" | `lionchat_booking_reports` (ver "Agendamentos" no fim deste guia) |
156
157
 
157
158
  ---
158
159
 
@@ -330,6 +331,11 @@ Retorna:
330
331
 
331
332
  **Filtros aceitos (expostos na tool desde 2026-07-24):** `inbox_id`, `team_id`, `sla_policy_id`, `label_list[]`, `assigned_agent_id`, `since`/`until` (unix segundos).
332
333
 
334
+ Latência de detecção: o prazo é conferido a cada 5 min, e desde 21/08/2026 (entra com o próximo
335
+ deploy do app depois de 21/08/2026) as conferências saem espalhadas em até 2 min dentro do ciclo —
336
+ um estouro pode aparecer em `sla_list`/`sla_metrics` até ~7 min depois do horário-limite. Não é
337
+ defeito; não conclua "o SLA não está rodando" por isso.
338
+
333
339
  ## Padrões de interpretação
334
340
 
335
341
  ### Comparando períodos
@@ -555,7 +561,7 @@ nenhum `reports_*` responde; aqui é `funnel_stages` + `date_basis: closed` + `s
555
561
 
556
562
  Não é consulta livre: escolha um `widget_type` e preencha **só os campos daquele tipo**.
557
563
 
558
- ### Os 7 tipos de bloco
564
+ ### Os 9 tipos de bloco
559
565
 
560
566
  | Tipo | Campos | Recurso exigido |
561
567
  |---|---|---|
@@ -563,13 +569,26 @@ Não é consulta livre: escolha um `widget_type` e preencha **só os campos daqu
563
569
  | `entity_ranking` | `dimension` (agent/inbox/team/label) · `metric` (conversations, resolutions, avg_first_response_time, avg_resolution_time) · `time_range` | — |
564
570
  | `csat_summary` | `time_range` | — |
565
571
  | `sla_summary` | `time_range` | `sla` (Enterprise) |
566
- | `funnel_stages` | `funnel_id` · `date_basis` (created/moved/closed/any) · `status` (all/open/won/lost) · `time_range` | `kanban_board` |
572
+ | `funnel_stages` | `funnel_id` · `date_basis` (created/moved/closed/any) · `status` (all/open/won/lost) · `measure` (count padrão / value = soma do valor dos cards) · `time_range` | `kanban_board` |
573
+ | `stage_entries` | `funnel_id` · `measure` (count/value) · `time_range` — quantos cards DISTINTOS ENTRARAM em cada etapa no período (histórico desde 12/07/2026) | `kanban_board` |
574
+ | `calls_report` | `dimension` (agent/inbox) · `time_range` — ligações / atendidas / não atendidas / não concluídas / tempo total / tempo médio | — |
567
575
  | `lead_origin` | `time_range` | `liontrack` |
568
576
  | `agent_report` | `dimension` (agent/team/inbox) · `scope_type`+`scope_id` · `columns[]` · `time_range` | — |
569
577
 
570
- **`time_range`:** `last_7_days`, `last_30_days`, `this_month`, `last_month` — e `custom` **só em
571
- `conversations_timeseries` e `agent_report`**, exigindo `from`/`to`. **A janela não pode passar de 92
572
- dias**, e esse teto é da janela, não de um tipo: pedir "esse ano" é recusado com a explicação.
578
+ `stage_entries`, `calls_report`, `measure`, `today`/`yesterday` e os metadados `title`/`width`/`height`
579
+ são commits de 21/08/2026 (entram com o próximo deploy do app depois de 21/08/2026); `custom` em
580
+ todos os tipos está no ar desde 19/08/2026.
581
+
582
+ **`time_range`:** `today`, `yesterday` (desde 21/08 — o menor período era 7 dias), `last_7_days`,
583
+ `last_30_days`, `this_month`, `last_month` e `custom` (com `from`/`to`, **em qualquer tipo** desde
584
+ 19/08/2026). **A janela `custom` não pode passar de 92 dias** — o teto é da janela, não do tipo;
585
+ "esse ano" é recusado com a explicação. `today`/`yesterday` resolvem no fuso do `timezone_offset`
586
+ enviado — mande o da conta.
587
+
588
+ **Metadados do bloco (irmãos de `widget_type`, fora dos params):** `title` (nome que a pessoa dá ao
589
+ bloco, até 80 caracteres; vazio = o painel mostra o rótulo do tipo), `width` (1 a 4 colunas; padrão
590
+ 2) e `height` (`normal` | `tall`). Preencha `title` em todo bloco que você criar — quatro blocos de
591
+ funil sem nome chegam indistinguíveis pra quem lê depois.
573
592
 
574
593
  **Colunas do `agent_report`:** `leads`, `atendidos`, `resolvidas`, `abertas`, `pendentes`, `adiadas`,
575
594
  `label_count` (exige `label_id`) e `conversao` (exige `denominator` e `numerator`, que é **lista de
@@ -591,8 +610,9 @@ IDs de etiqueta**, nunca nome de métrica).
591
610
  equipe/caixa". Confundir troca a conta inteira.
592
611
  2. **Campo fora da lista é descartado em silêncio.** Se um valor "não fez efeito", provavelmente o
593
612
  nome do campo está errado.
594
- 3. **Sempre envie `timezone_offset` em HORAS** (Brasília = `-3`). Sem ele o cálculo é em UTC e o
595
- número não bate com o que o cliente vê na tela.
613
+ 3. **Sempre envie `timezone_offset` em HORAS, derivado do fuso DA CONTA** (`account_show.timezone`;
614
+ Brasília = `-3`, Cuiabá/Campo Grande/Manaus = `-4`). Sem ele o cálculo é em UTC e o número não
615
+ bate com o que o cliente vê na tela.
596
616
  4. **`update` substitui a lista de blocos inteira.** Leia com `list`, altere o array, devolva
597
617
  completo — e preserve o `id` de cada bloco que já existia.
598
618
  5. **`list` não pagina.** Se a resposta vier com aviso de corte, **não** use aquela lista para montar
@@ -669,6 +689,22 @@ Colunas: Ligações · Atendidas · Não atendidas · **Não concluídas** · Te
669
689
  Não a esconda ao resumir por pessoa.
670
690
  - A tabela lista só quem teve ligação no período — atendente ausente da tabela fez zero.
671
691
 
692
+ ### Agendamentos (`lionchat_booking_reports`) — 2026-08-19
693
+
694
+ `GET /api/v2/accounts/{id}/booking_reports` — a aba Relatórios > Agendamentos. Unidade = o
695
+ AGENDAMENTO (Booking). Params: `since`/`until` (datas; padrão 30 dias pra trás E 30 pra frente,
696
+ porque agenda tem futuro), `event_type_id`, `user_id` (responsável da tarefa), `status`
697
+ (`pending` | `completed` | `cancelled` | `snoozed`), `group_by` (`day` | `week` | `month`).
698
+ Resposta: `totals` (`total`, `pending`, `completed`, `cancelled`, `snoozed`, `attendance_rate`),
699
+ `timeline`, `by_event_type`, `by_agent`, `by_origin`.
700
+
701
+ - **`attendance_rate` = concluídos / (concluídos + cancelados)**, em %. Pendentes ficam FORA do
702
+ denominador (ainda não aconteceram). Não recalcule com o total.
703
+ - A SITUAÇÃO vem da tarefa da Agenda (`account_tasks.status`), não de `bookings.status` — quem
704
+ conclui/cancela pela Agenda deixa o booking parado em "confirmado". Ler `bookings_*` direto pra
705
+ contar "concluídos" dá zero.
706
+ - `snoozed` (adiado) aparece separado de `pending` de propósito.
707
+
672
708
  ### Faturamento (`measure`)
673
709
 
674
710
  `measure: 'value'` faz `funnel_stages`/`stage_entries` somarem o VALOR dos cards em vez de contar.
@@ -173,7 +173,9 @@ Feature flag específica (ex: `feature_kanban`, `feature_captain`) está OFF.
173
173
  - `"private must be boolean"` — true/false, não string
174
174
 
175
175
  ### KanbanItem
176
- - `"funnel_stage does not exist in funnel"` — etapa inválida pro funil
176
+ - `"STAGE_HAS_ITEMS"` (no `funnels_update`) — você tentou remover uma etapa que ainda tem card;
177
+ `stages` na resposta diz quantos. Mova com `migrate_stage` antes. (Card criado em etapa
178
+ inexistente NÃO dá erro: é redirecionado — confira o `funnel_stage` devolvido.)
177
179
  - `"conversation_display_id must exist"` — conversa não existe ou foi deletada
178
180
  - `"position must be a positive integer"` — não pode ser negativo
179
181
 
@@ -418,6 +420,18 @@ pelo painel de suporte — só volta no botão Retomar), `cancelled` (encerrada
418
420
  Enquanto uma importação está viva, o repescador de mensagens da sessão fica fora do caminho, de
419
421
  propósito. Pausar, retomar e cancelar são ações do painel de suporte — não existem no MCP.
420
422
 
423
+ **A mídia vem DEPOIS do texto (desde 19-20/08/2026).** O import grava as conversas só com o texto
424
+ (779 conversas em ~3 min num caso real) e busca os arquivos em segundo plano, numa fila por caixa
425
+ com poucas vagas na instalação inteira — pode levar horas (o dono aceitou "até 24 h, contanto que
426
+ não atrapalhe nada"). Enquanto isso a mensagem carrega `content_attributes.media_failed` com
427
+ `retryable: true` (bolha âmbar "mídia chegando"); quando o arquivo chega, o selo some e o anexo
428
+ aparece; se o WhatsApp já apagou o arquivo (tudo com mais de ~2 semanas), o selo vira
429
+ `retryable: false` (vermelho, definitivo — não há repesca). `lionchat_inboxes_waha_import_status`
430
+ responde "ainda está chegando?": `media_pending` (arquivos na fila desta caixa; 0 = tudo pedido),
431
+ `media_swept_at`/`media_swept_count` (varredura final que recolocou órfãos na fila). `status:
432
+ completed` com `media_pending > 0` é normal — texto pronto, fotos a caminho. Conversa de histórico
433
+ NÃO é repescada pelo vigia de mensagens, de propósito.
434
+
421
435
  ### "Editei o evento no Google Calendar e não sincronizou"
422
436
  Auto-cura desde 2026-06-09: o vigia horário re-arma o "watch" morto de conexões saudáveis
423
437
  sozinho (sem reconectar a conta). Se persistir >1h, aí sim investigar a conexão
@@ -498,6 +512,15 @@ recusado; brasileiro com 55 e 12-13 dígitos é aceito mesmo no formato antigo s
498
512
  sem erro de telefone); no import do KANBAN, telefone inválido cria o card SEM contato e SEM
499
513
  conversa, em silêncio — comportamento diferente do import de contatos.
500
514
 
515
+ **Complementos de 19/08:** telefone PREENCHIDO e inválido **recusa a linha inteira** — o contato não
516
+ nasce (antes ele nascia mudo, sem telefone). Coluna de telefone **vazia** continua criando o contato
517
+ (lista de nome + e-mail é uso legítimo). **Linha totalmente vazia não é erro**: é pulada e contada em
518
+ `blank_rows` no resultado — planilha de 300 linhas com 2 preenchidas deixa de gerar 298 "Nome é
519
+ obrigatório". Telefone em notação científica do Excel (`9,88888E+12`) recebe mensagem própria
520
+ ("formate a coluna como texto"), não "confira o DDI". No `contacts_import_validate`, o número da
521
+ linha no relatório é a posição REAL no arquivo (linhas vazias contam na numeração, não no total
522
+ conferido).
523
+
501
524
  ## "A caixa oficial parou de disparar / de receber" — avisos automáticos da Meta (18/08)
502
525
 
503
526
  Duas famílias de chaves novas em `additional_attributes` da caixa `Channel::Whatsapp`
@@ -512,6 +535,15 @@ Duas famílias de chaves novas em `additional_attributes` da caixa `Channel::Wha
512
535
  e `reauthorization_required` vira `true` SOZINHO. Com `reauthorization_required: true` a caixa
513
536
  fica MUDA (descarta o que chega) até reconectar. A ausência dessas chaves NÃO prova que a caixa
514
537
  está conectada (caixa antiga só ganha o aviso após reinscrição).
538
+ - **Registro do número incompleto** (20/08): `whatsapp_registration_error` (texto, a frase da
539
+ própria Meta — ex.: verificação em duas etapas ligada num número que veio de outra plataforma).
540
+ A caixa foi criada e **continua recebendo**; só o registro do número não terminou. É diferente de
541
+ `reauthorization_required` (esse emudece a caixa). Orientação: resolver do lado da Meta e clicar
542
+ em "Concluir registro" na caixa; a chave some quando o registro passa. Conectar uma caixa oficial
543
+ é ação de administrador e respeita o teto de caixas do plano (402 antes de abrir a janela da Meta).
544
+ - Reconectar uma caixa em convivência pelo botão volta a pedir o histórico de 180 dias sozinho
545
+ (19/08); é um tiro único por onboarding — se a Meta recusar fora da janela de 24 h, não há
546
+ repetição.
515
547
 
516
548
  ## "O filtro de etiqueta 'não está presente' mente" — NUNCA mentiu pela API
517
549
 
@@ -521,6 +553,17 @@ Se alguma anotação antiga disser que esse filtro mente por API, está errada.
521
553
  verdade nos filtros: data FIXA com `is_greater_than`/`is_less_than` passou a cortar o dia no fuso
522
554
  da CONTA (ver resource `filtros-e-relatorios`).
523
555
 
556
+ ## "Mapeei o campo da integração pro atributo da conversa e nada foi gravado" (21/08 — entra com o próximo deploy do app depois de 21/08/2026)
557
+
558
+ Quatro causas, nesta ordem: (1) o evento não abriu conversa — atributo de conversa só existe na
559
+ conversa que a automação/fluxo mapeado cria (contato sozinho não tem onde gravar); (2) a chave é
560
+ reservada (`imported_from`, `type`, `captain_*`... — lista em `api-conventions`) e foi recusada;
561
+ (3) o valor não é do TIPO do atributo (texto num campo de Número, data em formato estranho) e foi
562
+ descartado — o log do servidor tem `[IntegrationAttributes] ... tipo_invalido=[...]`; (4) nos
563
+ gateways, a chave não está em `conversation_attribute_keys` daquele evento (a granularidade é por
564
+ evento: "compra aprovada" e "carrinho abandonado" gravam listas diferentes). Gravar por integração é
565
+ silencioso: não espere automação nem webhook de saída reagindo ao atributo.
566
+
524
567
  ## Quando reportar pro suporte
525
568
 
526
569
  Reporte se:
@@ -533,3 +576,13 @@ NÃO precisa reportar:
533
576
  - 4xx (você fez algo errado)
534
577
  - Rate limit (esperado)
535
578
  - 404 de recurso deletado
579
+
580
+ ## Conector REMOTO "conecta e desconecta" a cada ~6 minutos (Claude Code / VS Code / Codex ligados direto)
581
+
582
+ Vale SÓ para o conector remoto (`mcp.lionchat.com.br`). O conector local (npm, stdio) não tem canal de rede.
583
+ Sintoma: `/mcp` alterna connected/disconnected a cada ~6 min; nenhuma chamada falha.
584
+ Causa (21/08/2026): o cliente segura um canal GET esperando avisos do servidor; o Cloudflare derruba
585
+ qualquer resposta que fique 125 s sem um byte (Proxy Read Timeout). Quem usa pela claude.ai/ChatGPT não
586
+ abre esse canal e nunca vê isso.
587
+ Correção (v1.15.1): o servidor manda um `ping` a cada 30 s enquanto o canal está aberto.
588
+ Interruptor: `MCP_KEEPALIVE_INTERVAL_MS` (0 = desligado). Detalhe: `docs/plans/mcp-keepalive-cloudflare/`.