@enfyra/mcp-server 0.0.85 → 0.0.86

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enfyra/mcp-server",
3
- "version": "0.0.85",
3
+ "version": "0.0.86",
4
4
  "description": "MCP server for Enfyra - manage Enfyra instances from MCP-compatible coding tools",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -155,7 +155,7 @@ onUnmounted(() => {
155
155
  },
156
156
  {
157
157
  name: 'OAuth provider setup values',
158
- code: `// Enfyra OAuth config row, stored in oauth_config_definition.
158
+ code: `// Enfyra OAuth config row, stored in enfyra_oauth_config.
159
159
  {
160
160
  "provider": "google",
161
161
  "clientId": "<google-client-id>",
@@ -168,7 +168,7 @@ onUnmounted(() => {
168
168
  // http://localhost:3000/api/auth/google/callback`,
169
169
  notes: [
170
170
  'redirectUri is the Enfyra callback URL: {ENFYRA_API_URL}/auth/google/callback.',
171
- 'The provider console callback URL and oauth_config_definition.redirectUri must match exactly.',
171
+ 'The provider console callback URL and enfyra_oauth_config.redirectUri must match exactly.',
172
172
  'This callback URL is not the app return page; the app return page is sent as the redirect query when starting OAuth.',
173
173
  'Use appCallbackUrl only for manual-token apps that intentionally read token query parameters.',
174
174
  ],
@@ -210,7 +210,7 @@ window.location.href = url.toString()`,
210
210
  ],
211
211
  },
212
212
  {
213
- name: 'Create relations directly to user_definition',
213
+ name: 'Create relations directly to enfyra_user',
214
214
  code: `create_table({
215
215
  name: "chat_message",
216
216
  columns: JSON.stringify([
@@ -228,7 +228,7 @@ window.location.href = url.toString()`,
228
228
  {
229
229
  propertyName: "sender",
230
230
  type: "many-to-one",
231
- targetTable: { id: "<user_definition_id>" },
231
+ targetTable: { id: "<enfyra_user_id>" },
232
232
  isNullable: false,
233
233
  onDelete: "CASCADE"
234
234
  }
@@ -238,9 +238,9 @@ window.location.href = url.toString()`,
238
238
  ])
239
239
  })`,
240
240
  notes: [
241
- 'Use user_definition as the user table.',
242
- 'Use table ids for targetTable when already known; MCP can also resolve exact table names such as "user_definition" before schema mutation.',
243
- 'Do not add inverse relations on user_definition unless the user explicitly asks.',
241
+ 'Use enfyra_user as the user table.',
242
+ 'Use table ids for targetTable when already known; MCP can also resolve exact table names such as "enfyra_user" before schema mutation.',
243
+ 'Do not add inverse relations on enfyra_user unless the user explicitly asks.',
244
244
  'createdAt, updatedAt, and custom date/datetime/timestamp fields already get auto-generated single-field indexes; add only compound indexes needed by hot filters.',
245
245
  'Do not provide physical FK column names; Enfyra derives them.',
246
246
  ],
@@ -253,7 +253,7 @@ window.location.href = url.toString()`,
253
253
  {
254
254
  propertyName: "createdBy",
255
255
  type: "many-to-one",
256
- targetTable: { id: "<user_definition_id>" },
256
+ targetTable: { id: "<enfyra_user_id>" },
257
257
  isNullable: true,
258
258
  onDelete: "CASCADE"
259
259
  },
@@ -282,7 +282,7 @@ window.location.href = url.toString()`,
282
282
  relations: JSON.stringify([
283
283
  { propertyName: "message", type: "many-to-one", targetTable: { id: "<chat_message_id>" }, onDelete: "CASCADE" },
284
284
  { propertyName: "conversation", type: "many-to-one", targetTable: { id: "<chat_conversation_id>" }, onDelete: "CASCADE" },
285
- { propertyName: "member", type: "many-to-one", targetTable: { id: "<user_definition_id>" }, onDelete: "CASCADE" }
285
+ { propertyName: "member", type: "many-to-one", targetTable: { id: "<enfyra_user_id>" }, onDelete: "CASCADE" }
286
286
  ]),
287
287
  uniques: JSON.stringify([["message", "member"]]),
288
288
  indexes: JSON.stringify([
@@ -299,7 +299,7 @@ window.location.href = url.toString()`,
299
299
  {
300
300
  name: 'Add server-owned user verification fields',
301
301
  code: `create_column({
302
- tableId: "<user_definition_table_id>",
302
+ tableId: "<enfyra_user_table_id>",
303
303
  name: "emailVerifiedAt",
304
304
  type: "datetime",
305
305
  isNullable: true,
@@ -308,7 +308,7 @@ window.location.href = url.toString()`,
308
308
  })
309
309
 
310
310
  create_column({
311
- tableId: "<user_definition_table_id>",
311
+ tableId: "<enfyra_user_table_id>",
312
312
  name: "emailVerificationStatus",
313
313
  type: "varchar",
314
314
  isNullable: false,
@@ -328,7 +328,7 @@ create_column({
328
328
  })`,
329
329
  notes: [
330
330
  'Run schema-changing calls sequentially. Do not parallelize create_column calls.',
331
- 'create_column fetches table_definition and patches only real persisted columns with id/_id; generated metadata projections such as createdAt, updatedAt, or relation FK display fields are skipped.',
331
+ 'create_column fetches enfyra_table and patches only real persisted columns with id/_id; generated metadata projections such as createdAt, updatedAt, or relation FK display fields are skipped.',
332
332
  'Use isEncrypted=true for encryption at rest. Add isUpdatable=false separately only when the field should be immutable.',
333
333
  'Use hooks or field permissions to prevent clients from updating server-owned fields.',
334
334
  ],
@@ -339,7 +339,7 @@ create_column({
339
339
  // 1. Read GET /metadata and find the target table.
340
340
  // 2. Keep only persisted column rows with id/_id.
341
341
  // 3. Add, change, or remove the intended column.
342
- // 4. PATCH /table_definition/:id with the full preserved columns array.
342
+ // 4. PATCH /enfyra_table/:id with the full preserved columns array.
343
343
  // 5. If the backend returns requiredConfirmHash, resend with ?schemaConfirmHash=<hash>.
344
344
  // 6. Re-read metadata and verify unrelated column ids still exist.
345
345
 
@@ -351,8 +351,8 @@ create_column({
351
351
  isEncrypted: true
352
352
  })`,
353
353
  notes: [
354
- 'Do not rebuild schema cascade payloads from table_definition?fields=columns.*; nested fields can be truncated or relation-derived.',
355
- 'Generated projections such as createdAt, updatedAt, and relation FK display fields without id/_id are not valid column_definition rows.',
354
+ 'Do not rebuild schema cascade payloads from enfyra_table?fields=columns.*; nested fields can be truncated or relation-derived.',
355
+ 'Generated projections such as createdAt, updatedAt, and relation FK display fields without id/_id are not valid enfyra_column rows.',
356
356
  'Never delete or omit unrelated persisted columns when adding one field.',
357
357
  'Run schema-changing calls sequentially; migration locks are backend-owned.',
358
358
  ],
@@ -366,7 +366,7 @@ create_column({
366
366
  {
367
367
  name: 'Minimal MCP query then explicit detail query',
368
368
  code: `query_table({
369
- tableName: "user_definition",
369
+ tableName: "enfyra_user",
370
370
  fields: ["id", "email"],
371
371
  filter: "{\\"email\\":{\\"_contains\\":\\"@example.com\\"}}",
372
372
  limit: 10
@@ -443,7 +443,7 @@ GET /enfyra/post?filter={"<primaryKeyFromMetadata>":{"_eq":123}}&limit=1`,
443
443
  {
444
444
  name: 'Exclude large generated fields',
445
445
  code: `query_table({
446
- tableName: "route_handler_definition",
446
+ tableName: "enfyra_route_handler",
447
447
  fields: ["-compiledCode"],
448
448
  limit: 20
449
449
  })
@@ -581,7 +581,7 @@ return { ok: true, email }\`
581
581
  notes: [
582
582
  'Use sourceCode, not logic. The server generates compiledCode.',
583
583
  'Use method for one handler, or methods only when the same sourceCode should be saved for multiple methods.',
584
- 'Do not pass name to route_handler_definition; one handler is identified by route + method.',
584
+ 'Do not pass name to enfyra_route_handler; one handler is identified by route + method.',
585
585
  ],
586
586
  },
587
587
  {
@@ -591,13 +591,13 @@ const password = @BODY.password
591
591
 
592
592
  if (!email || !password) @THROW400("Email and password are required")
593
593
 
594
- const existing = await #user_definition.find({
594
+ const existing = await #enfyra_user.find({
595
595
  filter: { email: { _eq: email } },
596
596
  limit: 1
597
597
  })
598
598
  if (existing.data[0]) @THROW409("Email is already registered")
599
599
 
600
- const result = await #user_definition.create({
600
+ const result = await #enfyra_user.create({
601
601
  data: {
602
602
  email,
603
603
  password: await @HELPERS.$bcrypt.hash(password)
@@ -656,7 +656,7 @@ const scope = {
656
656
  {
657
657
  name: 'Pre-hook strips protected body fields silently',
658
658
  code: `create_pre_hook({
659
- routeId: "<user_definition_patch_route_id>",
659
+ routeId: "<enfyra_user_patch_route_id>",
660
660
  name: "strip_email_verification_fields",
661
661
  methods: ["PATCH"],
662
662
  priority: -10,
@@ -665,7 +665,7 @@ delete @BODY.emailVerificationStatus
665
665
  delete @BODY.emailVerificationSentAt\`
666
666
  })`,
667
667
  notes: [
668
- 'Use this pattern when clients may send protected user fields through /me or user_definition PATCH.',
668
+ 'Use this pattern when clients may send protected user fields through /me or enfyra_user PATCH.',
669
669
  'Strip fields instead of throwing when the product wants a permissive client contract with server-owned fields.',
670
670
  'Use native macros such as @BODY instead of raw $ctx when a macro exists.',
671
671
  ],
@@ -724,7 +724,7 @@ ensure_route_access({
724
724
  {
725
725
  name: 'Publish read-only route',
726
726
  code: `update_record({
727
- tableName: "route_definition",
727
+ tableName: "enfyra_route",
728
728
  id: "<route_id>",
729
729
  data: {
730
730
  publicMethods: [{ id: "<GET_method_id_from_list_methods>" }]
@@ -739,7 +739,7 @@ ensure_route_access({
739
739
  {
740
740
  name: 'Column rule for email format',
741
741
  code: `create_column_rule({
742
- tableName: "user_definition",
742
+ tableName: "enfyra_user",
743
743
  columnName: "email",
744
744
  ruleType: "format",
745
745
  value: JSON.stringify({ v: "email" }),
@@ -810,25 +810,25 @@ const { checkPermissionCondition } = usePermissions()
810
810
  const canReadReports = computed(() => checkPermissionCondition({
811
811
  or: [
812
812
  { route: '/reports', methods: ['GET'] },
813
- { route: '/report_definition', methods: ['GET'] }
813
+ { route: '/report', methods: ['GET'] }
814
814
  ]
815
815
  }))
816
816
 
817
817
  const canCreateReport = computed(() => checkPermissionCondition({
818
- or: [{ route: '/report_definition', methods: ['POST'] }]
818
+ or: [{ route: '/report', methods: ['POST'] }]
819
819
  }))
820
820
 
821
821
  const canUpdateReport = computed(() => checkPermissionCondition({
822
- or: [{ route: '/report_definition', methods: ['PATCH'] }]
822
+ or: [{ route: '/report', methods: ['PATCH'] }]
823
823
  }))
824
824
 
825
825
  const canDeleteReport = computed(() => checkPermissionCondition({
826
- or: [{ route: '/report_definition', methods: ['DELETE'] }]
826
+ or: [{ route: '/report', methods: ['DELETE'] }]
827
827
  }))
828
828
  </script>`,
829
829
  notes: [
830
830
  'This is menu/extension visibility, not row-level RLS.',
831
- 'Set menu_definition.permission on every sensitive admin menu. Example for /reports: { or: [{ route: "/reports", methods: ["GET"] }, { route: "/report_definition", methods: ["GET"] }] }.',
831
+ 'Set enfyra_menu.permission on every sensitive admin menu. Example for /reports: { or: [{ route: "/reports", methods: ["GET"] }, { route: "/report", methods: ["GET"] }] }.',
832
832
  'Admin pages are sensitive. Use permission gates by default, not as an optional polish step.',
833
833
  'Menus should only be visible when the user has at least GET permission for the page route or backing data route.',
834
834
  'Inside the extension, gate each action by its own route/method: GET for page visibility, POST for create/flow-trigger buttons, PATCH for normal record edits, DELETE for native delete routes.',
@@ -976,13 +976,13 @@ return order && order.total > 1000`,
976
976
  notes: [
977
977
  'Prefer operation-sized flow steps with clear keys over one large script that performs SSH, Docker, DB, API, email, and finalization work together.',
978
978
  'Each step should return only ids, booleans, status keys, or small counters that later steps need.',
979
- 'When refactoring an existing flow, add or extract adjacent focused flow_step_definition rows instead of making an oversized sourceCode block longer.',
979
+ 'When refactoring an existing flow, add or extract adjacent focused enfyra_flow_step rows instead of making an oversized sourceCode block longer.',
980
980
  ],
981
981
  },
982
982
  {
983
983
  name: 'Flow query step config',
984
984
  code: `{
985
- "table": "user_definition",
985
+ "table": "enfyra_user",
986
986
  "filter": { "email": { "_contains": "@example.com" } },
987
987
  "limit": 50
988
988
  }`,
@@ -1031,7 +1031,7 @@ return saved`,
1031
1031
  notes: [
1032
1032
  'Use file-specific context only in upload-capable routes.',
1033
1033
  'For request uploads, pass file: @UPLOADED_FILE to @STORAGE.$upload/@STORAGE.$update so Enfyra streams from the temp file path.',
1034
- 'Use @STORAGE.$registerFile when an external process already uploaded the object and the script only needs to create the file_definition record.',
1034
+ 'Use @STORAGE.$registerFile when an external process already uploaded the object and the script only needs to create the enfyra_file record.',
1035
1035
  'Do not read @UPLOADED_FILE.path into a Buffer and do not generate examples using @UPLOADED_FILE.buffer.',
1036
1036
  'Use buffer only for small generated or transformed files, such as image thumbnails.',
1037
1037
  ],
@@ -1058,8 +1058,8 @@ update_method({
1058
1058
  textColor: "#b45309"
1059
1059
  })`,
1060
1060
  notes: [
1061
- 'Use dedicated method tools instead of generic CRUD on method_definition.',
1062
- 'The backend stores the method label in method_definition.name; do not send or filter a method_definition.method field.',
1061
+ 'Use dedicated method tools instead of generic CRUD on enfyra_method.',
1062
+ 'The backend stores the method label in enfyra_method.name; do not send or filter a `method` field on `enfyra_method`.',
1063
1063
  'buttonColor is the badge background and textColor is the badge text color.',
1064
1064
  'The Enfyra admin UI is /settings/methods.',
1065
1065
  'delete_method is preview-first and should only be used for unused custom methods.',
@@ -1077,7 +1077,7 @@ update_method({
1077
1077
  permission: JSON.stringify({
1078
1078
  or: [
1079
1079
  { route: "/reports", methods: ["GET"] },
1080
- { route: "/report_definition", methods: ["GET"] }
1080
+ { route: "/report", methods: ["GET"] }
1081
1081
  ]
1082
1082
  })
1083
1083
  })
@@ -1093,7 +1093,7 @@ create_extension({
1093
1093
  })`,
1094
1094
  notes: [
1095
1095
  'Menu provides navigation; extension provides content.',
1096
- 'Use menu_definition.label, not title.',
1096
+ 'Use enfyra_menu.label, not title.',
1097
1097
  'Sensitive admin menus should include a permission condition at creation time.',
1098
1098
  'For page extensions, create the menu first and pass menuId to create_extension.',
1099
1099
  'Page extensions must register the app-shell PageHeader with usePageHeaderRegistry instead of rendering a custom top header.',
@@ -1151,12 +1151,12 @@ create_extension({
1151
1151
  type: "page",
1152
1152
  name: "ReportsPage",
1153
1153
  menuId: "<reports-menu-id>",
1154
- code: "<template><section class=\\"min-h-full w-full space-y-4\\"><Widget :id=\\"<report-status-widget-id>\\" :total=\\"totalReports\\" :rows=\\"reportRows\\" :open-details=\\"openReportDetails\\" @refresh=\\"refresh\\" /><Widget :id=\\"<report-table-widget-id>\\" :rows=\\"reportRows\\" @refresh=\\"refresh\\" /></section></template><script setup>const { registerPageHeader } = usePageHeaderRegistry(); registerPageHeader({ title: 'Reports', description: 'Operational report overview.', leadingIcon: 'lucide:bar-chart-3', gradient: 'cyan', variant: 'minimal' }); const totalReports = ref(0); const reportRows = ref([]); function refresh() {} function openReportDetails(row) { navigateTo('/data/report_definition?filter=' + encodeURIComponent(JSON.stringify({ id: { _eq: row.id } }))) }</script>",
1154
+ code: "<template><section class=\\"min-h-full w-full space-y-4\\"><Widget :id=\\"<report-status-widget-id>\\" :total=\\"totalReports\\" :rows=\\"reportRows\\" :open-details=\\"openReportDetails\\" @refresh=\\"refresh\\" /><Widget :id=\\"<report-table-widget-id>\\" :rows=\\"reportRows\\" @refresh=\\"refresh\\" /></section></template><script setup>const { registerPageHeader } = usePageHeaderRegistry(); registerPageHeader({ title: 'Reports', description: 'Operational report overview.', leadingIcon: 'lucide:bar-chart-3', gradient: 'cyan', variant: 'minimal' }); const totalReports = ref(0); const reportRows = ref([]); function refresh() {} function openReportDetails(row) { navigateTo('/data/report?filter=' + encodeURIComponent(JSON.stringify({ id: { _eq: row.id } }))) }</script>",
1155
1155
  isEnabled: true
1156
1156
  })`,
1157
1157
  notes: [
1158
1158
  'Use widgets for bulky or reusable sections such as operation panels, timelines, tables, sidebars, and status cards.',
1159
- 'Embed widgets by their numeric extension_definition id, not by extensionId/name.',
1159
+ 'Embed widgets by their numeric enfyra_extension id, not by extensionId/name.',
1160
1160
  'Props and listeners pass through the Widget wrapper. Widget defineProps values update reactively when the parent refs/computed values change.',
1161
1161
  'Use kebab-case in the parent template for camelCase widget props, for example :open-details maps to openDetails.',
1162
1162
  'Do not mutate widget props. Use computed for derived display state, and use watch only when mirroring a prop into local editable draft state.',
@@ -1338,11 +1338,11 @@ registerHeaderActions([
1338
1338
  },
1339
1339
  {
1340
1340
  name: 'Debug menu or extension changes that do not appear in open Enfyra admin tabs',
1341
- code: `// Server side: menu_definition and extension_definition are runtime UI definitions.
1341
+ code: `// Server side: enfyra_menu and enfyra_extension are runtime UI definitions.
1342
1342
  // They must participate in partial reload, just like metadata/routes.
1343
1343
  // Expected server contract:
1344
- // - cache orchestrator maps menu_definition -> menu reload
1345
- // - cache orchestrator maps extension_definition -> extension reload
1344
+ // - cache orchestrator maps enfyra_menu -> menu reload
1345
+ // - cache orchestrator maps enfyra_extension -> extension reload
1346
1346
  // - successful writes emit $system:reload to the admin Socket.IO namespace
1347
1347
 
1348
1348
  // Enfyra admin UI side expected listener behavior:
@@ -1379,7 +1379,7 @@ create_menu({
1379
1379
  permission: JSON.stringify({
1380
1380
  or: [
1381
1381
  { route: "/operations/jobs", methods: ["GET"] },
1382
- { route: "/flow_execution_definition", methods: ["GET"] }
1382
+ { route: "/enfyra_flow_execution", methods: ["GET"] }
1383
1383
  ]
1384
1384
  })
1385
1385
  })
@@ -1391,7 +1391,7 @@ create_menu({
1391
1391
  // /operations/reports report configuration and delivery history
1392
1392
  // /operations/settings system readiness and configuration
1393
1393
  // Use UTabs inside large pages instead of placing every section in one dashboard.
1394
- // For admin record management, link to /data/<table>, e.g. /data/report_definition, not public website paths.`,
1394
+ // For admin record management, link to /data/<table>, e.g. /data/report, not public website paths.`,
1395
1395
  notes: [
1396
1396
  'Design the menu/page split before generating dashboard code.',
1397
1397
  'Permission-gate sensitive parent dropdown menus too, using any child page route or backing route that represents read access.',
@@ -1408,7 +1408,7 @@ create_menu({
1408
1408
  {
1409
1409
  name: 'Extension fetches Enfyra data',
1410
1410
  code: `<script setup>
1411
- const { data, pending, execute: fetchOrders } = useApi('/order_definition', {
1411
+ const { data, pending, execute: fetchOrders } = useApi('/order', {
1412
1412
  query: {
1413
1413
  limit: 10,
1414
1414
  sort: '-createdAt'
@@ -1510,7 +1510,7 @@ onMounted(async () => {
1510
1510
  </template>`,
1511
1511
  notes: [
1512
1512
  'Install browser-side extension dependencies as type: "App".',
1513
- 'Do not use static import statements in extension_definition.code.',
1513
+ 'Do not use static import statements in enfyra_extension.code.',
1514
1514
  'Load app packages with getPackages([...]) inside the extension runtime.',
1515
1515
  'Use onMounted or an explicit action for package loading when the UI can render a loading state.',
1516
1516
  ],
@@ -1528,7 +1528,7 @@ const rangeStart = computed(() => {
1528
1528
  return d.toISOString()
1529
1529
  })
1530
1530
 
1531
- const flowStats = useApi('/flow_execution_definition', {
1531
+ const flowStats = useApi('/enfyra_flow_execution', {
1532
1532
  query: computed(() => ({
1533
1533
  fields: 'id',
1534
1534
  limit: 1,
@@ -1541,7 +1541,7 @@ const flowStats = useApi('/flow_execution_definition', {
1541
1541
  }))
1542
1542
  })
1543
1543
 
1544
- const orderStats = useApi('/order_definition', {
1544
+ const orderStats = useApi('/order', {
1545
1545
  query: computed(() => ({
1546
1546
  fields: 'id',
1547
1547
  limit: 1,