@wabery/cli 0.14.0 → 0.14.2
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/README.md +3 -3
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +181 -143
- package/dist/mcp-server.js.map +1 -1
- package/package.json +3 -3
package/dist/mcp-server.js
CHANGED
|
@@ -85,13 +85,13 @@ const toolOutputSchema = {
|
|
|
85
85
|
.record(z.string(), z.unknown())
|
|
86
86
|
.describe("The structured Wabery API result object. Its operation-specific fields are described by the tool and Wabery API documentation."),
|
|
87
87
|
};
|
|
88
|
-
const SERVER_INSTRUCTIONS = `
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
88
|
+
const SERVER_INSTRUCTIONS = `Wabery is a developer platform for building and operating WhatsApp AI agents. Start discovery with wabery_list_projects, select the intended project, then call wabery_get_project_readiness; use channel readiness only for phone-number/provider detail.
|
|
89
|
+
Use Wabery for WhatsApp contacts, opt-in, conversations and message history, approved templates, Flows, broadcasts, routing/human handoff, signed webhooks, hosted functions, and Meta Business Agent configuration.
|
|
90
|
+
Keep sandbox and production readiness distinct: the shared sandbox supports controlled tests; production inbound, proactive templates, and broadcasts require an eligible dedicated WhatsApp channel. Enroll only controlled or explicitly opted-in contacts and retain the returned contact_id and channel_id.
|
|
91
|
+
Read conversations and message history before replying. Validate and preview config before apply; config apply may replace resources but never publishes a Flow. Draft and validate Flows before separately confirming publish or send.
|
|
92
|
+
For broadcasts, create a draft with approved templates, prepare exactly one audience source, poll until ready, review recipients/exclusions, then obtain explicit confirmation before send or schedule. Preparation freezes the audience.
|
|
93
|
+
Use routing and thread-control tools for automation ownership and human handoff. Treat hosted function test/invoke as potentially side-effecting code.
|
|
94
|
+
Obtain explicit user confirmation immediately before any external or irreversible action, including sends, publishes, deletions, secret rotation, provider updates, or function execution. After sending, call wabery_get_message, wabery_get_dispatch, or wabery_get_broadcast to report provider status; acceptance is not delivery.`;
|
|
95
95
|
// The write gate differs by transport, and the model has to be told the truth
|
|
96
96
|
// about the session it is actually in: a hosted OAuth client (ChatGPT, Claude)
|
|
97
97
|
// cannot set an env var, so advertising the env gate there makes it refuse to
|
|
@@ -113,6 +113,7 @@ const MCP_SENSITIVE_OUTPUT_KEY_SUFFIXES = [
|
|
|
113
113
|
"credentials",
|
|
114
114
|
"idtoken",
|
|
115
115
|
"jwt",
|
|
116
|
+
"oauthtoken",
|
|
116
117
|
"password",
|
|
117
118
|
"passwordhash",
|
|
118
119
|
"privatekey",
|
|
@@ -350,7 +351,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
350
351
|
}));
|
|
351
352
|
registerTool("wabery_check_connection", {
|
|
352
353
|
title: "Check Wabery connection",
|
|
353
|
-
description: "
|
|
354
|
+
description: "Use this when you need to verify that the current credential can reach Wabery projects, WhatsApp channels, and the config schema before other work.",
|
|
354
355
|
inputSchema: {},
|
|
355
356
|
annotations: {
|
|
356
357
|
readOnlyHint: true,
|
|
@@ -361,7 +362,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
361
362
|
}, async () => jsonResult(await checkWaberyConnection(client)));
|
|
362
363
|
registerTool("wabery_get_config_example", {
|
|
363
364
|
title: "Get example Wabery config",
|
|
364
|
-
description: "
|
|
365
|
+
description: "Use this when you need a starter wabery.config.json with one WhatsApp Flow and one send_flow automation; optional project_id comes from wabery_list_projects.",
|
|
365
366
|
inputSchema: {
|
|
366
367
|
project_id: z
|
|
367
368
|
.string()
|
|
@@ -378,7 +379,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
378
379
|
}, async ({ project_id }) => jsonResult(createExampleConfig(project_id)));
|
|
379
380
|
registerTool("wabery_get_config_schema", {
|
|
380
381
|
title: "Get Wabery config schema",
|
|
381
|
-
description: "
|
|
382
|
+
description: "Use this when you need the current JSON Schema before generating a wabery.config.json with Flows, automations, webhooks, or business_agent declarations.",
|
|
382
383
|
inputSchema: {},
|
|
383
384
|
annotations: {
|
|
384
385
|
readOnlyHint: true,
|
|
@@ -389,7 +390,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
389
390
|
}, async () => jsonResult(await client.get("/config/schema")));
|
|
390
391
|
registerTool("wabery_export_config", {
|
|
391
392
|
title: "Export Wabery config",
|
|
392
|
-
description: "
|
|
393
|
+
description: "Use this when you need the selected project's current Flows, automations, webhook settings, and Business Agent declarations as declarative config. Do not use it to inspect live provider status.",
|
|
393
394
|
inputSchema: {},
|
|
394
395
|
annotations: {
|
|
395
396
|
readOnlyHint: true,
|
|
@@ -400,7 +401,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
400
401
|
}, async () => jsonResult(await client.get("/config")));
|
|
401
402
|
registerTool("wabery_validate_config", {
|
|
402
403
|
title: "Validate Wabery config",
|
|
403
|
-
description: "
|
|
404
|
+
description: "Use this when you need to validate a complete declarative config without changing resources. Use wabery_preview_config_diff next to inspect effects.",
|
|
404
405
|
inputSchema: {
|
|
405
406
|
config: configSchema.describe("The full wabery.config.json object."),
|
|
406
407
|
},
|
|
@@ -413,7 +414,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
413
414
|
}, async ({ config }) => apiResult(client.post("/config/validate", config)));
|
|
414
415
|
registerTool("wabery_preview_config_diff", {
|
|
415
416
|
title: "Preview Wabery config diff",
|
|
416
|
-
description: "
|
|
417
|
+
description: "Use this when you need to preview what a complete config would create, update, delete, or leave unchanged without applying it. Use wabery_apply_config only after reviewing this diff.",
|
|
417
418
|
inputSchema: {
|
|
418
419
|
config: configSchema.describe("The full wabery.config.json object."),
|
|
419
420
|
},
|
|
@@ -426,7 +427,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
426
427
|
}, async ({ config }) => apiResult(client.post("/config/diff", config)));
|
|
427
428
|
registerTool("wabery_apply_config", {
|
|
428
429
|
title: "Apply Wabery config",
|
|
429
|
-
description: "
|
|
430
|
+
description: "Use this when you need to apply a reviewed complete config, creating, overwriting, or removing Wabery Flows, automations, webhooks, and eligible Business Agent resources. Do not use it for one resource update when a narrow update tool fits. It never publishes Flows; use wabery_publish_flow separately.",
|
|
430
431
|
inputSchema: {
|
|
431
432
|
config: configSchema.describe("The full wabery.config.json object."),
|
|
432
433
|
confirmation_token: z
|
|
@@ -438,7 +439,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
438
439
|
readOnlyHint: false,
|
|
439
440
|
destructiveHint: true,
|
|
440
441
|
idempotentHint: true,
|
|
441
|
-
openWorldHint:
|
|
442
|
+
openWorldHint: true,
|
|
442
443
|
},
|
|
443
444
|
}, async (input) => {
|
|
444
445
|
const { config, confirmation_token } = input;
|
|
@@ -468,7 +469,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
468
469
|
});
|
|
469
470
|
registerTool("wabery_list_business_agents", {
|
|
470
471
|
title: "List Meta Business Agents",
|
|
471
|
-
description: "
|
|
472
|
+
description: "Use this when you need the selected project's Meta Business Agent records and business_agent_id values. Do not use it for live settings; use wabery_get_business_agent_settings.",
|
|
472
473
|
inputSchema: {
|
|
473
474
|
channel_id: z.string().min(1).optional(),
|
|
474
475
|
},
|
|
@@ -483,22 +484,22 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
483
484
|
})));
|
|
484
485
|
registerTool("wabery_check_business_agent_eligibility", {
|
|
485
486
|
title: "Check Meta Business Agent eligibility",
|
|
486
|
-
description: "
|
|
487
|
+
description: "Use this when you need to query Meta eligibility for a WhatsApp channel_id from wabery_list_channels before provisioning a Business Agent. This also caches the provider result in Wabery.",
|
|
487
488
|
inputSchema: {
|
|
488
489
|
channel_id: z.string().min(1),
|
|
489
490
|
},
|
|
490
491
|
annotations: {
|
|
491
|
-
readOnlyHint:
|
|
492
|
+
readOnlyHint: false,
|
|
492
493
|
destructiveHint: false,
|
|
493
|
-
idempotentHint:
|
|
494
|
-
openWorldHint:
|
|
494
|
+
idempotentHint: false,
|
|
495
|
+
openWorldHint: true,
|
|
495
496
|
},
|
|
496
497
|
}, async ({ channel_id }) => jsonResult(await client.get("/business-agents/eligibility", {
|
|
497
498
|
channel_id,
|
|
498
499
|
})));
|
|
499
500
|
registerTool("wabery_apply_business_agent", {
|
|
500
501
|
title: "Apply Meta Business Agent settings",
|
|
501
|
-
description: "
|
|
502
|
+
description: "Use this when you need to provision or overwrite Meta Business Agent settings for a channel_id from wabery_list_channels. Prefer wabery_apply_config for reviewed project-wide declarative changes.",
|
|
502
503
|
inputSchema: {
|
|
503
504
|
channel_id: z.string().min(1),
|
|
504
505
|
enabled: z.boolean().optional(),
|
|
@@ -513,9 +514,9 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
513
514
|
},
|
|
514
515
|
annotations: {
|
|
515
516
|
readOnlyHint: false,
|
|
516
|
-
destructiveHint:
|
|
517
|
+
destructiveHint: true,
|
|
517
518
|
idempotentHint: true,
|
|
518
|
-
openWorldHint:
|
|
519
|
+
openWorldHint: true,
|
|
519
520
|
},
|
|
520
521
|
}, async (input) => {
|
|
521
522
|
const { confirmation_token, ...body } = input;
|
|
@@ -526,7 +527,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
526
527
|
});
|
|
527
528
|
registerTool("wabery_get_business_agent_settings", {
|
|
528
529
|
title: "Get Meta Business Agent settings",
|
|
529
|
-
description: "
|
|
530
|
+
description: "Use this when you need live Meta settings for a business_agent_id from wabery_list_business_agents. Do not use it for the cached Wabery record.",
|
|
530
531
|
inputSchema: {
|
|
531
532
|
business_agent_id: z.string().min(1),
|
|
532
533
|
},
|
|
@@ -539,7 +540,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
539
540
|
}, async ({ business_agent_id }) => jsonResult(await client.get(`/business-agents/${encodeURIComponent(business_agent_id)}/settings`)));
|
|
540
541
|
registerTool("wabery_update_business_agent_settings", {
|
|
541
542
|
title: "Update Meta Business Agent settings",
|
|
542
|
-
description: "
|
|
543
|
+
description: "Use this when you need to overwrite live Meta settings for a business_agent_id from wabery_list_business_agents. Prefer wabery_apply_business_agent when provisioning by channel.",
|
|
543
544
|
inputSchema: {
|
|
544
545
|
business_agent_id: z.string().min(1),
|
|
545
546
|
enabled: z.boolean().optional(),
|
|
@@ -554,7 +555,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
554
555
|
},
|
|
555
556
|
annotations: {
|
|
556
557
|
readOnlyHint: false,
|
|
557
|
-
destructiveHint:
|
|
558
|
+
destructiveHint: true,
|
|
558
559
|
idempotentHint: true,
|
|
559
560
|
openWorldHint: true,
|
|
560
561
|
},
|
|
@@ -567,7 +568,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
567
568
|
});
|
|
568
569
|
registerTool("wabery_list_business_agent_connectors", {
|
|
569
570
|
title: "List Meta Business Agent connectors",
|
|
570
|
-
description: "
|
|
571
|
+
description: "Use this when you need connector records and connector_id values for the selected project, optionally filtered by a business_agent_id from wabery_list_business_agents.",
|
|
571
572
|
inputSchema: {
|
|
572
573
|
business_agent_id: z.string().min(1).optional(),
|
|
573
574
|
},
|
|
@@ -582,7 +583,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
582
583
|
})));
|
|
583
584
|
registerTool("wabery_create_business_agent_connector", {
|
|
584
585
|
title: "Create Meta Business Agent connector",
|
|
585
|
-
description: "
|
|
586
|
+
description: "Use this when you need to create a connector in Meta for a provisioned business_agent_id from wabery_list_business_agents. Prefer wabery_apply_config for reviewed project-wide declarative changes.",
|
|
586
587
|
inputSchema: {
|
|
587
588
|
business_agent_id: z.string().min(1),
|
|
588
589
|
name: z.string().min(1).max(120),
|
|
@@ -597,8 +598,8 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
597
598
|
annotations: {
|
|
598
599
|
readOnlyHint: false,
|
|
599
600
|
destructiveHint: false,
|
|
600
|
-
idempotentHint:
|
|
601
|
-
openWorldHint:
|
|
601
|
+
idempotentHint: false,
|
|
602
|
+
openWorldHint: true,
|
|
602
603
|
},
|
|
603
604
|
}, async (input) => {
|
|
604
605
|
const { confirmation_token, ...body } = input;
|
|
@@ -609,7 +610,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
609
610
|
});
|
|
610
611
|
registerTool("wabery_create_business_agent_connector_tool", {
|
|
611
612
|
title: "Create Meta Business Agent connector tool",
|
|
612
|
-
description: "
|
|
613
|
+
description: "Use this when you need to create a Meta connector tool for a connector_id from wabery_list_business_agent_connectors. backing_type is FLOW, HOSTED_FUNCTION, API_ENDPOINT, or NOOP; use the matching id from wabery_list_flows or wabery_list_functions.",
|
|
613
614
|
inputSchema: {
|
|
614
615
|
connector_id: z.string().min(1),
|
|
615
616
|
name: z.string().min(1).max(120),
|
|
@@ -632,8 +633,8 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
632
633
|
annotations: {
|
|
633
634
|
readOnlyHint: false,
|
|
634
635
|
destructiveHint: false,
|
|
635
|
-
idempotentHint:
|
|
636
|
-
openWorldHint:
|
|
636
|
+
idempotentHint: false,
|
|
637
|
+
openWorldHint: true,
|
|
637
638
|
},
|
|
638
639
|
}, async (input) => {
|
|
639
640
|
const { connector_id, confirmation_token, ...body } = input;
|
|
@@ -644,7 +645,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
644
645
|
});
|
|
645
646
|
registerTool("wabery_list_business_agent_connector_tools", {
|
|
646
647
|
title: "List Meta Business Agent connector tools",
|
|
647
|
-
description: "
|
|
648
|
+
description: "Use this when you need local connector-tool records and tool_id values for a connector_id from wabery_list_business_agent_connectors.",
|
|
648
649
|
inputSchema: {
|
|
649
650
|
connector_id: z.string().min(1),
|
|
650
651
|
},
|
|
@@ -657,7 +658,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
657
658
|
}, async ({ connector_id }) => jsonResult(await client.get(`/business-agents/connectors/${encodeURIComponent(connector_id)}/tools`)));
|
|
658
659
|
registerTool("wabery_get_business_agent_connector_tool", {
|
|
659
660
|
title: "Get Meta Business Agent connector tool",
|
|
660
|
-
description: "
|
|
661
|
+
description: "Use this when you need one connector tool by connector_id and tool_id from wabery_list_business_agent_connector_tools.",
|
|
661
662
|
inputSchema: {
|
|
662
663
|
connector_id: z.string().min(1),
|
|
663
664
|
tool_id: z.string().min(1),
|
|
@@ -671,7 +672,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
671
672
|
}, async ({ connector_id, tool_id }) => jsonResult(await client.get(`/business-agents/connectors/${encodeURIComponent(connector_id)}/tools/${encodeURIComponent(tool_id)}`)));
|
|
672
673
|
registerTool("wabery_update_business_agent_connector_tool", {
|
|
673
674
|
title: "Update Meta Business Agent connector tool",
|
|
674
|
-
description: "
|
|
675
|
+
description: "Use this when you need to overwrite a Meta connector tool identified by connector_id and tool_id from wabery_list_business_agent_connector_tools. Use create only for a new tool.",
|
|
675
676
|
inputSchema: {
|
|
676
677
|
connector_id: z.string().min(1),
|
|
677
678
|
tool_id: z.string().min(1),
|
|
@@ -691,9 +692,9 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
691
692
|
},
|
|
692
693
|
annotations: {
|
|
693
694
|
readOnlyHint: false,
|
|
694
|
-
destructiveHint:
|
|
695
|
+
destructiveHint: true,
|
|
695
696
|
idempotentHint: true,
|
|
696
|
-
openWorldHint:
|
|
697
|
+
openWorldHint: true,
|
|
697
698
|
},
|
|
698
699
|
}, async (input) => {
|
|
699
700
|
const { connector_id, tool_id, confirmation_token, ...body } = input;
|
|
@@ -704,7 +705,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
704
705
|
});
|
|
705
706
|
registerTool("wabery_delete_business_agent_connector_tool", {
|
|
706
707
|
title: "Delete Meta Business Agent connector tool",
|
|
707
|
-
description: "
|
|
708
|
+
description: "Use this when you need to permanently delete a Meta connector tool identified by connector_id and tool_id from wabery_list_business_agent_connector_tools.",
|
|
708
709
|
inputSchema: {
|
|
709
710
|
connector_id: z.string().min(1),
|
|
710
711
|
tool_id: z.string().min(1),
|
|
@@ -717,7 +718,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
717
718
|
readOnlyHint: false,
|
|
718
719
|
destructiveHint: true,
|
|
719
720
|
idempotentHint: true,
|
|
720
|
-
openWorldHint:
|
|
721
|
+
openWorldHint: true,
|
|
721
722
|
},
|
|
722
723
|
}, async ({ connector_id, tool_id, confirmation_token }) => {
|
|
723
724
|
const blocked = await requireWrite("wabery_delete_business_agent_connector_tool", confirmation_token, "delete_business_agent_connector_tool");
|
|
@@ -727,7 +728,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
727
728
|
});
|
|
728
729
|
registerTool("wabery_get_business_agent_thread_control", {
|
|
729
730
|
title: "Get Meta Business Agent thread control",
|
|
730
|
-
description: "
|
|
731
|
+
description: "Use this when you need to inspect current WhatsApp thread ownership for a channel_id from wabery_list_channels and contact_id from wabery_list_contacts. Use the set tool for handoff.",
|
|
731
732
|
inputSchema: {
|
|
732
733
|
channel_id: z.string().min(1),
|
|
733
734
|
contact_id: z.string().min(1),
|
|
@@ -735,9 +736,9 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
735
736
|
thread_id: z.string().min(1).optional(),
|
|
736
737
|
},
|
|
737
738
|
annotations: {
|
|
738
|
-
readOnlyHint:
|
|
739
|
+
readOnlyHint: false,
|
|
739
740
|
destructiveHint: false,
|
|
740
|
-
idempotentHint:
|
|
741
|
+
idempotentHint: false,
|
|
741
742
|
openWorldHint: true,
|
|
742
743
|
},
|
|
743
744
|
}, async (input) => jsonResult(await client.post("/business-agents/thread-control", {
|
|
@@ -746,7 +747,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
746
747
|
})));
|
|
747
748
|
registerTool("wabery_set_business_agent_thread_control", {
|
|
748
749
|
title: "Set Meta Business Agent thread control",
|
|
749
|
-
description: "
|
|
750
|
+
description: "Use this when you need to take or pass WhatsApp thread control for a channel_id and contact_id, changing automation or human ownership. Inspect first with wabery_get_business_agent_thread_control.",
|
|
750
751
|
inputSchema: {
|
|
751
752
|
action: z.enum(["take", "pass"]),
|
|
752
753
|
channel_id: z.string().min(1),
|
|
@@ -762,7 +763,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
762
763
|
},
|
|
763
764
|
annotations: {
|
|
764
765
|
readOnlyHint: false,
|
|
765
|
-
destructiveHint:
|
|
766
|
+
destructiveHint: true,
|
|
766
767
|
idempotentHint: true,
|
|
767
768
|
openWorldHint: true,
|
|
768
769
|
},
|
|
@@ -775,22 +776,31 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
775
776
|
});
|
|
776
777
|
registerTool("wabery_test_business_agent", {
|
|
777
778
|
title: "Test Meta Business Agent",
|
|
778
|
-
description: "
|
|
779
|
+
description: "Use this when you need to submit a controlled test scenario to Meta for a business_agent_id from wabery_list_business_agents. This is a remote provider operation, not a read or a real-recipient message send.",
|
|
779
780
|
inputSchema: {
|
|
780
781
|
business_agent_id: z.string().min(1),
|
|
781
782
|
input: z.string().min(1).optional(),
|
|
782
783
|
scenario: z.record(z.string(), z.unknown()).optional(),
|
|
784
|
+
confirmation_token: z
|
|
785
|
+
.string()
|
|
786
|
+
.optional()
|
|
787
|
+
.describe("Required when write mode is enabled: test_business_agent"),
|
|
783
788
|
},
|
|
784
789
|
annotations: {
|
|
785
|
-
readOnlyHint:
|
|
790
|
+
readOnlyHint: false,
|
|
786
791
|
destructiveHint: false,
|
|
787
792
|
idempotentHint: false,
|
|
788
793
|
openWorldHint: true,
|
|
789
794
|
},
|
|
790
|
-
}, async (body) =>
|
|
795
|
+
}, async ({ confirmation_token, ...body }) => {
|
|
796
|
+
const blocked = await requireWrite("wabery_test_business_agent", confirmation_token, "test_business_agent");
|
|
797
|
+
if (blocked)
|
|
798
|
+
return blocked;
|
|
799
|
+
return jsonResult(await client.post("/business-agents/test", body));
|
|
800
|
+
});
|
|
791
801
|
registerTool("wabery_get_business_agent_eval", {
|
|
792
802
|
title: "Get Meta Business Agent eval summary",
|
|
793
|
-
description: "
|
|
803
|
+
description: "Use this when you need the live Meta evaluation summary for a business_agent_id from wabery_list_business_agents. Do not use it to run a test scenario.",
|
|
794
804
|
inputSchema: {
|
|
795
805
|
business_agent_id: z.string().min(1),
|
|
796
806
|
},
|
|
@@ -805,7 +815,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
805
815
|
})));
|
|
806
816
|
registerTool("wabery_list_business_agent_skills", {
|
|
807
817
|
title: "List Meta Business Agent skills",
|
|
808
|
-
description: "
|
|
818
|
+
description: "Use this when you need the current Meta skill list for a business_agent_id from wabery_list_business_agents. Use the set tool only to replace the full list.",
|
|
809
819
|
inputSchema: {
|
|
810
820
|
business_agent_id: z.string().min(1),
|
|
811
821
|
},
|
|
@@ -820,7 +830,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
820
830
|
})));
|
|
821
831
|
registerTool("wabery_set_business_agent_skills", {
|
|
822
832
|
title: "Set Meta Business Agent skills",
|
|
823
|
-
description: "
|
|
833
|
+
description: "Use this when you need to replace the entire Meta skill list for a business_agent_id from wabery_list_business_agents. Do not use it to append one skill without first preserving existing entries.",
|
|
824
834
|
inputSchema: {
|
|
825
835
|
business_agent_id: z.string().min(1),
|
|
826
836
|
skills: z.array(z.unknown()),
|
|
@@ -843,7 +853,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
843
853
|
});
|
|
844
854
|
registerTool("wabery_list_projects", {
|
|
845
855
|
title: "List Wabery projects",
|
|
846
|
-
description: "
|
|
856
|
+
description: "Use this when you need to discover Wabery projects and their project_id values before selecting a project or passing an explicit project_id.",
|
|
847
857
|
inputSchema: {},
|
|
848
858
|
annotations: {
|
|
849
859
|
readOnlyHint: true,
|
|
@@ -855,7 +865,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
855
865
|
if (options.projectSelection) {
|
|
856
866
|
registerTool("wabery_get_selected_project", {
|
|
857
867
|
title: "Get selected Wabery project",
|
|
858
|
-
description: "
|
|
868
|
+
description: "Use this when you need to confirm which project this MCP session will use. A null selection means the credential's default project remains active.",
|
|
859
869
|
inputSchema: {},
|
|
860
870
|
annotations: {
|
|
861
871
|
readOnlyHint: true,
|
|
@@ -870,7 +880,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
870
880
|
}));
|
|
871
881
|
registerTool("wabery_select_project", {
|
|
872
882
|
title: "Select Wabery project",
|
|
873
|
-
description: "
|
|
883
|
+
description: "Use this when you need subsequent tools in this MCP session to target a project_id returned by wabery_list_projects. This changes session state, not the project itself.",
|
|
874
884
|
inputSchema: {
|
|
875
885
|
project_id: z.string().min(1),
|
|
876
886
|
},
|
|
@@ -892,7 +902,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
892
902
|
}
|
|
893
903
|
registerTool("wabery_get_project_readiness", {
|
|
894
904
|
title: "Get Wabery project readiness",
|
|
895
|
-
description: "
|
|
905
|
+
description: "Use this when you need capability readiness for the selected project or a project_id from wabery_list_projects: sandbox_test, production_inbound, flow_publish, flow_send, templates, proactive_messages, or submission_handling. Use channel readiness only for provider-specific phone details.",
|
|
896
906
|
inputSchema: {
|
|
897
907
|
project_id: z.string().min(1).optional(),
|
|
898
908
|
requirements: z.array(readinessRequirementSchema).optional(),
|
|
@@ -906,7 +916,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
906
916
|
}, async ({ project_id, requirements }) => jsonResult(await getReadiness(project_id, requirements)));
|
|
907
917
|
registerTool("wabery_get_project", {
|
|
908
918
|
title: "Get a Wabery project",
|
|
909
|
-
description: "
|
|
919
|
+
description: "Use this when you need one project's user-safe settings by project_id from wabery_list_projects. Do not use it for capability readiness; use wabery_get_project_readiness.",
|
|
910
920
|
inputSchema: { project_id: z.string().min(1) },
|
|
911
921
|
annotations: {
|
|
912
922
|
readOnlyHint: true,
|
|
@@ -917,7 +927,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
917
927
|
}, async ({ project_id }) => jsonResult(await client.get(`/projects/${encodeURIComponent(project_id)}`)));
|
|
918
928
|
registerTool("wabery_update_project", {
|
|
919
929
|
title: "Update a Wabery project",
|
|
920
|
-
description: "
|
|
930
|
+
description: "Use this when you need to overwrite project name, description, routing_mode, require_opt_in, or signed-webhook settings for a project_id from wabery_list_projects. Prefer wabery_apply_config for reviewed project-wide declarative changes.",
|
|
921
931
|
inputSchema: {
|
|
922
932
|
project_id: z.string().min(1),
|
|
923
933
|
name: z.string().min(1).max(100).optional(),
|
|
@@ -927,25 +937,33 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
927
937
|
webhook_url: z.string().url().nullable().optional(),
|
|
928
938
|
webhook_signing_enabled: z.boolean().optional(),
|
|
929
939
|
webhook_secret: z.string().min(16).max(256).optional(),
|
|
940
|
+
confirmation_token: z
|
|
941
|
+
.string()
|
|
942
|
+
.optional()
|
|
943
|
+
.describe("Required when write mode is enabled: update_project"),
|
|
930
944
|
},
|
|
931
945
|
annotations: {
|
|
932
946
|
readOnlyHint: false,
|
|
933
|
-
destructiveHint:
|
|
934
|
-
idempotentHint:
|
|
947
|
+
destructiveHint: true,
|
|
948
|
+
idempotentHint: true,
|
|
935
949
|
openWorldHint: false,
|
|
936
950
|
},
|
|
937
|
-
}, async ({ project_id, ...body }) => {
|
|
938
|
-
const blocked = await requireWrite("wabery_update_project");
|
|
951
|
+
}, async ({ project_id, confirmation_token, ...body }) => {
|
|
952
|
+
const blocked = await requireWrite("wabery_update_project", confirmation_token, "update_project");
|
|
939
953
|
if (blocked)
|
|
940
954
|
return blocked;
|
|
941
955
|
return jsonResult(await client.patch(`/projects/${encodeURIComponent(project_id)}`, body));
|
|
942
956
|
});
|
|
943
957
|
registerTool("wabery_rotate_webhook_secret", {
|
|
944
958
|
title: "Rotate a project's webhook secret",
|
|
945
|
-
description: "
|
|
959
|
+
description: "Use this when you need to invalidate and replace the signed-webhook secret for a project_id from wabery_list_projects. The MCP result never returns the new secret; manage it in the Wabery dashboard.",
|
|
946
960
|
inputSchema: {
|
|
947
961
|
project_id: z.string().min(1),
|
|
948
962
|
webhook_secret: z.string().min(16).max(256).optional(),
|
|
963
|
+
confirmation_token: z
|
|
964
|
+
.string()
|
|
965
|
+
.optional()
|
|
966
|
+
.describe("Required when write mode is enabled: rotate_webhook_secret"),
|
|
949
967
|
},
|
|
950
968
|
annotations: {
|
|
951
969
|
readOnlyHint: false,
|
|
@@ -953,15 +971,15 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
953
971
|
idempotentHint: false,
|
|
954
972
|
openWorldHint: false,
|
|
955
973
|
},
|
|
956
|
-
}, async ({ project_id, webhook_secret }) => {
|
|
957
|
-
const blocked = await requireWrite("wabery_rotate_webhook_secret");
|
|
974
|
+
}, async ({ project_id, webhook_secret, confirmation_token }) => {
|
|
975
|
+
const blocked = await requireWrite("wabery_rotate_webhook_secret", confirmation_token, "rotate_webhook_secret");
|
|
958
976
|
if (blocked)
|
|
959
977
|
return blocked;
|
|
960
978
|
return jsonResult(await client.post(`/projects/${encodeURIComponent(project_id)}/rotate-webhook-secret`, webhook_secret ? { webhook_secret } : undefined));
|
|
961
979
|
});
|
|
962
980
|
registerTool("wabery_list_channels", {
|
|
963
981
|
title: "List Wabery channels",
|
|
964
|
-
description: "
|
|
982
|
+
description: "Use this when you need WhatsApp channel_id values, connection state, routing warnings, or provider publish_readiness. Use project readiness first for capability-level discovery.",
|
|
965
983
|
inputSchema: {},
|
|
966
984
|
annotations: {
|
|
967
985
|
readOnlyHint: true,
|
|
@@ -972,7 +990,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
972
990
|
}, async () => jsonResult(await client.get("/channels")));
|
|
973
991
|
registerTool("wabery_get_channel", {
|
|
974
992
|
title: "Get a Wabery channel",
|
|
975
|
-
description: "
|
|
993
|
+
description: "Use this when you need routing_warning and WhatsApp publish_readiness for a channel_id from wabery_list_channels. Do not use it as a substitute for project-level readiness.",
|
|
976
994
|
inputSchema: { channel_id: z.string().min(1) },
|
|
977
995
|
annotations: {
|
|
978
996
|
readOnlyHint: true,
|
|
@@ -983,19 +1001,23 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
983
1001
|
}, async ({ channel_id }) => jsonResult(await client.get(`/channels/${encodeURIComponent(channel_id)}`)));
|
|
984
1002
|
registerTool("wabery_update_channel", {
|
|
985
1003
|
title: "Update a Wabery channel's routing",
|
|
986
|
-
description: "
|
|
1004
|
+
description: "Use this when you need to overwrite a dedicated channel's routing_mode with NONE, FLOWS, or EXTERNAL using a channel_id from wabery_list_channels. Do not use it for the shared sandbox; update project routing instead.",
|
|
987
1005
|
inputSchema: {
|
|
988
1006
|
channel_id: z.string().min(1),
|
|
989
1007
|
routing_mode: z.enum(["NONE", "FLOWS", "EXTERNAL"]),
|
|
1008
|
+
confirmation_token: z
|
|
1009
|
+
.string()
|
|
1010
|
+
.optional()
|
|
1011
|
+
.describe("Required when write mode is enabled: update_channel"),
|
|
990
1012
|
},
|
|
991
1013
|
annotations: {
|
|
992
1014
|
readOnlyHint: false,
|
|
993
|
-
destructiveHint:
|
|
1015
|
+
destructiveHint: true,
|
|
994
1016
|
idempotentHint: true,
|
|
995
1017
|
openWorldHint: false,
|
|
996
1018
|
},
|
|
997
|
-
}, async ({ channel_id, routing_mode }) => {
|
|
998
|
-
const blocked = await requireWrite("wabery_update_channel");
|
|
1019
|
+
}, async ({ channel_id, routing_mode, confirmation_token }) => {
|
|
1020
|
+
const blocked = await requireWrite("wabery_update_channel", confirmation_token, "update_channel");
|
|
999
1021
|
if (blocked)
|
|
1000
1022
|
return blocked;
|
|
1001
1023
|
return jsonResult(await client.patch(`/channels/${encodeURIComponent(channel_id)}`, {
|
|
@@ -1004,7 +1026,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1004
1026
|
});
|
|
1005
1027
|
registerTool("wabery_create_registration_intent", {
|
|
1006
1028
|
title: "Create registration intent",
|
|
1007
|
-
description: "
|
|
1029
|
+
description: "Use this when you need a single-use wa.me link for an end customer to register with a project_id from wabery_list_projects. This creates the link but does not contact the customer.",
|
|
1008
1030
|
inputSchema: {
|
|
1009
1031
|
project_id: z
|
|
1010
1032
|
.string()
|
|
@@ -1035,7 +1057,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1035
1057
|
});
|
|
1036
1058
|
registerTool("wabery_get_registration_intent", {
|
|
1037
1059
|
title: "Get registration intent",
|
|
1038
|
-
description: "
|
|
1060
|
+
description: "Use this when you need to poll a registration intent by intent_id returned by wabery_create_registration_intent. Do not create another intent merely to check status.",
|
|
1039
1061
|
inputSchema: {
|
|
1040
1062
|
intent_id: z.string().min(1),
|
|
1041
1063
|
},
|
|
@@ -1048,7 +1070,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1048
1070
|
}, async ({ intent_id }) => jsonResult(await client.get(`/registration-intents/${encodeURIComponent(intent_id)}`)));
|
|
1049
1071
|
registerTool("wabery_get_limits", {
|
|
1050
1072
|
title: "Get Wabery API limits",
|
|
1051
|
-
description: "
|
|
1073
|
+
description: "Use this when you need the current credential's enforced public API rate limit and monthly request quota. Do not use it for product-plan feature readiness.",
|
|
1052
1074
|
inputSchema: {},
|
|
1053
1075
|
annotations: {
|
|
1054
1076
|
readOnlyHint: true,
|
|
@@ -1059,7 +1081,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1059
1081
|
}, async () => jsonResult(await client.get("/limits")));
|
|
1060
1082
|
registerTool("wabery_list_flows", {
|
|
1061
1083
|
title: "List Wabery flows",
|
|
1062
|
-
description: "
|
|
1084
|
+
description: "Use this when you need WhatsApp Flow ids, config keys, project ids, or Meta publish statuses before get, publish, send, dispatch, or submission operations.",
|
|
1063
1085
|
inputSchema: {},
|
|
1064
1086
|
annotations: {
|
|
1065
1087
|
readOnlyHint: true,
|
|
@@ -1070,7 +1092,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1070
1092
|
}, async () => jsonResult(await client.get("/flows")));
|
|
1071
1093
|
registerTool("wabery_get_flow", {
|
|
1072
1094
|
title: "Get Wabery flow",
|
|
1073
|
-
description: "
|
|
1095
|
+
description: "Use this when you need one WhatsApp Flow's draft, field schema, and publish status by flow_id from wabery_list_flows.",
|
|
1074
1096
|
inputSchema: {
|
|
1075
1097
|
flow_id: z.string().min(1),
|
|
1076
1098
|
},
|
|
@@ -1083,7 +1105,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1083
1105
|
}, async ({ flow_id }) => jsonResult(await client.get(`/flows/${flow_id}`)));
|
|
1084
1106
|
registerTool("wabery_publish_flow", {
|
|
1085
1107
|
title: "Publish Wabery flow",
|
|
1086
|
-
description: "
|
|
1108
|
+
description: "Use this when you need to publish a reviewed draft WhatsApp Flow to Meta using a flow_id from wabery_list_flows. Do not use it to save a draft; use config apply, and obtain explicit confirmation first.",
|
|
1087
1109
|
inputSchema: {
|
|
1088
1110
|
flow_id: z.string().min(1),
|
|
1089
1111
|
confirmation_token: z
|
|
@@ -1105,7 +1127,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1105
1127
|
});
|
|
1106
1128
|
registerTool("wabery_enroll_contact", {
|
|
1107
1129
|
title: "Enroll WhatsApp contact",
|
|
1108
|
-
description: "
|
|
1130
|
+
description: "Use this when you need to register a controlled or explicitly opted-in WhatsApp phone number for a project_id from wabery_list_projects. It returns stable contact_id and channel_id values for later sends.",
|
|
1109
1131
|
inputSchema: {
|
|
1110
1132
|
phone: z.string().min(5).describe("E.164 phone number."),
|
|
1111
1133
|
project_id: z.string().min(1),
|
|
@@ -1127,7 +1149,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1127
1149
|
annotations: {
|
|
1128
1150
|
readOnlyHint: false,
|
|
1129
1151
|
destructiveHint: false,
|
|
1130
|
-
idempotentHint:
|
|
1152
|
+
idempotentHint: false,
|
|
1131
1153
|
openWorldHint: false,
|
|
1132
1154
|
},
|
|
1133
1155
|
}, async (input) => {
|
|
@@ -1138,7 +1160,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1138
1160
|
});
|
|
1139
1161
|
registerTool("wabery_list_contacts", {
|
|
1140
1162
|
title: "List Wabery contacts",
|
|
1141
|
-
description: "
|
|
1163
|
+
description: "Use this when you need enrolled WhatsApp contacts, stable contact_id values, and opt-in metadata before a targeted send or audience preparation.",
|
|
1142
1164
|
inputSchema: {
|
|
1143
1165
|
limit: z.number().int().min(1).max(100).optional(),
|
|
1144
1166
|
starting_after: z.string().optional(),
|
|
@@ -1152,7 +1174,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1152
1174
|
}, async ({ limit, starting_after }) => jsonResult(await client.get("/contacts", { limit, starting_after })));
|
|
1153
1175
|
registerTool("wabery_get_contact", {
|
|
1154
1176
|
title: "Get Wabery contact",
|
|
1155
|
-
description: "
|
|
1177
|
+
description: "Use this when you need one enrolled WhatsApp contact and consent state by contact_id from wabery_list_contacts or wabery_enroll_contact.",
|
|
1156
1178
|
inputSchema: {
|
|
1157
1179
|
contact_id: z.string().min(1),
|
|
1158
1180
|
},
|
|
@@ -1165,7 +1187,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1165
1187
|
}, async ({ contact_id }) => jsonResult(await client.get(`/contacts/${contact_id}`)));
|
|
1166
1188
|
registerTool("wabery_list_contact_imports", {
|
|
1167
1189
|
title: "List Wabery contact imports",
|
|
1168
|
-
description: "
|
|
1190
|
+
description: "Use this when you need CSV import_id values and processing counts after uploading through the dashboard or CLI. Only a completed import belongs in wabery_prepare_broadcast_audience.",
|
|
1169
1191
|
inputSchema: {
|
|
1170
1192
|
limit: z.number().int().min(1).max(100).optional(),
|
|
1171
1193
|
starting_after: z.string().optional(),
|
|
@@ -1179,7 +1201,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1179
1201
|
}, async (query) => apiResult(client.get("/contact-imports", query)));
|
|
1180
1202
|
registerTool("wabery_get_contact_import", {
|
|
1181
1203
|
title: "Get Wabery contact import",
|
|
1182
|
-
description: "
|
|
1204
|
+
description: "Use this when you need status and row counts for an import_id from wabery_list_contact_imports. Wait for completed before broadcast preparation.",
|
|
1183
1205
|
inputSchema: {
|
|
1184
1206
|
import_id: z.string().min(1),
|
|
1185
1207
|
},
|
|
@@ -1192,7 +1214,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1192
1214
|
}, async ({ import_id }) => apiResult(client.get(`/contact-imports/${import_id}`)));
|
|
1193
1215
|
registerTool("wabery_unenroll_contact", {
|
|
1194
1216
|
title: "Unenroll Wabery contact",
|
|
1195
|
-
description: "
|
|
1217
|
+
description: "Use this when you need to remove sandbox authorization for a contact_id from wabery_list_contacts. Set erase=true only for confirmed, irreversible organization-scoped contact-data deletion.",
|
|
1196
1218
|
inputSchema: {
|
|
1197
1219
|
contact_id: z.string().min(1),
|
|
1198
1220
|
erase: z.boolean().optional(),
|
|
@@ -1215,7 +1237,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1215
1237
|
});
|
|
1216
1238
|
registerTool("wabery_list_broadcasts", {
|
|
1217
1239
|
title: "List Wabery broadcasts",
|
|
1218
|
-
description: "
|
|
1240
|
+
description: "Use this when you need WhatsApp broadcast_id values, lifecycle states, or aggregate delivery counts. Filter by status when monitoring preparation or delivery.",
|
|
1219
1241
|
inputSchema: {
|
|
1220
1242
|
limit: z.number().int().min(1).max(100).optional(),
|
|
1221
1243
|
starting_after: z.string().optional(),
|
|
@@ -1230,7 +1252,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1230
1252
|
}, async (query) => apiResult(client.get("/broadcasts", query)));
|
|
1231
1253
|
registerTool("wabery_get_broadcast", {
|
|
1232
1254
|
title: "Get Wabery broadcast",
|
|
1233
|
-
description: "
|
|
1255
|
+
description: "Use this when you need lifecycle status and recipient counts for a broadcast_id from wabery_list_broadcasts. Poll while preparing and review counts before send or schedule confirmation.",
|
|
1234
1256
|
inputSchema: {
|
|
1235
1257
|
broadcast_id: z.string().min(1),
|
|
1236
1258
|
},
|
|
@@ -1243,7 +1265,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1243
1265
|
}, async ({ broadcast_id }) => apiResult(client.get(`/broadcasts/${broadcast_id}`)));
|
|
1244
1266
|
registerTool("wabery_create_broadcast", {
|
|
1245
1267
|
title: "Create Wabery broadcast draft",
|
|
1246
|
-
description: "
|
|
1268
|
+
description: "Use this when you need a new WhatsApp broadcast draft from approved template variants and a channel_id from wabery_list_channels. This does not select recipients or send; use prepare next.",
|
|
1247
1269
|
inputSchema: {
|
|
1248
1270
|
name: z.string().min(1).max(120),
|
|
1249
1271
|
channel_id: z.string().min(1),
|
|
@@ -1286,7 +1308,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1286
1308
|
});
|
|
1287
1309
|
registerTool("wabery_prepare_broadcast_audience", {
|
|
1288
1310
|
title: "Prepare Wabery broadcast audience",
|
|
1289
|
-
description: "
|
|
1311
|
+
description: "Use this when you need to start asynchronous audience resolution and overwrite the frozen recipient snapshot for a draft broadcast_id. Supply exactly one source: contact_ids from wabery_list_contacts, a completed import_id, or filter. This does not send; poll wabery_get_broadcast.",
|
|
1290
1312
|
inputSchema: {
|
|
1291
1313
|
broadcast_id: z.string().min(1),
|
|
1292
1314
|
contact_ids: z.array(z.string().min(1)).max(1000).optional(),
|
|
@@ -1296,8 +1318,8 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1296
1318
|
},
|
|
1297
1319
|
annotations: {
|
|
1298
1320
|
readOnlyHint: false,
|
|
1299
|
-
destructiveHint:
|
|
1300
|
-
idempotentHint:
|
|
1321
|
+
destructiveHint: true,
|
|
1322
|
+
idempotentHint: false,
|
|
1301
1323
|
openWorldHint: false,
|
|
1302
1324
|
},
|
|
1303
1325
|
}, async ({ broadcast_id, contact_ids, import_id, filter, exclude_contact_ids, }) => {
|
|
@@ -1332,7 +1354,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1332
1354
|
});
|
|
1333
1355
|
registerTool("wabery_list_broadcast_recipients", {
|
|
1334
1356
|
title: "List Wabery broadcast recipients",
|
|
1335
|
-
description: "
|
|
1357
|
+
description: "Use this when you need the frozen recipients, language selection, exclusions, failures, or delivery state for a prepared broadcast_id from wabery_list_broadcasts.",
|
|
1336
1358
|
inputSchema: {
|
|
1337
1359
|
broadcast_id: z.string().min(1),
|
|
1338
1360
|
limit: z.number().int().min(1).max(100).optional(),
|
|
@@ -1348,7 +1370,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1348
1370
|
}, async ({ broadcast_id, ...query }) => apiResult(client.get(`/broadcasts/${broadcast_id}/recipients`, query)));
|
|
1349
1371
|
registerTool("wabery_send_broadcast", {
|
|
1350
1372
|
title: "Send Wabery broadcast",
|
|
1351
|
-
description: "
|
|
1373
|
+
description: "Use this when you need to start real WhatsApp delivery for a ready broadcast_id after reviewing its frozen audience and counts. Do not use it for preparation; explicit confirmation is required.",
|
|
1352
1374
|
inputSchema: {
|
|
1353
1375
|
broadcast_id: z.string().min(1),
|
|
1354
1376
|
confirmation_token: z
|
|
@@ -1370,7 +1392,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1370
1392
|
});
|
|
1371
1393
|
registerTool("wabery_schedule_broadcast", {
|
|
1372
1394
|
title: "Schedule Wabery broadcast",
|
|
1373
|
-
description: "
|
|
1395
|
+
description: "Use this when you need future WhatsApp delivery for a ready broadcast_id after reviewing its frozen audience, scheduled_at, and IANA timezone. Do not use it for immediate delivery; explicit confirmation is required.",
|
|
1374
1396
|
inputSchema: {
|
|
1375
1397
|
broadcast_id: z.string().min(1),
|
|
1376
1398
|
scheduled_at: z.string().datetime(),
|
|
@@ -1397,7 +1419,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1397
1419
|
});
|
|
1398
1420
|
registerTool("wabery_cancel_broadcast", {
|
|
1399
1421
|
title: "Cancel Wabery broadcast",
|
|
1400
|
-
description: "
|
|
1422
|
+
description: "Use this when you need to cancel a broadcast_id and stop recipients not yet dispatched. Already accepted WhatsApp messages cannot be recalled; explicit confirmation is required.",
|
|
1401
1423
|
inputSchema: {
|
|
1402
1424
|
broadcast_id: z.string().min(1),
|
|
1403
1425
|
confirmation_token: z
|
|
@@ -1409,7 +1431,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1409
1431
|
readOnlyHint: false,
|
|
1410
1432
|
destructiveHint: true,
|
|
1411
1433
|
idempotentHint: true,
|
|
1412
|
-
openWorldHint:
|
|
1434
|
+
openWorldHint: true,
|
|
1413
1435
|
},
|
|
1414
1436
|
}, async ({ broadcast_id, confirmation_token }) => {
|
|
1415
1437
|
const blocked = await requireBroadcastApproval("wabery_cancel_broadcast", `Cancel broadcast ${broadcast_id}? Messages already accepted by WhatsApp cannot be recalled.`, confirmation_token, `cancel_broadcast:${broadcast_id}`);
|
|
@@ -1419,7 +1441,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1419
1441
|
});
|
|
1420
1442
|
registerTool("wabery_duplicate_broadcast", {
|
|
1421
1443
|
title: "Duplicate Wabery broadcast",
|
|
1422
|
-
description: "
|
|
1444
|
+
description: "Use this when you need a new draft copied from a broadcast_id's channel, template variants, and mappings. The audience is never copied; prepare a new controlled audience.",
|
|
1423
1445
|
inputSchema: {
|
|
1424
1446
|
broadcast_id: z.string().min(1),
|
|
1425
1447
|
},
|
|
@@ -1437,7 +1459,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1437
1459
|
});
|
|
1438
1460
|
registerTool("wabery_list_conversations", {
|
|
1439
1461
|
title: "List Wabery conversations",
|
|
1440
|
-
description: "
|
|
1462
|
+
description: "Use this when you need organization-scoped WhatsApp conversation_id values for inbox review, support, or message-history lookup. Filter by contact_id when known.",
|
|
1441
1463
|
inputSchema: {
|
|
1442
1464
|
contact_id: z.string().optional(),
|
|
1443
1465
|
active: z.boolean().optional(),
|
|
@@ -1456,7 +1478,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1456
1478
|
})));
|
|
1457
1479
|
registerTool("wabery_get_conversation", {
|
|
1458
1480
|
title: "Get Wabery conversation",
|
|
1459
|
-
description: "
|
|
1481
|
+
description: "Use this when you need one organization-scoped WhatsApp conversation by conversation_id from wabery_list_conversations.",
|
|
1460
1482
|
inputSchema: {
|
|
1461
1483
|
conversation_id: z.string().min(1),
|
|
1462
1484
|
},
|
|
@@ -1469,7 +1491,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1469
1491
|
}, async ({ conversation_id }) => jsonResult(await client.get(`/conversations/${conversation_id}`)));
|
|
1470
1492
|
registerTool("wabery_list_conversation_messages", {
|
|
1471
1493
|
title: "List Wabery conversation messages",
|
|
1472
|
-
description: "
|
|
1494
|
+
description: "Use this when you need message history for a conversation_id from wabery_list_conversations. Retained inbound media may include short-lived signed URLs; expires_at is the retention deadline.",
|
|
1473
1495
|
inputSchema: {
|
|
1474
1496
|
conversation_id: z.string().min(1),
|
|
1475
1497
|
limit: z.number().int().min(1).max(100).optional(),
|
|
@@ -1484,10 +1506,16 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1484
1506
|
},
|
|
1485
1507
|
}, async ({ conversation_id, ...query }) => jsonResult(await client.get(`/conversations/${conversation_id}/messages`, query)));
|
|
1486
1508
|
registerTool("wabery_send_message", {
|
|
1487
|
-
title: "Send
|
|
1488
|
-
description: "
|
|
1509
|
+
title: "Send WhatsApp message",
|
|
1510
|
+
description: "Use this when you need to send one real WhatsApp text, approved template, media, or interactive message. Do not use it to send a Flow; use wabery_send_flow. The body must identify channel and recipient using ids from list tools and should include idempotency_key; explicit confirmation is required.",
|
|
1489
1511
|
inputSchema: {
|
|
1490
|
-
body: z
|
|
1512
|
+
body: z
|
|
1513
|
+
.record(z.string(), z.unknown())
|
|
1514
|
+
.describe("POST /messages body. Include channel_id plus contact_id, conversation_id, or to; include type-specific content and an idempotency_key for safe retries."),
|
|
1515
|
+
confirmation_token: z
|
|
1516
|
+
.string()
|
|
1517
|
+
.optional()
|
|
1518
|
+
.describe("Required when write mode is enabled: send_message"),
|
|
1491
1519
|
},
|
|
1492
1520
|
annotations: {
|
|
1493
1521
|
readOnlyHint: false,
|
|
@@ -1495,15 +1523,15 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1495
1523
|
idempotentHint: false,
|
|
1496
1524
|
openWorldHint: true,
|
|
1497
1525
|
},
|
|
1498
|
-
}, async ({ body }) => {
|
|
1499
|
-
const blocked = await requireWrite("wabery_send_message");
|
|
1526
|
+
}, async ({ body, confirmation_token }) => {
|
|
1527
|
+
const blocked = await requireWrite("wabery_send_message", confirmation_token, "send_message");
|
|
1500
1528
|
if (blocked)
|
|
1501
1529
|
return blocked;
|
|
1502
1530
|
return apiResult(client.post("/messages", body));
|
|
1503
1531
|
});
|
|
1504
1532
|
registerTool("wabery_get_message", {
|
|
1505
1533
|
title: "Get Wabery message",
|
|
1506
|
-
description: "
|
|
1534
|
+
description: "Use this when you need queued, provider, delivery, or failure status for a message_id returned by wabery_send_message or message history. An accepted send is not proof of delivery.",
|
|
1507
1535
|
inputSchema: {
|
|
1508
1536
|
message_id: z.string().min(1),
|
|
1509
1537
|
},
|
|
@@ -1516,7 +1544,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1516
1544
|
}, async ({ message_id }) => jsonResult(await client.get(`/messages/${message_id}`)));
|
|
1517
1545
|
registerTool("wabery_list_templates", {
|
|
1518
1546
|
title: "List WhatsApp templates",
|
|
1519
|
-
description: "
|
|
1547
|
+
description: "Use this when you need WhatsApp template_id values and approval states, optionally for a channel_id from wabery_list_channels, before template sends or broadcasts.",
|
|
1520
1548
|
inputSchema: {
|
|
1521
1549
|
channel_id: z.string().optional(),
|
|
1522
1550
|
status: z.string().optional(),
|
|
@@ -1530,25 +1558,31 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1530
1558
|
}, async (query) => jsonResult(await client.get("/templates", query)));
|
|
1531
1559
|
registerTool("wabery_get_template", {
|
|
1532
1560
|
title: "Get WhatsApp template",
|
|
1533
|
-
description: "
|
|
1561
|
+
description: "Use this when you need one template by template_id from wabery_list_templates. Set refresh=true only for a live Meta check that also updates Wabery's cached status.",
|
|
1534
1562
|
inputSchema: {
|
|
1535
1563
|
template_id: z.string().min(1),
|
|
1536
1564
|
refresh: z.boolean().optional(),
|
|
1537
1565
|
},
|
|
1538
1566
|
annotations: {
|
|
1539
|
-
readOnlyHint:
|
|
1567
|
+
readOnlyHint: false,
|
|
1540
1568
|
destructiveHint: false,
|
|
1541
|
-
idempotentHint:
|
|
1542
|
-
openWorldHint:
|
|
1569
|
+
idempotentHint: false,
|
|
1570
|
+
openWorldHint: true,
|
|
1543
1571
|
},
|
|
1544
1572
|
}, async ({ template_id, refresh }) => jsonResult(await client.get(`/templates/${template_id}`, {
|
|
1545
1573
|
refresh: refresh ? "true" : undefined,
|
|
1546
1574
|
})));
|
|
1547
1575
|
registerTool("wabery_create_template", {
|
|
1548
1576
|
title: "Create WhatsApp template",
|
|
1549
|
-
description: "
|
|
1577
|
+
description: "Use this when you need to submit a new WhatsApp template to Meta for approval after checking channel publish_readiness. Do not use it to inspect or send an existing template; explicit confirmation is required.",
|
|
1550
1578
|
inputSchema: {
|
|
1551
|
-
body: z
|
|
1579
|
+
body: z
|
|
1580
|
+
.record(z.string(), z.unknown())
|
|
1581
|
+
.describe("Template submission body including a dedicated WhatsApp channel_id, name, category, language, and components accepted by POST /templates."),
|
|
1582
|
+
confirmation_token: z
|
|
1583
|
+
.string()
|
|
1584
|
+
.optional()
|
|
1585
|
+
.describe("Required when write mode is enabled: create_template"),
|
|
1552
1586
|
},
|
|
1553
1587
|
annotations: {
|
|
1554
1588
|
readOnlyHint: false,
|
|
@@ -1556,33 +1590,33 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1556
1590
|
idempotentHint: false,
|
|
1557
1591
|
openWorldHint: true,
|
|
1558
1592
|
},
|
|
1559
|
-
}, async ({ body }) => {
|
|
1560
|
-
const blocked = await requireWrite("wabery_create_template");
|
|
1593
|
+
}, async ({ body, confirmation_token }) => {
|
|
1594
|
+
const blocked = await requireWrite("wabery_create_template", confirmation_token, "create_template");
|
|
1561
1595
|
if (blocked)
|
|
1562
1596
|
return blocked;
|
|
1563
1597
|
return apiResult(client.post("/templates", body));
|
|
1564
1598
|
});
|
|
1565
1599
|
registerTool("wabery_wait_template", {
|
|
1566
1600
|
title: "Wait for WhatsApp template approval",
|
|
1567
|
-
description: "
|
|
1601
|
+
description: "Use this when you need to poll Meta for a template_id from wabery_list_templates until APPROVED or timeout. This repeatedly refreshes Wabery's cached provider status; do not use it for a single cached read.",
|
|
1568
1602
|
inputSchema: {
|
|
1569
1603
|
template_id: z.string().min(1),
|
|
1570
1604
|
timeout_seconds: z.number().int().min(1).max(86_400).optional(),
|
|
1571
1605
|
interval_seconds: z.number().int().min(1).max(300).optional(),
|
|
1572
1606
|
},
|
|
1573
1607
|
annotations: {
|
|
1574
|
-
readOnlyHint:
|
|
1608
|
+
readOnlyHint: false,
|
|
1575
1609
|
destructiveHint: false,
|
|
1576
|
-
idempotentHint:
|
|
1577
|
-
openWorldHint:
|
|
1610
|
+
idempotentHint: false,
|
|
1611
|
+
openWorldHint: true,
|
|
1578
1612
|
},
|
|
1579
1613
|
}, async ({ template_id, timeout_seconds, interval_seconds }) => jsonResult(await waitUntilTemplateApproved(client, template_id, {
|
|
1580
1614
|
timeoutMs: (timeout_seconds ?? 86_400) * 1000,
|
|
1581
1615
|
intervalMs: (interval_seconds ?? 60) * 1000,
|
|
1582
1616
|
})));
|
|
1583
1617
|
registerTool("wabery_send_flow", {
|
|
1584
|
-
title: "Send
|
|
1585
|
-
description: "
|
|
1618
|
+
title: "Send WhatsApp Flow",
|
|
1619
|
+
description: "Use this when you need to send one published WhatsApp Flow using flow_id and channel_id from list tools plus exactly one controlled contact_id, conversation_id, or phone number. Do not use wabery_send_message for a Flow; explicit confirmation is required.",
|
|
1586
1620
|
inputSchema: {
|
|
1587
1621
|
flow_id: z.string().min(1),
|
|
1588
1622
|
channel_id: z.string().min(1),
|
|
@@ -1595,6 +1629,10 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1595
1629
|
footer_text: z.string().max(60).optional(),
|
|
1596
1630
|
first_screen: z.string().optional(),
|
|
1597
1631
|
screen_data: z.record(z.string(), z.unknown()).optional(),
|
|
1632
|
+
confirmation_token: z
|
|
1633
|
+
.string()
|
|
1634
|
+
.optional()
|
|
1635
|
+
.describe("Required when write mode is enabled: send_flow:<flow_id>"),
|
|
1598
1636
|
},
|
|
1599
1637
|
annotations: {
|
|
1600
1638
|
readOnlyHint: false,
|
|
@@ -1602,15 +1640,15 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1602
1640
|
idempotentHint: false,
|
|
1603
1641
|
openWorldHint: true,
|
|
1604
1642
|
},
|
|
1605
|
-
}, async ({ flow_id, ...body }) => {
|
|
1606
|
-
const blocked = await requireWrite("wabery_send_flow");
|
|
1643
|
+
}, async ({ flow_id, confirmation_token, ...body }) => {
|
|
1644
|
+
const blocked = await requireWrite("wabery_send_flow", confirmation_token, `send_flow:${flow_id}`);
|
|
1607
1645
|
if (blocked)
|
|
1608
1646
|
return blocked;
|
|
1609
1647
|
return apiResult(client.post(`/flows/${flow_id}/send`, body));
|
|
1610
1648
|
});
|
|
1611
1649
|
registerTool("wabery_list_submissions", {
|
|
1612
1650
|
title: "List Wabery submissions",
|
|
1613
|
-
description: "
|
|
1651
|
+
description: "Use this when you need completed WhatsApp Flow submissions, optionally filtered by project agent_id or flow_id from wabery_list_flows.",
|
|
1614
1652
|
inputSchema: {
|
|
1615
1653
|
agent_id: z.string().optional(),
|
|
1616
1654
|
flow_id: z.string().optional(),
|
|
@@ -1626,7 +1664,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1626
1664
|
}, async (query) => jsonResult(await client.get("/submissions", query)));
|
|
1627
1665
|
registerTool("wabery_list_dispatches", {
|
|
1628
1666
|
title: "List Wabery dispatches",
|
|
1629
|
-
description: "
|
|
1667
|
+
description: "Use this when you need sent WhatsApp Flow dispatches and flow_token values, optionally filtered by flow_id or contact_id. Use wabery_get_dispatch for one token.",
|
|
1630
1668
|
inputSchema: {
|
|
1631
1669
|
flow_id: z.string().optional(),
|
|
1632
1670
|
contact_id: z.string().optional(),
|
|
@@ -1643,7 +1681,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1643
1681
|
}, async (query) => jsonResult(await client.get("/dispatches", query)));
|
|
1644
1682
|
registerTool("wabery_get_dispatch", {
|
|
1645
1683
|
title: "Get Wabery dispatch",
|
|
1646
|
-
description: "
|
|
1684
|
+
description: "Use this when you need provider and completion status for one WhatsApp Flow dispatch by flow_token returned by wabery_send_flow or wabery_list_dispatches.",
|
|
1647
1685
|
inputSchema: {
|
|
1648
1686
|
flow_token: z.string().min(1),
|
|
1649
1687
|
},
|
|
@@ -1657,7 +1695,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1657
1695
|
// ─── Hosted functions (serverless logic the agent authors) ───────────
|
|
1658
1696
|
registerTool("wabery_list_functions", {
|
|
1659
1697
|
title: "List hosted functions",
|
|
1660
|
-
description: "
|
|
1698
|
+
description: "Use this when you need hosted function_id values, deployment state, or exposure settings for the selected project before get, deploy, test, invoke, update, or delete operations.",
|
|
1661
1699
|
inputSchema: {},
|
|
1662
1700
|
annotations: {
|
|
1663
1701
|
readOnlyHint: true,
|
|
@@ -1668,7 +1706,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1668
1706
|
}, async () => jsonResult(await client.get("/functions")));
|
|
1669
1707
|
registerTool("wabery_get_function", {
|
|
1670
1708
|
title: "Get a hosted function",
|
|
1671
|
-
description: "
|
|
1709
|
+
description: "Use this when you need metadata and current source for a function_id from wabery_list_functions. Do not use it to execute the function.",
|
|
1672
1710
|
inputSchema: { function_id: z.string().min(1) },
|
|
1673
1711
|
annotations: {
|
|
1674
1712
|
readOnlyHint: true,
|
|
@@ -1679,7 +1717,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1679
1717
|
}, async ({ function_id }) => jsonResult(await client.get(`/functions/${function_id}`)));
|
|
1680
1718
|
registerTool("wabery_create_function", {
|
|
1681
1719
|
title: "Create a hosted function",
|
|
1682
|
-
description: "
|
|
1720
|
+
description: "Use this when you need a new hosted-function record without deploying source. trigger_type accepts values such as KEYWORD, WELCOME, or ANY_MESSAGE; use wabery_deploy_function next.",
|
|
1683
1721
|
inputSchema: {
|
|
1684
1722
|
slug: z
|
|
1685
1723
|
.string()
|
|
@@ -1708,7 +1746,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1708
1746
|
});
|
|
1709
1747
|
registerTool("wabery_deploy_function", {
|
|
1710
1748
|
title: "Deploy a hosted function",
|
|
1711
|
-
description: "
|
|
1749
|
+
description: "Use this when you need to bundle and overwrite the active TypeScript deployment for a function_id from wabery_list_functions. Do not use it to execute code; use test or invoke after reviewing diagnostics.",
|
|
1712
1750
|
inputSchema: {
|
|
1713
1751
|
function_id: z.string().min(1),
|
|
1714
1752
|
source: z.string().min(1),
|
|
@@ -1719,9 +1757,9 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1719
1757
|
},
|
|
1720
1758
|
annotations: {
|
|
1721
1759
|
readOnlyHint: false,
|
|
1722
|
-
destructiveHint:
|
|
1723
|
-
idempotentHint:
|
|
1724
|
-
openWorldHint:
|
|
1760
|
+
destructiveHint: true,
|
|
1761
|
+
idempotentHint: false,
|
|
1762
|
+
openWorldHint: true,
|
|
1725
1763
|
},
|
|
1726
1764
|
}, async ({ function_id, source, confirmation_token }) => {
|
|
1727
1765
|
const blocked = await requireWrite("wabery_deploy_function", confirmation_token, "deploy_function");
|
|
@@ -1731,7 +1769,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1731
1769
|
});
|
|
1732
1770
|
registerTool("wabery_test_function", {
|
|
1733
1771
|
title: "Test a hosted function",
|
|
1734
|
-
description: "
|
|
1772
|
+
description: "Use this when you need to execute a function_id with a synthetic message event and inspect its result and logs. Do not use it as a side-effect-free preview: function code can persist data or call external APIs; use wabery_invoke_function for a real structured tool call.",
|
|
1735
1773
|
inputSchema: {
|
|
1736
1774
|
function_id: z.string().min(1),
|
|
1737
1775
|
text: z.string().max(4000).optional(),
|
|
@@ -1742,9 +1780,9 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1742
1780
|
},
|
|
1743
1781
|
annotations: {
|
|
1744
1782
|
readOnlyHint: false,
|
|
1745
|
-
destructiveHint:
|
|
1746
|
-
idempotentHint:
|
|
1747
|
-
openWorldHint:
|
|
1783
|
+
destructiveHint: true,
|
|
1784
|
+
idempotentHint: false,
|
|
1785
|
+
openWorldHint: true,
|
|
1748
1786
|
},
|
|
1749
1787
|
}, async ({ function_id, text, confirmation_token }) => {
|
|
1750
1788
|
const blocked = await requireWrite("wabery_test_function", confirmation_token, "test_function");
|
|
@@ -1754,7 +1792,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1754
1792
|
});
|
|
1755
1793
|
registerTool("wabery_tail_function_logs", {
|
|
1756
1794
|
title: "Tail hosted function logs",
|
|
1757
|
-
description: "
|
|
1795
|
+
description: "Use this when you need recent invocation status, CPU, errors, or captured logs for a function_id from wabery_list_functions. This does not execute the function.",
|
|
1758
1796
|
inputSchema: { function_id: z.string().min(1) },
|
|
1759
1797
|
annotations: {
|
|
1760
1798
|
readOnlyHint: true,
|
|
@@ -1765,7 +1803,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1765
1803
|
}, async ({ function_id }) => jsonResult(await client.get(`/functions/${function_id}/logs`)));
|
|
1766
1804
|
registerTool("wabery_delete_function", {
|
|
1767
1805
|
title: "Delete a hosted function",
|
|
1768
|
-
description: "
|
|
1806
|
+
description: "Use this when you need to permanently delete a function_id from wabery_list_functions and its deployed Worker. Do not use update to simulate deletion.",
|
|
1769
1807
|
inputSchema: {
|
|
1770
1808
|
function_id: z.string().min(1),
|
|
1771
1809
|
confirmation_token: z
|
|
@@ -1777,7 +1815,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1777
1815
|
readOnlyHint: false,
|
|
1778
1816
|
destructiveHint: true,
|
|
1779
1817
|
idempotentHint: true,
|
|
1780
|
-
openWorldHint:
|
|
1818
|
+
openWorldHint: true,
|
|
1781
1819
|
},
|
|
1782
1820
|
}, async ({ function_id, confirmation_token }) => {
|
|
1783
1821
|
const blocked = await requireWrite("wabery_delete_function", confirmation_token, "delete_function");
|
|
@@ -1787,7 +1825,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1787
1825
|
});
|
|
1788
1826
|
registerTool("wabery_update_function", {
|
|
1789
1827
|
title: "Update a hosted function",
|
|
1790
|
-
description: "
|
|
1828
|
+
description: "Use this when you need to overwrite metadata for a function_id from wabery_list_functions: name, expose_as_mcp_tool, is_active, or input_schema. Do not use it to deploy source or invoke code.",
|
|
1791
1829
|
inputSchema: {
|
|
1792
1830
|
function_id: z.string().min(1),
|
|
1793
1831
|
name: z.string().min(1).max(120).optional(),
|
|
@@ -1801,7 +1839,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1801
1839
|
},
|
|
1802
1840
|
annotations: {
|
|
1803
1841
|
readOnlyHint: false,
|
|
1804
|
-
destructiveHint:
|
|
1842
|
+
destructiveHint: true,
|
|
1805
1843
|
idempotentHint: true,
|
|
1806
1844
|
openWorldHint: false,
|
|
1807
1845
|
},
|
|
@@ -1814,7 +1852,7 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1814
1852
|
});
|
|
1815
1853
|
registerTool("wabery_invoke_function", {
|
|
1816
1854
|
title: "Invoke a hosted function as a tool",
|
|
1817
|
-
description: "
|
|
1855
|
+
description: "Use this when you need a real structured mcp_call to an exposed function_id from wabery_list_functions, optionally with contact_id from wabery_list_contacts. Do not use it for synthetic testing; arbitrary function code can persist data, call APIs, or send messages.",
|
|
1818
1856
|
inputSchema: {
|
|
1819
1857
|
function_id: z.string().min(1),
|
|
1820
1858
|
arguments: z.record(z.string(), z.unknown()).optional(),
|
|
@@ -1826,8 +1864,8 @@ export function createWaberyMcpServer(client = new WaberyApiClient(), options =
|
|
|
1826
1864
|
},
|
|
1827
1865
|
annotations: {
|
|
1828
1866
|
readOnlyHint: false,
|
|
1829
|
-
destructiveHint:
|
|
1830
|
-
idempotentHint:
|
|
1867
|
+
destructiveHint: true,
|
|
1868
|
+
idempotentHint: false,
|
|
1831
1869
|
openWorldHint: true,
|
|
1832
1870
|
},
|
|
1833
1871
|
}, async ({ function_id, arguments: args, contact_id, confirmation_token, }) => {
|