@lumibase/mcp-server 0.22.0 → 0.24.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 (4) hide show
  1. package/LICENSE +192 -21
  2. package/dist/index.cjs +529 -136
  3. package/dist/index.js +529 -136
  4. package/package.json +3 -2
package/dist/index.js CHANGED
@@ -612,6 +612,14 @@ function registerAgentTools(server, client) {
612
612
  { description: "List recent runs of a flow.", inputSchema: { id: idPathSegmentSchema } },
613
613
  async ({ id }) => run(() => client.get(`/flows/${encodePathSegment(id)}/runs`))
614
614
  );
615
+ server.registerTool(
616
+ "get_flow_run",
617
+ {
618
+ description: "Get a single flow run by id (status, per-step results, error) for diagnosis.",
619
+ inputSchema: { id: idPathSegmentSchema, runId: idPathSegmentSchema }
620
+ },
621
+ async ({ id, runId }) => run(() => client.get(`/flows/${encodePathSegment(id)}/runs/${encodePathSegment(runId)}`))
622
+ );
615
623
  }
616
624
 
617
625
  // src/tools/api-keys.ts
@@ -997,6 +1005,22 @@ function registerContentConfigTools(server, client) {
997
1005
  createSchema: presetSchema.shape,
998
1006
  updateSchema: presetSchema.partial().shape
999
1007
  });
1008
+ server.registerTool(
1009
+ "get_effective_preset",
1010
+ {
1011
+ description: "Resolve the effective default view for a collection (user > role-chain > global precedence).",
1012
+ inputSchema: { collection: z9.string().min(1) }
1013
+ },
1014
+ async ({ collection }) => run(() => client.get(`/presets/effective?collection=${encodeURIComponent(collection)}`))
1015
+ );
1016
+ server.registerTool(
1017
+ "list_preset_bookmarks",
1018
+ {
1019
+ description: "List the named preset bookmarks visible to the principal for a collection (with scope).",
1020
+ inputSchema: { collection: z9.string().min(1) }
1021
+ },
1022
+ async ({ collection }) => run(() => client.get(`/presets/bookmarks?collection=${encodeURIComponent(collection)}`))
1023
+ );
1000
1024
  registerCrud(server, client, {
1001
1025
  basePath: "/translations",
1002
1026
  resource: "translation",
@@ -1052,18 +1076,134 @@ function registerContentConfigTools(server, client) {
1052
1076
  );
1053
1077
  }
1054
1078
 
1055
- // src/tools/extensions.ts
1079
+ // src/tools/deployments.ts
1056
1080
  import { z as z10 } from "zod";
1081
+ function registerDeploymentTools(server, client) {
1082
+ server.registerTool(
1083
+ "list_deployment_targets",
1084
+ {
1085
+ description: "List configured deployment targets (Vercel/Netlify connections) for the site.",
1086
+ inputSchema: {}
1087
+ },
1088
+ async () => run(() => client.get("/deployments/targets"))
1089
+ );
1090
+ server.registerTool(
1091
+ "list_deployments",
1092
+ {
1093
+ description: "List recent deployments, optionally filtered by target or status.",
1094
+ inputSchema: {
1095
+ targetId: z10.string().optional(),
1096
+ status: z10.string().optional().describe("queued | building | ready | error | canceled."),
1097
+ limit: z10.number().int().min(1).max(200).optional()
1098
+ }
1099
+ },
1100
+ async (args) => run(
1101
+ () => client.get(
1102
+ `/deployments${buildQs(args)}`
1103
+ )
1104
+ )
1105
+ );
1106
+ server.registerTool(
1107
+ "get_deployment",
1108
+ {
1109
+ description: "Get a single deployment\u2019s status and details by id.",
1110
+ inputSchema: { id: idPathSegmentSchema }
1111
+ },
1112
+ async ({ id }) => run(() => client.get(`/deployments/${encodePathSegment(id)}`))
1113
+ );
1114
+ server.registerTool(
1115
+ "get_deployment_logs",
1116
+ {
1117
+ description: "Fetch the build/deploy logs for a deployment (for diagnosing a failed build).",
1118
+ inputSchema: { id: idPathSegmentSchema }
1119
+ },
1120
+ async ({ id }) => run(() => client.get(`/deployments/${encodePathSegment(id)}/logs`))
1121
+ );
1122
+ }
1123
+
1124
+ // src/tools/editorial.ts
1125
+ import { z as z11 } from "zod";
1126
+ function registerEditorialTools(server, client) {
1127
+ server.registerTool(
1128
+ "list_reviews",
1129
+ {
1130
+ description: "List the editorial review queue, optionally filtered by status or assignee.",
1131
+ inputSchema: {
1132
+ status: z11.enum(["pending", "approved", "rejected"]).optional(),
1133
+ assignedTo: z11.string().max(128).optional()
1134
+ }
1135
+ },
1136
+ async (args) => run(
1137
+ () => client.get(
1138
+ `/editorial/reviews${buildQs(args)}`
1139
+ )
1140
+ )
1141
+ );
1142
+ server.registerTool(
1143
+ "submit_review",
1144
+ {
1145
+ description: "Submit an item for editorial review, optionally assigning a reviewer.",
1146
+ inputSchema: {
1147
+ collection: collectionNameSchema,
1148
+ id: idPathSegmentSchema,
1149
+ assignedTo: z11.string().min(1).max(128).nullable().optional()
1150
+ }
1151
+ },
1152
+ async ({ collection, id, assignedTo }) => run(
1153
+ () => client.post(
1154
+ `/editorial/${encodePathSegment(collection)}/${encodePathSegment(id)}/submit-review`,
1155
+ { assignedTo }
1156
+ )
1157
+ )
1158
+ );
1159
+ server.registerTool(
1160
+ "approve_content",
1161
+ {
1162
+ description: "Approve an item in editorial review (a publish-gate decision). Optional reason is audited.",
1163
+ inputSchema: {
1164
+ collection: collectionNameSchema,
1165
+ id: idPathSegmentSchema,
1166
+ reason: z11.string().max(2e3).optional()
1167
+ }
1168
+ },
1169
+ async ({ collection, id, reason }) => run(
1170
+ () => client.post(
1171
+ `/editorial/${encodePathSegment(collection)}/${encodePathSegment(id)}/approve`,
1172
+ { reason }
1173
+ )
1174
+ )
1175
+ );
1176
+ server.registerTool(
1177
+ "reject_content",
1178
+ {
1179
+ description: "Reject an item in editorial review. Optional reason is audited.",
1180
+ inputSchema: {
1181
+ collection: collectionNameSchema,
1182
+ id: idPathSegmentSchema,
1183
+ reason: z11.string().max(2e3).optional()
1184
+ }
1185
+ },
1186
+ async ({ collection, id, reason }) => run(
1187
+ () => client.post(
1188
+ `/editorial/${encodePathSegment(collection)}/${encodePathSegment(id)}/reject`,
1189
+ { reason }
1190
+ )
1191
+ )
1192
+ );
1193
+ }
1194
+
1195
+ // src/tools/extensions.ts
1196
+ import { z as z12 } from "zod";
1057
1197
  var EXTENSION_TYPES = ["interface", "display", "layout", "panel", "module", "hook", "endpoint"];
1058
- var extensionSchema = z10.object({
1059
- key: z10.string().regex(/^[a-z0-9_:-]+$/).optional(),
1060
- name: z10.string().min(1),
1061
- version: z10.string().min(1),
1062
- type: z10.enum(EXTENSION_TYPES),
1063
- enabled: z10.boolean().optional(),
1064
- bundleUrl: z10.string().min(1).describe("https:, http:, or data:text/javascript bundle URL."),
1065
- manifest: z10.record(z10.string()).optional(),
1066
- capabilities: z10.array(z10.string()).optional()
1198
+ var extensionSchema = z12.object({
1199
+ key: z12.string().regex(/^[a-z0-9_:-]+$/).optional(),
1200
+ name: z12.string().min(1),
1201
+ version: z12.string().min(1),
1202
+ type: z12.enum(EXTENSION_TYPES),
1203
+ enabled: z12.boolean().optional(),
1204
+ bundleUrl: z12.string().min(1).describe("https:, http:, or data:text/javascript bundle URL."),
1205
+ manifest: z12.record(z12.string()).optional(),
1206
+ capabilities: z12.array(z12.string()).optional()
1067
1207
  });
1068
1208
  function registerExtensionTools(server, client) {
1069
1209
  server.registerTool(
@@ -1091,7 +1231,7 @@ function registerExtensionTools(server, client) {
1091
1231
  "uninstall_extension",
1092
1232
  {
1093
1233
  description: "Uninstall an extension from the site. DESTRUCTIVE \u2014 pass confirm=true.",
1094
- inputSchema: { id: idPathSegmentSchema, confirm: z10.literal(true).describe(confirmDescription) }
1234
+ inputSchema: { id: idPathSegmentSchema, confirm: z12.literal(true).describe(confirmDescription) }
1095
1235
  },
1096
1236
  async ({ id }) => run(async () => {
1097
1237
  await client.delete(`/extensions/${encodePathSegment(id)}`);
@@ -1103,12 +1243,12 @@ function registerExtensionTools(server, client) {
1103
1243
  {
1104
1244
  description: "Browse the published extension marketplace.",
1105
1245
  inputSchema: {
1106
- q: z10.string().optional(),
1107
- category: z10.string().optional(),
1108
- tags: z10.string().optional().describe("Comma-separated tags."),
1109
- sort: z10.string().optional(),
1110
- page: z10.number().int().min(1).optional(),
1111
- perPage: z10.number().int().min(1).optional()
1246
+ q: z12.string().optional(),
1247
+ category: z12.string().optional(),
1248
+ tags: z12.string().optional().describe("Comma-separated tags."),
1249
+ sort: z12.string().optional(),
1250
+ page: z12.number().int().min(1).optional(),
1251
+ perPage: z12.number().int().min(1).optional()
1112
1252
  }
1113
1253
  },
1114
1254
  async (args) => run(
@@ -1143,13 +1283,13 @@ function registerExtensionTools(server, client) {
1143
1283
  {
1144
1284
  description: "Publish an extension to the marketplace (signs + marks it published).",
1145
1285
  inputSchema: {
1146
- extensionId: z10.string().min(1),
1147
- marketplaceSlug: z10.string().min(1),
1148
- publisher: z10.record(z10.unknown()).optional(),
1149
- signature: z10.string().optional(),
1150
- signatureAlg: z10.string().optional(),
1151
- publisherKeyId: z10.string().optional(),
1152
- bundleSha256: z10.string().optional()
1286
+ extensionId: z12.string().min(1),
1287
+ marketplaceSlug: z12.string().min(1),
1288
+ publisher: z12.record(z12.unknown()).optional(),
1289
+ signature: z12.string().optional(),
1290
+ signatureAlg: z12.string().optional(),
1291
+ publisherKeyId: z12.string().optional(),
1292
+ bundleSha256: z12.string().optional()
1153
1293
  }
1154
1294
  },
1155
1295
  async (input) => run(() => client.post("/marketplace/publish", input))
@@ -1157,39 +1297,39 @@ function registerExtensionTools(server, client) {
1157
1297
  }
1158
1298
 
1159
1299
  // src/tools/fields.ts
1160
- import { z as z11 } from "zod";
1161
- var fieldInputSchema2 = z11.object({
1162
- type: z11.string().min(1).describe(
1300
+ import { z as z13 } from "zod";
1301
+ var fieldInputSchema2 = z13.object({
1302
+ type: z13.string().min(1).describe(
1163
1303
  "Storage type: string, text, integer, bigInteger, float, decimal, boolean, date, dateTime, time, json, uuid, csv, hash, alias"
1164
1304
  ),
1165
- interface: z11.string().min(1).describe(
1305
+ interface: z13.string().min(1).describe(
1166
1306
  "UI widget: input, textarea, select, toggle, datetime, file, image, repeater, relation-m2o, relation-o2m, relation-m2m, code, markdown, wysiwyg, \u2026"
1167
1307
  ),
1168
- display: z11.string().optional(),
1169
- label: z11.string().optional(),
1170
- note: z11.string().optional(),
1171
- defaultValue: z11.unknown().optional(),
1172
- nullable: z11.boolean().optional().default(true),
1173
- unique: z11.boolean().optional().default(false),
1174
- indexed: z11.boolean().optional().default(false),
1175
- searchable: z11.boolean().optional().default(false),
1176
- length: z11.number().int().positive().optional(),
1177
- precision: z11.number().int().positive().optional(),
1178
- scale: z11.number().int().min(0).optional(),
1179
- special: z11.array(z11.string()).optional(),
1180
- options: z11.record(z11.unknown()).optional(),
1181
- displayOptions: z11.record(z11.unknown()).optional(),
1182
- conditions: z11.array(z11.unknown()).optional(),
1183
- required: z11.boolean().optional().default(false),
1184
- readonly: z11.boolean().optional().default(false),
1185
- hidden: z11.boolean().optional().default(false),
1186
- encrypted: z11.boolean().optional().default(false),
1187
- versioned: z11.boolean().optional().default(false),
1188
- width: z11.enum(["half", "full", "fill"]).optional().default("full"),
1189
- group: z11.string().optional(),
1190
- sortOrder: z11.number().int().optional(),
1308
+ display: z13.string().optional(),
1309
+ label: z13.string().optional(),
1310
+ note: z13.string().optional(),
1311
+ defaultValue: z13.unknown().optional(),
1312
+ nullable: z13.boolean().optional().default(true),
1313
+ unique: z13.boolean().optional().default(false),
1314
+ indexed: z13.boolean().optional().default(false),
1315
+ searchable: z13.boolean().optional().default(false),
1316
+ length: z13.number().int().positive().optional(),
1317
+ precision: z13.number().int().positive().optional(),
1318
+ scale: z13.number().int().min(0).optional(),
1319
+ special: z13.array(z13.string()).optional(),
1320
+ options: z13.record(z13.unknown()).optional(),
1321
+ displayOptions: z13.record(z13.unknown()).optional(),
1322
+ conditions: z13.array(z13.unknown()).optional(),
1323
+ required: z13.boolean().optional().default(false),
1324
+ readonly: z13.boolean().optional().default(false),
1325
+ hidden: z13.boolean().optional().default(false),
1326
+ encrypted: z13.boolean().optional().default(false),
1327
+ versioned: z13.boolean().optional().default(false),
1328
+ width: z13.enum(["half", "full", "fill"]).optional().default("full"),
1329
+ group: z13.string().optional(),
1330
+ sortOrder: z13.number().int().optional(),
1191
1331
  renameFrom: fieldNameSchema.optional().describe("Previous field name if this is a rename operation"),
1192
- confirmRiskyChange: z11.boolean().optional().describe("Set true to confirm type-change or destructive migration")
1332
+ confirmRiskyChange: z13.boolean().optional().describe("Set true to confirm type-change or destructive migration")
1193
1333
  });
1194
1334
  function formatError3(err) {
1195
1335
  if (err instanceof LumiBaseApiError) {
@@ -1244,8 +1384,8 @@ function registerFieldTools(server, client) {
1244
1384
  inputSchema: {
1245
1385
  collection: collectionNameSchema,
1246
1386
  field_name: fieldNameSchema,
1247
- confirm: z11.literal(true).describe("Must be true to confirm destructive operation"),
1248
- force: z11.boolean().optional().describe("Force deletion even if risky (foreign keys, etc.)")
1387
+ confirm: z13.literal(true).describe("Must be true to confirm destructive operation"),
1388
+ force: z13.boolean().optional().describe("Force deletion even if risky (foreign keys, etc.)")
1249
1389
  }
1250
1390
  },
1251
1391
  async ({ collection, field_name, force }) => {
@@ -1264,8 +1404,91 @@ function registerFieldTools(server, client) {
1264
1404
  );
1265
1405
  }
1266
1406
 
1407
+ // src/tools/insights.ts
1408
+ import { z as z14 } from "zod";
1409
+ var AGGREGATES = ["count", "sum", "avg", "min", "max"];
1410
+ var dateRangeSchema = z14.object({
1411
+ field: z14.string().min(1),
1412
+ gte: z14.string().optional(),
1413
+ lte: z14.string().optional(),
1414
+ preset: z14.string().optional()
1415
+ }).describe("Restrict the query to a date window on the given field.");
1416
+ var panelQueryShape = {
1417
+ collection: z14.string().min(1),
1418
+ aggregate: z14.enum(AGGREGATES).describe("Aggregate function. `field` is required for everything except `count`."),
1419
+ field: z14.string().min(1).optional().describe("Field to aggregate (required unless aggregate=count)."),
1420
+ groupBy: z14.string().min(1).optional().describe("Field to group rows by (produces a series)."),
1421
+ filter: z14.record(z14.unknown()).optional().describe('Directus-style condition rule, e.g. { status: { _eq: "published" } }.'),
1422
+ dateRange: dateRangeSchema.optional(),
1423
+ limit: z14.number().int().min(1).max(1e3).optional().describe("Max grouped rows to return (default 50).")
1424
+ };
1425
+ function registerInsightsTools(server, client) {
1426
+ server.registerTool(
1427
+ "list_dashboards",
1428
+ {
1429
+ description: "List insight dashboards for the current site.",
1430
+ inputSchema: {}
1431
+ },
1432
+ async () => run(() => client.get("/dashboards"))
1433
+ );
1434
+ server.registerTool(
1435
+ "get_dashboard",
1436
+ {
1437
+ description: "Get a single dashboard by id.",
1438
+ inputSchema: { id: idPathSegmentSchema }
1439
+ },
1440
+ async ({ id }) => run(() => client.get(`/dashboards/${encodePathSegment(id)}`))
1441
+ );
1442
+ server.registerTool(
1443
+ "list_dashboard_panels",
1444
+ {
1445
+ description: "List the panels of a dashboard (their definitions, not the computed data).",
1446
+ inputSchema: { id: idPathSegmentSchema }
1447
+ },
1448
+ async ({ id }) => run(() => client.get(`/dashboards/${encodePathSegment(id)}/panels`))
1449
+ );
1450
+ server.registerTool(
1451
+ "run_panel",
1452
+ {
1453
+ description: "Run a saved panel and return its computed result. Optionally override the panel\u2019s filter or date range for this run only (does not modify the panel).",
1454
+ inputSchema: {
1455
+ dashboardId: idPathSegmentSchema,
1456
+ panelId: idPathSegmentSchema,
1457
+ filter: z14.record(z14.unknown()).optional().describe("Override the panel filter for this run (Directus-style condition rule)."),
1458
+ dateRange: dateRangeSchema.optional().describe("Override the panel date range for this run.")
1459
+ }
1460
+ },
1461
+ async ({ dashboardId, panelId, filter, dateRange }) => {
1462
+ const override = {};
1463
+ if (filter !== void 0) override["filter"] = filter;
1464
+ if (dateRange !== void 0) override["dateRange"] = dateRange;
1465
+ return run(
1466
+ () => client.post(
1467
+ `/dashboards/${encodePathSegment(dashboardId)}/panels/${encodePathSegment(panelId)}/data`,
1468
+ override
1469
+ )
1470
+ );
1471
+ }
1472
+ );
1473
+ server.registerTool(
1474
+ "query_insights",
1475
+ {
1476
+ description: "Ad-hoc aggregate query over a collection \u2014 no saved panel required. Answers operational questions (counts, sums, averages, breakdowns) directly. Read-only.",
1477
+ inputSchema: {
1478
+ dashboardId: idPathSegmentSchema.describe(
1479
+ "Any dashboard id you can access; the query runs ad-hoc and does not read that dashboard."
1480
+ ),
1481
+ ...panelQueryShape
1482
+ }
1483
+ },
1484
+ async ({ dashboardId, ...query }) => run(
1485
+ () => client.post(`/dashboards/${encodePathSegment(dashboardId)}/panels/preview`, query)
1486
+ )
1487
+ );
1488
+ }
1489
+
1267
1490
  // src/tools/items.ts
1268
- import { z as z12 } from "zod";
1491
+ import { z as z15 } from "zod";
1269
1492
  function formatError4(err) {
1270
1493
  if (err instanceof LumiBaseApiError) {
1271
1494
  return err.errors.map((e) => `[${e.code}] ${e.message}`).join("; ");
@@ -1287,12 +1510,12 @@ function registerItemTools(server, client) {
1287
1510
  description: "List items from a collection with optional filtering, sorting, and pagination.",
1288
1511
  inputSchema: {
1289
1512
  collection: collectionNameSchema,
1290
- limit: z12.number().int().min(1).max(200).optional().default(25),
1291
- offset: z12.number().int().min(0).optional().default(0),
1292
- status: z12.enum(["draft", "published", "archived"]).optional(),
1293
- sort: z12.string().optional().describe('Comma-separated field names; prefix with - for descending (e.g. "-created_at")'),
1294
- fields: z12.string().optional().describe('Comma-separated field names to return (e.g. "id,title,status")'),
1295
- search: z12.string().optional().describe("Full-text search across searchable fields")
1513
+ limit: z15.number().int().min(1).max(200).optional().default(25),
1514
+ offset: z15.number().int().min(0).optional().default(0),
1515
+ status: z15.enum(["draft", "published", "archived"]).optional(),
1516
+ sort: z15.string().optional().describe('Comma-separated field names; prefix with - for descending (e.g. "-created_at")'),
1517
+ fields: z15.string().optional().describe('Comma-separated field names to return (e.g. "id,title,status")'),
1518
+ search: z15.string().optional().describe("Full-text search across searchable fields")
1296
1519
  }
1297
1520
  },
1298
1521
  async ({ collection, ...params }) => {
@@ -1312,7 +1535,7 @@ function registerItemTools(server, client) {
1312
1535
  inputSchema: {
1313
1536
  collection: collectionNameSchema,
1314
1537
  id: idPathSegmentSchema,
1315
- fields: z12.string().optional().describe("Comma-separated field names to return")
1538
+ fields: z15.string().optional().describe("Comma-separated field names to return")
1316
1539
  }
1317
1540
  },
1318
1541
  async ({ collection, id, fields }) => {
@@ -1333,8 +1556,8 @@ function registerItemTools(server, client) {
1333
1556
  description: "Create a new item in a collection.",
1334
1557
  inputSchema: {
1335
1558
  collection: collectionNameSchema,
1336
- data: z12.record(z12.unknown()).describe("Field values for the new item"),
1337
- status: z12.enum(["draft", "published"]).optional().default("draft")
1559
+ data: z15.record(z15.unknown()).describe("Field values for the new item"),
1560
+ status: z15.enum(["draft", "published"]).optional().default("draft")
1338
1561
  }
1339
1562
  },
1340
1563
  async ({ collection, data: itemData, status }) => {
@@ -1356,7 +1579,7 @@ function registerItemTools(server, client) {
1356
1579
  inputSchema: {
1357
1580
  collection: collectionNameSchema,
1358
1581
  id: idPathSegmentSchema,
1359
- data: z12.record(z12.unknown()).describe("Fields to update")
1582
+ data: z15.record(z15.unknown()).describe("Fields to update")
1360
1583
  }
1361
1584
  },
1362
1585
  async ({ collection, id, data: itemData }) => {
@@ -1378,7 +1601,7 @@ function registerItemTools(server, client) {
1378
1601
  inputSchema: {
1379
1602
  collection: collectionNameSchema,
1380
1603
  id: idPathSegmentSchema,
1381
- confirm: z12.literal(true).describe("Must be true to confirm deletion")
1604
+ confirm: z15.literal(true).describe("Must be true to confirm deletion")
1382
1605
  }
1383
1606
  },
1384
1607
  async ({ collection, id }) => {
@@ -1392,16 +1615,137 @@ function registerItemTools(server, client) {
1392
1615
  );
1393
1616
  }
1394
1617
 
1618
+ // src/tools/releases.ts
1619
+ import { z as z16 } from "zod";
1620
+ var releaseItemSchema = z16.object({
1621
+ collection: z16.string().min(1),
1622
+ itemId: z16.string().min(1),
1623
+ targetStatus: z16.enum(["draft", "published", "archived"]).optional(),
1624
+ revisionId: z16.string().nullable().optional()
1625
+ });
1626
+ function registerReleaseTools(server, client) {
1627
+ server.registerTool(
1628
+ "list_releases",
1629
+ {
1630
+ description: "List content releases for the site, optionally filtered by status.",
1631
+ inputSchema: {
1632
+ status: z16.string().optional(),
1633
+ page: z16.number().int().min(1).optional(),
1634
+ limit: z16.number().int().min(1).max(200).optional()
1635
+ }
1636
+ },
1637
+ async (args) => run(
1638
+ () => client.get(
1639
+ `/releases${buildQs(args)}`
1640
+ )
1641
+ )
1642
+ );
1643
+ server.registerTool(
1644
+ "get_release",
1645
+ {
1646
+ description: "Get a single content release by id (with its staged items).",
1647
+ inputSchema: { id: idPathSegmentSchema }
1648
+ },
1649
+ async ({ id }) => run(() => client.get(`/releases/${encodePathSegment(id)}`))
1650
+ );
1651
+ server.registerTool(
1652
+ "create_release",
1653
+ {
1654
+ description: "Create a content release. Set publishAt for a scheduled release; omit for a manual one.",
1655
+ inputSchema: {
1656
+ name: z16.string().min(1),
1657
+ description: z16.string().nullable().optional(),
1658
+ atomicityMode: z16.enum(["all_or_nothing", "best_effort"]).optional(),
1659
+ publishAt: z16.string().nullable().optional().describe("ISO datetime to auto-publish, or null.")
1660
+ }
1661
+ },
1662
+ async (input) => run(() => client.post("/releases", input))
1663
+ );
1664
+ server.registerTool(
1665
+ "update_release",
1666
+ {
1667
+ description: "Update a release and/or stage/unstage items (partial PATCH).",
1668
+ inputSchema: {
1669
+ id: idPathSegmentSchema,
1670
+ name: z16.string().min(1).optional(),
1671
+ description: z16.string().nullable().optional(),
1672
+ atomicityMode: z16.enum(["all_or_nothing", "best_effort"]).optional(),
1673
+ publishAt: z16.string().nullable().optional(),
1674
+ addItems: z16.array(releaseItemSchema).optional().describe("Items to stage into the release."),
1675
+ removeItems: z16.array(z16.object({ collection: z16.string(), itemId: z16.string() })).optional().describe("Items to unstage.")
1676
+ }
1677
+ },
1678
+ async ({ id, ...patch }) => run(() => client.patch(`/releases/${encodePathSegment(id)}`, patch))
1679
+ );
1680
+ server.registerTool(
1681
+ "publish_release",
1682
+ {
1683
+ description: "Publish a release now (applies every staged item\u2019s target status per the atomicity mode).",
1684
+ inputSchema: { id: idPathSegmentSchema }
1685
+ },
1686
+ async ({ id }) => run(() => client.post(`/releases/${encodePathSegment(id)}/publish`, {}))
1687
+ );
1688
+ server.registerTool(
1689
+ "delete_release",
1690
+ {
1691
+ description: "Delete a content release. DESTRUCTIVE \u2014 warn the user first and pass confirm=true.",
1692
+ inputSchema: {
1693
+ id: idPathSegmentSchema,
1694
+ confirm: z16.literal(true).describe(confirmDescription)
1695
+ }
1696
+ },
1697
+ async ({ id }) => run(async () => {
1698
+ await client.delete(`/releases/${encodePathSegment(id)}`);
1699
+ return okText(`Release "${id}" deleted.`);
1700
+ })
1701
+ );
1702
+ }
1703
+
1704
+ // src/tools/shares.ts
1705
+ import { z as z17 } from "zod";
1706
+ function registerShareTools(server, client) {
1707
+ server.registerTool(
1708
+ "create_share",
1709
+ {
1710
+ description: "Create a scoped public share link for a single item, viewed through a given role.",
1711
+ inputSchema: {
1712
+ collection: z17.string().min(1),
1713
+ itemId: z17.string().min(1),
1714
+ roleId: z17.string().min(1).describe("Role whose permissions the link is viewed through."),
1715
+ password: z17.string().min(1).optional(),
1716
+ validFrom: z17.string().datetime().nullable().optional(),
1717
+ validUntil: z17.string().datetime().nullable().optional(),
1718
+ maxUses: z17.number().int().min(1).nullable().optional()
1719
+ }
1720
+ },
1721
+ async (input) => run(() => client.post("/shares", input))
1722
+ );
1723
+ server.registerTool(
1724
+ "revoke_share",
1725
+ {
1726
+ description: "Revoke a share link by id. DESTRUCTIVE \u2014 warn the user first and pass confirm=true.",
1727
+ inputSchema: {
1728
+ id: idPathSegmentSchema,
1729
+ confirm: z17.literal(true).describe(confirmDescription)
1730
+ }
1731
+ },
1732
+ async ({ id }) => run(async () => {
1733
+ await client.post(`/shares/${encodePathSegment(id)}/revoke`, {});
1734
+ return okText(`Share link "${id}" revoked.`);
1735
+ })
1736
+ );
1737
+ }
1738
+
1395
1739
  // src/tools/ops.ts
1396
- import { z as z13 } from "zod";
1740
+ import { z as z18 } from "zod";
1397
1741
  function registerOpsTools(server, client) {
1398
1742
  server.registerTool(
1399
1743
  "list_activity",
1400
1744
  {
1401
1745
  description: "List the site activity / audit trail (most recent first).",
1402
1746
  inputSchema: {
1403
- limit: z13.number().int().min(1).max(500).optional(),
1404
- offset: z13.number().int().min(0).optional()
1747
+ limit: z18.number().int().min(1).max(500).optional(),
1748
+ offset: z18.number().int().min(0).optional()
1405
1749
  }
1406
1750
  },
1407
1751
  async (args) => run(
@@ -1410,6 +1754,14 @@ function registerOpsTools(server, client) {
1410
1754
  )
1411
1755
  )
1412
1756
  );
1757
+ server.registerTool(
1758
+ "get_site",
1759
+ {
1760
+ description: "Get the current site\u2019s configuration record (name, domain, settings).",
1761
+ inputSchema: {}
1762
+ },
1763
+ async () => run(() => client.get("/site"))
1764
+ );
1413
1765
  server.registerTool(
1414
1766
  "get_health",
1415
1767
  { description: "Check the CMS health endpoint.", inputSchema: {} },
@@ -1423,7 +1775,7 @@ function registerOpsTools(server, client) {
1423
1775
  }
1424
1776
 
1425
1777
  // src/tools/permissions.ts
1426
- import { z as z14 } from "zod";
1778
+ import { z as z19 } from "zod";
1427
1779
  function registerPermissionTools(server, client) {
1428
1780
  server.registerTool(
1429
1781
  "get_my_permissions",
@@ -1438,9 +1790,9 @@ function registerPermissionTools(server, client) {
1438
1790
  {
1439
1791
  description: "Evaluate whether the current principal may perform an action on a collection (optionally against a specific item), returning { allowed, reason, fields }.",
1440
1792
  inputSchema: {
1441
- collection: z14.string().min(1),
1442
- action: z14.enum(["create", "read", "update", "delete", "share"]),
1443
- item: z14.record(z14.unknown()).optional().describe("Item payload to evaluate row-level rules against.")
1793
+ collection: z19.string().min(1),
1794
+ action: z19.enum(["create", "read", "update", "delete", "share"]),
1795
+ item: z19.record(z19.unknown()).optional().describe("Item payload to evaluate row-level rules against.")
1444
1796
  }
1445
1797
  },
1446
1798
  async (input) => run(() => client.post("/permissions/check", input))
@@ -1448,21 +1800,21 @@ function registerPermissionTools(server, client) {
1448
1800
  }
1449
1801
 
1450
1802
  // src/tools/relations.ts
1451
- import { z as z15 } from "zod";
1803
+ import { z as z20 } from "zod";
1452
1804
  var relationInputSchema = {
1453
- manyCollection: z15.string().min(1).describe('Collection that holds the foreign key (the "many" side).'),
1454
- manyField: z15.string().min(1).describe("Field on manyCollection that stores the relation."),
1455
- oneCollection: z15.string().min(1).describe('Related collection (the "one" side).'),
1456
- oneField: z15.string().nullable().optional(),
1457
- junctionCollection: z15.string().nullable().optional().describe("Junction table for m2m relations."),
1458
- type: z15.enum(["m2o", "o2m", "m2m", "m2a"]).optional(),
1459
- aliasField: z15.string().nullable().optional(),
1460
- relatedDisplayTemplate: z15.string().nullable().optional(),
1461
- junctionManyField: z15.string().nullable().optional(),
1462
- junctionOneField: z15.string().nullable().optional(),
1463
- sortField: z15.string().nullable().optional(),
1464
- onDelete: z15.enum(["restrict", "cascade", "set null", "no action"]).optional(),
1465
- meta: z15.record(z15.unknown()).optional()
1805
+ manyCollection: z20.string().min(1).describe('Collection that holds the foreign key (the "many" side).'),
1806
+ manyField: z20.string().min(1).describe("Field on manyCollection that stores the relation."),
1807
+ oneCollection: z20.string().min(1).describe('Related collection (the "one" side).'),
1808
+ oneField: z20.string().nullable().optional(),
1809
+ junctionCollection: z20.string().nullable().optional().describe("Junction table for m2m relations."),
1810
+ type: z20.enum(["m2o", "o2m", "m2m", "m2a"]).optional(),
1811
+ aliasField: z20.string().nullable().optional(),
1812
+ relatedDisplayTemplate: z20.string().nullable().optional(),
1813
+ junctionManyField: z20.string().nullable().optional(),
1814
+ junctionOneField: z20.string().nullable().optional(),
1815
+ sortField: z20.string().nullable().optional(),
1816
+ onDelete: z20.enum(["restrict", "cascade", "set null", "no action"]).optional(),
1817
+ meta: z20.record(z20.unknown()).optional()
1466
1818
  };
1467
1819
  function registerRelationTools(server, client) {
1468
1820
  server.registerTool(
@@ -1484,7 +1836,7 @@ function registerRelationTools(server, client) {
1484
1836
  description: "Delete a relation by id. DESTRUCTIVE \u2014 warn the user first and pass confirm=true.",
1485
1837
  inputSchema: {
1486
1838
  id: idPathSegmentSchema,
1487
- confirm: z15.literal(true).describe(confirmDescription)
1839
+ confirm: z20.literal(true).describe(confirmDescription)
1488
1840
  }
1489
1841
  },
1490
1842
  async ({ id }) => run(async () => {
@@ -1495,19 +1847,19 @@ function registerRelationTools(server, client) {
1495
1847
  }
1496
1848
 
1497
1849
  // src/tools/search-media.ts
1498
- import { z as z16 } from "zod";
1850
+ import { z as z21 } from "zod";
1499
1851
  function registerSearchMediaTools(server, client) {
1500
1852
  server.registerTool(
1501
1853
  "search",
1502
1854
  {
1503
1855
  description: "Full-text search within a collection. Returns ranked hits from the search backend. The `collection` parameter is required.",
1504
1856
  inputSchema: {
1505
- q: z16.string().min(1).describe("Query string."),
1506
- collection: z16.string().min(1).describe("Collection to search."),
1507
- filter: z16.string().optional().describe("Backend filter expression."),
1508
- sort: z16.string().optional().describe("Comma-separated sort fields."),
1509
- limit: z16.number().int().min(1).max(200).optional(),
1510
- offset: z16.number().int().min(0).optional()
1857
+ q: z21.string().min(1).describe("Query string."),
1858
+ collection: z21.string().min(1).describe("Collection to search."),
1859
+ filter: z21.string().optional().describe("Backend filter expression."),
1860
+ sort: z21.string().optional().describe("Comma-separated sort fields."),
1861
+ limit: z21.number().int().min(1).max(200).optional(),
1862
+ offset: z21.number().int().min(0).optional()
1511
1863
  }
1512
1864
  },
1513
1865
  async (args) => run(
@@ -1520,7 +1872,7 @@ function registerSearchMediaTools(server, client) {
1520
1872
  "list_media",
1521
1873
  {
1522
1874
  description: "List media asset keys, optionally filtered by key prefix.",
1523
- inputSchema: { prefix: z16.string().optional() }
1875
+ inputSchema: { prefix: z21.string().optional() }
1524
1876
  },
1525
1877
  async ({ prefix }) => run(() => client.get(`/media${prefix ? `?prefix=${encodeURIComponent(prefix)}` : ""}`))
1526
1878
  );
@@ -1530,7 +1882,7 @@ function registerSearchMediaTools(server, client) {
1530
1882
  description: "Delete a media asset by key. DESTRUCTIVE \u2014 warn the user first and pass confirm=true.",
1531
1883
  inputSchema: {
1532
1884
  key: mediaKeySchema.describe("Full storage key of the asset."),
1533
- confirm: z16.literal(true).describe(confirmDescription)
1885
+ confirm: z21.literal(true).describe(confirmDescription)
1534
1886
  }
1535
1887
  },
1536
1888
  async ({ key }) => run(async () => {
@@ -1538,18 +1890,26 @@ function registerSearchMediaTools(server, client) {
1538
1890
  return okText(`Media asset "${key}" deleted.`);
1539
1891
  })
1540
1892
  );
1893
+ server.registerTool(
1894
+ "list_transform_presets",
1895
+ {
1896
+ description: "List named image-transform presets available for media delivery (key + DSL).",
1897
+ inputSchema: {}
1898
+ },
1899
+ async () => run(() => client.get("/transform-presets"))
1900
+ );
1541
1901
  }
1542
1902
 
1543
1903
  // src/tools/translation-memory.ts
1544
- import { z as z17 } from "zod";
1904
+ import { z as z22 } from "zod";
1545
1905
  function registerTranslationMemoryTools(server, client) {
1546
1906
  server.registerTool(
1547
1907
  "list_tm",
1548
1908
  {
1549
1909
  description: "List translation-memory entries, optionally filtered by source/target language.",
1550
1910
  inputSchema: {
1551
- source: z17.string().optional().describe("Source language code."),
1552
- target: z17.string().optional().describe("Target language code.")
1911
+ source: z22.string().optional().describe("Source language code."),
1912
+ target: z22.string().optional().describe("Target language code.")
1553
1913
  }
1554
1914
  },
1555
1915
  async (args) => run(
@@ -1561,14 +1921,14 @@ function registerTranslationMemoryTools(server, client) {
1561
1921
  {
1562
1922
  description: "Add or update a translation-memory entry.",
1563
1923
  inputSchema: {
1564
- sourceLang: z17.string().min(2),
1565
- targetLang: z17.string().min(2),
1566
- sourceText: z17.string().min(1),
1567
- targetText: z17.string().min(1),
1568
- context: z17.string().optional(),
1569
- quality: z17.number().min(0).max(100).optional(),
1570
- source: z17.enum(["human", "mt", "imported"]).optional(),
1571
- provider: z17.string().optional()
1924
+ sourceLang: z22.string().min(2),
1925
+ targetLang: z22.string().min(2),
1926
+ sourceText: z22.string().min(1),
1927
+ targetText: z22.string().min(1),
1928
+ context: z22.string().optional(),
1929
+ quality: z22.number().min(0).max(100).optional(),
1930
+ source: z22.enum(["human", "mt", "imported"]).optional(),
1931
+ provider: z22.string().optional()
1572
1932
  }
1573
1933
  },
1574
1934
  async (input) => run(() => client.post("/tm", input))
@@ -1578,10 +1938,10 @@ function registerTranslationMemoryTools(server, client) {
1578
1938
  {
1579
1939
  description: "Fuzzy-match a query string against translation memory for a language pair.",
1580
1940
  inputSchema: {
1581
- query: z17.string().min(1),
1582
- sourceLang: z17.string().min(2),
1583
- targetLang: z17.string().min(2),
1584
- threshold: z17.number().min(0).max(100).optional().describe("Minimum match score (default 75).")
1941
+ query: z22.string().min(1),
1942
+ sourceLang: z22.string().min(2),
1943
+ targetLang: z22.string().min(2),
1944
+ threshold: z22.number().min(0).max(100).optional().describe("Minimum match score (default 75).")
1585
1945
  }
1586
1946
  },
1587
1947
  async (input) => run(() => client.post("/tm/lookup", input))
@@ -1591,18 +1951,46 @@ function registerTranslationMemoryTools(server, client) {
1591
1951
  {
1592
1952
  description: "Run the full translation pipeline (TM + glossary + MT provider) for a text.",
1593
1953
  inputSchema: {
1594
- text: z17.string().min(1),
1595
- from: z17.string().min(2),
1596
- to: z17.string().min(2),
1597
- provider: z17.string().optional()
1954
+ text: z22.string().min(1),
1955
+ from: z22.string().min(2),
1956
+ to: z22.string().min(2),
1957
+ provider: z22.string().optional()
1598
1958
  }
1599
1959
  },
1600
1960
  async (input) => run(() => client.post("/tm/translate", input))
1601
1961
  );
1962
+ server.registerTool(
1963
+ "update_tm",
1964
+ {
1965
+ description: "Edit an existing translation-memory entry (partial PATCH).",
1966
+ inputSchema: {
1967
+ id: idPathSegmentSchema,
1968
+ targetText: z22.string().min(1).optional(),
1969
+ quality: z22.number().min(0).max(100).optional(),
1970
+ context: z22.string().nullable().optional(),
1971
+ source: z22.enum(["human", "mt", "imported"]).optional()
1972
+ }
1973
+ },
1974
+ async ({ id, ...patch }) => run(() => client.patch(`/tm/${encodePathSegment(id)}`, patch))
1975
+ );
1976
+ server.registerTool(
1977
+ "delete_tm",
1978
+ {
1979
+ description: "Delete a translation-memory entry. DESTRUCTIVE \u2014 warn the user first and pass confirm=true.",
1980
+ inputSchema: {
1981
+ id: idPathSegmentSchema,
1982
+ confirm: z22.literal(true).describe(confirmDescription)
1983
+ }
1984
+ },
1985
+ async ({ id }) => run(async () => {
1986
+ await client.delete(`/tm/${encodePathSegment(id)}`);
1987
+ return okText(`Translation-memory entry "${id}" deleted.`);
1988
+ })
1989
+ );
1602
1990
  }
1603
1991
 
1604
1992
  // src/tools/users-teams.ts
1605
- import { z as z18 } from "zod";
1993
+ import { z as z23 } from "zod";
1606
1994
  function registerUsersTeamsTools(server, client) {
1607
1995
  server.registerTool(
1608
1996
  "list_users",
@@ -1619,8 +2007,8 @@ function registerUsersTeamsTools(server, client) {
1619
2007
  {
1620
2008
  description: "Invite a user to the site by email, optionally assigning a role. Sends an invite email.",
1621
2009
  inputSchema: {
1622
- email: z18.string().email(),
1623
- roleId: z18.string().optional()
2010
+ email: z23.string().email(),
2011
+ roleId: z23.string().optional()
1624
2012
  }
1625
2013
  },
1626
2014
  async (input) => run(() => client.post("/users/invite", input))
@@ -1631,8 +2019,8 @@ function registerUsersTeamsTools(server, client) {
1631
2019
  description: "Update a user's site membership (role and/or status).",
1632
2020
  inputSchema: {
1633
2021
  id: idPathSegmentSchema,
1634
- roleId: z18.string().nullable().optional(),
1635
- status: z18.string().optional().describe("e.g. active, suspended.")
2022
+ roleId: z23.string().nullable().optional(),
2023
+ status: z23.string().optional().describe("e.g. active, suspended.")
1636
2024
  }
1637
2025
  },
1638
2026
  async ({ id, ...patch }) => run(() => client.patch(`/users/${encodePathSegment(id)}`, patch))
@@ -1641,7 +2029,7 @@ function registerUsersTeamsTools(server, client) {
1641
2029
  "remove_user",
1642
2030
  {
1643
2031
  description: "Remove a user from the site. DESTRUCTIVE \u2014 pass confirm=true.",
1644
- inputSchema: { id: idPathSegmentSchema, confirm: z18.literal(true).describe(confirmDescription) }
2032
+ inputSchema: { id: idPathSegmentSchema, confirm: z23.literal(true).describe(confirmDescription) }
1645
2033
  },
1646
2034
  async ({ id }) => run(async () => {
1647
2035
  await client.delete(`/users/${encodePathSegment(id)}`);
@@ -1662,7 +2050,7 @@ function registerUsersTeamsTools(server, client) {
1662
2050
  "create_team",
1663
2051
  {
1664
2052
  description: "Create a team.",
1665
- inputSchema: { name: z18.string().min(1).max(128), description: z18.string().nullable().optional() }
2053
+ inputSchema: { name: z23.string().min(1).max(128), description: z23.string().nullable().optional() }
1666
2054
  },
1667
2055
  async (input) => run(() => client.post("/teams", input))
1668
2056
  );
@@ -1672,8 +2060,8 @@ function registerUsersTeamsTools(server, client) {
1672
2060
  description: "Update a team (partial PATCH).",
1673
2061
  inputSchema: {
1674
2062
  id: idPathSegmentSchema,
1675
- name: z18.string().min(1).max(128).optional(),
1676
- description: z18.string().nullable().optional()
2063
+ name: z23.string().min(1).max(128).optional(),
2064
+ description: z23.string().nullable().optional()
1677
2065
  }
1678
2066
  },
1679
2067
  async ({ id, ...patch }) => run(() => client.patch(`/teams/${encodePathSegment(id)}`, patch))
@@ -1682,7 +2070,7 @@ function registerUsersTeamsTools(server, client) {
1682
2070
  "delete_team",
1683
2071
  {
1684
2072
  description: "Delete a team. DESTRUCTIVE \u2014 pass confirm=true.",
1685
- inputSchema: { id: idPathSegmentSchema, confirm: z18.literal(true).describe(confirmDescription) }
2073
+ inputSchema: { id: idPathSegmentSchema, confirm: z23.literal(true).describe(confirmDescription) }
1686
2074
  },
1687
2075
  async ({ id }) => run(async () => {
1688
2076
  await client.delete(`/teams/${encodePathSegment(id)}`);
@@ -1709,7 +2097,7 @@ function registerUsersTeamsTools(server, client) {
1709
2097
  inputSchema: {
1710
2098
  id: idPathSegmentSchema.describe("Team id."),
1711
2099
  userId: idPathSegmentSchema,
1712
- confirm: z18.literal(true).describe(confirmDescription)
2100
+ confirm: z23.literal(true).describe(confirmDescription)
1713
2101
  }
1714
2102
  },
1715
2103
  async ({ id, userId }) => run(async () => {
@@ -1720,15 +2108,15 @@ function registerUsersTeamsTools(server, client) {
1720
2108
  }
1721
2109
 
1722
2110
  // src/tools/webhooks.ts
1723
- import { z as z19 } from "zod";
1724
- var webhookSchema = z19.object({
1725
- name: z19.string().min(1).max(255),
1726
- url: z19.string().url(),
1727
- actions: z19.array(z19.string()).optional().describe("Item events that trigger the webhook (e.g. create, update, delete)."),
1728
- collections: z19.array(z19.string()).optional().describe("Collections to filter on (empty = all)."),
1729
- headers: z19.record(z19.string()).optional(),
1730
- status: z19.enum(["active", "inactive"]).optional(),
1731
- secret: z19.string().nullable().optional()
2111
+ import { z as z24 } from "zod";
2112
+ var webhookSchema = z24.object({
2113
+ name: z24.string().min(1).max(255),
2114
+ url: z24.string().url(),
2115
+ actions: z24.array(z24.string()).optional().describe("Item events that trigger the webhook (e.g. create, update, delete)."),
2116
+ collections: z24.array(z24.string()).optional().describe("Collections to filter on (empty = all)."),
2117
+ headers: z24.record(z24.string()).optional(),
2118
+ status: z24.enum(["active", "inactive"]).optional(),
2119
+ secret: z24.string().nullable().optional()
1732
2120
  });
1733
2121
  function registerWebhookTools(server, client) {
1734
2122
  registerCrud(server, client, {
@@ -1751,6 +2139,10 @@ function registerAllTools(server, client) {
1751
2139
  registerContentConfigTools(server, client);
1752
2140
  registerSearchMediaTools(server, client);
1753
2141
  registerTranslationMemoryTools(server, client);
2142
+ registerInsightsTools(server, client);
2143
+ registerEditorialTools(server, client);
2144
+ registerReleaseTools(server, client);
2145
+ registerShareTools(server, client);
1754
2146
  registerPermissionTools(server, client);
1755
2147
  registerAccessTools(server, client);
1756
2148
  registerApiKeyTools(server, client);
@@ -1761,6 +2153,7 @@ function registerAllTools(server, client) {
1761
2153
  registerOpsTools(server, client);
1762
2154
  registerAdminTools(server, client);
1763
2155
  registerExtensionTools(server, client);
2156
+ registerDeploymentTools(server, client);
1764
2157
  }
1765
2158
 
1766
2159
  // src/index.ts