funifier-mcp 0.3.20 → 0.3.22

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 (45) hide show
  1. package/.cursor/rules/funifier.mdc +1 -0
  2. package/.github/copilot-instructions.md +1 -0
  3. package/AGENTS.md +1 -0
  4. package/CHANGELOG.md +31 -0
  5. package/datasource-funifier-docs/.coverage.json +22 -6
  6. package/datasource-funifier-docs/.validation.json +87 -11
  7. package/datasource-funifier-docs/knowledge/guides/database-access.md +3 -0
  8. package/datasource-funifier-docs/knowledge/guides/explain-diagnostics.md +170 -0
  9. package/datasource-funifier-docs/knowledge/guides/server-utils.md +718 -0
  10. package/datasource-funifier-docs/knowledge/index.md +4 -0
  11. package/datasource-funifier-docs/knowledge/modules/custom-object.md +12 -7
  12. package/datasource-funifier-docs/knowledge/modules/database.md +48 -5
  13. package/dist/mcp/bundle.js +131 -108
  14. package/dist/mcp/tools/database.d.ts.map +1 -1
  15. package/dist/mcp/tools/database.js +14 -2
  16. package/dist/mcp/tools/database.js.map +1 -1
  17. package/dist/mcp/tools/database.test.js +16 -0
  18. package/dist/mcp/tools/database.test.js.map +1 -1
  19. package/dist/mcp/tools/db-explain.d.ts +4 -0
  20. package/dist/mcp/tools/db-explain.d.ts.map +1 -0
  21. package/dist/mcp/tools/db-explain.js +187 -0
  22. package/dist/mcp/tools/db-explain.js.map +1 -0
  23. package/dist/mcp/tools/db-explain.test.d.ts +2 -0
  24. package/dist/mcp/tools/db-explain.test.d.ts.map +1 -0
  25. package/dist/mcp/tools/db-explain.test.js +142 -0
  26. package/dist/mcp/tools/db-explain.test.js.map +1 -0
  27. package/dist/mcp/tools/index.d.ts.map +1 -1
  28. package/dist/mcp/tools/index.js +2 -0
  29. package/dist/mcp/tools/index.js.map +1 -1
  30. package/dist/mcp/tools/list-tools.d.ts.map +1 -1
  31. package/dist/mcp/tools/list-tools.js +8 -0
  32. package/dist/mcp/tools/list-tools.js.map +1 -1
  33. package/package.json +1 -1
  34. package/skills/funifier/SKILL.md +1 -0
  35. package/skills/funifier/references/create-aggregate.md +10 -5
  36. package/skills/funifier/references/create-audit.md +0 -8
  37. package/skills/funifier/references/create-custom-object.md +0 -6
  38. package/skills/funifier/references/date-handling.md +0 -6
  39. package/skills/funifier/references/debug.md +2 -1
  40. package/skills/funifier/references/help.md +0 -6
  41. package/skills/funifier/references/manage-indexes.md +0 -6
  42. package/skills/funifier/references/query-aggregate.md +2 -6
  43. package/skills/funifier/references/server-utils.md +94 -0
  44. package/datasource-funifier-docs/.search-index.json +0 -59689
  45. package/datasource-funifier-docs/.skills-map.json +0 -150
@@ -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.20",
3
+ "version": "0.3.22",
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",
@@ -70,6 +70,7 @@ Then read a result with `funifier_read_doc path=<path>`.
70
70
  | Upload files to Funifier — images and documents for player avatars, challenge resources, and visual assets; use when adding media to the platform, not for CSV data import (use funifier-import-csv) or static frontend hosting (use funifier-implement-frontend) | `references/upload-file.md` |
71
71
  | Create, list, and drop MongoDB single-field indexes on Funifier collections via the REST API. Composite (multi-field) indexes are NOT supported by this endpoint — see Limitation section. | `references/manage-indexes.md` |
72
72
  | Cross-check a project's Funifier API calls against the live security document — scan code for usage, build an evidence-backed manifest, run the deterministic audit engine, and report missing scopes, excess tokens, and static danger findings; use when debugging 401s, auditing minimum privilege, or verifying permissions before deploying; audit is read-only and never changes any configuration | `references/audit-permissions.md` |
73
+ | Use the server-side utility classes from com.funifier.engine.util in Groovy triggers, schedulers, and public endpoints — validates CPF, encrypts fields with AES/BCrypt/PGP, renders Mustache templates, evaluates inline expressions, computes object diffs/changelogs, converts JSON, generates Excel, makes HTTP calls, and handles files and pagination | `references/server-utils.md` |
73
74
 
74
75
  ## Documented Modules
75
76
 
@@ -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
@@ -79,9 +79,3 @@ Baseado na tabela acima, instrua o usuário a usar a skill específica.
79
79
  ### 4. Se não encontrar skill específica
80
80
 
81
81
  Consulte `funifier_read_doc path=index` e leia o módulo relevante diretamente.
82
-
83
- ## Verified References
84
-
85
- | Claim | Status | Evidence |
86
- |-------|--------|----------|
87
- | Achievement is the core entity class representing all gamification rewards in funifier-service | ✓ verified | Class:src/main/java/com/funifier/engine/achievement/Achievement.java:Achievement |
@@ -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
-
@@ -0,0 +1,94 @@
1
+ # funifier-server-utils
2
+
3
+ Use the server-side utility classes from com.funifier.engine.util in Groovy triggers, schedulers, and public endpoints — validates CPF, encrypts fields with AES/BCrypt/PGP, renders Mustache templates, evaluates inline expressions, computes object diffs/changelogs, converts JSON, generates Excel, makes HTTP calls, and handles files and pagination
4
+
5
+ ---
6
+
7
+ ## Formato do payload (obrigatório)
8
+
9
+ Funifier armazena código como **strings JSON escapadas**. Ao montar o payload do `funifier_save`:
10
+
11
+ - **Quebra de linha** → `\n` (nunca newline literal dentro da string)
12
+ - **Aspas duplas** dentro do código → `\"`
13
+ - **Backslash** → `\\` (regex `\b` vira `\\b`; dentro de Groovy com string-building pode exigir `\\\\b`)
14
+ - **Tab** → `\t` (se usar)
15
+ - **Pipelines de aggregate** vão como **string JSON** (não objeto aninhado) — serialize o array inteiro
16
+
17
+ A regra prática: monte o objeto em JavaScript normalmente e passe por `JSON.stringify` — o MCP faz isso automaticamente quando você entrega o payload como JSON. **Nunca** cole código multilinha cru no meio do JSON.
18
+
19
+ ### Exemplo 1 — custom-page (html + angularjs script)
20
+
21
+ ```json
22
+ {
23
+ "title": "Ciclos",
24
+ "slug": "studio/custom/ciclos",
25
+ "html": "<div class=\"row\">\n <div class=\"col-md-12\">\n <h2>Ciclos</h2>\n </div>\n</div>\n",
26
+ "script": "$scope.all = [];\n$scope.loading = false;\n\n$scope.list = function () {\n $scope.loading = true;\n};\n$scope.list();\n"
27
+ }
28
+ ```
29
+
30
+ ### Exemplo 2 — aggregate preparado (pipeline JSON + script Groovy)
31
+
32
+ ```json
33
+ {
34
+ "_id": "extrato",
35
+ "title": "Extrato de Pontos",
36
+ "collection": "extrato",
37
+ "aggregate": "[\n {\n \"$match\": { \"player\": \"$param:player\" }\n },\n {\n \"$sort\": { \"time\": -1 }\n }\n]",
38
+ "script": "void prepare(aggregations, params) {\n if (context.get(\"player\") != null) {\n params.put(\"player\", context.get(\"player\"));\n } else {\n params.put(\"player\", \"NAO_EXISTE\");\n }\n}\n"
39
+ }
40
+ ```
41
+
42
+ Note que `aggregate` é uma **string** contendo JSON serializado (com `\n` e `\"` escapados), **não** um array nativo. Mesma regra vale para `script` em triggers/schedulers/aggregates e `html`/`script` em custom-pages.
43
+
44
+ ---
45
+
46
+ ## Before starting — find relevant docs
47
+
48
+ Use the `funifier_search_docs` MCP tool to load only what you need:
49
+
50
+ ```
51
+ funifier_search_docs "cpf cnpj validar validate cpf-util aes encrypt decrypt criptografar criptografia bcrypt hash senha password pgp pgpcrypt rsa asymmetric totp otp 2fa qrcode google-authenticator mustache template render handlebars expression inline formula avaliar diff changelog auditoria comparar compare json serialize deserialize jsonutil excel xlsx spreadsheet planilha relatorio currency moeda formatar format http get post requisicao external url read-url pagination paginar paginacao paginate file stream arquivo util helper utility server-side groovy"
52
+ ```
53
+
54
+ Then read the most relevant results with `funifier_read_doc path=<path>`.
55
+
56
+ ## Primary docs for this skill
57
+
58
+ If search returns insufficient results, read these directly:
59
+
60
+ - `funifier_read_doc path=guides/server-utils`
61
+ - `funifier_read_doc path=guides/triggers-guide`
62
+ - `funifier_read_doc path=guides/java-managers`
63
+
64
+ ## Steps
65
+
66
+ ### 1. Understand the requirement
67
+
68
+ Ask the user what they want to create or accomplish. Gather:
69
+ - The name/title
70
+ - The purpose and behavior
71
+ - Any specific configuration or constraints
72
+
73
+ ### 2. Search for relevant documentation
74
+
75
+ Run the lexical search (command shown above) and read the returned files.
76
+
77
+ ### 3. Check existing resources (if MCP available)
78
+
79
+ Use `funifier_list` with the relevant type and a `search` parameter to see
80
+ if a similar resource already exists. Never list all resources without a search term.
81
+
82
+ ### 4. Design and confirm
83
+
84
+ Based on the docs, outline the configuration to the user and confirm before saving.
85
+
86
+ ### 5. Create or update
87
+
88
+ Use `funifier_save` with the appropriate type and a JSON payload to create or
89
+ update the resource. If MCP is unavailable, show the complete JSON for manual use.
90
+
91
+ ### 6. Validate
92
+
93
+ Use `funifier_logs` (for triggers/schedulers) or `funifier_get` to confirm
94
+ the resource was saved correctly and executed without errors.