@lionchat/mcp-server 0.2.0 → 0.3.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.
@@ -0,0 +1,219 @@
1
+ # Guia de Relatórios e Métricas
2
+
3
+ Como interpretar cada um dos endpoints de relatório (`lionchat_reports_*`) e métricas correlatas. Use sempre que o usuário pedir métricas, KPIs, dashboards ou comparativos.
4
+
5
+ ## ⚠️ Unidades de tempo
6
+
7
+ **TODOS os tempos médios são retornados em SEGUNDOS.** Sempre converta antes de exibir:
8
+
9
+ ```
10
+ 245 segundos → "4 min 5 seg" ou "4:05"
11
+ 3600 segundos → "1 hora"
12
+ 86400 segundos → "24 horas" ou "1 dia"
13
+ ```
14
+
15
+ ## Endpoints disponíveis (19 total)
16
+
17
+ ### 1. `lionchat_reports_summary` — Resumo geral
18
+ **Use quando o usuário pedir:** "como tá o desempenho?", "resumo da semana", "visão geral"
19
+
20
+ **Retorna:**
21
+ ```json
22
+ {
23
+ "conversations_count": 142,
24
+ "incoming_messages_count": 1250,
25
+ "outgoing_messages_count": 980,
26
+ "resolutions_count": 98,
27
+ "avg_first_response_time": 245, // segundos
28
+ "avg_resolution_time": 7200, // segundos
29
+ "previous": { ...mesma estrutura para comparativo... }
30
+ }
31
+ ```
32
+
33
+ **Parâmetros principais:**
34
+ - `type`: `account` (padrão), `agent`, `inbox`, `label`, `team`
35
+ - `since` / `until`: Unix timestamp (segundos) — período
36
+ - `business_hours`: `true` excluí horários fora do expediente
37
+
38
+ **Exemplo de uso:**
39
+ ```
40
+ since = 7 dias atrás
41
+ until = agora
42
+ type = account
43
+ → retorna resumo dos últimos 7 dias da conta toda
44
+ ```
45
+
46
+ ### 2. `lionchat_reports_list` — Por agente
47
+ **Use quando:** "produtividade por atendente", "ranking de agentes"
48
+
49
+ Retorna array de métricas, uma por agente. Cada item:
50
+ ```json
51
+ {
52
+ "id": 6,
53
+ "name": "Elvis",
54
+ "conversations_count": 23,
55
+ "avg_first_response_time": 180,
56
+ "avg_resolution_time": 5400,
57
+ "csat_score_average": 4.3,
58
+ "online_at_total": 28800 // segundos online no período
59
+ }
60
+ ```
61
+
62
+ ### 3. `lionchat_reports_list_1` — Por time
63
+ **Use quando:** "comparar times", "como está o time Premium vs Standard"
64
+
65
+ Mesma estrutura por team_id.
66
+
67
+ ### 4. `lionchat_reports_list_2` — Por inbox
68
+ **Use quando:** "qual canal está com mais demanda", "comparar WhatsApp vs Email"
69
+
70
+ Mesma estrutura por inbox_id.
71
+
72
+ ### 5. `lionchat_reports_list_3` — Por label
73
+ **Use quando:** "quantas conversas urgentes", "comparativo por label"
74
+
75
+ Mesma estrutura por label.
76
+
77
+ ### 6. `lionchat_reports_list_4` — Por canal
78
+ **Use quando:** "WhatsApp vs Email vs Webchat"
79
+
80
+ Agrupa por `channel_type`.
81
+
82
+ ### 7. `lionchat_reports_list_5` — Relatórios detalhados
83
+ **Use quando:** "dia a dia da última semana", "evolução temporal"
84
+
85
+ Retorna timeseries (data + valor) para um metric específico:
86
+ - `metric`: `conversations_count`, `incoming_messages_count`, `outgoing_messages_count`, `resolutions_count`, `avg_first_response_time`, `avg_resolution_time`, `reply_time`, `resolutions_count`
87
+ - `group_by`: `day`, `week`, `month`, `year`
88
+ - `since`/`until`: período
89
+
90
+ ### 8. `lionchat_reports_list_6` — Resumo do Bot
91
+ **Use quando:** "como tá o bot resolvendo", "% de handoff pra humano"
92
+
93
+ ```json
94
+ {
95
+ "bot_resolutions_count": 45,
96
+ "bot_handoffs_count": 12,
97
+ "bot_resolution_rate": 0.79
98
+ }
99
+ ```
100
+
101
+ ### 9. `lionchat_reports_list_7` — Conversation Traffic (tráfego)
102
+ **Use quando:** "horário de pico", "quando tem mais demanda"
103
+
104
+ Retorna heatmap por hora do dia ou dia da semana:
105
+ ```json
106
+ [
107
+ { "hour": 9, "conversations_count": 18 },
108
+ { "hour": 10, "conversations_count": 25 },
109
+ ...
110
+ ]
111
+ ```
112
+
113
+ ### 10. `lionchat_reports_list_8` — Agente em tempo real
114
+ **Use quando:** "quem tá online agora", "carga atual"
115
+
116
+ ```json
117
+ [
118
+ { "id": 6, "name": "Elvis", "status": "online", "open_count": 5, "unattended_count": 2 }
119
+ ]
120
+ ```
121
+
122
+ ### 11-15. CSAT
123
+ - `lionchat_csat_metrics`: agregação (média, distribuição)
124
+ - `lionchat_csat_list`: respostas individuais
125
+ - `lionchat_csat_download`: CSV pra download
126
+
127
+ ### 16-18. SLA
128
+ - `lionchat_sla_metrics`: hits / breaches por período
129
+ - `lionchat_sla_list`: SLAs aplicadas a conversas
130
+ - `lionchat_sla_download`: CSV
131
+
132
+ ### 19. `lionchat_reports_list_9` — Aggregated agent overview
133
+ **Use quando:** combinação de tudo: produtividade + CSAT + SLA por agente
134
+
135
+ ## Padrões de interpretação
136
+
137
+ ### Comparando períodos
138
+ Quando passa `since/until`, a maioria dos endpoints retorna `previous` com o período anterior de mesmo tamanho:
139
+
140
+ ```
141
+ Esta semana: 142 conversas
142
+ Semana anterior: 120 conversas
143
+ → Crescimento de 18%
144
+ ```
145
+
146
+ **Dica:** sempre apresente comparativos pra dar contexto.
147
+
148
+ ### Business hours
149
+ - Sem `business_hours: true`: tempos médios incluem madrugada/feriado (puxa pra cima)
150
+ - Com `business_hours: true`: só conta período de atendimento configurado (mais preciso pra SLA)
151
+
152
+ **Use business_hours: true** quando o usuário perguntar de "produtividade real" ou comparar com SLA.
153
+
154
+ ### CSAT
155
+ - Score: 1-5 estrelas
156
+ - Médias típicas: 4.0+ é bom, 3.5-4.0 é OK, abaixo de 3.5 é alerta
157
+ - `csat_response_rate`: % de conversas resolvidas que ganharam resposta CSAT (taxa baixa = pouco feedback)
158
+
159
+ ### SLA
160
+ - `breach_count` alto = problema sério, agentes não cumprindo prazos
161
+ - Sempre olhar `hit_rate` (hits / (hits + breaches)) — meta 95%+
162
+
163
+ ## Workflows comuns
164
+
165
+ ### "Relatório semanal completo"
166
+ ```
167
+ 1. reports_summary com since=7d, type=account → visão geral
168
+ 2. reports_list (por agente) → ranking
169
+ 3. reports_list_3 (por label) → tipos de demanda
170
+ 4. csat_metrics → satisfação
171
+ 5. sla_metrics → cumprimento
172
+ 6. Compilar resumo em markdown
173
+ ```
174
+
175
+ ### "Quem tá com gargalo"
176
+ ```
177
+ 1. reports_list_8 (real-time) → quem tá com muita conversa aberta
178
+ 2. reports_list (por agente, últimos 7d) → quem tá com avg_first_response alto
179
+ 3. Cruzar: agente sobrecarregado E com tempo médio alto
180
+ ```
181
+
182
+ ### "Mês a mês evolução"
183
+ ```
184
+ reports_list_5 com group_by=month, metric=conversations_count, since=12 meses atrás
185
+ ```
186
+
187
+ ## Pegadinhas comuns
188
+
189
+ ### ⚠️ Comparar agente "online_at_total"
190
+ Tempo online inclui breaks, almoço, etc. Pra produtividade real, prefira:
191
+ - `conversations_count / online_at_total` = conversas por hora online
192
+
193
+ ### ⚠️ Avg time pode ser enganador
194
+ Mediana é mais representativa que média (1 conversa que durou 5 dias puxa tudo).
195
+ **Mas o LionChat hoje só retorna média.** Reporte com ressalva: "Tempo MÉDIO de X — pode ter outliers."
196
+
197
+ ### ⚠️ Reports não pegam conversas em tempo real
198
+ A maioria dos endpoints é eventually consistent (cache 5min). Pra info real-time use `conversations_meta`.
199
+
200
+ ### ⚠️ Comparativos de período
201
+ `previous` tem o MESMO tamanho do período atual. Se since-until = 7d, previous = 7d antes.
202
+ NÃO compare manualmente "esse mês vs mês passado" — passe `since/until` com mês inteiro e use o `previous` retornado.
203
+
204
+ ## Quando o usuário pede algo MUITO específico que não existe num endpoint
205
+
206
+ Se a pergunta requer cálculos custom (ex: "conversas por agente que duraram mais de X minutos"):
207
+ 1. Liste as conversations com filtros
208
+ 2. Filtre no client-side
209
+ 3. Agrege e apresente
210
+
211
+ Mas avise: "essa métrica não existe pronta — vou compor a partir de dados crus"
212
+
213
+ ## Custos de chamadas (importante!)
214
+
215
+ Endpoints de relatório podem retornar **MUITOS** dados:
216
+ - `reports_list_5` com `group_by=day, since=1 ano` → 365 datapoints
217
+ - `csat_list` sem filtro → milhares
218
+
219
+ **Sempre limite período** quando o usuário não foi específico. Se pediu "esta semana", use 7d. Se pediu "vamos ver tudo", confirme antes (ano inteiro pode ser muito).
package/dist/index.js CHANGED
@@ -7,6 +7,9 @@ import { dirname, resolve } from 'path';
7
7
  import { loadConfig } from './config.js';
8
8
  import { LionChatClient } from './client.js';
9
9
  import { registerTools } from './tools.js';
10
+ import { getServerInstructions } from './instructions.js';
11
+ import { registerResources } from './resources.js';
12
+ import { registerPrompts } from './prompts.js';
10
13
  // AIDEV-NOTE: Read version from package.json to avoid hardcoding in multiple places
11
14
  const __dirname = dirname(fileURLToPath(import.meta.url));
12
15
  const pkg = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf-8'));
@@ -21,20 +24,33 @@ async function main() {
21
24
  !config.baseUrl.includes('127.0.0.1')) {
22
25
  console.error('WARNING: Base URL is not HTTPS. API token may be transmitted in cleartext.');
23
26
  }
24
- // AIDEV-NOTE: Create MCP server instance with name and version from package.json
27
+ // AIDEV-NOTE: Create MCP server com instructions, capabilities (tools/resources/prompts).
28
+ // Instructions explica modelo de dados, convencoes, glossario pra IA conectada.
25
29
  const server = new McpServer({
26
30
  name: 'lionchat-mcp-server',
27
31
  version: VERSION,
32
+ }, {
33
+ instructions: getServerInstructions(),
34
+ capabilities: {
35
+ tools: {},
36
+ resources: { subscribe: false, listChanged: false },
37
+ prompts: { listChanged: false },
38
+ },
28
39
  });
29
40
  // AIDEV-NOTE: Create HTTP client that wraps fetch calls to LionChat API
30
41
  const client = new LionChatClient(config);
31
42
  // AIDEV-NOTE: Register tools from endpoints.json, filtered by config.categories if set
32
43
  const toolCount = registerTools(server, config, client);
44
+ // AIDEV-NOTE: Resources (docs sob demanda) + Prompts (templates de workflow)
45
+ registerResources(server);
46
+ registerPrompts(server);
33
47
  // AIDEV-NOTE: Use stderr for logs — stdout is reserved for MCP JSON-RPC protocol
34
48
  console.error(`LionChat MCP Server v${VERSION}`);
35
49
  console.error(`Base URL: ${config.baseUrl}`);
36
50
  console.error(`Account: ${config.accountId}`);
37
51
  console.error(`Tools registered: ${toolCount}`);
52
+ console.error(`Resources registered: 4 (glossary, data-model, reports-guide, api-conventions)`);
53
+ console.error(`Prompts registered: 4 (productivity_report, stuck_leads, weekly_recap, customer_health)`);
38
54
  if (config.categories) {
39
55
  console.error(`Categories filter: ${config.categories.join(', ')}`);
40
56
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,oFAAoF;AACpF,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AACxF,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC;AAEpC,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,6FAA6F;QAC7F,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAE5B,+EAA+E;QAC/E,IACE,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC;YACtC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;YACrC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,CAAC;YACD,OAAO,CAAC,KAAK,CAAC,4EAA4E,CAAC,CAAC;QAC9F,CAAC;QAED,iFAAiF;QACjF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;YAC3B,IAAI,EAAE,qBAAqB;YAC3B,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,wEAAwE;QACxE,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;QAE1C,uFAAuF;QACvF,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAExD,iFAAiF;QACjF,OAAO,CAAC,KAAK,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,KAAK,CAAC,aAAa,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,KAAK,CAAC,YAAY,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,KAAK,CAAC,qBAAqB,SAAS,EAAE,CAAC,CAAC;QAChD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,sBAAsB,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,kEAAkE;QAClE,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function getServerInstructions(): string;
@@ -0,0 +1,26 @@
1
+ // AIDEV-NOTE: Carrega instructions.md de src/docs (dev) ou dist/docs (prod).
2
+ // Sincronizado de docs-lionchat/mcp/instructions.md via sync-to-mcps.sh.
3
+ // Conteudo enviado pra IA conectada via McpServer instructions option.
4
+ import { readFileSync, existsSync } from 'node:fs';
5
+ import { dirname, join } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ let cachedInstructions = null;
9
+ export function getServerInstructions() {
10
+ if (cachedInstructions !== null)
11
+ return cachedInstructions;
12
+ const candidates = [
13
+ join(__dirname, '../docs/instructions.md'),
14
+ join(__dirname, '../../src/docs/instructions.md'),
15
+ ];
16
+ for (const filepath of candidates) {
17
+ if (existsSync(filepath)) {
18
+ cachedInstructions = readFileSync(filepath, 'utf-8');
19
+ return cachedInstructions;
20
+ }
21
+ }
22
+ cachedInstructions =
23
+ 'LionChat MCP Server — Plataforma brasileira de atendimento. Consulte resources/list pra mais info.';
24
+ return cachedInstructions;
25
+ }
26
+ //# sourceMappingURL=instructions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instructions.js","sourceRoot":"","sources":["../src/instructions.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,yEAAyE;AACzE,uEAAuE;AAEvE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,IAAI,kBAAkB,GAAkB,IAAI,CAAC;AAE7C,MAAM,UAAU,qBAAqB;IACnC,IAAI,kBAAkB,KAAK,IAAI;QAAE,OAAO,kBAAkB,CAAC;IAE3D,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,SAAS,EAAE,yBAAyB,CAAC;QAC1C,IAAI,CAAC,SAAS,EAAE,gCAAgC,CAAC;KAClD,CAAC;IAEF,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QAClC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,kBAAkB,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrD,OAAO,kBAAkB,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,kBAAkB;QAChB,oGAAoG,CAAC;IACvG,OAAO,kBAAkB,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerPrompts(server: McpServer): void;
@@ -0,0 +1,70 @@
1
+ // AIDEV-NOTE: Registra MCP Prompts no McpServer (high-level SDK).
2
+ // Templates JSON sincronizados de docs-lionchat/mcp/prompts/.
3
+ // Cada prompt declara argumentos opcionais e um template Mustache-style ({{var|default}}).
4
+ import { readFileSync, readdirSync, existsSync } from 'node:fs';
5
+ import { dirname, join } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ import { z } from 'zod';
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ function findPromptsDir() {
10
+ const candidates = [
11
+ join(__dirname, '../docs/prompts'),
12
+ join(__dirname, '../../src/docs/prompts'),
13
+ ];
14
+ for (const p of candidates) {
15
+ if (existsSync(p))
16
+ return p;
17
+ }
18
+ return null;
19
+ }
20
+ function loadPrompts() {
21
+ const dir = findPromptsDir();
22
+ if (!dir) {
23
+ console.error('[mcp] prompts directory not found');
24
+ return [];
25
+ }
26
+ const files = readdirSync(dir).filter((f) => f.endsWith('.json'));
27
+ const prompts = [];
28
+ for (const file of files) {
29
+ try {
30
+ const parsed = JSON.parse(readFileSync(join(dir, file), 'utf-8'));
31
+ if (parsed.name && parsed.template)
32
+ prompts.push(parsed);
33
+ }
34
+ catch (err) {
35
+ console.error(`[mcp] failed to parse ${file}: ${err.message}`);
36
+ }
37
+ }
38
+ return prompts;
39
+ }
40
+ function renderTemplate(template, args) {
41
+ return template.replace(/\{\{(\w+)(?:\|([^}]*))?\}\}/g, (_m, name, fallback) => {
42
+ const value = args[name];
43
+ if (value !== undefined && value !== '')
44
+ return String(value);
45
+ return fallback ?? '';
46
+ });
47
+ }
48
+ export function registerPrompts(server) {
49
+ const prompts = loadPrompts();
50
+ for (const prompt of prompts) {
51
+ // Build Zod schema from argument list (all optional)
52
+ const argsSchema = {};
53
+ for (const arg of prompt.arguments) {
54
+ argsSchema[arg.name] = z.string().optional().describe(arg.description);
55
+ }
56
+ server.prompt(prompt.name, prompt.description, argsSchema, async (args) => {
57
+ const rendered = renderTemplate(prompt.template, args);
58
+ return {
59
+ description: prompt.title,
60
+ messages: [
61
+ {
62
+ role: 'user',
63
+ content: { type: 'text', text: rendered },
64
+ },
65
+ ],
66
+ };
67
+ });
68
+ }
69
+ }
70
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ interface ResourceDef {
3
+ name: string;
4
+ uri: string;
5
+ description: string;
6
+ filename: string;
7
+ }
8
+ export declare const RESOURCES: ResourceDef[];
9
+ export declare function registerResources(server: McpServer): void;
10
+ export {};
@@ -0,0 +1,66 @@
1
+ // AIDEV-NOTE: Registra MCP Resources no McpServer (high-level SDK).
2
+ // 4 docs Markdown sincronizados de docs-lionchat/mcp/resources/.
3
+ import { readFileSync, existsSync } from 'node:fs';
4
+ import { dirname, join } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ export const RESOURCES = [
8
+ {
9
+ name: 'Glossario LionChat',
10
+ uri: 'lionchat://docs/glossary',
11
+ description: 'Glossario completo de termos, status codes, enums e conceitos. Consulte sempre que encontrar campo numerico ou enum desconhecido.',
12
+ filename: 'glossary.md',
13
+ },
14
+ {
15
+ name: 'Modelo de Dados',
16
+ uri: 'lionchat://docs/data-model',
17
+ description: 'Mapa completo de entidades, relacionamentos e FKs. Use quando precisar entender como dados conectam.',
18
+ filename: 'data-model.md',
19
+ },
20
+ {
21
+ name: 'Guia de Relatorios',
22
+ uri: 'lionchat://docs/reports-guide',
23
+ description: 'Como interpretar cada um dos 19 endpoints de relatorio. Unidades, comparativos, business hours, CSAT, SLA.',
24
+ filename: 'reports-guide.md',
25
+ },
26
+ {
27
+ name: 'Convencoes da API',
28
+ uri: 'lionchat://docs/api-conventions',
29
+ description: 'Auth, paginacao, filtros, datas, codigos HTTP, rate limits. Use quando tiver duvida sobre como chamar endpoint.',
30
+ filename: 'api-conventions.md',
31
+ },
32
+ ];
33
+ function findDocsPath(filename) {
34
+ const candidates = [
35
+ join(__dirname, '../docs/resources', filename),
36
+ join(__dirname, '../../src/docs/resources', filename),
37
+ ];
38
+ for (const p of candidates) {
39
+ if (existsSync(p))
40
+ return p;
41
+ }
42
+ return null;
43
+ }
44
+ export function registerResources(server) {
45
+ for (const res of RESOURCES) {
46
+ server.registerResource(res.name, res.uri, {
47
+ description: res.description,
48
+ mimeType: 'text/markdown',
49
+ }, async (uri) => {
50
+ const filepath = findDocsPath(res.filename);
51
+ if (!filepath) {
52
+ throw new Error(`Resource file missing: ${res.filename}`);
53
+ }
54
+ return {
55
+ contents: [
56
+ {
57
+ uri: uri.href,
58
+ mimeType: 'text/markdown',
59
+ text: readFileSync(filepath, 'utf-8'),
60
+ },
61
+ ],
62
+ };
63
+ });
64
+ }
65
+ }
66
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,iEAAiE;AAEjE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAS1D,MAAM,CAAC,MAAM,SAAS,GAAkB;IACtC;QACE,IAAI,EAAE,oBAAoB;QAC1B,GAAG,EAAE,0BAA0B;QAC/B,WAAW,EACT,mIAAmI;QACrI,QAAQ,EAAE,aAAa;KACxB;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,GAAG,EAAE,4BAA4B;QACjC,WAAW,EACT,sGAAsG;QACxG,QAAQ,EAAE,eAAe;KAC1B;IACD;QACE,IAAI,EAAE,oBAAoB;QAC1B,GAAG,EAAE,+BAA+B;QACpC,WAAW,EACT,4GAA4G;QAC9G,QAAQ,EAAE,kBAAkB;KAC7B;IACD;QACE,IAAI,EAAE,mBAAmB;QACzB,GAAG,EAAE,iCAAiC;QACtC,WAAW,EACT,iHAAiH;QACnH,QAAQ,EAAE,oBAAoB;KAC/B;CACF,CAAC;AAEF,SAAS,YAAY,CAAC,QAAgB;IACpC,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,SAAS,EAAE,mBAAmB,EAAE,QAAQ,CAAC;QAC9C,IAAI,CAAC,SAAS,EAAE,0BAA0B,EAAE,QAAQ,CAAC;KACtD,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,CAAC,gBAAgB,CACrB,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,GAAG,EACP;YACE,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,QAAQ,EAAE,eAAe;SAC1B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;YACZ,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC5C,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG,EAAE,GAAG,CAAC,IAAI;wBACb,QAAQ,EAAE,eAAe;wBACzB,IAAI,EAAE,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC;qBACtC;iBACF;aACF,CAAC;QACJ,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC"}
package/dist/tools.js CHANGED
@@ -270,6 +270,137 @@ function registerListCategoriesTool(server, allEndpoints) {
270
270
  };
271
271
  });
272
272
  }
273
+ // AIDEV-NOTE: Meta tool — returns full Flow Builder schema reference (no API call).
274
+ // Helps LLMs build correct flow_data without hitting trial-and-error on
275
+ // node types, action keys, source handles, etc.
276
+ function registerFlowsSchemaReferenceTool(server) {
277
+ const reference = `LIONCHAT FLOW BUILDER — SCHEMA REFERENCE
278
+
279
+ flow_data tem o formato Vue Flow: { nodes: [...], edges: [...] }.
280
+
281
+ ═══ NODE GERAL ═══
282
+ { "id": "string-unico", "type": "start|send_message|wait_response|condition|action|api|set_variable|wait|randomizer|update_group|ai|end", "position": {"x":0,"y":0}, "data": { ... } }
283
+
284
+ ═══ NODE TYPES + source handles ═══
285
+
286
+ ▸ start
287
+ data: { label }
288
+ (sem handles — start tem so output default pro proximo node)
289
+
290
+ ▸ send_message
291
+ data: { label, messageItems: [
292
+ { id, type:"text", content },
293
+ { id, type:"image", url, caption },
294
+ { id, type:"template", template_name, ... }
295
+ ]}
296
+ Handles: "success", "no_response" (se timeout), "error", "window_closed" (WhatsApp API Official).
297
+ Se messageItem text com buttons_enabled=true: gera "button_{value}" por botao.
298
+
299
+ ▸ wait_response
300
+ data: {
301
+ label, waitTime, waitUnit: "minutes"|"seconds",
302
+ validation: "any"|"options"|"regex",
303
+ acceptedOptions: ["1","2"], // se validation='options'
304
+ regexPattern, // se validation='regex'
305
+ invalidMessage, maxRetries,
306
+ saveTo: "variable"|"attribute"|"",
307
+ saveVariable, saveAttrKey
308
+ }
309
+ Handles validation='options': "option_{val}" por opcao + "timeout"
310
+ Handles outros: "success" + "timeout"
311
+ IMPORTANTE: validation='options' ja roteia por opcao — NAO precisa condition depois.
312
+
313
+ ▸ condition
314
+ data: { label, conditions: [
315
+ { id, label, field, operator, value, valueType }
316
+ ]}
317
+ Handles: id de cada condicao + "default" (fallback).
318
+
319
+ ▸ action
320
+ data: { label, items: [
321
+ { key, config: {...} }
322
+ ]}
323
+ ATENCAO: items[].config NAO items[].params.
324
+ Keys validas:
325
+ Conversa: assign_agent({agent_id}), assign_team({team_id}),
326
+ change_status({status,snooze_option}), change_priority({priority}),
327
+ mute_conversation({}), add_private_note({content}),
328
+ send_email_transcript({email}), deactivate_flow({}),
329
+ assign_captain({assistant_id}), deactivate_captain({})
330
+ Contato: add_label({labels:[...]}), remove_label({labels:[...]}),
331
+ update_attribute({attr_source,attr_key,attr_value})
332
+ Kanban: create_kanban_item({funnel_id,funnel_stage,...}),
333
+ move_kanban_stage({funnel_id,funnel_stage}),
334
+ set_won({funnel_id}), set_lost({funnel_id,lost_reason}),
335
+ assign_agent_card({funnel_id,agent_id}),
336
+ add_card_note({funnel_id,text})
337
+ Handles: "success", "error"
338
+
339
+ ▸ api
340
+ data: { label, method, url, headers:[{key,value}], body, apiResponseVar }
341
+ Handles: "success", "error"
342
+
343
+ ▸ set_variable
344
+ data: { label, variables: [{name,value}] }
345
+
346
+ ▸ wait
347
+ data: { label, waitTime, waitUnit }
348
+
349
+ ▸ randomizer
350
+ data: { label, branches:[{id,percent}] }
351
+ Handles: id de cada branch.
352
+
353
+ ═══ EDGES ═══
354
+ [{ "id", "source", "target", "sourceHandle", "type":"deletable", "animated":true }]
355
+ sourceHandle OBRIGATORIO casar com handle exposto pelo node source.
356
+
357
+ ═══ ERROS COMUNS ═══
358
+ 1. action items[].config (nao params)
359
+ 2. send_message messageItems (nao items)
360
+ 3. wait_response validation='options' roteia por handle 'option_X' — NAO use condition depois
361
+ 4. sourceHandle precisa ser o handle REAL do node source ('success', 'option_1', 'timeout', 'no_response', 'c1' do condition, etc)
362
+ 5. inbox_ids no MCP vai no nivel raiz; no PUT bruto vai em {flow:{inbox_ids:[]}}
363
+ 6. send_message com buttons gera 'button_{value}' (value do botao, nao titulo)
364
+ 7. condition.field aceita liquid: '{{conversation.team_id}}', '{{contact.attributes.cpf}}', '{{var_nome}}'
365
+
366
+ ═══ EXEMPLO MINIMO — Menu 3 opcoes ═══
367
+ {
368
+ "nodes": [
369
+ {"id":"s1","type":"start","position":{"x":50,"y":200},"data":{"label":"Inicio"}},
370
+ {"id":"m1","type":"send_message","position":{"x":300,"y":200},"data":{
371
+ "label":"Menu",
372
+ "messageItems":[{"id":"t1","type":"text","content":"Digite:\\n1 - Vendas\\n2 - Suporte\\n3 - Financeiro"}]
373
+ }},
374
+ {"id":"w1","type":"wait_response","position":{"x":600,"y":200},"data":{
375
+ "label":"Aguarda","waitTime":60,"waitUnit":"minutes",
376
+ "validation":"options","acceptedOptions":["1","2","3"],
377
+ "invalidMessage":"Digite 1, 2 ou 3.","maxRetries":3,
378
+ "saveTo":"variable","saveVariable":"menu"
379
+ }},
380
+ {"id":"a1","type":"action","position":{"x":900,"y":50},"data":{
381
+ "label":"Vendas","items":[{"key":"assign_team","config":{"team_id":24}}]
382
+ }},
383
+ {"id":"a2","type":"action","position":{"x":900,"y":200},"data":{
384
+ "label":"Suporte","items":[{"key":"assign_team","config":{"team_id":23}}]
385
+ }},
386
+ {"id":"a3","type":"action","position":{"x":900,"y":350},"data":{
387
+ "label":"Financeiro","items":[{"key":"assign_team","config":{"team_id":25}}]
388
+ }}
389
+ ],
390
+ "edges":[
391
+ {"id":"e1","source":"s1","target":"m1","type":"deletable","animated":true},
392
+ {"id":"e2","source":"m1","target":"w1","type":"deletable","animated":true},
393
+ {"id":"e3","source":"w1","sourceHandle":"option_1","target":"a1","type":"deletable","animated":true},
394
+ {"id":"e4","source":"w1","sourceHandle":"option_2","target":"a2","type":"deletable","animated":true},
395
+ {"id":"e5","source":"w1","sourceHandle":"option_3","target":"a3","type":"deletable","animated":true}
396
+ ]
397
+ }`;
398
+ server.tool('lionchat_flows_schema_reference', 'Returns the full Flow Builder schema reference: node types, action keys, source handles, edge format, common pitfalls and a minimal working example. CALL THIS BEFORE building or editing a flow_data via lionchat_flows_create or lionchat_flows_update.', {}, { readOnlyHint: true, destructiveHint: false, idempotentHint: true }, async () => {
399
+ return {
400
+ content: [{ type: 'text', text: reference }],
401
+ };
402
+ });
403
+ }
273
404
  // AIDEV-NOTE: Main entry point — reads endpoints.json, filters, and registers all tools + meta tools
274
405
  export function registerTools(server, config, client) {
275
406
  // AIDEV-NOTE: Resolve endpoints.json relative to compiled dist/ directory (one level up)
@@ -301,6 +432,7 @@ export function registerTools(server, config, client) {
301
432
  // AIDEV-NOTE: Always register meta tools regardless of category filters
302
433
  registerPingTool(server, config, client);
303
434
  registerListCategoriesTool(server, endpoints);
304
- return filtered.length + 2; // +2 for ping and list_categories
435
+ registerFlowsSchemaReferenceTool(server);
436
+ return filtered.length + 3; // +3 for ping, list_categories, flows_schema_reference
305
437
  }
306
438
  //# sourceMappingURL=tools.js.map