@centrali-io/centrali-mcp 4.2.4 → 4.2.6

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.
@@ -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, webhook).", {
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", "webhook"])
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
- timeout: zod_1.z.number().optional().describe("Execution timeout in milliseconds (default: 30000)"),
162
- }, (_a) => __awaiter(this, [_a], void 0, function* ({ name, slug, code, description, timeout }) {
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, slug, code };
163
+ const input = { name, code };
165
164
  if (description !== undefined)
166
165
  input.description = description;
167
- if (timeout !== undefined)
168
- input.timeout = timeout;
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 '${slug}'`),
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
- timeout: zod_1.z.number().optional().describe("Updated execution timeout in milliseconds"),
194
- }, (_a) => __awaiter(this, [_a], void 0, function* ({ functionId, name, description, code, timeout }) {
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 (timeout !== undefined)
204
- input.timeout = timeout;
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
- input: zod_1.z
251
+ params: zod_1.z
253
252
  .record(zod_1.z.string(), zod_1.z.any())
254
253
  .optional()
255
- .describe("Optional input data passed to the function as ctx.input"),
256
- }, (_a) => __awaiter(this, [_a], void 0, function* ({ code, input }) {
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 (input !== undefined)
260
- testInput.input = input;
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", "webhook"])
309
- .describe("How the trigger fires: on-demand (manual), event-driven (data events), scheduled (cron), or webhook (HTTP)"),
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 webhook: auto-generated URL."),
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 {
@@ -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, webhook).",
65
+ summary: "Server-side JavaScript functions with triggers (on-demand, event-driven, scheduled, http-trigger).",
66
66
  describeWith: "describe_compute",
67
67
  tools: [
68
68
  "list_functions",
@@ -211,8 +211,8 @@ function registerDescribeTools(server) {
211
211
  },
212
212
  crud_tools: {
213
213
  create_collection: {
214
- description: "Create a new collection with name, slug, properties, and optional settings",
215
- required_params: ["name", "slug"],
214
+ description: "Create a new collection with name, recordSlug, properties, and optional settings",
215
+ required_params: ["name", "recordSlug"],
216
216
  optional_params: ["description", "properties", "enableVersioning", "schemaDiscoveryMode", "tags"],
217
217
  },
218
218
  update_collection: {
@@ -369,11 +369,14 @@ function registerDescribeTools(server) {
369
369
  function_shape: {
370
370
  id: "UUID",
371
371
  name: "string — display name",
372
- slug: "string — unique identifier",
373
372
  description: "string | null",
374
373
  code: "string — the JavaScript source code",
375
- status: "'active' | 'inactive'",
376
- testPayload: "object | null — sample payload for testing",
374
+ timeoutMs: "number | null — execution timeout in milliseconds (default: 30000, max: 300000)",
375
+ workspaceSlug: "string",
376
+ createdBy: "UUID",
377
+ updatedBy: "UUID | null",
378
+ createdAt: "ISO 8601 datetime",
379
+ updatedAt: "ISO 8601 datetime",
377
380
  },
378
381
  trigger_types: {
379
382
  "on-demand": {
@@ -398,18 +401,24 @@ function registerDescribeTools(server) {
398
401
  description: "Runs on a cron schedule (e.g., every hour, daily at midnight).",
399
402
  config: "Uses standard cron expression syntax (e.g., '0 * * * *' for hourly)",
400
403
  },
401
- webhook: {
404
+ "http-trigger": {
402
405
  description: "Triggered by an external HTTP POST to a generated webhook URL.",
403
- config: "Each webhook trigger gets a unique URL to share with external services",
406
+ config: "Each http-trigger gets a unique URL to share with external services",
404
407
  },
405
408
  },
406
409
  trigger_shape: {
407
410
  id: "UUID",
408
411
  name: "string",
412
+ description: "string | null",
409
413
  functionId: "UUID — the compute function to execute",
410
- executionType: "'on-demand' | 'event-driven' | 'scheduled' | 'webhook'",
411
- status: "'active' | 'paused'",
412
- config: "objecttype-specific configuration (cron, event filters, etc.)",
414
+ executionType: "'on-demand' | 'event-driven' | 'scheduled' | 'http-trigger'",
415
+ triggerMetadata: "object type-specific configuration (event, cron, params, etc.)",
416
+ enabled: "booleanwhether the trigger is active (default: true)",
417
+ workspaceSlug: "string",
418
+ createdBy: "UUID",
419
+ updatedBy: "UUID",
420
+ createdAt: "ISO 8601 datetime",
421
+ updatedAt: "ISO 8601 datetime",
413
422
  },
414
423
  function_crud: {
415
424
  get_function: {
@@ -418,14 +427,14 @@ function registerDescribeTools(server) {
418
427
  },
419
428
  create_function: {
420
429
  description: "Create a new compute function",
421
- required_params: ["name", "slug", "code"],
422
- optional_params: ["description", "timeout"],
430
+ required_params: ["name", "code"],
431
+ optional_params: ["description", "timeoutMs"],
423
432
  code_format: "module.exports = async (ctx) => { /* your code */ return result; }",
424
433
  },
425
434
  update_function: {
426
435
  description: "Update an existing function. Partial updates supported.",
427
436
  required_params: ["functionId"],
428
- optional_params: ["name", "description", "code", "timeout"],
437
+ optional_params: ["name", "description", "code", "timeoutMs"],
429
438
  },
430
439
  delete_function: {
431
440
  description: "Delete a compute function by ID",
@@ -434,7 +443,7 @@ function registerDescribeTools(server) {
434
443
  test_function: {
435
444
  description: "Test execute code without saving. Returns output, duration, and logs.",
436
445
  required_params: ["code"],
437
- optional_params: ["input"],
446
+ optional_params: ["params", "timeoutMs"],
438
447
  },
439
448
  },
440
449
  trigger_crud: {
@@ -469,6 +478,16 @@ function registerDescribeTools(server) {
469
478
  required_params: ["triggerId"],
470
479
  },
471
480
  },
481
+ sandbox_api: {
482
+ description: "Functions receive an `api` object with built-in utilities. Key crypto methods:",
483
+ crypto: {
484
+ "api.crypto.sha256(data)": "SHA256 hash → base64 string",
485
+ "api.crypto.hmacSha256(key, data, options?)": "HMAC-SHA256 → base64 string. options: { keyEncoding: 'utf8' | 'base64' }",
486
+ "api.crypto.rsaSign(privateKeyPem, data, algorithm?)": "RSA signature → base64url string. algorithm: 'RS256' (default), 'RS384', 'RS512'",
487
+ "api.crypto.signJwt(privateKeyPem, payload, options?)": "Build + sign a JWT → 'header.payload.signature'. options: { algorithm, expiresIn (seconds), issuer }",
488
+ },
489
+ note: "Private keys should be stored as encrypted trigger params. signJwt automatically sets iat and supports RS256/RS384/RS512.",
490
+ },
472
491
  tips: [
473
492
  "Use list_functions to see all available functions",
474
493
  "Use list_triggers to see how functions are wired to execution events",
@@ -477,6 +496,7 @@ function registerDescribeTools(server) {
477
496
  "Use pause_trigger/resume_trigger to temporarily disable triggers without deleting them",
478
497
  "Use test_function to validate code before creating or updating a function",
479
498
  "Use create_function + create_trigger together to set up a complete compute pipeline",
499
+ "Use api.crypto.signJwt() for GitHub App, Google Cloud, or Azure AD authentication flows",
480
500
  ],
481
501
  }, null, 2),
482
502
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centrali-io/centrali-mcp",
3
- "version": "4.2.4",
3
+ "version": "4.2.6",
4
4
  "description": "Centrali MCP Server - AI assistant integration for Centrali workspaces",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",
@@ -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, webhook).",
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", "webhook"])
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
- timeout: z.number().optional().describe("Execution timeout in milliseconds (default: 30000)"),
179
+ timeoutMs: z.number().optional().describe("Execution timeout in milliseconds (default: 30000, min: 1000, max: 300000)"),
181
180
  },
182
- async ({ name, slug, code, description, timeout }) => {
181
+ async ({ name, code, description, timeoutMs }) => {
183
182
  try {
184
- const input: Record<string, any> = { name, slug, code };
183
+ const input: Record<string, any> = { name, code };
185
184
  if (description !== undefined) input.description = description;
186
- if (timeout !== undefined) input.timeout = timeout;
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 '${slug}'`),
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
- timeout: z.number().optional().describe("Updated execution timeout in milliseconds"),
215
+ timeoutMs: z.number().optional().describe("Updated execution timeout in milliseconds (min: 1000, max: 300000)"),
217
216
  },
218
- async ({ functionId, name, description, code, timeout }) => {
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 (timeout !== undefined) input.timeout = timeout;
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
- input: z
281
+ params: z
283
282
  .record(z.string(), z.any())
284
283
  .optional()
285
- .describe("Optional input data passed to the function as ctx.input"),
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, input }) => {
287
+ async ({ code, params, timeoutMs }) => {
288
288
  try {
289
289
  const testInput: Record<string, any> = { code };
290
- if (input !== undefined) testInput.input = input;
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", "webhook"])
350
- .describe("How the trigger fires: on-demand (manual), event-driven (data events), scheduled (cron), or webhook (HTTP)"),
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 webhook: auto-generated URL."),
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 }) => {
@@ -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, webhook).",
65
+ "Server-side JavaScript functions with triggers (on-demand, event-driven, scheduled, http-trigger).",
66
66
  describeWith: "describe_compute",
67
67
  tools: [
68
68
  "list_functions",
@@ -239,8 +239,8 @@ export function registerDescribeTools(server: McpServer) {
239
239
  },
240
240
  crud_tools: {
241
241
  create_collection: {
242
- description: "Create a new collection with name, slug, properties, and optional settings",
243
- required_params: ["name", "slug"],
242
+ description: "Create a new collection with name, recordSlug, properties, and optional settings",
243
+ required_params: ["name", "recordSlug"],
244
244
  optional_params: ["description", "properties", "enableVersioning", "schemaDiscoveryMode", "tags"],
245
245
  },
246
246
  update_collection: {
@@ -434,11 +434,14 @@ export function registerDescribeTools(server: McpServer) {
434
434
  function_shape: {
435
435
  id: "UUID",
436
436
  name: "string — display name",
437
- slug: "string — unique identifier",
438
437
  description: "string | null",
439
438
  code: "string — the JavaScript source code",
440
- status: "'active' | 'inactive'",
441
- testPayload: "object | null — sample payload for testing",
439
+ timeoutMs: "number | null — execution timeout in milliseconds (default: 30000, max: 300000)",
440
+ workspaceSlug: "string",
441
+ createdBy: "UUID",
442
+ updatedBy: "UUID | null",
443
+ createdAt: "ISO 8601 datetime",
444
+ updatedAt: "ISO 8601 datetime",
442
445
  },
443
446
  trigger_types: {
444
447
  "on-demand": {
@@ -467,19 +470,25 @@ export function registerDescribeTools(server: McpServer) {
467
470
  "Runs on a cron schedule (e.g., every hour, daily at midnight).",
468
471
  config: "Uses standard cron expression syntax (e.g., '0 * * * *' for hourly)",
469
472
  },
470
- webhook: {
473
+ "http-trigger": {
471
474
  description:
472
475
  "Triggered by an external HTTP POST to a generated webhook URL.",
473
- config: "Each webhook trigger gets a unique URL to share with external services",
476
+ config: "Each http-trigger gets a unique URL to share with external services",
474
477
  },
475
478
  },
476
479
  trigger_shape: {
477
480
  id: "UUID",
478
481
  name: "string",
482
+ description: "string | null",
479
483
  functionId: "UUID — the compute function to execute",
480
- executionType: "'on-demand' | 'event-driven' | 'scheduled' | 'webhook'",
481
- status: "'active' | 'paused'",
482
- config: "objecttype-specific configuration (cron, event filters, etc.)",
484
+ executionType: "'on-demand' | 'event-driven' | 'scheduled' | 'http-trigger'",
485
+ triggerMetadata: "object type-specific configuration (event, cron, params, etc.)",
486
+ enabled: "booleanwhether the trigger is active (default: true)",
487
+ workspaceSlug: "string",
488
+ createdBy: "UUID",
489
+ updatedBy: "UUID",
490
+ createdAt: "ISO 8601 datetime",
491
+ updatedAt: "ISO 8601 datetime",
483
492
  },
484
493
  function_crud: {
485
494
  get_function: {
@@ -488,14 +497,14 @@ export function registerDescribeTools(server: McpServer) {
488
497
  },
489
498
  create_function: {
490
499
  description: "Create a new compute function",
491
- required_params: ["name", "slug", "code"],
492
- optional_params: ["description", "timeout"],
500
+ required_params: ["name", "code"],
501
+ optional_params: ["description", "timeoutMs"],
493
502
  code_format: "module.exports = async (ctx) => { /* your code */ return result; }",
494
503
  },
495
504
  update_function: {
496
505
  description: "Update an existing function. Partial updates supported.",
497
506
  required_params: ["functionId"],
498
- optional_params: ["name", "description", "code", "timeout"],
507
+ optional_params: ["name", "description", "code", "timeoutMs"],
499
508
  },
500
509
  delete_function: {
501
510
  description: "Delete a compute function by ID",
@@ -504,7 +513,7 @@ export function registerDescribeTools(server: McpServer) {
504
513
  test_function: {
505
514
  description: "Test execute code without saving. Returns output, duration, and logs.",
506
515
  required_params: ["code"],
507
- optional_params: ["input"],
516
+ optional_params: ["params", "timeoutMs"],
508
517
  },
509
518
  },
510
519
  trigger_crud: {
@@ -539,6 +548,16 @@ export function registerDescribeTools(server: McpServer) {
539
548
  required_params: ["triggerId"],
540
549
  },
541
550
  },
551
+ sandbox_api: {
552
+ description: "Functions receive an `api` object with built-in utilities. Key crypto methods:",
553
+ crypto: {
554
+ "api.crypto.sha256(data)": "SHA256 hash → base64 string",
555
+ "api.crypto.hmacSha256(key, data, options?)": "HMAC-SHA256 → base64 string. options: { keyEncoding: 'utf8' | 'base64' }",
556
+ "api.crypto.rsaSign(privateKeyPem, data, algorithm?)": "RSA signature → base64url string. algorithm: 'RS256' (default), 'RS384', 'RS512'",
557
+ "api.crypto.signJwt(privateKeyPem, payload, options?)": "Build + sign a JWT → 'header.payload.signature'. options: { algorithm, expiresIn (seconds), issuer }",
558
+ },
559
+ note: "Private keys should be stored as encrypted trigger params. signJwt automatically sets iat and supports RS256/RS384/RS512.",
560
+ },
542
561
  tips: [
543
562
  "Use list_functions to see all available functions",
544
563
  "Use list_triggers to see how functions are wired to execution events",
@@ -547,6 +566,7 @@ export function registerDescribeTools(server: McpServer) {
547
566
  "Use pause_trigger/resume_trigger to temporarily disable triggers without deleting them",
548
567
  "Use test_function to validate code before creating or updating a function",
549
568
  "Use create_function + create_trigger together to set up a complete compute pipeline",
569
+ "Use api.crypto.signJwt() for GitHub App, Google Cloud, or Azure AD authentication flows",
550
570
  ],
551
571
  },
552
572
  null,