@lumibase/mcp-server 0.13.0 → 0.14.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.
- package/dist/index.cjs +464 -442
- package/dist/index.js +464 -442
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -109,10 +109,10 @@ function configFromEnv() {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// src/tools/access.ts
|
|
112
|
-
import { z as
|
|
112
|
+
import { z as z3 } from "zod";
|
|
113
113
|
|
|
114
114
|
// src/tools/_crud.ts
|
|
115
|
-
import { z } from "zod";
|
|
115
|
+
import { z as z2 } from "zod";
|
|
116
116
|
|
|
117
117
|
// src/tools/_shared.ts
|
|
118
118
|
function formatError(err) {
|
|
@@ -154,6 +154,20 @@ async function run(fn) {
|
|
|
154
154
|
}
|
|
155
155
|
var confirmDescription = "Must be true to confirm the destructive operation";
|
|
156
156
|
|
|
157
|
+
// src/tools/path.ts
|
|
158
|
+
import { z } from "zod";
|
|
159
|
+
var namePattern = /^[a-z][a-z0-9_]{0,62}$/;
|
|
160
|
+
var collectionNameSchema = z.string().min(1).max(63).regex(namePattern, "Must be lowercase, start with a letter, only a-z0-9_");
|
|
161
|
+
var fieldNameSchema = z.string().min(1).max(63).regex(namePattern, "Must be lowercase snake_case, start with a letter");
|
|
162
|
+
var idPathSegmentSchema = z.string().min(1).refine((value) => value !== "." && value !== "..", "Must not be . or ..").refine((value) => !/[\\/]/.test(value), "Must not contain path separators");
|
|
163
|
+
function encodePathSegment(segment) {
|
|
164
|
+
return encodeURIComponent(segment);
|
|
165
|
+
}
|
|
166
|
+
var mediaKeySchema = z.string().min(1).refine((value) => !value.includes(".."), 'Must not contain ".."').refine((value) => !value.startsWith("/"), 'Must not start with "/"').refine((value) => !value.includes("\\"), "Must not contain backslashes");
|
|
167
|
+
function encodeMediaKey(key) {
|
|
168
|
+
return key.split("/").map((segment) => encodeURIComponent(segment)).join("/");
|
|
169
|
+
}
|
|
170
|
+
|
|
157
171
|
// src/tools/_crud.ts
|
|
158
172
|
function registerCrud(server, client, opts) {
|
|
159
173
|
const {
|
|
@@ -184,9 +198,9 @@ function registerCrud(server, client, opts) {
|
|
|
184
198
|
`get_${namePrefix}`,
|
|
185
199
|
{
|
|
186
200
|
description: `Get a single ${resource} by ${idParam}.`,
|
|
187
|
-
inputSchema: { [idParam]:
|
|
201
|
+
inputSchema: { [idParam]: idPathSegmentSchema }
|
|
188
202
|
},
|
|
189
|
-
async (args) => run(() => client.get(`${basePath}/${String(args[idParam])}`))
|
|
203
|
+
async (args) => run(() => client.get(`${basePath}/${encodePathSegment(String(args[idParam]))}`))
|
|
190
204
|
);
|
|
191
205
|
}
|
|
192
206
|
if (createSchema) {
|
|
@@ -204,11 +218,11 @@ function registerCrud(server, client, opts) {
|
|
|
204
218
|
`update_${namePrefix}`,
|
|
205
219
|
{
|
|
206
220
|
description: `Update an existing ${resource} (partial PATCH).`,
|
|
207
|
-
inputSchema: { [idParam]:
|
|
221
|
+
inputSchema: { [idParam]: idPathSegmentSchema, ...updateSchema }
|
|
208
222
|
},
|
|
209
223
|
async (args) => {
|
|
210
224
|
const { [idParam]: id, ...patch } = args;
|
|
211
|
-
return run(() => client.patch(`${basePath}/${String(id)}`, patch));
|
|
225
|
+
return run(() => client.patch(`${basePath}/${encodePathSegment(String(id))}`, patch));
|
|
212
226
|
}
|
|
213
227
|
);
|
|
214
228
|
}
|
|
@@ -218,14 +232,14 @@ function registerCrud(server, client, opts) {
|
|
|
218
232
|
{
|
|
219
233
|
description: `Delete a ${resource}. DESTRUCTIVE \u2014 warn the user first and pass confirm=true.`,
|
|
220
234
|
inputSchema: {
|
|
221
|
-
[idParam]:
|
|
222
|
-
confirm:
|
|
235
|
+
[idParam]: idPathSegmentSchema,
|
|
236
|
+
confirm: z2.literal(true).describe(confirmDescription)
|
|
223
237
|
}
|
|
224
238
|
},
|
|
225
239
|
async (args) => {
|
|
226
240
|
const id = String(args[idParam]);
|
|
227
241
|
return run(async () => {
|
|
228
|
-
await client.delete(`${basePath}/${id}`);
|
|
242
|
+
await client.delete(`${basePath}/${encodePathSegment(id)}`);
|
|
229
243
|
return okText(`${resource} "${id}" deleted.`);
|
|
230
244
|
});
|
|
231
245
|
}
|
|
@@ -234,37 +248,37 @@ function registerCrud(server, client, opts) {
|
|
|
234
248
|
}
|
|
235
249
|
|
|
236
250
|
// src/tools/access.ts
|
|
237
|
-
var roleSchema =
|
|
238
|
-
key:
|
|
239
|
-
systemKey:
|
|
240
|
-
name:
|
|
241
|
-
description:
|
|
242
|
-
icon:
|
|
243
|
-
parentId:
|
|
244
|
-
adminAccess:
|
|
245
|
-
appAccess:
|
|
251
|
+
var roleSchema = z3.object({
|
|
252
|
+
key: z3.string().min(1).max(96).optional(),
|
|
253
|
+
systemKey: z3.string().min(1).max(96).optional(),
|
|
254
|
+
name: z3.string().min(1).max(64),
|
|
255
|
+
description: z3.string().max(512).optional(),
|
|
256
|
+
icon: z3.string().max(64).optional(),
|
|
257
|
+
parentId: z3.string().nullable().optional(),
|
|
258
|
+
adminAccess: z3.boolean().optional(),
|
|
259
|
+
appAccess: z3.boolean().optional()
|
|
246
260
|
});
|
|
247
|
-
var policySchema =
|
|
248
|
-
key:
|
|
249
|
-
name:
|
|
250
|
-
icon:
|
|
251
|
-
description:
|
|
252
|
-
adminAccess:
|
|
253
|
-
appAccess:
|
|
254
|
-
enforceTfa:
|
|
255
|
-
ipAllow:
|
|
256
|
-
ipDeny:
|
|
257
|
-
validFrom:
|
|
258
|
-
validUntil:
|
|
259
|
-
rules:
|
|
261
|
+
var policySchema = z3.object({
|
|
262
|
+
key: z3.string().min(1).max(96).optional(),
|
|
263
|
+
name: z3.string().min(1).max(64),
|
|
264
|
+
icon: z3.string().max(64).optional(),
|
|
265
|
+
description: z3.string().max(512).optional(),
|
|
266
|
+
adminAccess: z3.boolean().optional(),
|
|
267
|
+
appAccess: z3.boolean().optional(),
|
|
268
|
+
enforceTfa: z3.boolean().optional(),
|
|
269
|
+
ipAllow: z3.array(z3.string()).optional(),
|
|
270
|
+
ipDeny: z3.array(z3.string()).optional(),
|
|
271
|
+
validFrom: z3.string().datetime().nullable().optional(),
|
|
272
|
+
validUntil: z3.string().datetime().nullable().optional(),
|
|
273
|
+
rules: z3.record(z3.unknown()).optional()
|
|
260
274
|
});
|
|
261
|
-
var permissionSchema =
|
|
262
|
-
collection:
|
|
263
|
-
action:
|
|
264
|
-
permissions:
|
|
265
|
-
validation:
|
|
266
|
-
presets:
|
|
267
|
-
fields:
|
|
275
|
+
var permissionSchema = z3.object({
|
|
276
|
+
collection: z3.string().min(1).max(64),
|
|
277
|
+
action: z3.enum(["create", "read", "update", "delete", "share"]),
|
|
278
|
+
permissions: z3.record(z3.unknown()).optional(),
|
|
279
|
+
validation: z3.record(z3.unknown()).optional(),
|
|
280
|
+
presets: z3.record(z3.unknown()).optional(),
|
|
281
|
+
fields: z3.array(z3.string()).optional()
|
|
268
282
|
});
|
|
269
283
|
function registerAccessTools(server, client) {
|
|
270
284
|
registerCrud(server, client, {
|
|
@@ -279,26 +293,26 @@ function registerAccessTools(server, client) {
|
|
|
279
293
|
{
|
|
280
294
|
description: "Attach a policy to a role. Conflicts/warnings may require overrideWarnings=true.",
|
|
281
295
|
inputSchema: {
|
|
282
|
-
id:
|
|
283
|
-
policyId:
|
|
284
|
-
priority:
|
|
285
|
-
overrideWarnings:
|
|
296
|
+
id: idPathSegmentSchema.describe("Role id."),
|
|
297
|
+
policyId: idPathSegmentSchema,
|
|
298
|
+
priority: z3.number().int().optional(),
|
|
299
|
+
overrideWarnings: z3.boolean().optional()
|
|
286
300
|
}
|
|
287
301
|
},
|
|
288
|
-
async ({ id, ...body }) => run(() => client.post(`/roles/${id}/policies`, body))
|
|
302
|
+
async ({ id, ...body }) => run(() => client.post(`/roles/${encodePathSegment(id)}/policies`, body))
|
|
289
303
|
);
|
|
290
304
|
server.registerTool(
|
|
291
305
|
"detach_role_policy",
|
|
292
306
|
{
|
|
293
307
|
description: "Detach a policy from a role. DESTRUCTIVE \u2014 pass confirm=true.",
|
|
294
308
|
inputSchema: {
|
|
295
|
-
id:
|
|
296
|
-
policyId:
|
|
297
|
-
confirm:
|
|
309
|
+
id: idPathSegmentSchema.describe("Role id."),
|
|
310
|
+
policyId: idPathSegmentSchema,
|
|
311
|
+
confirm: z3.literal(true).describe(confirmDescription)
|
|
298
312
|
}
|
|
299
313
|
},
|
|
300
314
|
async ({ id, policyId }) => run(async () => {
|
|
301
|
-
await client.delete(`/roles/${id}/policies/${policyId}`);
|
|
315
|
+
await client.delete(`/roles/${encodePathSegment(id)}/policies/${encodePathSegment(policyId)}`);
|
|
302
316
|
return okText(`Policy "${policyId}" detached from role "${id}".`);
|
|
303
317
|
})
|
|
304
318
|
);
|
|
@@ -306,22 +320,22 @@ function registerAccessTools(server, client) {
|
|
|
306
320
|
"assign_role_user",
|
|
307
321
|
{
|
|
308
322
|
description: "Assign a role to a user (sets the user's primary role for this site).",
|
|
309
|
-
inputSchema: { id:
|
|
323
|
+
inputSchema: { id: idPathSegmentSchema.describe("Role id."), userId: idPathSegmentSchema }
|
|
310
324
|
},
|
|
311
|
-
async ({ id, userId }) => run(() => client.post(`/roles/${id}/users`, { userId }))
|
|
325
|
+
async ({ id, userId }) => run(() => client.post(`/roles/${encodePathSegment(id)}/users`, { userId }))
|
|
312
326
|
);
|
|
313
327
|
server.registerTool(
|
|
314
328
|
"remove_role_user",
|
|
315
329
|
{
|
|
316
330
|
description: "Remove a user's role assignment. DESTRUCTIVE \u2014 pass confirm=true.",
|
|
317
331
|
inputSchema: {
|
|
318
|
-
id:
|
|
319
|
-
userId:
|
|
320
|
-
confirm:
|
|
332
|
+
id: idPathSegmentSchema.describe("Role id."),
|
|
333
|
+
userId: idPathSegmentSchema,
|
|
334
|
+
confirm: z3.literal(true).describe(confirmDescription)
|
|
321
335
|
}
|
|
322
336
|
},
|
|
323
337
|
async ({ id, userId }) => run(async () => {
|
|
324
|
-
await client.delete(`/roles/${id}/users/${userId}`);
|
|
338
|
+
await client.delete(`/roles/${encodePathSegment(id)}/users/${encodePathSegment(userId)}`);
|
|
325
339
|
return okText(`User "${userId}" removed from role "${id}".`);
|
|
326
340
|
})
|
|
327
341
|
);
|
|
@@ -337,34 +351,34 @@ function registerAccessTools(server, client) {
|
|
|
337
351
|
"add_policy_permission",
|
|
338
352
|
{
|
|
339
353
|
description: "Add a permission row (collection + action) to a policy.",
|
|
340
|
-
inputSchema: { id:
|
|
354
|
+
inputSchema: { id: idPathSegmentSchema.describe("Policy id."), ...permissionSchema.shape }
|
|
341
355
|
},
|
|
342
|
-
async ({ id, ...body }) => run(() => client.post(`/policies/${id}/permissions`, body))
|
|
356
|
+
async ({ id, ...body }) => run(() => client.post(`/policies/${encodePathSegment(id)}/permissions`, body))
|
|
343
357
|
);
|
|
344
358
|
server.registerTool(
|
|
345
359
|
"update_policy_permission",
|
|
346
360
|
{
|
|
347
361
|
description: "Update a permission row on a policy (partial PATCH).",
|
|
348
362
|
inputSchema: {
|
|
349
|
-
id:
|
|
350
|
-
permId:
|
|
363
|
+
id: idPathSegmentSchema.describe("Policy id."),
|
|
364
|
+
permId: idPathSegmentSchema.describe("Permission row id."),
|
|
351
365
|
...permissionSchema.partial().shape
|
|
352
366
|
}
|
|
353
367
|
},
|
|
354
|
-
async ({ id, permId, ...body }) => run(() => client.patch(`/policies/${id}/permissions/${permId}`, body))
|
|
368
|
+
async ({ id, permId, ...body }) => run(() => client.patch(`/policies/${encodePathSegment(id)}/permissions/${encodePathSegment(permId)}`, body))
|
|
355
369
|
);
|
|
356
370
|
server.registerTool(
|
|
357
371
|
"delete_policy_permission",
|
|
358
372
|
{
|
|
359
373
|
description: "Delete a permission row from a policy. DESTRUCTIVE \u2014 pass confirm=true.",
|
|
360
374
|
inputSchema: {
|
|
361
|
-
id:
|
|
362
|
-
permId:
|
|
363
|
-
confirm:
|
|
375
|
+
id: idPathSegmentSchema.describe("Policy id."),
|
|
376
|
+
permId: idPathSegmentSchema.describe("Permission row id."),
|
|
377
|
+
confirm: z3.literal(true).describe(confirmDescription)
|
|
364
378
|
}
|
|
365
379
|
},
|
|
366
380
|
async ({ id, permId }) => run(async () => {
|
|
367
|
-
await client.delete(`/policies/${id}/permissions/${permId}`);
|
|
381
|
+
await client.delete(`/policies/${encodePathSegment(id)}/permissions/${encodePathSegment(permId)}`);
|
|
368
382
|
return okText(`Permission "${permId}" deleted from policy "${id}".`);
|
|
369
383
|
})
|
|
370
384
|
);
|
|
@@ -373,26 +387,26 @@ function registerAccessTools(server, client) {
|
|
|
373
387
|
{
|
|
374
388
|
description: "Attach a policy directly to a user. Warnings may require overrideWarnings=true.",
|
|
375
389
|
inputSchema: {
|
|
376
|
-
id:
|
|
377
|
-
userId:
|
|
378
|
-
priority:
|
|
379
|
-
overrideWarnings:
|
|
390
|
+
id: idPathSegmentSchema.describe("Policy id."),
|
|
391
|
+
userId: idPathSegmentSchema,
|
|
392
|
+
priority: z3.number().int().optional(),
|
|
393
|
+
overrideWarnings: z3.boolean().optional()
|
|
380
394
|
}
|
|
381
395
|
},
|
|
382
|
-
async ({ id, ...body }) => run(() => client.post(`/policies/${id}/users`, body))
|
|
396
|
+
async ({ id, ...body }) => run(() => client.post(`/policies/${encodePathSegment(id)}/users`, body))
|
|
383
397
|
);
|
|
384
398
|
server.registerTool(
|
|
385
399
|
"detach_policy_user",
|
|
386
400
|
{
|
|
387
401
|
description: "Detach a policy from a user. DESTRUCTIVE \u2014 pass confirm=true.",
|
|
388
402
|
inputSchema: {
|
|
389
|
-
id:
|
|
390
|
-
userId:
|
|
391
|
-
confirm:
|
|
403
|
+
id: idPathSegmentSchema.describe("Policy id."),
|
|
404
|
+
userId: idPathSegmentSchema,
|
|
405
|
+
confirm: z3.literal(true).describe(confirmDescription)
|
|
392
406
|
}
|
|
393
407
|
},
|
|
394
408
|
async ({ id, userId }) => run(async () => {
|
|
395
|
-
await client.delete(`/policies/${id}/users/${userId}`);
|
|
409
|
+
await client.delete(`/policies/${encodePathSegment(id)}/users/${encodePathSegment(userId)}`);
|
|
396
410
|
return okText(`Policy "${id}" detached from user "${userId}".`);
|
|
397
411
|
})
|
|
398
412
|
);
|
|
@@ -405,7 +419,7 @@ function registerAccessTools(server, client) {
|
|
|
405
419
|
"dry_run_access_import",
|
|
406
420
|
{
|
|
407
421
|
description: "Validate an RBAC manifest import without applying it. Returns the planned changes.",
|
|
408
|
-
inputSchema: { manifest:
|
|
422
|
+
inputSchema: { manifest: z3.record(z3.unknown()).describe("RBAC manifest from export_access.") }
|
|
409
423
|
},
|
|
410
424
|
async ({ manifest }) => run(() => client.post("/access/import?dryRun=true", manifest))
|
|
411
425
|
);
|
|
@@ -414,9 +428,9 @@ function registerAccessTools(server, client) {
|
|
|
414
428
|
{
|
|
415
429
|
description: "Apply an RBAC manifest import. High-impact \u2014 changes roles/policies/permissions. Pass confirm=true.",
|
|
416
430
|
inputSchema: {
|
|
417
|
-
manifest:
|
|
418
|
-
mode:
|
|
419
|
-
confirm:
|
|
431
|
+
manifest: z3.record(z3.unknown()).describe("RBAC manifest from export_access."),
|
|
432
|
+
mode: z3.enum(["merge", "replace-managed", "replace-all"]).optional().describe("Import mode (default merge)."),
|
|
433
|
+
confirm: z3.literal(true).describe(confirmDescription)
|
|
420
434
|
}
|
|
421
435
|
},
|
|
422
436
|
async ({ manifest, mode }) => run(() => client.post(`/access/import${mode ? `?mode=${mode}` : ""}`, manifest))
|
|
@@ -426,9 +440,9 @@ function registerAccessTools(server, client) {
|
|
|
426
440
|
{
|
|
427
441
|
description: "Check for permission conflicts before attaching/detaching policies on a target.",
|
|
428
442
|
inputSchema: {
|
|
429
|
-
target:
|
|
430
|
-
addPolicies:
|
|
431
|
-
removePolicies:
|
|
443
|
+
target: z3.object({ type: z3.enum(["role", "user", "api_key"]), id: z3.string().min(1) }).describe("The role/user/api_key the policies would apply to."),
|
|
444
|
+
addPolicies: z3.array(z3.string()).optional(),
|
|
445
|
+
removePolicies: z3.array(z3.string()).optional()
|
|
432
446
|
}
|
|
433
447
|
},
|
|
434
448
|
async (input) => run(() => client.post("/access/conflicts/check", input))
|
|
@@ -436,14 +450,14 @@ function registerAccessTools(server, client) {
|
|
|
436
450
|
}
|
|
437
451
|
|
|
438
452
|
// src/tools/admin.ts
|
|
439
|
-
import { z as
|
|
440
|
-
var materializeSchema =
|
|
441
|
-
collection:
|
|
442
|
-
target:
|
|
443
|
-
refreshStrategy:
|
|
444
|
-
refreshCron:
|
|
445
|
-
projection:
|
|
446
|
-
filter:
|
|
453
|
+
import { z as z4 } from "zod";
|
|
454
|
+
var materializeSchema = z4.object({
|
|
455
|
+
collection: z4.string().min(1).describe("Source collection name."),
|
|
456
|
+
target: z4.string().regex(/^[a-z][a-z0-9_]{0,62}$/).describe("Physical table name (snake_case)."),
|
|
457
|
+
refreshStrategy: z4.enum(["auto", "cron", "manual"]).optional(),
|
|
458
|
+
refreshCron: z4.string().optional(),
|
|
459
|
+
projection: z4.object({ fields: z4.array(z4.string()).optional(), orderBy: z4.string().optional() }).optional(),
|
|
460
|
+
filter: z4.record(z4.unknown()).optional()
|
|
447
461
|
});
|
|
448
462
|
function registerAdminTools(server, client) {
|
|
449
463
|
server.registerTool(
|
|
@@ -459,8 +473,8 @@ function registerAdminTools(server, client) {
|
|
|
459
473
|
{
|
|
460
474
|
description: "Restore a site configuration from an NDJSON bundle (as produced by export_backup). Existing rows are skipped (idempotent). DESTRUCTIVE / high-impact \u2014 pass confirm=true.",
|
|
461
475
|
inputSchema: {
|
|
462
|
-
ndjson:
|
|
463
|
-
confirm:
|
|
476
|
+
ndjson: z4.string().min(1).describe("Raw NDJSON backup content, one JSON object per line."),
|
|
477
|
+
confirm: z4.literal(true).describe(confirmDescription)
|
|
464
478
|
}
|
|
465
479
|
},
|
|
466
480
|
async ({ ndjson }) => run(() => client.postRaw("/admin/restore", ndjson))
|
|
@@ -482,58 +496,58 @@ function registerAdminTools(server, client) {
|
|
|
482
496
|
"refresh_materialization",
|
|
483
497
|
{
|
|
484
498
|
description: "Refresh a materialized collection (truncate + re-insert from source).",
|
|
485
|
-
inputSchema: { id:
|
|
499
|
+
inputSchema: { id: idPathSegmentSchema }
|
|
486
500
|
},
|
|
487
|
-
async ({ id }) => run(() => client.post(`/materialize/${id}/refresh`, {}))
|
|
501
|
+
async ({ id }) => run(() => client.post(`/materialize/${encodePathSegment(id)}/refresh`, {}))
|
|
488
502
|
);
|
|
489
503
|
server.registerTool(
|
|
490
504
|
"query_materialization",
|
|
491
505
|
{
|
|
492
506
|
description: "Query the physical table of a materialized collection directly.",
|
|
493
|
-
inputSchema: { id:
|
|
507
|
+
inputSchema: { id: idPathSegmentSchema }
|
|
494
508
|
},
|
|
495
|
-
async ({ id }) => run(() => client.get(`/materialize/${id}/data`))
|
|
509
|
+
async ({ id }) => run(() => client.get(`/materialize/${encodePathSegment(id)}/data`))
|
|
496
510
|
);
|
|
497
511
|
server.registerTool(
|
|
498
512
|
"drop_materialization",
|
|
499
513
|
{
|
|
500
514
|
description: "Drop a materialized collection (physical table + metadata). DESTRUCTIVE \u2014 pass confirm=true.",
|
|
501
|
-
inputSchema: { id:
|
|
515
|
+
inputSchema: { id: idPathSegmentSchema, confirm: z4.literal(true).describe(confirmDescription) }
|
|
502
516
|
},
|
|
503
517
|
async ({ id }) => run(async () => {
|
|
504
|
-
await client.delete(`/materialize/${id}`);
|
|
518
|
+
await client.delete(`/materialize/${encodePathSegment(id)}`);
|
|
505
519
|
return okText(`Materialization "${id}" dropped.`);
|
|
506
520
|
})
|
|
507
521
|
);
|
|
508
522
|
}
|
|
509
523
|
|
|
510
524
|
// src/tools/agent.ts
|
|
511
|
-
import { z as
|
|
512
|
-
var intentSchema =
|
|
513
|
-
name:
|
|
514
|
-
collection:
|
|
515
|
-
rules:
|
|
516
|
-
schedule:
|
|
517
|
-
budget:
|
|
518
|
-
autonomyCap:
|
|
519
|
-
maintenanceWindow:
|
|
525
|
+
import { z as z5 } from "zod";
|
|
526
|
+
var intentSchema = z5.object({
|
|
527
|
+
name: z5.string().min(1).max(120),
|
|
528
|
+
collection: z5.string().min(1).max(120),
|
|
529
|
+
rules: z5.array(z5.record(z5.unknown())).describe("SLO rules (required_fields, freshness, translations, link_health, \u2026)."),
|
|
530
|
+
schedule: z5.string().describe("5-field cron expression for reconciliation cadence."),
|
|
531
|
+
budget: z5.record(z5.unknown()).optional(),
|
|
532
|
+
autonomyCap: z5.number().int().min(0).max(4).optional().describe("Max autonomy level L0\u2013L4 for this intent."),
|
|
533
|
+
maintenanceWindow: z5.record(z5.unknown()).nullable().optional()
|
|
520
534
|
});
|
|
521
|
-
var flowNode =
|
|
522
|
-
id:
|
|
523
|
-
key:
|
|
524
|
-
options:
|
|
525
|
-
next:
|
|
526
|
-
onError:
|
|
535
|
+
var flowNode = z5.object({
|
|
536
|
+
id: z5.string(),
|
|
537
|
+
key: z5.string(),
|
|
538
|
+
options: z5.record(z5.unknown()).optional(),
|
|
539
|
+
next: z5.string().nullable().optional(),
|
|
540
|
+
onError: z5.string().nullable().optional()
|
|
527
541
|
});
|
|
528
|
-
var flowSchema =
|
|
529
|
-
name:
|
|
530
|
-
description:
|
|
531
|
-
status:
|
|
532
|
-
triggerType:
|
|
533
|
-
triggerOptions:
|
|
534
|
-
graph:
|
|
535
|
-
entry:
|
|
536
|
-
nodes:
|
|
542
|
+
var flowSchema = z5.object({
|
|
543
|
+
name: z5.string().min(1),
|
|
544
|
+
description: z5.string().optional(),
|
|
545
|
+
status: z5.enum(["active", "inactive", "draft"]).optional(),
|
|
546
|
+
triggerType: z5.enum(["webhook", "event", "schedule", "manual"]),
|
|
547
|
+
triggerOptions: z5.record(z5.unknown()).optional(),
|
|
548
|
+
graph: z5.object({
|
|
549
|
+
entry: z5.string().optional(),
|
|
550
|
+
nodes: z5.array(flowNode).optional()
|
|
537
551
|
})
|
|
538
552
|
});
|
|
539
553
|
function registerAgentTools(server, client) {
|
|
@@ -546,31 +560,31 @@ function registerAgentTools(server, client) {
|
|
|
546
560
|
});
|
|
547
561
|
server.registerTool(
|
|
548
562
|
"pause_intent",
|
|
549
|
-
{ description: "Pause an intent (stops scheduled reconciliation).", inputSchema: { id:
|
|
550
|
-
async ({ id }) => run(() => client.post(`/agent/intents/${id}/pause`, {}))
|
|
563
|
+
{ description: "Pause an intent (stops scheduled reconciliation).", inputSchema: { id: idPathSegmentSchema } },
|
|
564
|
+
async ({ id }) => run(() => client.post(`/agent/intents/${encodePathSegment(id)}/pause`, {}))
|
|
551
565
|
);
|
|
552
566
|
server.registerTool(
|
|
553
567
|
"resume_intent",
|
|
554
|
-
{ description: "Resume a paused intent.", inputSchema: { id:
|
|
555
|
-
async ({ id }) => run(() => client.post(`/agent/intents/${id}/resume`, {}))
|
|
568
|
+
{ description: "Resume a paused intent.", inputSchema: { id: idPathSegmentSchema } },
|
|
569
|
+
async ({ id }) => run(() => client.post(`/agent/intents/${encodePathSegment(id)}/resume`, {}))
|
|
556
570
|
);
|
|
557
571
|
server.registerTool(
|
|
558
572
|
"list_intent_drifts",
|
|
559
|
-
{ description: "List detected drifts (intent violations) for an intent.", inputSchema: { id:
|
|
560
|
-
async ({ id }) => run(() => client.get(`/agent/intents/${id}/drifts`))
|
|
573
|
+
{ description: "List detected drifts (intent violations) for an intent.", inputSchema: { id: idPathSegmentSchema } },
|
|
574
|
+
async ({ id }) => run(() => client.get(`/agent/intents/${encodePathSegment(id)}/drifts`))
|
|
561
575
|
);
|
|
562
576
|
server.registerTool(
|
|
563
577
|
"scan_intent",
|
|
564
|
-
{ description: "Trigger an on-demand drift scan for an intent.", inputSchema: { id:
|
|
565
|
-
async ({ id }) => run(() => client.post(`/agent/intents/${id}/scan`, {}))
|
|
578
|
+
{ description: "Trigger an on-demand drift scan for an intent.", inputSchema: { id: idPathSegmentSchema } },
|
|
579
|
+
async ({ id }) => run(() => client.post(`/agent/intents/${encodePathSegment(id)}/scan`, {}))
|
|
566
580
|
);
|
|
567
581
|
server.registerTool(
|
|
568
582
|
"compile_intent",
|
|
569
583
|
{
|
|
570
584
|
description: "Compile a natural-language description into structured intent rules (preview, does not persist).",
|
|
571
585
|
inputSchema: {
|
|
572
|
-
description:
|
|
573
|
-
collection:
|
|
586
|
+
description: z5.string().min(1).max(4e3),
|
|
587
|
+
collection: z5.string().min(1).max(120)
|
|
574
588
|
}
|
|
575
589
|
},
|
|
576
590
|
async (input) => run(() => client.post("/agent/intents/compile", input))
|
|
@@ -587,21 +601,21 @@ function registerAgentTools(server, client) {
|
|
|
587
601
|
{
|
|
588
602
|
description: "Trigger a manual run of a flow with an optional input payload.",
|
|
589
603
|
inputSchema: {
|
|
590
|
-
id:
|
|
591
|
-
input:
|
|
604
|
+
id: idPathSegmentSchema,
|
|
605
|
+
input: z5.record(z5.unknown()).optional().describe("Initial context passed to the flow.")
|
|
592
606
|
}
|
|
593
607
|
},
|
|
594
|
-
async ({ id, input }) => run(() => client.post(`/flows/${id}/run`, input ?? {}))
|
|
608
|
+
async ({ id, input }) => run(() => client.post(`/flows/${encodePathSegment(id)}/run`, input ?? {}))
|
|
595
609
|
);
|
|
596
610
|
server.registerTool(
|
|
597
611
|
"list_flow_runs",
|
|
598
|
-
{ description: "List recent runs of a flow.", inputSchema: { id:
|
|
599
|
-
async ({ id }) => run(() => client.get(`/flows/${id}/runs`))
|
|
612
|
+
{ description: "List recent runs of a flow.", inputSchema: { id: idPathSegmentSchema } },
|
|
613
|
+
async ({ id }) => run(() => client.get(`/flows/${encodePathSegment(id)}/runs`))
|
|
600
614
|
);
|
|
601
615
|
}
|
|
602
616
|
|
|
603
617
|
// src/tools/api-keys.ts
|
|
604
|
-
import { z as
|
|
618
|
+
import { z as z6 } from "zod";
|
|
605
619
|
function registerApiKeyTools(server, client) {
|
|
606
620
|
server.registerTool(
|
|
607
621
|
"list_api_keys",
|
|
@@ -610,18 +624,18 @@ function registerApiKeyTools(server, client) {
|
|
|
610
624
|
);
|
|
611
625
|
server.registerTool(
|
|
612
626
|
"get_api_key",
|
|
613
|
-
{ description: "Get a single API key by id.", inputSchema: { id:
|
|
614
|
-
async ({ id }) => run(() => client.get(`/api-keys/${id}`))
|
|
627
|
+
{ description: "Get a single API key by id.", inputSchema: { id: idPathSegmentSchema } },
|
|
628
|
+
async ({ id }) => run(() => client.get(`/api-keys/${encodePathSegment(id)}`))
|
|
615
629
|
);
|
|
616
630
|
server.registerTool(
|
|
617
631
|
"create_api_key",
|
|
618
632
|
{
|
|
619
633
|
description: "Create a new API key. The plaintext token is returned ONCE in the response \u2014 surface it to the user and tell them it cannot be retrieved again.",
|
|
620
634
|
inputSchema: {
|
|
621
|
-
name:
|
|
622
|
-
description:
|
|
623
|
-
expiresAt:
|
|
624
|
-
metadata:
|
|
635
|
+
name: z6.string().min(1).max(96),
|
|
636
|
+
description: z6.string().max(512).optional(),
|
|
637
|
+
expiresAt: z6.string().datetime().nullable().optional(),
|
|
638
|
+
metadata: z6.record(z6.unknown()).optional()
|
|
625
639
|
}
|
|
626
640
|
},
|
|
627
641
|
async (input) => run(() => client.post("/api-keys", input))
|
|
@@ -631,46 +645,46 @@ function registerApiKeyTools(server, client) {
|
|
|
631
645
|
{
|
|
632
646
|
description: "Rotate an API key \u2014 issues a new token (returned once) and invalidates the old one. DESTRUCTIVE for existing integrations \u2014 pass confirm=true.",
|
|
633
647
|
inputSchema: {
|
|
634
|
-
id:
|
|
635
|
-
expiresAt:
|
|
636
|
-
confirm:
|
|
648
|
+
id: idPathSegmentSchema,
|
|
649
|
+
expiresAt: z6.string().datetime().nullable().optional(),
|
|
650
|
+
confirm: z6.literal(true).describe(confirmDescription)
|
|
637
651
|
}
|
|
638
652
|
},
|
|
639
|
-
async ({ id, expiresAt }) => run(() => client.post(`/api-keys/${id}/rotate`, expiresAt !== void 0 ? { expiresAt } : {}))
|
|
653
|
+
async ({ id, expiresAt }) => run(() => client.post(`/api-keys/${encodePathSegment(id)}/rotate`, expiresAt !== void 0 ? { expiresAt } : {}))
|
|
640
654
|
);
|
|
641
655
|
server.registerTool(
|
|
642
656
|
"revoke_api_key",
|
|
643
657
|
{
|
|
644
658
|
description: "Revoke an API key permanently. DESTRUCTIVE \u2014 pass confirm=true.",
|
|
645
|
-
inputSchema: { id:
|
|
659
|
+
inputSchema: { id: idPathSegmentSchema, confirm: z6.literal(true).describe(confirmDescription) }
|
|
646
660
|
},
|
|
647
|
-
async ({ id }) => run(() => client.post(`/api-keys/${id}/revoke`, {}))
|
|
661
|
+
async ({ id }) => run(() => client.post(`/api-keys/${encodePathSegment(id)}/revoke`, {}))
|
|
648
662
|
);
|
|
649
663
|
server.registerTool(
|
|
650
664
|
"attach_api_key_role",
|
|
651
665
|
{
|
|
652
666
|
description: "Attach a role to an API key (grants the role\u2019s policies to the key).",
|
|
653
667
|
inputSchema: {
|
|
654
|
-
id:
|
|
655
|
-
roleId:
|
|
656
|
-
priority:
|
|
657
|
-
overrideWarnings:
|
|
668
|
+
id: idPathSegmentSchema.describe("API key id."),
|
|
669
|
+
roleId: idPathSegmentSchema,
|
|
670
|
+
priority: z6.number().int().optional(),
|
|
671
|
+
overrideWarnings: z6.boolean().optional()
|
|
658
672
|
}
|
|
659
673
|
},
|
|
660
|
-
async ({ id, ...body }) => run(() => client.post(`/api-keys/${id}/roles`, body))
|
|
674
|
+
async ({ id, ...body }) => run(() => client.post(`/api-keys/${encodePathSegment(id)}/roles`, body))
|
|
661
675
|
);
|
|
662
676
|
server.registerTool(
|
|
663
677
|
"detach_api_key_role",
|
|
664
678
|
{
|
|
665
679
|
description: "Detach a role from an API key. DESTRUCTIVE \u2014 pass confirm=true.",
|
|
666
680
|
inputSchema: {
|
|
667
|
-
id:
|
|
668
|
-
roleId:
|
|
669
|
-
confirm:
|
|
681
|
+
id: idPathSegmentSchema.describe("API key id."),
|
|
682
|
+
roleId: idPathSegmentSchema,
|
|
683
|
+
confirm: z6.literal(true).describe(confirmDescription)
|
|
670
684
|
}
|
|
671
685
|
},
|
|
672
686
|
async ({ id, roleId }) => run(async () => {
|
|
673
|
-
await client.delete(`/api-keys/${id}/roles/${roleId}`);
|
|
687
|
+
await client.delete(`/api-keys/${encodePathSegment(id)}/roles/${encodePathSegment(roleId)}`);
|
|
674
688
|
return okText(`Role "${roleId}" detached from API key "${id}".`);
|
|
675
689
|
})
|
|
676
690
|
);
|
|
@@ -679,73 +693,72 @@ function registerApiKeyTools(server, client) {
|
|
|
679
693
|
{
|
|
680
694
|
description: "Attach a policy directly to an API key.",
|
|
681
695
|
inputSchema: {
|
|
682
|
-
id:
|
|
683
|
-
policyId:
|
|
684
|
-
priority:
|
|
685
|
-
overrideWarnings:
|
|
696
|
+
id: idPathSegmentSchema.describe("API key id."),
|
|
697
|
+
policyId: idPathSegmentSchema,
|
|
698
|
+
priority: z6.number().int().optional(),
|
|
699
|
+
overrideWarnings: z6.boolean().optional()
|
|
686
700
|
}
|
|
687
701
|
},
|
|
688
|
-
async ({ id, ...body }) => run(() => client.post(`/api-keys/${id}/policies`, body))
|
|
702
|
+
async ({ id, ...body }) => run(() => client.post(`/api-keys/${encodePathSegment(id)}/policies`, body))
|
|
689
703
|
);
|
|
690
704
|
server.registerTool(
|
|
691
705
|
"detach_api_key_policy",
|
|
692
706
|
{
|
|
693
707
|
description: "Detach a policy from an API key. DESTRUCTIVE \u2014 pass confirm=true.",
|
|
694
708
|
inputSchema: {
|
|
695
|
-
id:
|
|
696
|
-
policyId:
|
|
697
|
-
confirm:
|
|
709
|
+
id: idPathSegmentSchema.describe("API key id."),
|
|
710
|
+
policyId: idPathSegmentSchema,
|
|
711
|
+
confirm: z6.literal(true).describe(confirmDescription)
|
|
698
712
|
}
|
|
699
713
|
},
|
|
700
714
|
async ({ id, policyId }) => run(async () => {
|
|
701
|
-
await client.delete(`/api-keys/${id}/policies/${policyId}`);
|
|
715
|
+
await client.delete(`/api-keys/${encodePathSegment(id)}/policies/${encodePathSegment(policyId)}`);
|
|
702
716
|
return okText(`Policy "${policyId}" detached from API key "${id}".`);
|
|
703
717
|
})
|
|
704
718
|
);
|
|
705
719
|
}
|
|
706
720
|
|
|
707
721
|
// src/tools/collections.ts
|
|
708
|
-
import { z as
|
|
709
|
-
var
|
|
710
|
-
var collectionInputSchema = z6.object({
|
|
722
|
+
import { z as z7 } from "zod";
|
|
723
|
+
var collectionInputSchema = z7.object({
|
|
711
724
|
name: collectionNameSchema,
|
|
712
|
-
label:
|
|
713
|
-
pluralLabel:
|
|
714
|
-
hidden:
|
|
715
|
-
singleton:
|
|
716
|
-
icon:
|
|
717
|
-
color:
|
|
718
|
-
note:
|
|
719
|
-
primaryKeyField:
|
|
720
|
-
primaryKeyType:
|
|
721
|
-
storageMode:
|
|
722
|
-
displayTemplate:
|
|
723
|
-
sortField:
|
|
724
|
-
archiveField:
|
|
725
|
-
archiveValue:
|
|
726
|
-
unarchiveValue:
|
|
727
|
-
accountability:
|
|
728
|
-
versioning:
|
|
725
|
+
label: z7.string().optional(),
|
|
726
|
+
pluralLabel: z7.string().optional(),
|
|
727
|
+
hidden: z7.boolean().optional(),
|
|
728
|
+
singleton: z7.boolean().optional(),
|
|
729
|
+
icon: z7.string().optional(),
|
|
730
|
+
color: z7.string().optional(),
|
|
731
|
+
note: z7.string().optional(),
|
|
732
|
+
primaryKeyField: z7.string().optional(),
|
|
733
|
+
primaryKeyType: z7.enum(["nanoid", "uuid", "integer", "bigInteger", "string"]).optional(),
|
|
734
|
+
storageMode: z7.enum(["jsonb", "materialized", "physical", "external"]).optional(),
|
|
735
|
+
displayTemplate: z7.string().optional(),
|
|
736
|
+
sortField: z7.string().optional(),
|
|
737
|
+
archiveField: z7.string().optional(),
|
|
738
|
+
archiveValue: z7.string().optional(),
|
|
739
|
+
unarchiveValue: z7.string().optional(),
|
|
740
|
+
accountability: z7.enum(["all", "activity", "none"]).optional(),
|
|
741
|
+
versioning: z7.boolean().optional()
|
|
729
742
|
});
|
|
730
|
-
var fieldInputSchema =
|
|
731
|
-
name:
|
|
732
|
-
type:
|
|
733
|
-
interface:
|
|
734
|
-
display:
|
|
735
|
-
label:
|
|
736
|
-
note:
|
|
737
|
-
nullable:
|
|
738
|
-
unique:
|
|
739
|
-
indexed:
|
|
740
|
-
searchable:
|
|
741
|
-
required:
|
|
742
|
-
readonly:
|
|
743
|
-
hidden:
|
|
744
|
-
width:
|
|
745
|
-
sortOrder:
|
|
746
|
-
group:
|
|
747
|
-
options:
|
|
748
|
-
defaultValue:
|
|
743
|
+
var fieldInputSchema = z7.object({
|
|
744
|
+
name: fieldNameSchema,
|
|
745
|
+
type: z7.string().min(1),
|
|
746
|
+
interface: z7.string().min(1),
|
|
747
|
+
display: z7.string().optional(),
|
|
748
|
+
label: z7.string().optional(),
|
|
749
|
+
note: z7.string().optional(),
|
|
750
|
+
nullable: z7.boolean().optional(),
|
|
751
|
+
unique: z7.boolean().optional(),
|
|
752
|
+
indexed: z7.boolean().optional(),
|
|
753
|
+
searchable: z7.boolean().optional(),
|
|
754
|
+
required: z7.boolean().optional(),
|
|
755
|
+
readonly: z7.boolean().optional(),
|
|
756
|
+
hidden: z7.boolean().optional(),
|
|
757
|
+
width: z7.enum(["half", "full", "fill"]).optional(),
|
|
758
|
+
sortOrder: z7.number().int().optional(),
|
|
759
|
+
group: z7.string().optional(),
|
|
760
|
+
options: z7.record(z7.unknown()).optional(),
|
|
761
|
+
defaultValue: z7.unknown().optional()
|
|
749
762
|
});
|
|
750
763
|
function formatError2(err) {
|
|
751
764
|
if (err instanceof LumiBaseApiError) {
|
|
@@ -773,11 +786,11 @@ function registerCollectionTools(server, client) {
|
|
|
773
786
|
"get_collection",
|
|
774
787
|
{
|
|
775
788
|
description: "Get a collection with its compiled schema (all fields, system fields, meta).",
|
|
776
|
-
inputSchema: { name:
|
|
789
|
+
inputSchema: { name: collectionNameSchema }
|
|
777
790
|
},
|
|
778
791
|
async ({ name }) => {
|
|
779
792
|
try {
|
|
780
|
-
const data = await client.get(`/collections/${name}/compiled`);
|
|
793
|
+
const data = await client.get(`/collections/${encodePathSegment(name)}/compiled`);
|
|
781
794
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
782
795
|
} catch (err) {
|
|
783
796
|
return { content: [{ type: "text", text: `Error: ${formatError2(err)}` }], isError: true };
|
|
@@ -804,13 +817,13 @@ function registerCollectionTools(server, client) {
|
|
|
804
817
|
{
|
|
805
818
|
description: "Update metadata on an existing collection (label, icon, note, accountability, etc.).",
|
|
806
819
|
inputSchema: {
|
|
807
|
-
name:
|
|
820
|
+
name: collectionNameSchema,
|
|
808
821
|
patch: collectionInputSchema.omit({ name: true }).partial()
|
|
809
822
|
}
|
|
810
823
|
},
|
|
811
824
|
async ({ name, patch }) => {
|
|
812
825
|
try {
|
|
813
|
-
const data = await client.patch(`/collections/${name}`, patch);
|
|
826
|
+
const data = await client.patch(`/collections/${encodePathSegment(name)}`, patch);
|
|
814
827
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
815
828
|
} catch (err) {
|
|
816
829
|
return { content: [{ type: "text", text: `Error: ${formatError2(err)}` }], isError: true };
|
|
@@ -822,13 +835,13 @@ function registerCollectionTools(server, client) {
|
|
|
822
835
|
{
|
|
823
836
|
description: "Delete a collection and all its items. DESTRUCTIVE \u2014 cannot be undone. You MUST pass confirm=true explicitly after warning the user.",
|
|
824
837
|
inputSchema: {
|
|
825
|
-
name:
|
|
826
|
-
confirm:
|
|
838
|
+
name: collectionNameSchema,
|
|
839
|
+
confirm: z7.literal(true).describe("Must be true to confirm destructive operation")
|
|
827
840
|
}
|
|
828
841
|
},
|
|
829
842
|
async ({ name, confirm: _ }) => {
|
|
830
843
|
try {
|
|
831
|
-
await client.delete(`/collections/${name}`);
|
|
844
|
+
await client.delete(`/collections/${encodePathSegment(name)}`);
|
|
832
845
|
return { content: [{ type: "text", text: `Collection "${name}" deleted.` }] };
|
|
833
846
|
} catch (err) {
|
|
834
847
|
return { content: [{ type: "text", text: `Error: ${formatError2(err)}` }], isError: true };
|
|
@@ -840,10 +853,10 @@ function registerCollectionTools(server, client) {
|
|
|
840
853
|
{
|
|
841
854
|
description: "Preview what would change if you applied a schema update. Returns added/modified/removed fields and any risky changes. Always call this before apply_schema to check for breaking changes.",
|
|
842
855
|
inputSchema: {
|
|
843
|
-
name:
|
|
844
|
-
fields:
|
|
845
|
-
label:
|
|
846
|
-
note:
|
|
856
|
+
name: collectionNameSchema,
|
|
857
|
+
fields: z7.array(fieldInputSchema).optional(),
|
|
858
|
+
label: z7.string().optional(),
|
|
859
|
+
note: z7.string().optional()
|
|
847
860
|
}
|
|
848
861
|
},
|
|
849
862
|
async (input) => {
|
|
@@ -860,23 +873,26 @@ function registerCollectionTools(server, client) {
|
|
|
860
873
|
{
|
|
861
874
|
description: "Atomically apply a schema migration to a collection (add/update/remove fields and relations). Call diff_schema first to preview changes. Pass confirmRiskyChange=true on field inputs that have risky changes.",
|
|
862
875
|
inputSchema: {
|
|
863
|
-
name:
|
|
864
|
-
fields:
|
|
876
|
+
name: collectionNameSchema,
|
|
877
|
+
fields: z7.array(
|
|
865
878
|
fieldInputSchema.extend({
|
|
866
|
-
renameFrom:
|
|
867
|
-
confirmRiskyChange:
|
|
879
|
+
renameFrom: fieldNameSchema.optional(),
|
|
880
|
+
confirmRiskyChange: z7.boolean().optional()
|
|
868
881
|
})
|
|
869
882
|
).optional(),
|
|
870
|
-
label:
|
|
871
|
-
note:
|
|
872
|
-
accountability:
|
|
873
|
-
versioning:
|
|
883
|
+
label: z7.string().optional(),
|
|
884
|
+
note: z7.string().optional(),
|
|
885
|
+
accountability: z7.enum(["all", "activity", "none"]).optional(),
|
|
886
|
+
versioning: z7.boolean().optional()
|
|
874
887
|
}
|
|
875
888
|
},
|
|
876
889
|
async (input) => {
|
|
877
890
|
try {
|
|
878
891
|
const { name, ...rest } = input;
|
|
879
|
-
const data = await client.put(
|
|
892
|
+
const data = await client.put(
|
|
893
|
+
`/collections/${encodePathSegment(name)}/schema`,
|
|
894
|
+
rest
|
|
895
|
+
);
|
|
880
896
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
881
897
|
} catch (err) {
|
|
882
898
|
return { content: [{ type: "text", text: `Error: ${formatError2(err)}` }], isError: true };
|
|
@@ -886,34 +902,34 @@ function registerCollectionTools(server, client) {
|
|
|
886
902
|
}
|
|
887
903
|
|
|
888
904
|
// src/tools/content-config.ts
|
|
889
|
-
import { z as
|
|
890
|
-
var presetSchema =
|
|
891
|
-
bookmark:
|
|
892
|
-
collection:
|
|
893
|
-
userId:
|
|
894
|
-
roleId:
|
|
895
|
-
layout:
|
|
896
|
-
layoutQuery:
|
|
897
|
-
layoutOptions:
|
|
898
|
-
search:
|
|
899
|
-
filter:
|
|
900
|
-
icon:
|
|
901
|
-
color:
|
|
902
|
-
refreshInterval:
|
|
905
|
+
import { z as z8 } from "zod";
|
|
906
|
+
var presetSchema = z8.object({
|
|
907
|
+
bookmark: z8.string().nullable().optional(),
|
|
908
|
+
collection: z8.string(),
|
|
909
|
+
userId: z8.string().nullable().optional(),
|
|
910
|
+
roleId: z8.string().nullable().optional(),
|
|
911
|
+
layout: z8.string().optional(),
|
|
912
|
+
layoutQuery: z8.record(z8.unknown()).optional(),
|
|
913
|
+
layoutOptions: z8.record(z8.unknown()).optional(),
|
|
914
|
+
search: z8.string().nullable().optional(),
|
|
915
|
+
filter: z8.record(z8.unknown()).optional(),
|
|
916
|
+
icon: z8.string().nullable().optional(),
|
|
917
|
+
color: z8.string().nullable().optional(),
|
|
918
|
+
refreshInterval: z8.number().int().min(0).optional()
|
|
903
919
|
});
|
|
904
|
-
var translationSchema =
|
|
905
|
-
language:
|
|
906
|
-
namespace:
|
|
907
|
-
key:
|
|
908
|
-
value:
|
|
909
|
-
status:
|
|
920
|
+
var translationSchema = z8.object({
|
|
921
|
+
language: z8.string(),
|
|
922
|
+
namespace: z8.string(),
|
|
923
|
+
key: z8.string(),
|
|
924
|
+
value: z8.string(),
|
|
925
|
+
status: z8.string().optional()
|
|
910
926
|
});
|
|
911
927
|
function registerContentConfigTools(server, client) {
|
|
912
928
|
registerCrud(server, client, {
|
|
913
929
|
basePath: "/presets",
|
|
914
930
|
resource: "preset",
|
|
915
931
|
namePrefix: "preset",
|
|
916
|
-
listQuery: { collection:
|
|
932
|
+
listQuery: { collection: z8.string().optional() },
|
|
917
933
|
createSchema: presetSchema.shape,
|
|
918
934
|
updateSchema: presetSchema.partial().shape
|
|
919
935
|
});
|
|
@@ -922,8 +938,8 @@ function registerContentConfigTools(server, client) {
|
|
|
922
938
|
resource: "translation",
|
|
923
939
|
namePrefix: "translation",
|
|
924
940
|
listQuery: {
|
|
925
|
-
namespace:
|
|
926
|
-
language:
|
|
941
|
+
namespace: z8.string().optional(),
|
|
942
|
+
language: z8.string().optional()
|
|
927
943
|
},
|
|
928
944
|
createSchema: translationSchema.shape,
|
|
929
945
|
updateSchema: translationSchema.partial().shape
|
|
@@ -932,7 +948,7 @@ function registerContentConfigTools(server, client) {
|
|
|
932
948
|
"list_settings",
|
|
933
949
|
{
|
|
934
950
|
description: "List site settings, optionally filtered by scope.",
|
|
935
|
-
inputSchema: { scope:
|
|
951
|
+
inputSchema: { scope: z8.string().optional() }
|
|
936
952
|
},
|
|
937
953
|
async ({ scope }) => run(() => client.get(`/settings${scope ? `?scope=${encodeURIComponent(scope)}` : ""}`))
|
|
938
954
|
);
|
|
@@ -940,18 +956,18 @@ function registerContentConfigTools(server, client) {
|
|
|
940
956
|
"get_setting",
|
|
941
957
|
{
|
|
942
958
|
description: "Get a single setting by key.",
|
|
943
|
-
inputSchema: { key:
|
|
959
|
+
inputSchema: { key: idPathSegmentSchema }
|
|
944
960
|
},
|
|
945
|
-
async ({ key }) => run(() => client.get(`/settings/${
|
|
961
|
+
async ({ key }) => run(() => client.get(`/settings/${encodePathSegment(key)}`))
|
|
946
962
|
);
|
|
947
963
|
server.registerTool(
|
|
948
964
|
"upsert_setting",
|
|
949
965
|
{
|
|
950
966
|
description: "Create or update a setting (upsert by key).",
|
|
951
967
|
inputSchema: {
|
|
952
|
-
key:
|
|
953
|
-
value:
|
|
954
|
-
scope:
|
|
968
|
+
key: idPathSegmentSchema,
|
|
969
|
+
value: z8.record(z8.unknown()).describe("Arbitrary JSON value object for the setting."),
|
|
970
|
+
scope: z8.string().optional()
|
|
955
971
|
}
|
|
956
972
|
},
|
|
957
973
|
async (input) => run(() => client.post("/settings", input))
|
|
@@ -961,29 +977,29 @@ function registerContentConfigTools(server, client) {
|
|
|
961
977
|
{
|
|
962
978
|
description: "Delete a setting by key. DESTRUCTIVE \u2014 warn the user first and pass confirm=true.",
|
|
963
979
|
inputSchema: {
|
|
964
|
-
key:
|
|
965
|
-
confirm:
|
|
980
|
+
key: idPathSegmentSchema,
|
|
981
|
+
confirm: z8.literal(true).describe(confirmDescription)
|
|
966
982
|
}
|
|
967
983
|
},
|
|
968
984
|
async ({ key }) => run(async () => {
|
|
969
|
-
await client.delete(`/settings/${
|
|
985
|
+
await client.delete(`/settings/${encodePathSegment(key)}`);
|
|
970
986
|
return okText(`Setting "${key}" deleted.`);
|
|
971
987
|
})
|
|
972
988
|
);
|
|
973
989
|
}
|
|
974
990
|
|
|
975
991
|
// src/tools/extensions.ts
|
|
976
|
-
import { z as
|
|
992
|
+
import { z as z9 } from "zod";
|
|
977
993
|
var EXTENSION_TYPES = ["interface", "display", "layout", "panel", "module", "hook", "endpoint"];
|
|
978
|
-
var extensionSchema =
|
|
979
|
-
key:
|
|
980
|
-
name:
|
|
981
|
-
version:
|
|
982
|
-
type:
|
|
983
|
-
enabled:
|
|
984
|
-
bundleUrl:
|
|
985
|
-
manifest:
|
|
986
|
-
capabilities:
|
|
994
|
+
var extensionSchema = z9.object({
|
|
995
|
+
key: z9.string().regex(/^[a-z0-9_:-]+$/).optional(),
|
|
996
|
+
name: z9.string().min(1),
|
|
997
|
+
version: z9.string().min(1),
|
|
998
|
+
type: z9.enum(EXTENSION_TYPES),
|
|
999
|
+
enabled: z9.boolean().optional(),
|
|
1000
|
+
bundleUrl: z9.string().min(1).describe("https:, http:, or data:text/javascript bundle URL."),
|
|
1001
|
+
manifest: z9.record(z9.string()).optional(),
|
|
1002
|
+
capabilities: z9.array(z9.string()).optional()
|
|
987
1003
|
});
|
|
988
1004
|
function registerExtensionTools(server, client) {
|
|
989
1005
|
server.registerTool(
|
|
@@ -1003,18 +1019,18 @@ function registerExtensionTools(server, client) {
|
|
|
1003
1019
|
"update_extension",
|
|
1004
1020
|
{
|
|
1005
1021
|
description: "Update an installed extension (enable/disable, version, config). Partial PATCH.",
|
|
1006
|
-
inputSchema: { id:
|
|
1022
|
+
inputSchema: { id: idPathSegmentSchema, ...extensionSchema.partial().shape }
|
|
1007
1023
|
},
|
|
1008
|
-
async ({ id, ...patch }) => run(() => client.patch(`/extensions/${id}`, patch))
|
|
1024
|
+
async ({ id, ...patch }) => run(() => client.patch(`/extensions/${encodePathSegment(id)}`, patch))
|
|
1009
1025
|
);
|
|
1010
1026
|
server.registerTool(
|
|
1011
1027
|
"uninstall_extension",
|
|
1012
1028
|
{
|
|
1013
1029
|
description: "Uninstall an extension from the site. DESTRUCTIVE \u2014 pass confirm=true.",
|
|
1014
|
-
inputSchema: { id:
|
|
1030
|
+
inputSchema: { id: idPathSegmentSchema, confirm: z9.literal(true).describe(confirmDescription) }
|
|
1015
1031
|
},
|
|
1016
1032
|
async ({ id }) => run(async () => {
|
|
1017
|
-
await client.delete(`/extensions/${id}`);
|
|
1033
|
+
await client.delete(`/extensions/${encodePathSegment(id)}`);
|
|
1018
1034
|
return okText(`Extension "${id}" uninstalled.`);
|
|
1019
1035
|
})
|
|
1020
1036
|
);
|
|
@@ -1023,12 +1039,12 @@ function registerExtensionTools(server, client) {
|
|
|
1023
1039
|
{
|
|
1024
1040
|
description: "Browse the published extension marketplace.",
|
|
1025
1041
|
inputSchema: {
|
|
1026
|
-
q:
|
|
1027
|
-
category:
|
|
1028
|
-
tags:
|
|
1029
|
-
sort:
|
|
1030
|
-
page:
|
|
1031
|
-
perPage:
|
|
1042
|
+
q: z9.string().optional(),
|
|
1043
|
+
category: z9.string().optional(),
|
|
1044
|
+
tags: z9.string().optional().describe("Comma-separated tags."),
|
|
1045
|
+
sort: z9.string().optional(),
|
|
1046
|
+
page: z9.number().int().min(1).optional(),
|
|
1047
|
+
perPage: z9.number().int().min(1).optional()
|
|
1032
1048
|
}
|
|
1033
1049
|
},
|
|
1034
1050
|
async (args) => run(
|
|
@@ -1041,9 +1057,9 @@ function registerExtensionTools(server, client) {
|
|
|
1041
1057
|
"get_marketplace_extension",
|
|
1042
1058
|
{
|
|
1043
1059
|
description: "Get a single marketplace extension by slug.",
|
|
1044
|
-
inputSchema: { slug:
|
|
1060
|
+
inputSchema: { slug: idPathSegmentSchema }
|
|
1045
1061
|
},
|
|
1046
|
-
async ({ slug }) => run(() => client.get(`/marketplace/extensions/${slug}`))
|
|
1062
|
+
async ({ slug }) => run(() => client.get(`/marketplace/extensions/${encodePathSegment(slug)}`))
|
|
1047
1063
|
);
|
|
1048
1064
|
server.registerTool(
|
|
1049
1065
|
"list_marketplace_updates",
|
|
@@ -1054,22 +1070,22 @@ function registerExtensionTools(server, client) {
|
|
|
1054
1070
|
"install_marketplace_extension",
|
|
1055
1071
|
{
|
|
1056
1072
|
description: "Install a published marketplace extension onto the active site by slug.",
|
|
1057
|
-
inputSchema: { slug:
|
|
1073
|
+
inputSchema: { slug: idPathSegmentSchema }
|
|
1058
1074
|
},
|
|
1059
|
-
async ({ slug }) => run(() => client.post(`/marketplace/extensions/${slug}/install`, {}))
|
|
1075
|
+
async ({ slug }) => run(() => client.post(`/marketplace/extensions/${encodePathSegment(slug)}/install`, {}))
|
|
1060
1076
|
);
|
|
1061
1077
|
server.registerTool(
|
|
1062
1078
|
"publish_extension",
|
|
1063
1079
|
{
|
|
1064
1080
|
description: "Publish an extension to the marketplace (signs + marks it published).",
|
|
1065
1081
|
inputSchema: {
|
|
1066
|
-
extensionId:
|
|
1067
|
-
marketplaceSlug:
|
|
1068
|
-
publisher:
|
|
1069
|
-
signature:
|
|
1070
|
-
signatureAlg:
|
|
1071
|
-
publisherKeyId:
|
|
1072
|
-
bundleSha256:
|
|
1082
|
+
extensionId: z9.string().min(1),
|
|
1083
|
+
marketplaceSlug: z9.string().min(1),
|
|
1084
|
+
publisher: z9.record(z9.unknown()).optional(),
|
|
1085
|
+
signature: z9.string().optional(),
|
|
1086
|
+
signatureAlg: z9.string().optional(),
|
|
1087
|
+
publisherKeyId: z9.string().optional(),
|
|
1088
|
+
bundleSha256: z9.string().optional()
|
|
1073
1089
|
}
|
|
1074
1090
|
},
|
|
1075
1091
|
async (input) => run(() => client.post("/marketplace/publish", input))
|
|
@@ -1077,40 +1093,39 @@ function registerExtensionTools(server, client) {
|
|
|
1077
1093
|
}
|
|
1078
1094
|
|
|
1079
1095
|
// src/tools/fields.ts
|
|
1080
|
-
import { z as
|
|
1081
|
-
var
|
|
1082
|
-
|
|
1083
|
-
type: z9.string().min(1).describe(
|
|
1096
|
+
import { z as z10 } from "zod";
|
|
1097
|
+
var fieldInputSchema2 = z10.object({
|
|
1098
|
+
type: z10.string().min(1).describe(
|
|
1084
1099
|
"Storage type: string, text, integer, bigInteger, float, decimal, boolean, date, dateTime, time, json, uuid, csv, hash, alias"
|
|
1085
1100
|
),
|
|
1086
|
-
interface:
|
|
1101
|
+
interface: z10.string().min(1).describe(
|
|
1087
1102
|
"UI widget: input, textarea, select, toggle, datetime, file, image, repeater, relation-m2o, relation-o2m, relation-m2m, code, markdown, wysiwyg, \u2026"
|
|
1088
1103
|
),
|
|
1089
|
-
display:
|
|
1090
|
-
label:
|
|
1091
|
-
note:
|
|
1092
|
-
defaultValue:
|
|
1093
|
-
nullable:
|
|
1094
|
-
unique:
|
|
1095
|
-
indexed:
|
|
1096
|
-
searchable:
|
|
1097
|
-
length:
|
|
1098
|
-
precision:
|
|
1099
|
-
scale:
|
|
1100
|
-
special:
|
|
1101
|
-
options:
|
|
1102
|
-
displayOptions:
|
|
1103
|
-
conditions:
|
|
1104
|
-
required:
|
|
1105
|
-
readonly:
|
|
1106
|
-
hidden:
|
|
1107
|
-
encrypted:
|
|
1108
|
-
versioned:
|
|
1109
|
-
width:
|
|
1110
|
-
group:
|
|
1111
|
-
sortOrder:
|
|
1112
|
-
renameFrom:
|
|
1113
|
-
confirmRiskyChange:
|
|
1104
|
+
display: z10.string().optional(),
|
|
1105
|
+
label: z10.string().optional(),
|
|
1106
|
+
note: z10.string().optional(),
|
|
1107
|
+
defaultValue: z10.unknown().optional(),
|
|
1108
|
+
nullable: z10.boolean().optional().default(true),
|
|
1109
|
+
unique: z10.boolean().optional().default(false),
|
|
1110
|
+
indexed: z10.boolean().optional().default(false),
|
|
1111
|
+
searchable: z10.boolean().optional().default(false),
|
|
1112
|
+
length: z10.number().int().positive().optional(),
|
|
1113
|
+
precision: z10.number().int().positive().optional(),
|
|
1114
|
+
scale: z10.number().int().min(0).optional(),
|
|
1115
|
+
special: z10.array(z10.string()).optional(),
|
|
1116
|
+
options: z10.record(z10.unknown()).optional(),
|
|
1117
|
+
displayOptions: z10.record(z10.unknown()).optional(),
|
|
1118
|
+
conditions: z10.array(z10.unknown()).optional(),
|
|
1119
|
+
required: z10.boolean().optional().default(false),
|
|
1120
|
+
readonly: z10.boolean().optional().default(false),
|
|
1121
|
+
hidden: z10.boolean().optional().default(false),
|
|
1122
|
+
encrypted: z10.boolean().optional().default(false),
|
|
1123
|
+
versioned: z10.boolean().optional().default(false),
|
|
1124
|
+
width: z10.enum(["half", "full", "fill"]).optional().default("full"),
|
|
1125
|
+
group: z10.string().optional(),
|
|
1126
|
+
sortOrder: z10.number().int().optional(),
|
|
1127
|
+
renameFrom: fieldNameSchema.optional().describe("Previous field name if this is a rename operation"),
|
|
1128
|
+
confirmRiskyChange: z10.boolean().optional().describe("Set true to confirm type-change or destructive migration")
|
|
1114
1129
|
});
|
|
1115
1130
|
function formatError3(err) {
|
|
1116
1131
|
if (err instanceof LumiBaseApiError) {
|
|
@@ -1124,12 +1139,12 @@ function registerFieldTools(server, client) {
|
|
|
1124
1139
|
{
|
|
1125
1140
|
description: "List all fields in a collection, including system fields.",
|
|
1126
1141
|
inputSchema: {
|
|
1127
|
-
collection:
|
|
1142
|
+
collection: collectionNameSchema
|
|
1128
1143
|
}
|
|
1129
1144
|
},
|
|
1130
1145
|
async ({ collection }) => {
|
|
1131
1146
|
try {
|
|
1132
|
-
const data = await client.get(`/collections/${collection}/fields`);
|
|
1147
|
+
const data = await client.get(`/collections/${encodePathSegment(collection)}/fields`);
|
|
1133
1148
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
1134
1149
|
} catch (err) {
|
|
1135
1150
|
return { content: [{ type: "text", text: `Error: ${formatError3(err)}` }], isError: true };
|
|
@@ -1141,15 +1156,15 @@ function registerFieldTools(server, client) {
|
|
|
1141
1156
|
{
|
|
1142
1157
|
description: 'Create or update a field in a collection. field_name must be lowercase snake_case (e.g. "published_at"). Common types: string (varchar), text (longtext), integer, boolean, dateTime, json, uuid. Common interfaces: input, textarea, datetime, toggle, select, file, markdown.',
|
|
1143
1158
|
inputSchema: {
|
|
1144
|
-
collection:
|
|
1145
|
-
field_name:
|
|
1159
|
+
collection: collectionNameSchema,
|
|
1160
|
+
field_name: fieldNameSchema.describe("Machine name of the field"),
|
|
1146
1161
|
...fieldInputSchema2.shape
|
|
1147
1162
|
}
|
|
1148
1163
|
},
|
|
1149
1164
|
async ({ collection, field_name, ...fieldInput }) => {
|
|
1150
1165
|
try {
|
|
1151
1166
|
const data = await client.put(
|
|
1152
|
-
`/collections/${collection}/fields/${field_name}`,
|
|
1167
|
+
`/collections/${encodePathSegment(collection)}/fields/${encodePathSegment(field_name)}`,
|
|
1153
1168
|
fieldInput
|
|
1154
1169
|
);
|
|
1155
1170
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
@@ -1163,16 +1178,18 @@ function registerFieldTools(server, client) {
|
|
|
1163
1178
|
{
|
|
1164
1179
|
description: "Delete a field from a collection. Data stored in this field will be lost. Pass confirm=true to confirm the destructive operation.",
|
|
1165
1180
|
inputSchema: {
|
|
1166
|
-
collection:
|
|
1167
|
-
field_name:
|
|
1168
|
-
confirm:
|
|
1169
|
-
force:
|
|
1181
|
+
collection: collectionNameSchema,
|
|
1182
|
+
field_name: fieldNameSchema,
|
|
1183
|
+
confirm: z10.literal(true).describe("Must be true to confirm destructive operation"),
|
|
1184
|
+
force: z10.boolean().optional().describe("Force deletion even if risky (foreign keys, etc.)")
|
|
1170
1185
|
}
|
|
1171
1186
|
},
|
|
1172
1187
|
async ({ collection, field_name, force }) => {
|
|
1173
1188
|
try {
|
|
1174
1189
|
const qs = force ? "?force=true" : "";
|
|
1175
|
-
await client.delete(
|
|
1190
|
+
await client.delete(
|
|
1191
|
+
`/collections/${encodePathSegment(collection)}/fields/${encodePathSegment(field_name)}${qs}`
|
|
1192
|
+
);
|
|
1176
1193
|
return {
|
|
1177
1194
|
content: [{ type: "text", text: `Field "${field_name}" deleted from "${collection}".` }]
|
|
1178
1195
|
};
|
|
@@ -1184,7 +1201,7 @@ function registerFieldTools(server, client) {
|
|
|
1184
1201
|
}
|
|
1185
1202
|
|
|
1186
1203
|
// src/tools/items.ts
|
|
1187
|
-
import { z as
|
|
1204
|
+
import { z as z11 } from "zod";
|
|
1188
1205
|
function formatError4(err) {
|
|
1189
1206
|
if (err instanceof LumiBaseApiError) {
|
|
1190
1207
|
return err.errors.map((e) => `[${e.code}] ${e.message}`).join("; ");
|
|
@@ -1205,19 +1222,19 @@ function registerItemTools(server, client) {
|
|
|
1205
1222
|
{
|
|
1206
1223
|
description: "List items from a collection with optional filtering, sorting, and pagination.",
|
|
1207
1224
|
inputSchema: {
|
|
1208
|
-
collection:
|
|
1209
|
-
limit:
|
|
1210
|
-
offset:
|
|
1211
|
-
status:
|
|
1212
|
-
sort:
|
|
1213
|
-
fields:
|
|
1214
|
-
search:
|
|
1225
|
+
collection: collectionNameSchema,
|
|
1226
|
+
limit: z11.number().int().min(1).max(200).optional().default(25),
|
|
1227
|
+
offset: z11.number().int().min(0).optional().default(0),
|
|
1228
|
+
status: z11.enum(["draft", "published", "archived"]).optional(),
|
|
1229
|
+
sort: z11.string().optional().describe('Comma-separated field names; prefix with - for descending (e.g. "-created_at")'),
|
|
1230
|
+
fields: z11.string().optional().describe('Comma-separated field names to return (e.g. "id,title,status")'),
|
|
1231
|
+
search: z11.string().optional().describe("Full-text search across searchable fields")
|
|
1215
1232
|
}
|
|
1216
1233
|
},
|
|
1217
1234
|
async ({ collection, ...params }) => {
|
|
1218
1235
|
try {
|
|
1219
1236
|
const qs = buildQs2(params);
|
|
1220
|
-
const data = await client.get(`/items/${collection}${qs}`);
|
|
1237
|
+
const data = await client.get(`/items/${encodePathSegment(collection)}${qs}`);
|
|
1221
1238
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
1222
1239
|
} catch (err) {
|
|
1223
1240
|
return { content: [{ type: "text", text: `Error: ${formatError4(err)}` }], isError: true };
|
|
@@ -1229,15 +1246,17 @@ function registerItemTools(server, client) {
|
|
|
1229
1246
|
{
|
|
1230
1247
|
description: "Get a single item by ID from a collection.",
|
|
1231
1248
|
inputSchema: {
|
|
1232
|
-
collection:
|
|
1233
|
-
id:
|
|
1234
|
-
fields:
|
|
1249
|
+
collection: collectionNameSchema,
|
|
1250
|
+
id: idPathSegmentSchema,
|
|
1251
|
+
fields: z11.string().optional().describe("Comma-separated field names to return")
|
|
1235
1252
|
}
|
|
1236
1253
|
},
|
|
1237
1254
|
async ({ collection, id, fields }) => {
|
|
1238
1255
|
try {
|
|
1239
1256
|
const qs = buildQs2({ fields });
|
|
1240
|
-
const data = await client.get(
|
|
1257
|
+
const data = await client.get(
|
|
1258
|
+
`/items/${encodePathSegment(collection)}/${encodePathSegment(id)}${qs}`
|
|
1259
|
+
);
|
|
1241
1260
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
1242
1261
|
} catch (err) {
|
|
1243
1262
|
return { content: [{ type: "text", text: `Error: ${formatError4(err)}` }], isError: true };
|
|
@@ -1249,14 +1268,14 @@ function registerItemTools(server, client) {
|
|
|
1249
1268
|
{
|
|
1250
1269
|
description: "Create a new item in a collection.",
|
|
1251
1270
|
inputSchema: {
|
|
1252
|
-
collection:
|
|
1253
|
-
data:
|
|
1254
|
-
status:
|
|
1271
|
+
collection: collectionNameSchema,
|
|
1272
|
+
data: z11.record(z11.unknown()).describe("Field values for the new item"),
|
|
1273
|
+
status: z11.enum(["draft", "published"]).optional().default("draft")
|
|
1255
1274
|
}
|
|
1256
1275
|
},
|
|
1257
1276
|
async ({ collection, data: itemData, status }) => {
|
|
1258
1277
|
try {
|
|
1259
|
-
const data = await client.post(`/items/${collection}`, {
|
|
1278
|
+
const data = await client.post(`/items/${encodePathSegment(collection)}`, {
|
|
1260
1279
|
...itemData,
|
|
1261
1280
|
status
|
|
1262
1281
|
});
|
|
@@ -1271,14 +1290,17 @@ function registerItemTools(server, client) {
|
|
|
1271
1290
|
{
|
|
1272
1291
|
description: "Partially update an item (PATCH \u2014 only provided fields are changed).",
|
|
1273
1292
|
inputSchema: {
|
|
1274
|
-
collection:
|
|
1275
|
-
id:
|
|
1276
|
-
data:
|
|
1293
|
+
collection: collectionNameSchema,
|
|
1294
|
+
id: idPathSegmentSchema,
|
|
1295
|
+
data: z11.record(z11.unknown()).describe("Fields to update")
|
|
1277
1296
|
}
|
|
1278
1297
|
},
|
|
1279
1298
|
async ({ collection, id, data: itemData }) => {
|
|
1280
1299
|
try {
|
|
1281
|
-
const data = await client.patch(
|
|
1300
|
+
const data = await client.patch(
|
|
1301
|
+
`/items/${encodePathSegment(collection)}/${encodePathSegment(id)}`,
|
|
1302
|
+
itemData
|
|
1303
|
+
);
|
|
1282
1304
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
1283
1305
|
} catch (err) {
|
|
1284
1306
|
return { content: [{ type: "text", text: `Error: ${formatError4(err)}` }], isError: true };
|
|
@@ -1290,14 +1312,14 @@ function registerItemTools(server, client) {
|
|
|
1290
1312
|
{
|
|
1291
1313
|
description: "Soft-delete an item (sets deleted_at, recoverable). Pass confirm=true.",
|
|
1292
1314
|
inputSchema: {
|
|
1293
|
-
collection:
|
|
1294
|
-
id:
|
|
1295
|
-
confirm:
|
|
1315
|
+
collection: collectionNameSchema,
|
|
1316
|
+
id: idPathSegmentSchema,
|
|
1317
|
+
confirm: z11.literal(true).describe("Must be true to confirm deletion")
|
|
1296
1318
|
}
|
|
1297
1319
|
},
|
|
1298
1320
|
async ({ collection, id }) => {
|
|
1299
1321
|
try {
|
|
1300
|
-
await client.delete(`/items/${collection}/${id}`);
|
|
1322
|
+
await client.delete(`/items/${encodePathSegment(collection)}/${encodePathSegment(id)}`);
|
|
1301
1323
|
return { content: [{ type: "text", text: `Item "${id}" deleted from "${collection}".` }] };
|
|
1302
1324
|
} catch (err) {
|
|
1303
1325
|
return { content: [{ type: "text", text: `Error: ${formatError4(err)}` }], isError: true };
|
|
@@ -1307,15 +1329,15 @@ function registerItemTools(server, client) {
|
|
|
1307
1329
|
}
|
|
1308
1330
|
|
|
1309
1331
|
// src/tools/ops.ts
|
|
1310
|
-
import { z as
|
|
1332
|
+
import { z as z12 } from "zod";
|
|
1311
1333
|
function registerOpsTools(server, client) {
|
|
1312
1334
|
server.registerTool(
|
|
1313
1335
|
"list_activity",
|
|
1314
1336
|
{
|
|
1315
1337
|
description: "List the site activity / audit trail (most recent first).",
|
|
1316
1338
|
inputSchema: {
|
|
1317
|
-
limit:
|
|
1318
|
-
offset:
|
|
1339
|
+
limit: z12.number().int().min(1).max(500).optional(),
|
|
1340
|
+
offset: z12.number().int().min(0).optional()
|
|
1319
1341
|
}
|
|
1320
1342
|
},
|
|
1321
1343
|
async (args) => run(
|
|
@@ -1337,7 +1359,7 @@ function registerOpsTools(server, client) {
|
|
|
1337
1359
|
}
|
|
1338
1360
|
|
|
1339
1361
|
// src/tools/permissions.ts
|
|
1340
|
-
import { z as
|
|
1362
|
+
import { z as z13 } from "zod";
|
|
1341
1363
|
function registerPermissionTools(server, client) {
|
|
1342
1364
|
server.registerTool(
|
|
1343
1365
|
"get_my_permissions",
|
|
@@ -1352,9 +1374,9 @@ function registerPermissionTools(server, client) {
|
|
|
1352
1374
|
{
|
|
1353
1375
|
description: "Evaluate whether the current principal may perform an action on a collection (optionally against a specific item), returning { allowed, reason, fields }.",
|
|
1354
1376
|
inputSchema: {
|
|
1355
|
-
collection:
|
|
1356
|
-
action:
|
|
1357
|
-
item:
|
|
1377
|
+
collection: z13.string().min(1),
|
|
1378
|
+
action: z13.enum(["create", "read", "update", "delete", "share"]),
|
|
1379
|
+
item: z13.record(z13.unknown()).optional().describe("Item payload to evaluate row-level rules against.")
|
|
1358
1380
|
}
|
|
1359
1381
|
},
|
|
1360
1382
|
async (input) => run(() => client.post("/permissions/check", input))
|
|
@@ -1362,21 +1384,21 @@ function registerPermissionTools(server, client) {
|
|
|
1362
1384
|
}
|
|
1363
1385
|
|
|
1364
1386
|
// src/tools/relations.ts
|
|
1365
|
-
import { z as
|
|
1387
|
+
import { z as z14 } from "zod";
|
|
1366
1388
|
var relationInputSchema = {
|
|
1367
|
-
manyCollection:
|
|
1368
|
-
manyField:
|
|
1369
|
-
oneCollection:
|
|
1370
|
-
oneField:
|
|
1371
|
-
junctionCollection:
|
|
1372
|
-
type:
|
|
1373
|
-
aliasField:
|
|
1374
|
-
relatedDisplayTemplate:
|
|
1375
|
-
junctionManyField:
|
|
1376
|
-
junctionOneField:
|
|
1377
|
-
sortField:
|
|
1378
|
-
onDelete:
|
|
1379
|
-
meta:
|
|
1389
|
+
manyCollection: z14.string().min(1).describe('Collection that holds the foreign key (the "many" side).'),
|
|
1390
|
+
manyField: z14.string().min(1).describe("Field on manyCollection that stores the relation."),
|
|
1391
|
+
oneCollection: z14.string().min(1).describe('Related collection (the "one" side).'),
|
|
1392
|
+
oneField: z14.string().nullable().optional(),
|
|
1393
|
+
junctionCollection: z14.string().nullable().optional().describe("Junction table for m2m relations."),
|
|
1394
|
+
type: z14.enum(["m2o", "o2m", "m2m", "m2a"]).optional(),
|
|
1395
|
+
aliasField: z14.string().nullable().optional(),
|
|
1396
|
+
relatedDisplayTemplate: z14.string().nullable().optional(),
|
|
1397
|
+
junctionManyField: z14.string().nullable().optional(),
|
|
1398
|
+
junctionOneField: z14.string().nullable().optional(),
|
|
1399
|
+
sortField: z14.string().nullable().optional(),
|
|
1400
|
+
onDelete: z14.enum(["restrict", "cascade", "set null", "no action"]).optional(),
|
|
1401
|
+
meta: z14.record(z14.unknown()).optional()
|
|
1380
1402
|
};
|
|
1381
1403
|
function registerRelationTools(server, client) {
|
|
1382
1404
|
server.registerTool(
|
|
@@ -1397,31 +1419,31 @@ function registerRelationTools(server, client) {
|
|
|
1397
1419
|
{
|
|
1398
1420
|
description: "Delete a relation by id. DESTRUCTIVE \u2014 warn the user first and pass confirm=true.",
|
|
1399
1421
|
inputSchema: {
|
|
1400
|
-
id:
|
|
1401
|
-
confirm:
|
|
1422
|
+
id: idPathSegmentSchema,
|
|
1423
|
+
confirm: z14.literal(true).describe(confirmDescription)
|
|
1402
1424
|
}
|
|
1403
1425
|
},
|
|
1404
1426
|
async ({ id }) => run(async () => {
|
|
1405
|
-
await client.delete(`/relations/${id}`);
|
|
1427
|
+
await client.delete(`/relations/${encodePathSegment(id)}`);
|
|
1406
1428
|
return okText(`Relation "${id}" deleted.`);
|
|
1407
1429
|
})
|
|
1408
1430
|
);
|
|
1409
1431
|
}
|
|
1410
1432
|
|
|
1411
1433
|
// src/tools/search-media.ts
|
|
1412
|
-
import { z as
|
|
1434
|
+
import { z as z15 } from "zod";
|
|
1413
1435
|
function registerSearchMediaTools(server, client) {
|
|
1414
1436
|
server.registerTool(
|
|
1415
1437
|
"search",
|
|
1416
1438
|
{
|
|
1417
1439
|
description: "Full-text search within a collection. Returns ranked hits from the search backend. The `collection` parameter is required.",
|
|
1418
1440
|
inputSchema: {
|
|
1419
|
-
q:
|
|
1420
|
-
collection:
|
|
1421
|
-
filter:
|
|
1422
|
-
sort:
|
|
1423
|
-
limit:
|
|
1424
|
-
offset:
|
|
1441
|
+
q: z15.string().min(1).describe("Query string."),
|
|
1442
|
+
collection: z15.string().min(1).describe("Collection to search."),
|
|
1443
|
+
filter: z15.string().optional().describe("Backend filter expression."),
|
|
1444
|
+
sort: z15.string().optional().describe("Comma-separated sort fields."),
|
|
1445
|
+
limit: z15.number().int().min(1).max(200).optional(),
|
|
1446
|
+
offset: z15.number().int().min(0).optional()
|
|
1425
1447
|
}
|
|
1426
1448
|
},
|
|
1427
1449
|
async (args) => run(
|
|
@@ -1434,7 +1456,7 @@ function registerSearchMediaTools(server, client) {
|
|
|
1434
1456
|
"list_media",
|
|
1435
1457
|
{
|
|
1436
1458
|
description: "List media asset keys, optionally filtered by key prefix.",
|
|
1437
|
-
inputSchema: { prefix:
|
|
1459
|
+
inputSchema: { prefix: z15.string().optional() }
|
|
1438
1460
|
},
|
|
1439
1461
|
async ({ prefix }) => run(() => client.get(`/media${prefix ? `?prefix=${encodeURIComponent(prefix)}` : ""}`))
|
|
1440
1462
|
);
|
|
@@ -1443,27 +1465,27 @@ function registerSearchMediaTools(server, client) {
|
|
|
1443
1465
|
{
|
|
1444
1466
|
description: "Delete a media asset by key. DESTRUCTIVE \u2014 warn the user first and pass confirm=true.",
|
|
1445
1467
|
inputSchema: {
|
|
1446
|
-
key:
|
|
1447
|
-
confirm:
|
|
1468
|
+
key: mediaKeySchema.describe("Full storage key of the asset."),
|
|
1469
|
+
confirm: z15.literal(true).describe(confirmDescription)
|
|
1448
1470
|
}
|
|
1449
1471
|
},
|
|
1450
1472
|
async ({ key }) => run(async () => {
|
|
1451
|
-
await client.delete(`/media/${key}`);
|
|
1473
|
+
await client.delete(`/media/${encodeMediaKey(key)}`);
|
|
1452
1474
|
return okText(`Media asset "${key}" deleted.`);
|
|
1453
1475
|
})
|
|
1454
1476
|
);
|
|
1455
1477
|
}
|
|
1456
1478
|
|
|
1457
1479
|
// src/tools/translation-memory.ts
|
|
1458
|
-
import { z as
|
|
1480
|
+
import { z as z16 } from "zod";
|
|
1459
1481
|
function registerTranslationMemoryTools(server, client) {
|
|
1460
1482
|
server.registerTool(
|
|
1461
1483
|
"list_tm",
|
|
1462
1484
|
{
|
|
1463
1485
|
description: "List translation-memory entries, optionally filtered by source/target language.",
|
|
1464
1486
|
inputSchema: {
|
|
1465
|
-
source:
|
|
1466
|
-
target:
|
|
1487
|
+
source: z16.string().optional().describe("Source language code."),
|
|
1488
|
+
target: z16.string().optional().describe("Target language code.")
|
|
1467
1489
|
}
|
|
1468
1490
|
},
|
|
1469
1491
|
async (args) => run(
|
|
@@ -1475,14 +1497,14 @@ function registerTranslationMemoryTools(server, client) {
|
|
|
1475
1497
|
{
|
|
1476
1498
|
description: "Add or update a translation-memory entry.",
|
|
1477
1499
|
inputSchema: {
|
|
1478
|
-
sourceLang:
|
|
1479
|
-
targetLang:
|
|
1480
|
-
sourceText:
|
|
1481
|
-
targetText:
|
|
1482
|
-
context:
|
|
1483
|
-
quality:
|
|
1484
|
-
source:
|
|
1485
|
-
provider:
|
|
1500
|
+
sourceLang: z16.string().min(2),
|
|
1501
|
+
targetLang: z16.string().min(2),
|
|
1502
|
+
sourceText: z16.string().min(1),
|
|
1503
|
+
targetText: z16.string().min(1),
|
|
1504
|
+
context: z16.string().optional(),
|
|
1505
|
+
quality: z16.number().min(0).max(100).optional(),
|
|
1506
|
+
source: z16.enum(["human", "mt", "imported"]).optional(),
|
|
1507
|
+
provider: z16.string().optional()
|
|
1486
1508
|
}
|
|
1487
1509
|
},
|
|
1488
1510
|
async (input) => run(() => client.post("/tm", input))
|
|
@@ -1492,10 +1514,10 @@ function registerTranslationMemoryTools(server, client) {
|
|
|
1492
1514
|
{
|
|
1493
1515
|
description: "Fuzzy-match a query string against translation memory for a language pair.",
|
|
1494
1516
|
inputSchema: {
|
|
1495
|
-
query:
|
|
1496
|
-
sourceLang:
|
|
1497
|
-
targetLang:
|
|
1498
|
-
threshold:
|
|
1517
|
+
query: z16.string().min(1),
|
|
1518
|
+
sourceLang: z16.string().min(2),
|
|
1519
|
+
targetLang: z16.string().min(2),
|
|
1520
|
+
threshold: z16.number().min(0).max(100).optional().describe("Minimum match score (default 75).")
|
|
1499
1521
|
}
|
|
1500
1522
|
},
|
|
1501
1523
|
async (input) => run(() => client.post("/tm/lookup", input))
|
|
@@ -1505,10 +1527,10 @@ function registerTranslationMemoryTools(server, client) {
|
|
|
1505
1527
|
{
|
|
1506
1528
|
description: "Run the full translation pipeline (TM + glossary + MT provider) for a text.",
|
|
1507
1529
|
inputSchema: {
|
|
1508
|
-
text:
|
|
1509
|
-
from:
|
|
1510
|
-
to:
|
|
1511
|
-
provider:
|
|
1530
|
+
text: z16.string().min(1),
|
|
1531
|
+
from: z16.string().min(2),
|
|
1532
|
+
to: z16.string().min(2),
|
|
1533
|
+
provider: z16.string().optional()
|
|
1512
1534
|
}
|
|
1513
1535
|
},
|
|
1514
1536
|
async (input) => run(() => client.post("/tm/translate", input))
|
|
@@ -1516,7 +1538,7 @@ function registerTranslationMemoryTools(server, client) {
|
|
|
1516
1538
|
}
|
|
1517
1539
|
|
|
1518
1540
|
// src/tools/users-teams.ts
|
|
1519
|
-
import { z as
|
|
1541
|
+
import { z as z17 } from "zod";
|
|
1520
1542
|
function registerUsersTeamsTools(server, client) {
|
|
1521
1543
|
server.registerTool(
|
|
1522
1544
|
"list_users",
|
|
@@ -1525,16 +1547,16 @@ function registerUsersTeamsTools(server, client) {
|
|
|
1525
1547
|
);
|
|
1526
1548
|
server.registerTool(
|
|
1527
1549
|
"get_user",
|
|
1528
|
-
{ description: "Get a single user in the active site by id.", inputSchema: { id:
|
|
1529
|
-
async ({ id }) => run(() => client.get(`/users/${id}`))
|
|
1550
|
+
{ description: "Get a single user in the active site by id.", inputSchema: { id: idPathSegmentSchema } },
|
|
1551
|
+
async ({ id }) => run(() => client.get(`/users/${encodePathSegment(id)}`))
|
|
1530
1552
|
);
|
|
1531
1553
|
server.registerTool(
|
|
1532
1554
|
"invite_user",
|
|
1533
1555
|
{
|
|
1534
1556
|
description: "Invite a user to the site by email, optionally assigning a role. Sends an invite email.",
|
|
1535
1557
|
inputSchema: {
|
|
1536
|
-
email:
|
|
1537
|
-
roleId:
|
|
1558
|
+
email: z17.string().email(),
|
|
1559
|
+
roleId: z17.string().optional()
|
|
1538
1560
|
}
|
|
1539
1561
|
},
|
|
1540
1562
|
async (input) => run(() => client.post("/users/invite", input))
|
|
@@ -1544,21 +1566,21 @@ function registerUsersTeamsTools(server, client) {
|
|
|
1544
1566
|
{
|
|
1545
1567
|
description: "Update a user's site membership (role and/or status).",
|
|
1546
1568
|
inputSchema: {
|
|
1547
|
-
id:
|
|
1548
|
-
roleId:
|
|
1549
|
-
status:
|
|
1569
|
+
id: idPathSegmentSchema,
|
|
1570
|
+
roleId: z17.string().nullable().optional(),
|
|
1571
|
+
status: z17.string().optional().describe("e.g. active, suspended.")
|
|
1550
1572
|
}
|
|
1551
1573
|
},
|
|
1552
|
-
async ({ id, ...patch }) => run(() => client.patch(`/users/${id}`, patch))
|
|
1574
|
+
async ({ id, ...patch }) => run(() => client.patch(`/users/${encodePathSegment(id)}`, patch))
|
|
1553
1575
|
);
|
|
1554
1576
|
server.registerTool(
|
|
1555
1577
|
"remove_user",
|
|
1556
1578
|
{
|
|
1557
1579
|
description: "Remove a user from the site. DESTRUCTIVE \u2014 pass confirm=true.",
|
|
1558
|
-
inputSchema: { id:
|
|
1580
|
+
inputSchema: { id: idPathSegmentSchema, confirm: z17.literal(true).describe(confirmDescription) }
|
|
1559
1581
|
},
|
|
1560
1582
|
async ({ id }) => run(async () => {
|
|
1561
|
-
await client.delete(`/users/${id}`);
|
|
1583
|
+
await client.delete(`/users/${encodePathSegment(id)}`);
|
|
1562
1584
|
return okText(`User "${id}" removed from the site.`);
|
|
1563
1585
|
})
|
|
1564
1586
|
);
|
|
@@ -1569,14 +1591,14 @@ function registerUsersTeamsTools(server, client) {
|
|
|
1569
1591
|
);
|
|
1570
1592
|
server.registerTool(
|
|
1571
1593
|
"get_team",
|
|
1572
|
-
{ description: "Get a single team by id.", inputSchema: { id:
|
|
1573
|
-
async ({ id }) => run(() => client.get(`/teams/${id}`))
|
|
1594
|
+
{ description: "Get a single team by id.", inputSchema: { id: idPathSegmentSchema } },
|
|
1595
|
+
async ({ id }) => run(() => client.get(`/teams/${encodePathSegment(id)}`))
|
|
1574
1596
|
);
|
|
1575
1597
|
server.registerTool(
|
|
1576
1598
|
"create_team",
|
|
1577
1599
|
{
|
|
1578
1600
|
description: "Create a team.",
|
|
1579
|
-
inputSchema: { name:
|
|
1601
|
+
inputSchema: { name: z17.string().min(1).max(128), description: z17.string().nullable().optional() }
|
|
1580
1602
|
},
|
|
1581
1603
|
async (input) => run(() => client.post("/teams", input))
|
|
1582
1604
|
);
|
|
@@ -1585,64 +1607,64 @@ function registerUsersTeamsTools(server, client) {
|
|
|
1585
1607
|
{
|
|
1586
1608
|
description: "Update a team (partial PATCH).",
|
|
1587
1609
|
inputSchema: {
|
|
1588
|
-
id:
|
|
1589
|
-
name:
|
|
1590
|
-
description:
|
|
1610
|
+
id: idPathSegmentSchema,
|
|
1611
|
+
name: z17.string().min(1).max(128).optional(),
|
|
1612
|
+
description: z17.string().nullable().optional()
|
|
1591
1613
|
}
|
|
1592
1614
|
},
|
|
1593
|
-
async ({ id, ...patch }) => run(() => client.patch(`/teams/${id}`, patch))
|
|
1615
|
+
async ({ id, ...patch }) => run(() => client.patch(`/teams/${encodePathSegment(id)}`, patch))
|
|
1594
1616
|
);
|
|
1595
1617
|
server.registerTool(
|
|
1596
1618
|
"delete_team",
|
|
1597
1619
|
{
|
|
1598
1620
|
description: "Delete a team. DESTRUCTIVE \u2014 pass confirm=true.",
|
|
1599
|
-
inputSchema: { id:
|
|
1621
|
+
inputSchema: { id: idPathSegmentSchema, confirm: z17.literal(true).describe(confirmDescription) }
|
|
1600
1622
|
},
|
|
1601
1623
|
async ({ id }) => run(async () => {
|
|
1602
|
-
await client.delete(`/teams/${id}`);
|
|
1624
|
+
await client.delete(`/teams/${encodePathSegment(id)}`);
|
|
1603
1625
|
return okText(`Team "${id}" deleted.`);
|
|
1604
1626
|
})
|
|
1605
1627
|
);
|
|
1606
1628
|
server.registerTool(
|
|
1607
1629
|
"list_team_members",
|
|
1608
|
-
{ description: "List members of a team.", inputSchema: { id:
|
|
1609
|
-
async ({ id }) => run(() => client.get(`/teams/${id}/members`))
|
|
1630
|
+
{ description: "List members of a team.", inputSchema: { id: idPathSegmentSchema.describe("Team id.") } },
|
|
1631
|
+
async ({ id }) => run(() => client.get(`/teams/${encodePathSegment(id)}/members`))
|
|
1610
1632
|
);
|
|
1611
1633
|
server.registerTool(
|
|
1612
1634
|
"add_team_member",
|
|
1613
1635
|
{
|
|
1614
1636
|
description: "Add a user to a team.",
|
|
1615
|
-
inputSchema: { id:
|
|
1637
|
+
inputSchema: { id: idPathSegmentSchema.describe("Team id."), userId: idPathSegmentSchema }
|
|
1616
1638
|
},
|
|
1617
|
-
async ({ id, userId }) => run(() => client.post(`/teams/${id}/members`, { userId }))
|
|
1639
|
+
async ({ id, userId }) => run(() => client.post(`/teams/${encodePathSegment(id)}/members`, { userId }))
|
|
1618
1640
|
);
|
|
1619
1641
|
server.registerTool(
|
|
1620
1642
|
"remove_team_member",
|
|
1621
1643
|
{
|
|
1622
1644
|
description: "Remove a user from a team. DESTRUCTIVE \u2014 pass confirm=true.",
|
|
1623
1645
|
inputSchema: {
|
|
1624
|
-
id:
|
|
1625
|
-
userId:
|
|
1626
|
-
confirm:
|
|
1646
|
+
id: idPathSegmentSchema.describe("Team id."),
|
|
1647
|
+
userId: idPathSegmentSchema,
|
|
1648
|
+
confirm: z17.literal(true).describe(confirmDescription)
|
|
1627
1649
|
}
|
|
1628
1650
|
},
|
|
1629
1651
|
async ({ id, userId }) => run(async () => {
|
|
1630
|
-
await client.delete(`/teams/${id}/members/${userId}`);
|
|
1652
|
+
await client.delete(`/teams/${encodePathSegment(id)}/members/${encodePathSegment(userId)}`);
|
|
1631
1653
|
return okText(`User "${userId}" removed from team "${id}".`);
|
|
1632
1654
|
})
|
|
1633
1655
|
);
|
|
1634
1656
|
}
|
|
1635
1657
|
|
|
1636
1658
|
// src/tools/webhooks.ts
|
|
1637
|
-
import { z as
|
|
1638
|
-
var webhookSchema =
|
|
1639
|
-
name:
|
|
1640
|
-
url:
|
|
1641
|
-
actions:
|
|
1642
|
-
collections:
|
|
1643
|
-
headers:
|
|
1644
|
-
status:
|
|
1645
|
-
secret:
|
|
1659
|
+
import { z as z18 } from "zod";
|
|
1660
|
+
var webhookSchema = z18.object({
|
|
1661
|
+
name: z18.string().min(1).max(255),
|
|
1662
|
+
url: z18.string().url(),
|
|
1663
|
+
actions: z18.array(z18.string()).optional().describe("Item events that trigger the webhook (e.g. create, update, delete)."),
|
|
1664
|
+
collections: z18.array(z18.string()).optional().describe("Collections to filter on (empty = all)."),
|
|
1665
|
+
headers: z18.record(z18.string()).optional(),
|
|
1666
|
+
status: z18.enum(["active", "inactive"]).optional(),
|
|
1667
|
+
secret: z18.string().nullable().optional()
|
|
1646
1668
|
});
|
|
1647
1669
|
function registerWebhookTools(server, client) {
|
|
1648
1670
|
registerCrud(server, client, {
|