funifier-mcp 0.3.21 → 0.4.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +15 -11
  3. package/datasource-funifier-docs/.coverage.json +11 -3
  4. package/datasource-funifier-docs/.validation.json +87 -11
  5. package/datasource-funifier-docs/knowledge/guides/database-access.md +3 -0
  6. package/datasource-funifier-docs/knowledge/guides/explain-diagnostics.md +170 -0
  7. package/datasource-funifier-docs/knowledge/index.md +3 -0
  8. package/datasource-funifier-docs/knowledge/modules/custom-object.md +12 -7
  9. package/datasource-funifier-docs/knowledge/modules/database.md +48 -5
  10. package/dist/cli/config-writers.d.ts +1 -3
  11. package/dist/cli/config-writers.d.ts.map +1 -1
  12. package/dist/cli/config-writers.js +20 -11
  13. package/dist/cli/config-writers.js.map +1 -1
  14. package/dist/cli/config-writers.test.js +25 -18
  15. package/dist/cli/config-writers.test.js.map +1 -1
  16. package/dist/cli/init.d.ts.map +1 -1
  17. package/dist/cli/init.js +37 -36
  18. package/dist/cli/init.js.map +1 -1
  19. package/dist/cli/init.test.js +51 -17
  20. package/dist/cli/init.test.js.map +1 -1
  21. package/dist/cli/prompts.d.ts +1 -0
  22. package/dist/cli/prompts.d.ts.map +1 -1
  23. package/dist/cli/prompts.js +9 -0
  24. package/dist/cli/prompts.js.map +1 -1
  25. package/dist/mcp/bundle.js +132 -109
  26. package/dist/mcp/tools/database.d.ts.map +1 -1
  27. package/dist/mcp/tools/database.js +14 -2
  28. package/dist/mcp/tools/database.js.map +1 -1
  29. package/dist/mcp/tools/database.test.js +16 -0
  30. package/dist/mcp/tools/database.test.js.map +1 -1
  31. package/dist/mcp/tools/db-explain.d.ts +4 -0
  32. package/dist/mcp/tools/db-explain.d.ts.map +1 -0
  33. package/dist/mcp/tools/db-explain.js +187 -0
  34. package/dist/mcp/tools/db-explain.js.map +1 -0
  35. package/dist/mcp/tools/db-explain.test.d.ts +2 -0
  36. package/dist/mcp/tools/db-explain.test.d.ts.map +1 -0
  37. package/dist/mcp/tools/db-explain.test.js +142 -0
  38. package/dist/mcp/tools/db-explain.test.js.map +1 -0
  39. package/dist/mcp/tools/index.d.ts.map +1 -1
  40. package/dist/mcp/tools/index.js +2 -0
  41. package/dist/mcp/tools/index.js.map +1 -1
  42. package/dist/mcp/tools/list-tools.d.ts.map +1 -1
  43. package/dist/mcp/tools/list-tools.js +8 -0
  44. package/dist/mcp/tools/list-tools.js.map +1 -1
  45. package/package.json +1 -1
  46. package/skills/funifier/references/create-aggregate.md +10 -5
  47. package/skills/funifier/references/create-audit.md +0 -8
  48. package/skills/funifier/references/create-custom-object.md +0 -6
  49. package/skills/funifier/references/date-handling.md +0 -6
  50. package/skills/funifier/references/debug.md +2 -1
  51. package/skills/funifier/references/manage-indexes.md +0 -6
  52. package/skills/funifier/references/query-aggregate.md +2 -6
@@ -1 +1 @@
1
- {"version":3,"file":"list-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/list-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"list-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/list-tools.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "funifier-mcp",
3
- "version": "0.3.21",
3
+ "version": "0.4.0",
4
4
  "description": "Funifier AI toolkit — MCP server, API client, and Claude Code skills for the Funifier gamification platform",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -59,6 +59,7 @@ If search returns insufficient results, read these directly:
59
59
 
60
60
  - `funifier_read_doc path=guides/aggregates`
61
61
  - `funifier_read_doc path=guides/database-access`
62
+ - `funifier_read_doc path=guides/explain-diagnostics`
62
63
  - `funifier_read_doc path=modules/database`
63
64
 
64
65
  ## Steps
@@ -191,10 +192,14 @@ O `mode=analyze` é uma **inspeção (dry-run)** — compila/roda o `script`, ap
191
192
 
192
193
  Diagnóstico: resultado de `mode=run` vazio **ou** recurso com `script` não-vazio → rode `mode=analyze` e leia `script_exceptions` (script quebrado) e `aggregate_step_3` (se um param virou `null`, o `$match` não casa nada — isso distingue "script quebrado" de "resultado legitimamente vazio").
193
194
 
194
- > ⚠️ NÃO execute via `GET /v3/database/aggregate/{id}` — retorna null/405 silenciosamente. A execução é `POST /v3/find/<id>` (corpo JSON, nunca query string). Via frontend: `api.post('/v3/find/<id>', { player: 'abc' })`.
195
+ ### 10. Validar performance (recomendado)
196
+
197
+ O `aggregate_step_3` do `mode=analyze` é o pipeline **já resolvido** (com `$param` substituído) — é exatamente o que roda no Mongo, então é o que se deve explicar. Jogue-o no explain:
198
+
199
+ ```
200
+ funifier_db_explain collection=<coll> pipeline=<aggregate_step_3> verbosity=queryPlanner
201
+ ```
195
202
 
196
- ## Verified References
203
+ O `queryPlanner` **não executa** a query — só revela `IXSCAN` vs `COLLSCAN` (barato: 1 execução de scheduler). Se der `COLLSCAN` no `$match`/`$sort` inicial, crie o índice (§7) e revalide. Use `verbosity=executionStats` só para os números reais de `totalDocsExamined` vs `nReturned`. Como os valores de `$param` mudam o filtro efetivo, valide com params **representativos**. Guia: `funifier_read_doc path=guides/explain-diagnostics`.
197
204
 
198
- | Claim | Status | Evidence |
199
- |-------|--------|----------|
200
- | DatabaseManager provides MongoDB connection and collection access for aggregate queries in Groovy scripts | ✓ verified | Class:src/main/java/com/funifier/engine/database/DatabaseManager.java:DatabaseManager |
205
+ > ⚠️ NÃO execute via `GET /v3/database/aggregate/{id}` — retorna null/405 silenciosamente. A execução é `POST /v3/find/<id>` (corpo JSON, nunca query string). Via frontend: `api.post('/v3/find/<id>', { player: 'abc' })`.
@@ -113,11 +113,3 @@ Filtros combináveis em `$match`: `user`/`login` (ator), `type` (`studio`/`playe
113
113
  ### 6. Exclusão (cuidado)
114
114
 
115
115
  `funifier_delete type=audit id=<id>` remove a config **e todos os seus logs em cascata**. Confirme com o usuário antes.
116
-
117
- ## Verified References
118
-
119
- | Claim | Status | Evidence |
120
- |-------|--------|----------|
121
- | Audit config fields are _id, title, active, entity, event, clean, type with event constants create/update/delete and type constants studio/player/all | ✓ verified | Class:src/main/java/com/funifier/engine/audit/Audit.java:Audit |
122
- | AuditManager.log only writes an AuditLog when an active Audit matches entity+event and the config type matches the operation origin | ✓ verified | Class:src/main/java/com/funifier/engine/audit/AuditManager.java:AuditManager |
123
- | clearExpiredLogs purges audit_log entries older than each config's clean retention and is invoked from AsyncProcessor | ✓ verified | Method:src/main/java/com/funifier/engine/audit/AuditManager.java:AuditManager.clearExpiredLogs#0 |
@@ -89,9 +89,3 @@ DELETE /v3/database/car__c?q=_id:'car001'
89
89
  ### 7. Usar em triggers
90
90
 
91
91
  Para executar trigger em eventos da coleção, use `entity: "car__c"` no payload do trigger.
92
-
93
- ## Verified References
94
-
95
- | Claim | Status | Evidence |
96
- |-------|--------|----------|
97
- | DatabaseManager provides MongoDB connection for custom __c collection CRUD operations in funifier-service | ✓ verified | Class:src/main/java/com/funifier/engine/database/DatabaseManager.java:DatabaseManager |
@@ -170,9 +170,3 @@ Não coloque o parâmetro convertido para `Date` dentro de `{ "$date": "$param:s
170
170
  - [ ] Em prepared aggregate, usar `"$param:nome"` exatamente como string.
171
171
  - [ ] Para data absoluta em prepared aggregate, converter no `script` com `DateUtil.parse`, validar `null`, e substituir o `Date` diretamente em `$gte`/`$lte`.
172
172
  - [ ] Testar aggregate direto antes de salvar como prepared aggregate.
173
-
174
- ## Verified References
175
-
176
- | Claim | Status | Evidence |
177
- |-------|--------|----------|
178
-
@@ -9,7 +9,7 @@ Debug a Funifier resource — systematic diagnosis of triggers, schedulers, aggr
9
9
  Use the `funifier_search_docs` MCP tool to load only what you need:
10
10
 
11
11
  ```
12
- funifier_search_docs "debug error log exception timeout groovy stack trace fix"
12
+ funifier_search_docs "debug error log exception timeout groovy stack trace fix explain slow index collscan"
13
13
  ```
14
14
 
15
15
  Then read the most relevant results with `funifier_read_doc path=<path>`.
@@ -24,6 +24,7 @@ If search returns insufficient results, read these directly:
24
24
  - `funifier_read_doc path=guides/trigger-examples`
25
25
  - `funifier_read_doc path=modules/scheduler`
26
26
  - `funifier_read_doc path=guides/aggregates`
27
+ - `funifier_read_doc path=guides/explain-diagnostics`
27
28
  - `funifier_read_doc path=modules/public`
28
29
 
29
30
  ## Steps
@@ -83,9 +83,3 @@ Get the index name from `action=list`. The `_id_` index cannot be dropped.
83
83
  | Unique email | `{"email": 1}` (uniqueness enforced by MongoDB, not this API) |
84
84
 
85
85
  For a composite (e.g. `{player: 1, time: -1}` to back filter+sort in one plan), use the Groovy/trigger path shown in the Limitation section — not this tool.
86
-
87
- ## Verified References
88
-
89
- | Claim | Status | Evidence |
90
- |-------|--------|----------|
91
-
@@ -20,6 +20,7 @@ If search returns insufficient results, read these directly:
20
20
 
21
21
  - `funifier_read_doc path=guides/aggregates`
22
22
  - `funifier_read_doc path=guides/database-access`
23
+ - `funifier_read_doc path=guides/explain-diagnostics`
23
24
  - `funifier_read_doc path=modules/database`
24
25
 
25
26
  ## Steps
@@ -61,6 +62,7 @@ A gramática de expressões de data Funifier (`{"$date": "-0M-"}` = início do m
61
62
  2. Cheque/crie índices: `funifier_index action=list collection=<coll>` para cada coleção tocada; crie os single-field faltantes com `funifier_index action=create`. Índice **composto** (ex.: `{player:1,time:-1}`) → o endpoint REST é single-field apenas; use o caminho Groovy `createIndex(...append...)` (ver skill `funifier-manage-indexes`). Não duplique a mecânica de índice aqui.
62
63
  3. Boas práticas: `$match` o mais cedo possível · reduza documentos com `$project`/`$match` **antes** do `$lookup` · `$sort` seguido imediatamente de `$limit` · cuidado com explosão de documentos do `$unwind` · garanta o `$lookup.foreignField` indexado.
63
64
  4. ⚠️ **Ad-hoc NÃO usa `allowDiskUse`** — um `$match`/`$sort` sem índice em coleção grande tende a ser lento ou falhar. (Prepared aggregate usa `allowDiskUse(true)`; ad-hoc não.)
65
+ 5. **Confirmar o plano real** (recomendado quando o passo 2 achou campo de `$match`/`$sort` sem índice, ou a coleção é grande): `funifier_db_explain collection=<coll> pipeline=<json> verbosity=queryPlanner`. O `queryPlanner` **não executa** a query — só revela `IXSCAN` vs `COLLSCAN` (barato: 1 execução de scheduler). Se o estágio vencedor for `COLLSCAN` sobre o `$match`/`$sort` inicial, crie o índice (passo 2) e revalide. Suba para `verbosity=executionStats` só quando quiser `totalDocsExamined` real (aí sim roda a query). Detalhes: `funifier_read_doc path=guides/explain-diagnostics`.
64
66
 
65
67
  ### 5. Executar
66
68
 
@@ -103,9 +105,3 @@ POST /v3/database/{collection}/aggregate?strict=true
103
105
  ```
104
106
 
105
107
  Mais exemplos prontos (médias, distintos, top-N por período) em `aggregates.md` §6 — `funifier_read_doc path=guides/aggregates`.
106
-
107
- ## Verified References
108
-
109
- | Claim | Status | Evidence |
110
- |-------|--------|----------|
111
-