@enfyra/mcp-server 0.0.74 → 0.0.76
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.
- package/README.md +2 -0
- package/package.json +1 -1
- package/src/lib/mcp-examples.js +1 -0
- package/src/lib/mcp-instructions.js +2 -1
- package/src/mcp-server-entry.mjs +2 -0
package/README.md
CHANGED
|
@@ -188,6 +188,8 @@ Schema and script tools include safety guards for LLM callers: generic record mu
|
|
|
188
188
|
|
|
189
189
|
Read tools use Enfyra's `fields` parameter directly. Passing explicit includes such as `fields=id,email` returns only those fields, while any `-field` token switches that scope to exclude mode. For example, `fields=-compiledCode` returns all readable fields except `compiledCode`, and `fields=id,-compiledCode` still means all except `compiledCode`. Nested exclusions work with dotted fields and `deep`, such as `fields=-owner.avatar` or `deep.owner.fields=-avatar`.
|
|
190
190
|
|
|
191
|
+
Generated RLS for canonical table reads must keep projection and pagination client-owned. Pre-hooks may merge owner or membership constraints into `@QUERY.filter`, but they must not override `@QUERY.fields`, `@QUERY.deep`, `@QUERY.sort`, `@QUERY.limit`, `@QUERY.page`, `@QUERY.meta`, `@QUERY.aggregate`, or `debugMode`. Fixed projections belong only on clearly custom summary or workflow endpoints with an explicit response contract.
|
|
192
|
+
|
|
191
193
|
Quick checklist for a new LLM using Enfyra MCP: discover the live system first, inspect the specific table/route, load the matching example category, mutate with explicit fields and relation property names, validate or test scripts/routes before relying on them, re-read the saved row when mutation output is summarized, and preview destructive operations before confirming.
|
|
192
194
|
|
|
193
195
|
Use `update_script_source` when updating existing long script-backed records such as `flow_step_definition`, `route_handler_definition`, hook tables, websocket scripts, GraphQL scripts, or bootstrap scripts. It accepts raw `sourceCode` directly, validates the source, and saves `sourceCode`/`scriptLanguage` without requiring the caller to manually JSON-escape the full script. Use generic `update_record` for small record patches or patches that include non-script metadata fields.
|
package/package.json
CHANGED
package/src/lib/mcp-examples.js
CHANGED
|
@@ -605,6 +605,7 @@ const scope = {
|
|
|
605
605
|
notes: [
|
|
606
606
|
'@QUERY.filter is initialized as an object for REST pre-hooks.',
|
|
607
607
|
'Mutate @QUERY.filter before canonical CRUD runs.',
|
|
608
|
+
'Do not override @QUERY.fields, @QUERY.deep, @QUERY.sort, @QUERY.limit, @QUERY.page, @QUERY.meta, @QUERY.aggregate, or debugMode in RLS; keep projection and pagination client-owned.',
|
|
608
609
|
],
|
|
609
610
|
},
|
|
610
611
|
{
|
|
@@ -135,7 +135,8 @@ export function buildMcpServerInstructions(apiBaseUrl) {
|
|
|
135
135
|
'- Each route has **publishedMethods** (which HTTP verbs are “public”) and **routePermissions** (roles/users for protected access).',
|
|
136
136
|
'- If the **current request method** is listed in **publishedMethods** for that route, the server allows the call **without** a Bearer token (`RoleGuard`).',
|
|
137
137
|
'- Otherwise the client must send an **Authorization** header with **Bearer** JWT from login. Then the user must satisfy **routePermissions** (unless root admin).',
|
|
138
|
-
'- Owner-scoped GET handlers must preserve caller filters and merge the owner scope for normal users, while root admin operational views may bypass
|
|
138
|
+
'- Owner-scoped GET handlers must preserve caller filters and merge the owner scope for normal users, while root admin operational views may bypass only the owner scope with `@USER.isRootAdmin` and must keep caller filters intact. Never replace `@QUERY.filter` with `{}` for root admins; doing so breaks detail reads, pagination, and `debugMode=true` explain checks.',
|
|
139
|
+
'- GET pre-hooks and handlers must preserve client-controlled query shape: do not override `@QUERY.fields`, `@QUERY.deep`, `@QUERY.sort`, `@QUERY.limit`, `@QUERY.page`, `@QUERY.meta`, `@QUERY.aggregate`, or `debugMode` for canonical table reads. RLS may only merge security filters into `@QUERY.filter`. If a route intentionally returns a fixed summary/aggregate workflow response, make it a clearly custom endpoint contract instead of changing canonical table projection.',
|
|
139
140
|
'- MCP tools that use `fetchAPI` authenticate with the configured `ENFYRA_API_TOKEN`. Explain to users that **direct HTTP** calls need a Bearer token unless the route/method is published.',
|
|
140
141
|
'',
|
|
141
142
|
'### Post-hooks (REST)',
|
package/src/mcp-server-entry.mjs
CHANGED
|
@@ -771,12 +771,14 @@ server.tool(
|
|
|
771
771
|
runs: 'Before handler.',
|
|
772
772
|
data: ['@BODY', '@QUERY', '@PARAMS', '@USER', '@REPOS', '@CACHE', '@HELPERS', '@STORAGE', '@THROW*', '@SOCKET emit helpers'],
|
|
773
773
|
queryContract: '@QUERY.filter is initialized as an object. When adding RLS/scope filters in pre-hooks, merge directly with _and; do not add defensive type checks around @QUERY.filter.',
|
|
774
|
+
projectionContract: 'For canonical table reads, preserve client-controlled query shape. Do not override @QUERY.fields, @QUERY.deep, @QUERY.sort, @QUERY.limit, @QUERY.page, @QUERY.meta, @QUERY.aggregate, or debugMode. RLS should only merge security constraints into @QUERY.filter.',
|
|
774
775
|
rlsPattern: 'For relation-scoped reads, mutate @QUERY.filter instead of returning data. Example: const incomingFilter = @QUERY.filter; const scope = { memberships: { member: { id: { _eq: @USER.id } } } }; @QUERY.filter = Object.keys(incomingFilter).length ? { _and: [incomingFilter, scope] } : scope;',
|
|
775
776
|
returnBehavior: 'Returning a non-undefined value skips handler and becomes response data.',
|
|
776
777
|
},
|
|
777
778
|
handler: {
|
|
778
779
|
runs: 'Main route logic, or canonical CRUD if no handler overrides.',
|
|
779
780
|
data: ['@BODY', '@QUERY', '@PARAMS', '@USER', '@UPLOADED_FILE for multipart request file metadata', '@REPOS.main', '@REPOS.secure', '@CACHE', '@HELPERS', '@STORAGE', '@PKGS', '@SOCKET emit helpers', '@TRIGGER'],
|
|
781
|
+
queryContract: 'When a handler wraps a canonical table read, pass through client fields/deep/sort/page/limit/meta/aggregate/debugMode unless the route is a clearly custom summary or workflow endpoint.',
|
|
780
782
|
returnBehavior: 'Return value becomes response body unless post-hook changes it.',
|
|
781
783
|
},
|
|
782
784
|
postHook: {
|