@centrali-io/centrali-mcp 4.2.5 → 4.2.7
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/tools/compute.js +94 -21
- package/dist/tools/describe.js +52 -15
- package/package.json +1 -1
- package/src/tools/compute.ts +106 -18
- package/src/tools/describe.ts +52 -15
package/dist/tools/compute.js
CHANGED
|
@@ -63,9 +63,9 @@ function registerComputeTools(server, sdk) {
|
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
}));
|
|
66
|
-
server.tool("list_triggers", "List function triggers in the workspace. Triggers define how and when compute functions are executed (on-demand, event-driven, scheduled,
|
|
66
|
+
server.tool("list_triggers", "List function triggers in the workspace. Triggers define how and when compute functions are executed (on-demand, event-driven, scheduled, http-trigger).", {
|
|
67
67
|
executionType: zod_1.z
|
|
68
|
-
.enum(["on-demand", "event-driven", "scheduled", "
|
|
68
|
+
.enum(["on-demand", "event-driven", "scheduled", "http-trigger"])
|
|
69
69
|
.optional()
|
|
70
70
|
.describe("Filter by trigger execution type"),
|
|
71
71
|
page: zod_1.z.number().optional().describe("Page number"),
|
|
@@ -155,17 +155,16 @@ function registerComputeTools(server, sdk) {
|
|
|
155
155
|
}));
|
|
156
156
|
server.tool("create_function", "Create a new compute function. Compute functions are JavaScript code blocks that run server-side.", {
|
|
157
157
|
name: zod_1.z.string().describe("Display name for the function"),
|
|
158
|
-
slug: zod_1.z.string().describe("URL-safe unique identifier (e.g., 'process-order')"),
|
|
159
158
|
code: zod_1.z.string().describe("JavaScript source code. Must export an async function: module.exports = async (ctx) => { ... }"),
|
|
160
159
|
description: zod_1.z.string().optional().describe("Optional description of what the function does"),
|
|
161
|
-
|
|
162
|
-
}, (_a) => __awaiter(this, [_a], void 0, function* ({ name,
|
|
160
|
+
timeoutMs: zod_1.z.number().optional().describe("Execution timeout in milliseconds (default: 30000, min: 1000, max: 300000)"),
|
|
161
|
+
}, (_a) => __awaiter(this, [_a], void 0, function* ({ name, code, description, timeoutMs }) {
|
|
163
162
|
try {
|
|
164
|
-
const input = { name,
|
|
163
|
+
const input = { name, code };
|
|
165
164
|
if (description !== undefined)
|
|
166
165
|
input.description = description;
|
|
167
|
-
if (
|
|
168
|
-
input.
|
|
166
|
+
if (timeoutMs !== undefined)
|
|
167
|
+
input.timeoutMs = timeoutMs;
|
|
169
168
|
const result = yield sdk.functions.create(input);
|
|
170
169
|
return {
|
|
171
170
|
content: [
|
|
@@ -178,7 +177,7 @@ function registerComputeTools(server, sdk) {
|
|
|
178
177
|
content: [
|
|
179
178
|
{
|
|
180
179
|
type: "text",
|
|
181
|
-
text: formatError(error, `creating function '${
|
|
180
|
+
text: formatError(error, `creating function '${name}'`),
|
|
182
181
|
},
|
|
183
182
|
],
|
|
184
183
|
isError: true,
|
|
@@ -190,8 +189,8 @@ function registerComputeTools(server, sdk) {
|
|
|
190
189
|
name: zod_1.z.string().optional().describe("Updated display name"),
|
|
191
190
|
description: zod_1.z.string().optional().describe("Updated description"),
|
|
192
191
|
code: zod_1.z.string().optional().describe("Updated JavaScript source code"),
|
|
193
|
-
|
|
194
|
-
}, (_a) => __awaiter(this, [_a], void 0, function* ({ functionId, name, description, code,
|
|
192
|
+
timeoutMs: zod_1.z.number().optional().describe("Updated execution timeout in milliseconds (min: 1000, max: 300000)"),
|
|
193
|
+
}, (_a) => __awaiter(this, [_a], void 0, function* ({ functionId, name, description, code, timeoutMs }) {
|
|
195
194
|
try {
|
|
196
195
|
const input = {};
|
|
197
196
|
if (name !== undefined)
|
|
@@ -200,8 +199,8 @@ function registerComputeTools(server, sdk) {
|
|
|
200
199
|
input.description = description;
|
|
201
200
|
if (code !== undefined)
|
|
202
201
|
input.code = code;
|
|
203
|
-
if (
|
|
204
|
-
input.
|
|
202
|
+
if (timeoutMs !== undefined)
|
|
203
|
+
input.timeoutMs = timeoutMs;
|
|
205
204
|
const result = yield sdk.functions.update(functionId, input);
|
|
206
205
|
return {
|
|
207
206
|
content: [
|
|
@@ -249,15 +248,18 @@ function registerComputeTools(server, sdk) {
|
|
|
249
248
|
}));
|
|
250
249
|
server.tool("test_function", "Test execute code without saving it as a function. Useful for validating function code before creating or updating.", {
|
|
251
250
|
code: zod_1.z.string().describe("JavaScript code to test. Must export an async function: module.exports = async (ctx) => { ... }"),
|
|
252
|
-
|
|
251
|
+
params: zod_1.z
|
|
253
252
|
.record(zod_1.z.string(), zod_1.z.any())
|
|
254
253
|
.optional()
|
|
255
|
-
.describe("Optional
|
|
256
|
-
|
|
254
|
+
.describe("Optional parameters passed to the function as executionParams"),
|
|
255
|
+
timeoutMs: zod_1.z.number().optional().describe("Execution timeout in milliseconds (default: 30000, min: 1000, max: 300000)"),
|
|
256
|
+
}, (_a) => __awaiter(this, [_a], void 0, function* ({ code, params, timeoutMs }) {
|
|
257
257
|
try {
|
|
258
258
|
const testInput = { code };
|
|
259
|
-
if (
|
|
260
|
-
testInput.
|
|
259
|
+
if (params !== undefined)
|
|
260
|
+
testInput.params = params;
|
|
261
|
+
if (timeoutMs !== undefined)
|
|
262
|
+
testInput.timeoutMs = timeoutMs;
|
|
261
263
|
const result = yield sdk.functions.testExecute(testInput);
|
|
262
264
|
return {
|
|
263
265
|
content: [
|
|
@@ -305,13 +307,13 @@ function registerComputeTools(server, sdk) {
|
|
|
305
307
|
name: zod_1.z.string().describe("Display name for the trigger"),
|
|
306
308
|
functionId: zod_1.z.string().describe("The compute function ID (UUID) to execute"),
|
|
307
309
|
executionType: zod_1.z
|
|
308
|
-
.enum(["on-demand", "event-driven", "scheduled", "
|
|
309
|
-
.describe("How the trigger fires: on-demand (manual), event-driven (data events), scheduled (cron), or
|
|
310
|
+
.enum(["on-demand", "event-driven", "scheduled", "http-trigger"])
|
|
311
|
+
.describe("How the trigger fires: on-demand (manual), event-driven (data events), scheduled (cron), or http-trigger (external HTTP POST)"),
|
|
310
312
|
description: zod_1.z.string().optional().describe("Optional description"),
|
|
311
313
|
triggerMetadata: zod_1.z
|
|
312
314
|
.record(zod_1.z.string(), zod_1.z.any())
|
|
313
315
|
.optional()
|
|
314
|
-
.describe("Type-specific configuration. For event-driven: { event, recordSlug }. For scheduled: { scheduleType, cronExpression, timezone }. For
|
|
316
|
+
.describe("Type-specific configuration. For event-driven: { event, recordSlug }. For scheduled: { scheduleType, cronExpression, timezone }. For http-trigger: auto-generated URL."),
|
|
315
317
|
enabled: zod_1.z.boolean().optional().describe("Whether the trigger is enabled (default: true)"),
|
|
316
318
|
}, (_a) => __awaiter(this, [_a], void 0, function* ({ name, functionId, executionType, description, triggerMetadata, enabled }) {
|
|
317
319
|
try {
|
|
@@ -452,4 +454,75 @@ function registerComputeTools(server, sdk) {
|
|
|
452
454
|
};
|
|
453
455
|
}
|
|
454
456
|
}));
|
|
457
|
+
// ── Allowed Domains tools ──────────────────────────────────────────
|
|
458
|
+
server.tool("list_allowed_domains", "List all allowed domains for compute function HTTP requests. Functions can only call external APIs on domains in this allowlist.", {}, () => __awaiter(this, void 0, void 0, function* () {
|
|
459
|
+
try {
|
|
460
|
+
const result = yield sdk.allowedDomains.list();
|
|
461
|
+
return {
|
|
462
|
+
content: [
|
|
463
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
464
|
+
],
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
catch (error) {
|
|
468
|
+
return {
|
|
469
|
+
content: [
|
|
470
|
+
{
|
|
471
|
+
type: "text",
|
|
472
|
+
text: formatError(error, "listing allowed domains"),
|
|
473
|
+
},
|
|
474
|
+
],
|
|
475
|
+
isError: true,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
}));
|
|
479
|
+
server.tool("add_allowed_domain", "Add a domain to the allowlist so compute functions can make HTTP requests to it. Supports wildcards (e.g., '*.example.com').", {
|
|
480
|
+
domain: zod_1.z.string().describe("Domain to allow (e.g., 'api.stripe.com' or '*.googleapis.com')"),
|
|
481
|
+
}, (_a) => __awaiter(this, [_a], void 0, function* ({ domain }) {
|
|
482
|
+
try {
|
|
483
|
+
const result = yield sdk.allowedDomains.add({ domain });
|
|
484
|
+
return {
|
|
485
|
+
content: [
|
|
486
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
487
|
+
],
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
catch (error) {
|
|
491
|
+
return {
|
|
492
|
+
content: [
|
|
493
|
+
{
|
|
494
|
+
type: "text",
|
|
495
|
+
text: formatError(error, `adding allowed domain '${domain}'`),
|
|
496
|
+
},
|
|
497
|
+
],
|
|
498
|
+
isError: true,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
}));
|
|
502
|
+
server.tool("remove_allowed_domain", "Remove a domain from the allowlist. Compute functions will no longer be able to call this domain.", {
|
|
503
|
+
domainId: zod_1.z.string().describe("The allowed domain ID (UUID) to remove"),
|
|
504
|
+
}, (_a) => __awaiter(this, [_a], void 0, function* ({ domainId }) {
|
|
505
|
+
try {
|
|
506
|
+
yield sdk.allowedDomains.remove(domainId);
|
|
507
|
+
return {
|
|
508
|
+
content: [
|
|
509
|
+
{
|
|
510
|
+
type: "text",
|
|
511
|
+
text: `Allowed domain '${domainId}' removed successfully.`,
|
|
512
|
+
},
|
|
513
|
+
],
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
catch (error) {
|
|
517
|
+
return {
|
|
518
|
+
content: [
|
|
519
|
+
{
|
|
520
|
+
type: "text",
|
|
521
|
+
text: formatError(error, `removing allowed domain '${domainId}'`),
|
|
522
|
+
},
|
|
523
|
+
],
|
|
524
|
+
isError: true,
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
}));
|
|
455
528
|
}
|
package/dist/tools/describe.js
CHANGED
|
@@ -62,7 +62,7 @@ function registerDescribeTools(server) {
|
|
|
62
62
|
tools: ["search_records"],
|
|
63
63
|
},
|
|
64
64
|
compute: {
|
|
65
|
-
summary: "Server-side JavaScript functions with triggers (on-demand, event-driven, scheduled,
|
|
65
|
+
summary: "Server-side JavaScript functions with triggers (on-demand, event-driven, scheduled, http-trigger) and domain allowlisting for external API calls.",
|
|
66
66
|
describeWith: "describe_compute",
|
|
67
67
|
tools: [
|
|
68
68
|
"list_functions",
|
|
@@ -79,6 +79,9 @@ function registerDescribeTools(server) {
|
|
|
79
79
|
"invoke_trigger",
|
|
80
80
|
"pause_trigger",
|
|
81
81
|
"resume_trigger",
|
|
82
|
+
"list_allowed_domains",
|
|
83
|
+
"add_allowed_domain",
|
|
84
|
+
"remove_allowed_domain",
|
|
82
85
|
],
|
|
83
86
|
},
|
|
84
87
|
smart_queries: {
|
|
@@ -211,8 +214,8 @@ function registerDescribeTools(server) {
|
|
|
211
214
|
},
|
|
212
215
|
crud_tools: {
|
|
213
216
|
create_collection: {
|
|
214
|
-
description: "Create a new collection with name,
|
|
215
|
-
required_params: ["name", "
|
|
217
|
+
description: "Create a new collection with name, recordSlug, properties, and optional settings",
|
|
218
|
+
required_params: ["name", "recordSlug"],
|
|
216
219
|
optional_params: ["description", "properties", "enableVersioning", "schemaDiscoveryMode", "tags"],
|
|
217
220
|
},
|
|
218
221
|
update_collection: {
|
|
@@ -369,11 +372,14 @@ function registerDescribeTools(server) {
|
|
|
369
372
|
function_shape: {
|
|
370
373
|
id: "UUID",
|
|
371
374
|
name: "string — display name",
|
|
372
|
-
slug: "string — unique identifier",
|
|
373
375
|
description: "string | null",
|
|
374
376
|
code: "string — the JavaScript source code",
|
|
375
|
-
|
|
376
|
-
|
|
377
|
+
timeoutMs: "number | null — execution timeout in milliseconds (default: 30000, max: 300000)",
|
|
378
|
+
workspaceSlug: "string",
|
|
379
|
+
createdBy: "UUID",
|
|
380
|
+
updatedBy: "UUID | null",
|
|
381
|
+
createdAt: "ISO 8601 datetime",
|
|
382
|
+
updatedAt: "ISO 8601 datetime",
|
|
377
383
|
},
|
|
378
384
|
trigger_types: {
|
|
379
385
|
"on-demand": {
|
|
@@ -398,18 +404,24 @@ function registerDescribeTools(server) {
|
|
|
398
404
|
description: "Runs on a cron schedule (e.g., every hour, daily at midnight).",
|
|
399
405
|
config: "Uses standard cron expression syntax (e.g., '0 * * * *' for hourly)",
|
|
400
406
|
},
|
|
401
|
-
|
|
407
|
+
"http-trigger": {
|
|
402
408
|
description: "Triggered by an external HTTP POST to a generated webhook URL.",
|
|
403
|
-
config: "Each
|
|
409
|
+
config: "Each http-trigger gets a unique URL to share with external services",
|
|
404
410
|
},
|
|
405
411
|
},
|
|
406
412
|
trigger_shape: {
|
|
407
413
|
id: "UUID",
|
|
408
414
|
name: "string",
|
|
415
|
+
description: "string | null",
|
|
409
416
|
functionId: "UUID — the compute function to execute",
|
|
410
|
-
executionType: "'on-demand' | 'event-driven' | 'scheduled' | '
|
|
411
|
-
|
|
412
|
-
|
|
417
|
+
executionType: "'on-demand' | 'event-driven' | 'scheduled' | 'http-trigger'",
|
|
418
|
+
triggerMetadata: "object — type-specific configuration (event, cron, params, etc.)",
|
|
419
|
+
enabled: "boolean — whether the trigger is active (default: true)",
|
|
420
|
+
workspaceSlug: "string",
|
|
421
|
+
createdBy: "UUID",
|
|
422
|
+
updatedBy: "UUID",
|
|
423
|
+
createdAt: "ISO 8601 datetime",
|
|
424
|
+
updatedAt: "ISO 8601 datetime",
|
|
413
425
|
},
|
|
414
426
|
function_crud: {
|
|
415
427
|
get_function: {
|
|
@@ -418,14 +430,14 @@ function registerDescribeTools(server) {
|
|
|
418
430
|
},
|
|
419
431
|
create_function: {
|
|
420
432
|
description: "Create a new compute function",
|
|
421
|
-
required_params: ["name", "
|
|
422
|
-
optional_params: ["description", "
|
|
433
|
+
required_params: ["name", "code"],
|
|
434
|
+
optional_params: ["description", "timeoutMs"],
|
|
423
435
|
code_format: "module.exports = async (ctx) => { /* your code */ return result; }",
|
|
424
436
|
},
|
|
425
437
|
update_function: {
|
|
426
438
|
description: "Update an existing function. Partial updates supported.",
|
|
427
439
|
required_params: ["functionId"],
|
|
428
|
-
optional_params: ["name", "description", "code", "
|
|
440
|
+
optional_params: ["name", "description", "code", "timeoutMs"],
|
|
429
441
|
},
|
|
430
442
|
delete_function: {
|
|
431
443
|
description: "Delete a compute function by ID",
|
|
@@ -434,7 +446,7 @@ function registerDescribeTools(server) {
|
|
|
434
446
|
test_function: {
|
|
435
447
|
description: "Test execute code without saving. Returns output, duration, and logs.",
|
|
436
448
|
required_params: ["code"],
|
|
437
|
-
optional_params: ["
|
|
449
|
+
optional_params: ["params", "timeoutMs"],
|
|
438
450
|
},
|
|
439
451
|
},
|
|
440
452
|
trigger_crud: {
|
|
@@ -469,6 +481,30 @@ function registerDescribeTools(server) {
|
|
|
469
481
|
required_params: ["triggerId"],
|
|
470
482
|
},
|
|
471
483
|
},
|
|
484
|
+
allowed_domains: {
|
|
485
|
+
description: "Workspace-level allowlist controlling which external domains compute functions can call via api.httpGet/httpPost/etc. Functions attempting to reach unlisted domains get an error.",
|
|
486
|
+
domain_shape: {
|
|
487
|
+
id: "UUID",
|
|
488
|
+
domain: "string — the allowed domain (e.g., 'api.stripe.com' or '*.googleapis.com')",
|
|
489
|
+
createdAt: "ISO 8601 datetime",
|
|
490
|
+
createdBy: "UUID",
|
|
491
|
+
},
|
|
492
|
+
tools: {
|
|
493
|
+
list_allowed_domains: {
|
|
494
|
+
description: "List all allowed domains in the workspace",
|
|
495
|
+
},
|
|
496
|
+
add_allowed_domain: {
|
|
497
|
+
description: "Add a domain to the allowlist",
|
|
498
|
+
required_params: ["domain"],
|
|
499
|
+
},
|
|
500
|
+
remove_allowed_domain: {
|
|
501
|
+
description: "Remove a domain from the allowlist by ID",
|
|
502
|
+
required_params: ["domainId"],
|
|
503
|
+
},
|
|
504
|
+
},
|
|
505
|
+
wildcards: "Use '*.example.com' to allow all subdomains of example.com",
|
|
506
|
+
note: "Functions can only make HTTP requests to domains on this list. Add domains before creating functions that call external APIs.",
|
|
507
|
+
},
|
|
472
508
|
sandbox_api: {
|
|
473
509
|
description: "Functions receive an `api` object with built-in utilities. Key crypto methods:",
|
|
474
510
|
crypto: {
|
|
@@ -488,6 +524,7 @@ function registerDescribeTools(server) {
|
|
|
488
524
|
"Use test_function to validate code before creating or updating a function",
|
|
489
525
|
"Use create_function + create_trigger together to set up a complete compute pipeline",
|
|
490
526
|
"Use api.crypto.signJwt() for GitHub App, Google Cloud, or Azure AD authentication flows",
|
|
527
|
+
"Before creating functions that call external APIs, add the target domains with add_allowed_domain",
|
|
491
528
|
],
|
|
492
529
|
}, null, 2),
|
|
493
530
|
},
|
package/package.json
CHANGED
package/src/tools/compute.ts
CHANGED
|
@@ -61,10 +61,10 @@ export function registerComputeTools(server: McpServer, sdk: CentraliSDK) {
|
|
|
61
61
|
|
|
62
62
|
server.tool(
|
|
63
63
|
"list_triggers",
|
|
64
|
-
"List function triggers in the workspace. Triggers define how and when compute functions are executed (on-demand, event-driven, scheduled,
|
|
64
|
+
"List function triggers in the workspace. Triggers define how and when compute functions are executed (on-demand, event-driven, scheduled, http-trigger).",
|
|
65
65
|
{
|
|
66
66
|
executionType: z
|
|
67
|
-
.enum(["on-demand", "event-driven", "scheduled", "
|
|
67
|
+
.enum(["on-demand", "event-driven", "scheduled", "http-trigger"])
|
|
68
68
|
.optional()
|
|
69
69
|
.describe("Filter by trigger execution type"),
|
|
70
70
|
page: z.number().optional().describe("Page number"),
|
|
@@ -174,16 +174,15 @@ export function registerComputeTools(server: McpServer, sdk: CentraliSDK) {
|
|
|
174
174
|
"Create a new compute function. Compute functions are JavaScript code blocks that run server-side.",
|
|
175
175
|
{
|
|
176
176
|
name: z.string().describe("Display name for the function"),
|
|
177
|
-
slug: z.string().describe("URL-safe unique identifier (e.g., 'process-order')"),
|
|
178
177
|
code: z.string().describe("JavaScript source code. Must export an async function: module.exports = async (ctx) => { ... }"),
|
|
179
178
|
description: z.string().optional().describe("Optional description of what the function does"),
|
|
180
|
-
|
|
179
|
+
timeoutMs: z.number().optional().describe("Execution timeout in milliseconds (default: 30000, min: 1000, max: 300000)"),
|
|
181
180
|
},
|
|
182
|
-
async ({ name,
|
|
181
|
+
async ({ name, code, description, timeoutMs }) => {
|
|
183
182
|
try {
|
|
184
|
-
const input: Record<string, any> = { name,
|
|
183
|
+
const input: Record<string, any> = { name, code };
|
|
185
184
|
if (description !== undefined) input.description = description;
|
|
186
|
-
if (
|
|
185
|
+
if (timeoutMs !== undefined) input.timeoutMs = timeoutMs;
|
|
187
186
|
|
|
188
187
|
const result = await sdk.functions.create(input as any);
|
|
189
188
|
return {
|
|
@@ -196,7 +195,7 @@ export function registerComputeTools(server: McpServer, sdk: CentraliSDK) {
|
|
|
196
195
|
content: [
|
|
197
196
|
{
|
|
198
197
|
type: "text",
|
|
199
|
-
text: formatError(error, `creating function '${
|
|
198
|
+
text: formatError(error, `creating function '${name}'`),
|
|
200
199
|
},
|
|
201
200
|
],
|
|
202
201
|
isError: true,
|
|
@@ -213,15 +212,15 @@ export function registerComputeTools(server: McpServer, sdk: CentraliSDK) {
|
|
|
213
212
|
name: z.string().optional().describe("Updated display name"),
|
|
214
213
|
description: z.string().optional().describe("Updated description"),
|
|
215
214
|
code: z.string().optional().describe("Updated JavaScript source code"),
|
|
216
|
-
|
|
215
|
+
timeoutMs: z.number().optional().describe("Updated execution timeout in milliseconds (min: 1000, max: 300000)"),
|
|
217
216
|
},
|
|
218
|
-
async ({ functionId, name, description, code,
|
|
217
|
+
async ({ functionId, name, description, code, timeoutMs }) => {
|
|
219
218
|
try {
|
|
220
219
|
const input: Record<string, any> = {};
|
|
221
220
|
if (name !== undefined) input.name = name;
|
|
222
221
|
if (description !== undefined) input.description = description;
|
|
223
222
|
if (code !== undefined) input.code = code;
|
|
224
|
-
if (
|
|
223
|
+
if (timeoutMs !== undefined) input.timeoutMs = timeoutMs;
|
|
225
224
|
|
|
226
225
|
const result = await sdk.functions.update(functionId, input as any);
|
|
227
226
|
return {
|
|
@@ -279,15 +278,17 @@ export function registerComputeTools(server: McpServer, sdk: CentraliSDK) {
|
|
|
279
278
|
"Test execute code without saving it as a function. Useful for validating function code before creating or updating.",
|
|
280
279
|
{
|
|
281
280
|
code: z.string().describe("JavaScript code to test. Must export an async function: module.exports = async (ctx) => { ... }"),
|
|
282
|
-
|
|
281
|
+
params: z
|
|
283
282
|
.record(z.string(), z.any())
|
|
284
283
|
.optional()
|
|
285
|
-
.describe("Optional
|
|
284
|
+
.describe("Optional parameters passed to the function as executionParams"),
|
|
285
|
+
timeoutMs: z.number().optional().describe("Execution timeout in milliseconds (default: 30000, min: 1000, max: 300000)"),
|
|
286
286
|
},
|
|
287
|
-
async ({ code,
|
|
287
|
+
async ({ code, params, timeoutMs }) => {
|
|
288
288
|
try {
|
|
289
289
|
const testInput: Record<string, any> = { code };
|
|
290
|
-
if (
|
|
290
|
+
if (params !== undefined) testInput.params = params;
|
|
291
|
+
if (timeoutMs !== undefined) testInput.timeoutMs = timeoutMs;
|
|
291
292
|
|
|
292
293
|
const result = await sdk.functions.testExecute(testInput as any);
|
|
293
294
|
return {
|
|
@@ -346,13 +347,13 @@ export function registerComputeTools(server: McpServer, sdk: CentraliSDK) {
|
|
|
346
347
|
name: z.string().describe("Display name for the trigger"),
|
|
347
348
|
functionId: z.string().describe("The compute function ID (UUID) to execute"),
|
|
348
349
|
executionType: z
|
|
349
|
-
.enum(["on-demand", "event-driven", "scheduled", "
|
|
350
|
-
.describe("How the trigger fires: on-demand (manual), event-driven (data events), scheduled (cron), or
|
|
350
|
+
.enum(["on-demand", "event-driven", "scheduled", "http-trigger"])
|
|
351
|
+
.describe("How the trigger fires: on-demand (manual), event-driven (data events), scheduled (cron), or http-trigger (external HTTP POST)"),
|
|
351
352
|
description: z.string().optional().describe("Optional description"),
|
|
352
353
|
triggerMetadata: z
|
|
353
354
|
.record(z.string(), z.any())
|
|
354
355
|
.optional()
|
|
355
|
-
.describe("Type-specific configuration. For event-driven: { event, recordSlug }. For scheduled: { scheduleType, cronExpression, timezone }. For
|
|
356
|
+
.describe("Type-specific configuration. For event-driven: { event, recordSlug }. For scheduled: { scheduleType, cronExpression, timezone }. For http-trigger: auto-generated URL."),
|
|
356
357
|
enabled: z.boolean().optional().describe("Whether the trigger is enabled (default: true)"),
|
|
357
358
|
},
|
|
358
359
|
async ({ name, functionId, executionType, description, triggerMetadata, enabled }) => {
|
|
@@ -509,4 +510,91 @@ export function registerComputeTools(server: McpServer, sdk: CentraliSDK) {
|
|
|
509
510
|
}
|
|
510
511
|
}
|
|
511
512
|
);
|
|
513
|
+
|
|
514
|
+
// ── Allowed Domains tools ──────────────────────────────────────────
|
|
515
|
+
|
|
516
|
+
server.tool(
|
|
517
|
+
"list_allowed_domains",
|
|
518
|
+
"List all allowed domains for compute function HTTP requests. Functions can only call external APIs on domains in this allowlist.",
|
|
519
|
+
{},
|
|
520
|
+
async () => {
|
|
521
|
+
try {
|
|
522
|
+
const result = await sdk.allowedDomains.list();
|
|
523
|
+
return {
|
|
524
|
+
content: [
|
|
525
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
526
|
+
],
|
|
527
|
+
};
|
|
528
|
+
} catch (error: unknown) {
|
|
529
|
+
return {
|
|
530
|
+
content: [
|
|
531
|
+
{
|
|
532
|
+
type: "text",
|
|
533
|
+
text: formatError(error, "listing allowed domains"),
|
|
534
|
+
},
|
|
535
|
+
],
|
|
536
|
+
isError: true,
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
);
|
|
541
|
+
|
|
542
|
+
server.tool(
|
|
543
|
+
"add_allowed_domain",
|
|
544
|
+
"Add a domain to the allowlist so compute functions can make HTTP requests to it. Supports wildcards (e.g., '*.example.com').",
|
|
545
|
+
{
|
|
546
|
+
domain: z.string().describe("Domain to allow (e.g., 'api.stripe.com' or '*.googleapis.com')"),
|
|
547
|
+
},
|
|
548
|
+
async ({ domain }) => {
|
|
549
|
+
try {
|
|
550
|
+
const result = await sdk.allowedDomains.add({ domain });
|
|
551
|
+
return {
|
|
552
|
+
content: [
|
|
553
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
554
|
+
],
|
|
555
|
+
};
|
|
556
|
+
} catch (error: unknown) {
|
|
557
|
+
return {
|
|
558
|
+
content: [
|
|
559
|
+
{
|
|
560
|
+
type: "text",
|
|
561
|
+
text: formatError(error, `adding allowed domain '${domain}'`),
|
|
562
|
+
},
|
|
563
|
+
],
|
|
564
|
+
isError: true,
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
);
|
|
569
|
+
|
|
570
|
+
server.tool(
|
|
571
|
+
"remove_allowed_domain",
|
|
572
|
+
"Remove a domain from the allowlist. Compute functions will no longer be able to call this domain.",
|
|
573
|
+
{
|
|
574
|
+
domainId: z.string().describe("The allowed domain ID (UUID) to remove"),
|
|
575
|
+
},
|
|
576
|
+
async ({ domainId }) => {
|
|
577
|
+
try {
|
|
578
|
+
await sdk.allowedDomains.remove(domainId);
|
|
579
|
+
return {
|
|
580
|
+
content: [
|
|
581
|
+
{
|
|
582
|
+
type: "text",
|
|
583
|
+
text: `Allowed domain '${domainId}' removed successfully.`,
|
|
584
|
+
},
|
|
585
|
+
],
|
|
586
|
+
};
|
|
587
|
+
} catch (error: unknown) {
|
|
588
|
+
return {
|
|
589
|
+
content: [
|
|
590
|
+
{
|
|
591
|
+
type: "text",
|
|
592
|
+
text: formatError(error, `removing allowed domain '${domainId}'`),
|
|
593
|
+
},
|
|
594
|
+
],
|
|
595
|
+
isError: true,
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
);
|
|
512
600
|
}
|
package/src/tools/describe.ts
CHANGED
|
@@ -62,7 +62,7 @@ export function registerDescribeTools(server: McpServer) {
|
|
|
62
62
|
},
|
|
63
63
|
compute: {
|
|
64
64
|
summary:
|
|
65
|
-
"Server-side JavaScript functions with triggers (on-demand, event-driven, scheduled,
|
|
65
|
+
"Server-side JavaScript functions with triggers (on-demand, event-driven, scheduled, http-trigger) and domain allowlisting for external API calls.",
|
|
66
66
|
describeWith: "describe_compute",
|
|
67
67
|
tools: [
|
|
68
68
|
"list_functions",
|
|
@@ -79,6 +79,9 @@ export function registerDescribeTools(server: McpServer) {
|
|
|
79
79
|
"invoke_trigger",
|
|
80
80
|
"pause_trigger",
|
|
81
81
|
"resume_trigger",
|
|
82
|
+
"list_allowed_domains",
|
|
83
|
+
"add_allowed_domain",
|
|
84
|
+
"remove_allowed_domain",
|
|
82
85
|
],
|
|
83
86
|
},
|
|
84
87
|
smart_queries: {
|
|
@@ -239,8 +242,8 @@ export function registerDescribeTools(server: McpServer) {
|
|
|
239
242
|
},
|
|
240
243
|
crud_tools: {
|
|
241
244
|
create_collection: {
|
|
242
|
-
description: "Create a new collection with name,
|
|
243
|
-
required_params: ["name", "
|
|
245
|
+
description: "Create a new collection with name, recordSlug, properties, and optional settings",
|
|
246
|
+
required_params: ["name", "recordSlug"],
|
|
244
247
|
optional_params: ["description", "properties", "enableVersioning", "schemaDiscoveryMode", "tags"],
|
|
245
248
|
},
|
|
246
249
|
update_collection: {
|
|
@@ -434,11 +437,14 @@ export function registerDescribeTools(server: McpServer) {
|
|
|
434
437
|
function_shape: {
|
|
435
438
|
id: "UUID",
|
|
436
439
|
name: "string — display name",
|
|
437
|
-
slug: "string — unique identifier",
|
|
438
440
|
description: "string | null",
|
|
439
441
|
code: "string — the JavaScript source code",
|
|
440
|
-
|
|
441
|
-
|
|
442
|
+
timeoutMs: "number | null — execution timeout in milliseconds (default: 30000, max: 300000)",
|
|
443
|
+
workspaceSlug: "string",
|
|
444
|
+
createdBy: "UUID",
|
|
445
|
+
updatedBy: "UUID | null",
|
|
446
|
+
createdAt: "ISO 8601 datetime",
|
|
447
|
+
updatedAt: "ISO 8601 datetime",
|
|
442
448
|
},
|
|
443
449
|
trigger_types: {
|
|
444
450
|
"on-demand": {
|
|
@@ -467,19 +473,25 @@ export function registerDescribeTools(server: McpServer) {
|
|
|
467
473
|
"Runs on a cron schedule (e.g., every hour, daily at midnight).",
|
|
468
474
|
config: "Uses standard cron expression syntax (e.g., '0 * * * *' for hourly)",
|
|
469
475
|
},
|
|
470
|
-
|
|
476
|
+
"http-trigger": {
|
|
471
477
|
description:
|
|
472
478
|
"Triggered by an external HTTP POST to a generated webhook URL.",
|
|
473
|
-
config: "Each
|
|
479
|
+
config: "Each http-trigger gets a unique URL to share with external services",
|
|
474
480
|
},
|
|
475
481
|
},
|
|
476
482
|
trigger_shape: {
|
|
477
483
|
id: "UUID",
|
|
478
484
|
name: "string",
|
|
485
|
+
description: "string | null",
|
|
479
486
|
functionId: "UUID — the compute function to execute",
|
|
480
|
-
executionType: "'on-demand' | 'event-driven' | 'scheduled' | '
|
|
481
|
-
|
|
482
|
-
|
|
487
|
+
executionType: "'on-demand' | 'event-driven' | 'scheduled' | 'http-trigger'",
|
|
488
|
+
triggerMetadata: "object — type-specific configuration (event, cron, params, etc.)",
|
|
489
|
+
enabled: "boolean — whether the trigger is active (default: true)",
|
|
490
|
+
workspaceSlug: "string",
|
|
491
|
+
createdBy: "UUID",
|
|
492
|
+
updatedBy: "UUID",
|
|
493
|
+
createdAt: "ISO 8601 datetime",
|
|
494
|
+
updatedAt: "ISO 8601 datetime",
|
|
483
495
|
},
|
|
484
496
|
function_crud: {
|
|
485
497
|
get_function: {
|
|
@@ -488,14 +500,14 @@ export function registerDescribeTools(server: McpServer) {
|
|
|
488
500
|
},
|
|
489
501
|
create_function: {
|
|
490
502
|
description: "Create a new compute function",
|
|
491
|
-
required_params: ["name", "
|
|
492
|
-
optional_params: ["description", "
|
|
503
|
+
required_params: ["name", "code"],
|
|
504
|
+
optional_params: ["description", "timeoutMs"],
|
|
493
505
|
code_format: "module.exports = async (ctx) => { /* your code */ return result; }",
|
|
494
506
|
},
|
|
495
507
|
update_function: {
|
|
496
508
|
description: "Update an existing function. Partial updates supported.",
|
|
497
509
|
required_params: ["functionId"],
|
|
498
|
-
optional_params: ["name", "description", "code", "
|
|
510
|
+
optional_params: ["name", "description", "code", "timeoutMs"],
|
|
499
511
|
},
|
|
500
512
|
delete_function: {
|
|
501
513
|
description: "Delete a compute function by ID",
|
|
@@ -504,7 +516,7 @@ export function registerDescribeTools(server: McpServer) {
|
|
|
504
516
|
test_function: {
|
|
505
517
|
description: "Test execute code without saving. Returns output, duration, and logs.",
|
|
506
518
|
required_params: ["code"],
|
|
507
|
-
optional_params: ["
|
|
519
|
+
optional_params: ["params", "timeoutMs"],
|
|
508
520
|
},
|
|
509
521
|
},
|
|
510
522
|
trigger_crud: {
|
|
@@ -539,6 +551,30 @@ export function registerDescribeTools(server: McpServer) {
|
|
|
539
551
|
required_params: ["triggerId"],
|
|
540
552
|
},
|
|
541
553
|
},
|
|
554
|
+
allowed_domains: {
|
|
555
|
+
description: "Workspace-level allowlist controlling which external domains compute functions can call via api.httpGet/httpPost/etc. Functions attempting to reach unlisted domains get an error.",
|
|
556
|
+
domain_shape: {
|
|
557
|
+
id: "UUID",
|
|
558
|
+
domain: "string — the allowed domain (e.g., 'api.stripe.com' or '*.googleapis.com')",
|
|
559
|
+
createdAt: "ISO 8601 datetime",
|
|
560
|
+
createdBy: "UUID",
|
|
561
|
+
},
|
|
562
|
+
tools: {
|
|
563
|
+
list_allowed_domains: {
|
|
564
|
+
description: "List all allowed domains in the workspace",
|
|
565
|
+
},
|
|
566
|
+
add_allowed_domain: {
|
|
567
|
+
description: "Add a domain to the allowlist",
|
|
568
|
+
required_params: ["domain"],
|
|
569
|
+
},
|
|
570
|
+
remove_allowed_domain: {
|
|
571
|
+
description: "Remove a domain from the allowlist by ID",
|
|
572
|
+
required_params: ["domainId"],
|
|
573
|
+
},
|
|
574
|
+
},
|
|
575
|
+
wildcards: "Use '*.example.com' to allow all subdomains of example.com",
|
|
576
|
+
note: "Functions can only make HTTP requests to domains on this list. Add domains before creating functions that call external APIs.",
|
|
577
|
+
},
|
|
542
578
|
sandbox_api: {
|
|
543
579
|
description: "Functions receive an `api` object with built-in utilities. Key crypto methods:",
|
|
544
580
|
crypto: {
|
|
@@ -558,6 +594,7 @@ export function registerDescribeTools(server: McpServer) {
|
|
|
558
594
|
"Use test_function to validate code before creating or updating a function",
|
|
559
595
|
"Use create_function + create_trigger together to set up a complete compute pipeline",
|
|
560
596
|
"Use api.crypto.signJwt() for GitHub App, Google Cloud, or Azure AD authentication flows",
|
|
597
|
+
"Before creating functions that call external APIs, add the target domains with add_allowed_domain",
|
|
561
598
|
],
|
|
562
599
|
},
|
|
563
600
|
null,
|