@enfyra/mcp-server 0.0.17 → 0.0.18
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/package.json +1 -1
- package/src/lib/mcp-instructions.js +16 -6
package/package.json
CHANGED
|
@@ -87,6 +87,16 @@ export function buildMcpServerInstructions(apiBaseUrl) {
|
|
|
87
87
|
'- **Tables confirmed to have REST routes (system):** `table_definition`, `route_definition`, `user_definition`, `setting_definition`, `ai_config_definition`, `role_definition`, `menu_definition`, `extension_definition`, `folder_definition`, `file_definition`, `file_permission_definition`, `package_definition`, `bootstrap_script_definition`, `storage_config_definition`, `ai_conversation_definition`, `ai_message_definition`, `websocket_definition`, `websocket_event_definition`, `oauth_config_definition`, `oauth_account_definition`, `method_definition`, `pre_hook_definition`, `post_hook_definition`, `route_handler_definition`, `route_permission_definition`, `flow_definition`, `flow_step_definition`, `flow_execution_definition`.',
|
|
88
88
|
'- **Tables without REST routes (internal/system only):** `column_definition`, `relation_definition` — these are managed indirectly via cascade on `table_definition` (PATCH /table_definition/{id} with columns/relations array). The `create_column` MCP tool handles this automatically.',
|
|
89
89
|
'',
|
|
90
|
+
'### Body validation & column rules',
|
|
91
|
+
'- Each `table_definition` has a **`validateBody`** flag (default `true` for new tables). When on, every `POST /<table>` and `PATCH /<table>/<id>` is validated server-side against the column types + any **column rules** attached to columns of that table.',
|
|
92
|
+
'- Failure returns **HTTP 400** with `{ statusCode: 400, message: string[], error: "Bad Request" }`. `message` is an **array of strings** (one per violation, prefixed with the field name like `"email: Invalid email"`).',
|
|
93
|
+
'- **`column_rule_definition`** stores per-column rules: fields are `column` (FK to `column_definition`), `ruleType` (one of `min`, `max`, `minLength`, `maxLength`, `pattern`, `format`, `minItems`, `maxItems`, `custom`), `value` (JSON payload e.g. `{v:10}` or `{v:"email"}` or `{v:"^[a-z]+$", flags:"i"}`), `message` (optional override), `isEnabled`. Has a default REST route at `/column_rule_definition` so MCP `create_record` / `update_record` / `delete_record` work — but the **canonical workflow is the admin UI** (Collections → table → column row → ruler icon → Manage Rules), which knows the per-`column.type` allowlist (e.g. `format` only for strings, `minItems` only for `array-select`) and prevents duplicate rule types per column.',
|
|
94
|
+
'- **Rules are additive only** — they never replace the column\'s built-in type/nullable/length checks. There is no `required` rule type; required-ness comes from `column.isNullable = false`.',
|
|
95
|
+
'- If the user wants to add a validation constraint to a field, the right answer is: open the column rules modal in the admin UI. **Do not** suggest writing pre-hooks for standard constraints (only for truly custom logic).',
|
|
96
|
+
'- For `pattern` rules: the `value.v` is a JavaScript RegExp body (no surrounding `/.../`). Anchors matter — `^[a-z]+$` requires a full match, plain `[a-z]+` matches any substring. Flags go in `value.flags` (e.g. `"i"`).',
|
|
97
|
+
'- Validation cache is invalidated **automatically** when a column rule is created/updated/deleted via MCP or UI — no manual `reload_*` call needed afterward. Same for flipping `validateBody` on `table_definition`.',
|
|
98
|
+
'- To turn validation off for an entire table (e.g. legacy or test tables), either toggle **Validate Body** in the table form UI, or `update_record` on `table_definition` with `{ validateBody: false }`.',
|
|
99
|
+
'',
|
|
90
100
|
'### Schema / table migration (sequential only)',
|
|
91
101
|
'- When creating, updating, or deleting tables (or columns), run operations **one at a time**. The migration process locks the DB per operation.',
|
|
92
102
|
'- Do NOT batch multiple schema changes (e.g. create 3 tables in parallel, or create table + add columns simultaneously). Execute each `create_table`, `create_column`, sync, or drop sequentially; wait for completion before the next.',
|
|
@@ -131,15 +141,15 @@ export function buildMcpServerInstructions(apiBaseUrl) {
|
|
|
131
141
|
'- **Flow** (`flow_definition`): `name`, `triggerType` (`schedule`, `manual`), `triggerConfig` (JSON), `timeout`, `maxExecutions` (default 100, auto-cleanup old history), `isEnabled`.',
|
|
132
142
|
'- **Step** (`flow_step_definition`): `flow` → flow id, `key` (unique identifier for data chain), `stepOrder`, `type` (`script`, `condition`, `query`, `create`, `update`, `delete`, `http`, `trigger_flow`, `sleep`, `log`), `config` (JSON), `timeout`, `onError` (`stop`, `skip`, `retry`), `retryAttempts`, `parent` → self-ref to condition step (null = root), `branch` (`true`/`false` — which branch of parent condition).',
|
|
133
143
|
'- **Execution history** (`flow_execution_definition`): `flow` → flow id, `status`, `payload`, `context` (full data chain), `completedSteps`, `currentStep`, `error`, `startedAt`, `completedAt`, `duration`. Query separately — NOT nested under flow_definition.',
|
|
134
|
-
'- **triggerConfig examples**: schedule: `{"cron":"0 2 * * *","timezone":"UTC"}`, manual: `{}`. For event/webhook use cases, create a handler/hook with `@
|
|
135
|
-
'- **Step config examples**: script: `{"code":"return #user_definition.find({limit:10})"}`, condition: `{"code":"return @
|
|
136
|
-
'- **Data chain**: Steps access previous results via `@FLOW.<stepKey>` and `@
|
|
137
|
-
'- **Template syntax (flows)**: `@
|
|
144
|
+
'- **triggerConfig examples**: schedule: `{"cron":"0 2 * * *","timezone":"UTC"}`, manual: `{}`. For event/webhook use cases, create a handler/hook with `@TRIGGER("flow-name", payload)` instead.',
|
|
145
|
+
'- **Step config examples**: script: `{"code":"return #user_definition.find({limit:10})"}`, condition: `{"code":"return @FLOW_LAST?.data?.length > 0"}` (uses JS truthy/falsy: `return user` = truthy if exists, `return null` = falsy), query: `{"table":"user_definition","filter":{"status":{"_eq":"active"}},"limit":10}`, http: `{"url":"https://api.example.com","method":"POST","body":{}}` (auto Content-Type: application/json; **http `url` must be public-safe**—see Safety), sleep: `{"ms":5000}`, trigger_flow: `{"flowId":2}`.',
|
|
146
|
+
'- **Data chain**: Steps access previous results via `@FLOW.<stepKey>` and `@FLOW_LAST`. Input payload via `@FLOW_PAYLOAD`. Repos via `#table_name`.',
|
|
147
|
+
'- **Template syntax (flows)**: `@FLOW_PAYLOAD` → `$ctx.$flow.$payload` (input data), `@FLOW_LAST` → `$ctx.$flow.$last`, `@FLOW` → `$ctx.$flow`, `@FLOW_META` → `$ctx.$flow.$meta`, `#table_name` → `$ctx.$repos.table_name`, `@HELPERS` → `$ctx.$helpers`, `@THROW400`–`@THROW503` / `@THROW` → `$ctx.$throw[...]`. Trigger other flows in handlers via `@TRIGGER(name, payload)` or `$ctx.$trigger(name, payload)`.',
|
|
138
148
|
'- **Condition branching**: Condition step uses JavaScript truthy/falsy evaluation (e.g. `return user` → truthy if exists, falsy if null/0/undefined). Children with matching `parent: {id: conditionStepId}` and `branch: "true"/"false"` execute. Root steps (no parent) always execute sequentially.',
|
|
139
|
-
'- **Safety**: Max nesting depth 10 (flow triggering flow). Circular flow detection prevents A→B→A loops. HTTP steps: **SSRF hardening** — only `http`/`https`; blocks `localhost`, private IPs, and hostnames resolving to private IPs (use internet-facing URLs like `https://api.example.com`, not internal services, unless server policy changes). Default HTTP timeout 30s (AbortController). `$
|
|
149
|
+
'- **Safety**: Max nesting depth 10 (flow triggering flow). Circular flow detection prevents A→B→A loops. HTTP steps: **SSRF hardening** — only `http`/`https`; blocks `localhost`, private IPs, and hostnames resolving to private IPs (use internet-facing URLs like `https://api.example.com`, not internal services, unless server policy changes). Default HTTP timeout 30s (AbortController). `$trigger()` available inside flow steps.',
|
|
140
150
|
'- **Workflow**: Create flow → `create_record` on `flow_definition`. Add steps → `create_record` on `flow_step_definition` with `flow: {id}`. For branch steps, set `parent: {id: conditionStepId}` and `branch: "true"` or `"false"`. Trigger manually via `POST /admin/flow/trigger/{flowId}`.',
|
|
141
151
|
'- **Test step**: `POST /admin/flow/test-step` with body `{type, config, timeout}` — runs a single step without saving, returns `{success, result, error, duration}`.',
|
|
142
|
-
'- **In handlers/hooks**: Trigger flows via `$ctx.$
|
|
152
|
+
'- **In handlers/hooks**: Trigger flows via `$ctx.$trigger("flow-name", {payload})` or `$ctx.$trigger(flowId, {payload})`.',
|
|
143
153
|
'',
|
|
144
154
|
'### Extension (Vue SFC only — NOT React)',
|
|
145
155
|
'- **CRITICAL:** MUST call `create_record` or `update_record` on `extension_definition` — outputting Vue code in chat does NOT save it. User will NOT see it.',
|