@daisyintel/whatsapp-cloud-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1187 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { basename } from "node:path";
3
+ import { z } from "zod";
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ function ensureValue(value, envName) {
6
+ if (!value) {
7
+ throw new Error(`${envName} is required for this operation.`);
8
+ }
9
+ return value;
10
+ }
11
+ function resolvePhoneNumberId(config, override) {
12
+ return ensureValue(override ?? config.phoneNumberId, "WHATSAPP_PHONE_NUMBER_ID");
13
+ }
14
+ function resolveWabaId(config, override) {
15
+ return ensureValue(override ?? config.wabaId, "WHATSAPP_WABA_ID");
16
+ }
17
+ function resolveBusinessId(config, override) {
18
+ return ensureValue(override ?? config.businessId, "WHATSAPP_BUSINESS_ID");
19
+ }
20
+ function extractMessageIds(payload) {
21
+ if (typeof payload !== "object" || payload === null) {
22
+ return [];
23
+ }
24
+ const messages = payload.messages;
25
+ if (!Array.isArray(messages)) {
26
+ return [];
27
+ }
28
+ return messages
29
+ .map((message) => (typeof message === "object" && message !== null ? message.id : null))
30
+ .filter((id) => typeof id === "string");
31
+ }
32
+ function formatToolResult(result) {
33
+ if (result.ok) {
34
+ return {
35
+ endpoint: result.endpoint,
36
+ request_ids: extractMessageIds(result.data),
37
+ payload: result.data
38
+ };
39
+ }
40
+ return {
41
+ endpoint: result.endpoint,
42
+ error: {
43
+ status: result.status,
44
+ request_id: result.requestId,
45
+ ...result.error
46
+ }
47
+ };
48
+ }
49
+ function withContext(base, contextMessageId) {
50
+ if (!contextMessageId) {
51
+ return base;
52
+ }
53
+ return {
54
+ ...base,
55
+ context: {
56
+ message_id: contextMessageId
57
+ }
58
+ };
59
+ }
60
+ function buildBlockUsers(users) {
61
+ if (users.length === 0) {
62
+ throw new Error("At least one user is required.");
63
+ }
64
+ return users.map((user) => ({ user }));
65
+ }
66
+ function defaultBusinessProfileFields(fields) {
67
+ if (fields && fields.length > 0) {
68
+ return fields.join(",");
69
+ }
70
+ return "about,address,description,email,profile_picture_url,websites,vertical";
71
+ }
72
+ export function createToolHandlers(client, config, eventStore) {
73
+ return {
74
+ async getOwnedWabas(args) {
75
+ return formatToolResult(await client.safeRequest({
76
+ path: `${resolveBusinessId(config, args.business_id)}/owned_whatsapp_business_accounts`
77
+ }));
78
+ },
79
+ async getWaba(args) {
80
+ return formatToolResult(await client.safeRequest({
81
+ path: resolveWabaId(config, args.waba_id)
82
+ }));
83
+ },
84
+ async getPhoneNumbers(args) {
85
+ return formatToolResult(await client.safeRequest({
86
+ path: `${resolveWabaId(config, args.waba_id)}/phone_numbers`
87
+ }));
88
+ },
89
+ async registerPhoneNumber(args) {
90
+ return formatToolResult(await client.safeRequest({
91
+ method: "POST",
92
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/register`,
93
+ body: {
94
+ messaging_product: "whatsapp",
95
+ pin: args.pin
96
+ }
97
+ }));
98
+ },
99
+ async requestVerificationCode(args) {
100
+ return formatToolResult(await client.safeRequest({
101
+ method: "POST",
102
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/request_code`,
103
+ body: {
104
+ code_method: args.code_method,
105
+ locale: args.locale
106
+ }
107
+ }));
108
+ },
109
+ async verifyCode(args) {
110
+ return formatToolResult(await client.safeRequest({
111
+ method: "POST",
112
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/verify_code`,
113
+ body: {
114
+ code: args.code
115
+ }
116
+ }));
117
+ },
118
+ async subscribeApp(args) {
119
+ return formatToolResult(await client.safeRequest({
120
+ method: "POST",
121
+ path: `${resolveWabaId(config, args.waba_id)}/subscribed_apps`
122
+ }));
123
+ },
124
+ async getSubscribedApps(args) {
125
+ return formatToolResult(await client.safeRequest({
126
+ path: `${resolveWabaId(config, args.waba_id)}/subscribed_apps`
127
+ }));
128
+ },
129
+ async unsubscribeApp(args) {
130
+ return formatToolResult(await client.safeRequest({
131
+ method: "DELETE",
132
+ path: `${resolveWabaId(config, args.waba_id)}/subscribed_apps`
133
+ }));
134
+ },
135
+ async debugAccessToken() {
136
+ return formatToolResult(await client.safeRequest({
137
+ path: "debug_token",
138
+ query: {
139
+ input_token: config.accessToken
140
+ }
141
+ }));
142
+ },
143
+ async getBusinessProfile(args) {
144
+ return formatToolResult(await client.safeRequest({
145
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/whatsapp_business_profile`,
146
+ query: {
147
+ fields: defaultBusinessProfileFields(args.fields)
148
+ }
149
+ }));
150
+ },
151
+ async updateBusinessProfile(args) {
152
+ return formatToolResult(await client.safeRequest({
153
+ method: "POST",
154
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/whatsapp_business_profile`,
155
+ body: {
156
+ messaging_product: "whatsapp",
157
+ ...(args.address !== undefined ? { address: args.address } : {}),
158
+ ...(args.description !== undefined ? { description: args.description } : {}),
159
+ ...(args.vertical !== undefined ? { vertical: args.vertical } : {}),
160
+ ...(args.about !== undefined ? { about: args.about } : {}),
161
+ ...(args.email !== undefined ? { email: args.email } : {}),
162
+ ...(args.websites !== undefined ? { websites: args.websites } : {}),
163
+ ...(args.profile_picture_handle !== undefined ? { profile_picture_handle: args.profile_picture_handle } : {})
164
+ }
165
+ }));
166
+ },
167
+ async getBlockedUsers(args) {
168
+ return formatToolResult(await client.safeRequest({
169
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/block_users`
170
+ }));
171
+ },
172
+ async blockUsers(args) {
173
+ return formatToolResult(await client.safeRequest({
174
+ method: "POST",
175
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/block_users`,
176
+ body: {
177
+ messaging_product: "whatsapp",
178
+ block_users: buildBlockUsers(args.users)
179
+ }
180
+ }));
181
+ },
182
+ async unblockUsers(args) {
183
+ return formatToolResult(await client.safeRequest({
184
+ method: "DELETE",
185
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/block_users`,
186
+ body: {
187
+ messaging_product: "whatsapp",
188
+ block_users: buildBlockUsers(args.users)
189
+ }
190
+ }));
191
+ },
192
+ async getTemplates(args) {
193
+ return formatToolResult(await client.safeRequest({
194
+ path: `${resolveWabaId(config, args.waba_id)}/message_templates`,
195
+ query: {
196
+ ...(args.limit !== undefined ? { limit: args.limit } : {}),
197
+ ...(args.name ? { name: args.name } : {}),
198
+ ...(args.fields && args.fields.length > 0 ? { fields: args.fields.join(",") } : {})
199
+ }
200
+ }));
201
+ },
202
+ async getTemplateById(args) {
203
+ return formatToolResult(await client.safeRequest({
204
+ path: args.template_id,
205
+ query: {
206
+ ...(args.fields && args.fields.length > 0 ? { fields: args.fields.join(",") } : {})
207
+ }
208
+ }));
209
+ },
210
+ async createTemplate(args) {
211
+ return formatToolResult(await client.safeRequest({
212
+ method: "POST",
213
+ path: `${resolveWabaId(config, args.waba_id)}/message_templates`,
214
+ body: {
215
+ name: args.name,
216
+ language: args.language,
217
+ category: args.category,
218
+ components: args.components,
219
+ ...(args.allow_category_change !== undefined ? { allow_category_change: args.allow_category_change } : {})
220
+ }
221
+ }));
222
+ },
223
+ async deleteTemplateByName(args) {
224
+ return formatToolResult(await client.safeRequest({
225
+ method: "DELETE",
226
+ path: `${resolveWabaId(config, args.waba_id)}/message_templates`,
227
+ query: {
228
+ name: args.name
229
+ }
230
+ }));
231
+ },
232
+ async sendTextMessage(args) {
233
+ return formatToolResult(await client.safeRequest({
234
+ method: "POST",
235
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/messages`,
236
+ body: withContext({
237
+ messaging_product: "whatsapp",
238
+ recipient_type: "individual",
239
+ to: args.to,
240
+ type: "text",
241
+ text: {
242
+ body: args.body,
243
+ preview_url: args.preview_url ?? false
244
+ }
245
+ }, args.context_message_id)
246
+ }));
247
+ },
248
+ async sendTemplateMessage(args) {
249
+ return formatToolResult(await client.safeRequest({
250
+ method: "POST",
251
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/messages`,
252
+ body: withContext({
253
+ messaging_product: "whatsapp",
254
+ recipient_type: "individual",
255
+ to: args.to,
256
+ type: "template",
257
+ template: {
258
+ name: args.name,
259
+ language: {
260
+ code: args.languageCode
261
+ },
262
+ ...(args.components ? { components: args.components } : {})
263
+ }
264
+ }, args.contextMessageId)
265
+ }));
266
+ },
267
+ async sendMediaMessage(args) {
268
+ if (!args.media_id && !args.link) {
269
+ throw new Error("Either media_id or link is required.");
270
+ }
271
+ const mediaPayload = {};
272
+ if (args.media_id) {
273
+ mediaPayload.id = args.media_id;
274
+ }
275
+ if (args.link) {
276
+ mediaPayload.link = args.link;
277
+ }
278
+ if (args.caption && (args.media_type === "image" || args.media_type === "document" || args.media_type === "video")) {
279
+ mediaPayload.caption = args.caption;
280
+ }
281
+ if (args.filename && args.media_type === "document") {
282
+ mediaPayload.filename = args.filename;
283
+ }
284
+ return formatToolResult(await client.safeRequest({
285
+ method: "POST",
286
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/messages`,
287
+ body: withContext({
288
+ messaging_product: "whatsapp",
289
+ recipient_type: "individual",
290
+ to: args.to,
291
+ type: args.media_type,
292
+ [args.media_type]: mediaPayload
293
+ }, args.context_message_id)
294
+ }));
295
+ },
296
+ async sendRawMessage(args) {
297
+ return formatToolResult(await client.safeRequest({
298
+ method: "POST",
299
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/messages`,
300
+ body: args.body
301
+ }));
302
+ },
303
+ async markMessageAsRead(args) {
304
+ return formatToolResult(await client.safeRequest({
305
+ method: "POST",
306
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/messages`,
307
+ body: {
308
+ messaging_product: "whatsapp",
309
+ status: "read",
310
+ message_id: args.message_id
311
+ }
312
+ }));
313
+ },
314
+ async uploadMedia(args) {
315
+ const fileBuffer = await readFile(args.file_path);
316
+ const formData = new FormData();
317
+ formData.append("messaging_product", "whatsapp");
318
+ formData.append("type", args.mime_type);
319
+ formData.append("file", new Blob([fileBuffer], { type: args.mime_type }), args.filename ?? basename(args.file_path));
320
+ return formatToolResult(await client.safeRequest({
321
+ method: "POST",
322
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/media`,
323
+ formData
324
+ }));
325
+ },
326
+ async getMediaUrl(args) {
327
+ return formatToolResult(await client.safeRequest({
328
+ path: args.media_id
329
+ }));
330
+ },
331
+ async deleteMedia(args) {
332
+ return formatToolResult(await client.safeRequest({
333
+ method: "DELETE",
334
+ path: args.media_id,
335
+ query: {
336
+ ...(args.phone_number_id ? { phone_number_id: args.phone_number_id } : {})
337
+ }
338
+ }));
339
+ },
340
+ async getRecentWebhookEvents(args) {
341
+ return {
342
+ payload: {
343
+ events: eventStore.list(args.limit ?? 20)
344
+ }
345
+ };
346
+ }
347
+ };
348
+ }
349
+ function toToolResult(result) {
350
+ return {
351
+ content: [
352
+ {
353
+ type: "text",
354
+ text: JSON.stringify(result, null, 2)
355
+ }
356
+ ],
357
+ structuredContent: result
358
+ };
359
+ }
360
+ export function registerWhatsAppTools(server, client, config, eventStore) {
361
+ const handlers = createToolHandlers(client, config, eventStore);
362
+ server.tool("whatsapp_get_owned_wabas", "List WhatsApp Business Accounts owned by the configured business.", {
363
+ business_id: z.string().optional()
364
+ }, async (args) => toToolResult(await handlers.getOwnedWabas(args)));
365
+ server.tool("whatsapp_get_waba", "Fetch metadata for a WhatsApp Business Account.", {
366
+ waba_id: z.string().optional()
367
+ }, async (args) => toToolResult(await handlers.getWaba(args)));
368
+ server.tool("whatsapp_get_phone_numbers", "List phone numbers attached to a WhatsApp Business Account.", {
369
+ waba_id: z.string().optional()
370
+ }, async (args) => toToolResult(await handlers.getPhoneNumbers(args)));
371
+ server.tool("whatsapp_register_phone_number", "Register a WhatsApp phone number and set the 6-digit verification PIN.", {
372
+ phone_number_id: z.string().optional(),
373
+ pin: z.string().regex(/^\d{6}$/)
374
+ }, async (args) => toToolResult(await handlers.registerPhoneNumber(args)));
375
+ server.tool("whatsapp_request_verification_code", "Request an SMS or voice verification code for a phone number.", {
376
+ phone_number_id: z.string().optional(),
377
+ code_method: z.enum(["SMS", "VOICE"]),
378
+ locale: z.string()
379
+ }, async (args) => toToolResult(await handlers.requestVerificationCode(args)));
380
+ server.tool("whatsapp_verify_code", "Verify a phone number using a previously requested code.", {
381
+ phone_number_id: z.string().optional(),
382
+ code: z.string().min(1)
383
+ }, async (args) => toToolResult(await handlers.verifyCode(args)));
384
+ server.tool("whatsapp_get_subscribed_apps", "List apps subscribed to the configured WABA webhooks.", {
385
+ waba_id: z.string().optional()
386
+ }, async (args) => toToolResult(await handlers.getSubscribedApps(args)));
387
+ server.tool("whatsapp_subscribe_app", "Subscribe the current app to receive webhook events for the configured WABA.", {
388
+ waba_id: z.string().optional()
389
+ }, async (args) => toToolResult(await handlers.subscribeApp(args)));
390
+ server.tool("whatsapp_unsubscribe_app", "Unsubscribe the current app from the configured WABA webhooks.", {
391
+ waba_id: z.string().optional()
392
+ }, async (args) => toToolResult(await handlers.unsubscribeApp(args)));
393
+ server.tool("whatsapp_debug_access_token", "Debug the configured access token using Graph API token introspection.", {}, async () => toToolResult(await handlers.debugAccessToken()));
394
+ server.tool("whatsapp_get_business_profile", "Fetch the WhatsApp business profile for a phone number.", {
395
+ phone_number_id: z.string().optional(),
396
+ fields: z.array(z.string()).optional()
397
+ }, async (args) => toToolResult(await handlers.getBusinessProfile(args)));
398
+ server.tool("whatsapp_update_business_profile", "Update the WhatsApp business profile for a phone number.", {
399
+ phone_number_id: z.string().optional(),
400
+ address: z.string().optional(),
401
+ description: z.string().optional(),
402
+ vertical: z.string().optional(),
403
+ about: z.string().optional(),
404
+ email: z.string().email().optional(),
405
+ websites: z.array(z.string().url()).max(2).optional(),
406
+ profile_picture_handle: z.string().optional()
407
+ }, async (args) => toToolResult(await handlers.updateBusinessProfile(args)));
408
+ server.tool("whatsapp_get_blocked_users", "List WhatsApp users blocked by the business phone number.", {
409
+ phone_number_id: z.string().optional()
410
+ }, async (args) => toToolResult(await handlers.getBlockedUsers(args)));
411
+ server.tool("whatsapp_block_users", "Block one or more WhatsApp users.", {
412
+ phone_number_id: z.string().optional(),
413
+ users: z.array(z.string()).min(1)
414
+ }, async (args) => toToolResult(await handlers.blockUsers(args)));
415
+ server.tool("whatsapp_unblock_users", "Unblock one or more WhatsApp users.", {
416
+ phone_number_id: z.string().optional(),
417
+ users: z.array(z.string()).min(1)
418
+ }, async (args) => toToolResult(await handlers.unblockUsers(args)));
419
+ server.tool("whatsapp_get_templates", "List message templates for the configured WABA.", {
420
+ waba_id: z.string().optional(),
421
+ limit: z.number().int().positive().optional(),
422
+ name: z.string().optional(),
423
+ fields: z.array(z.string()).optional()
424
+ }, async (args) => toToolResult(await handlers.getTemplates(args)));
425
+ server.tool("whatsapp_get_template_by_id", "Fetch a message template by template ID.", {
426
+ template_id: z.string(),
427
+ fields: z.array(z.string()).optional()
428
+ }, async (args) => toToolResult(await handlers.getTemplateById(args)));
429
+ server.tool("whatsapp_create_template", "Create a WhatsApp message template with a generic components payload.", {
430
+ waba_id: z.string().optional(),
431
+ name: z.string(),
432
+ language: z.string(),
433
+ category: z.string(),
434
+ components: z.array(z.record(z.string(), z.any())),
435
+ allow_category_change: z.boolean().optional()
436
+ }, async (args) => toToolResult(await handlers.createTemplate(args)));
437
+ server.tool("whatsapp_delete_template_by_name", "Delete a WhatsApp message template by name.", {
438
+ waba_id: z.string().optional(),
439
+ name: z.string()
440
+ }, async (args) => toToolResult(await handlers.deleteTemplateByName(args)));
441
+ server.tool("whatsapp_send_text_message", "Send a plain text WhatsApp message.", {
442
+ to: z.string(),
443
+ body: z.string().min(1),
444
+ phone_number_id: z.string().optional(),
445
+ preview_url: z.boolean().optional(),
446
+ context_message_id: z.string().optional()
447
+ }, async (args) => toToolResult(await handlers.sendTextMessage(args)));
448
+ server.tool("whatsapp_send_template_message", "Send a template WhatsApp message.", {
449
+ to: z.string(),
450
+ name: z.string(),
451
+ languageCode: z.string(),
452
+ components: z.array(z.custom()).optional(),
453
+ phone_number_id: z.string().optional(),
454
+ previewUrl: z.boolean().optional(),
455
+ contextMessageId: z.string().optional()
456
+ }, async (args) => toToolResult(await handlers.sendTemplateMessage(args)));
457
+ server.tool("whatsapp_send_media_message", "Send an image, document, audio, sticker, or video message.", {
458
+ to: z.string(),
459
+ media_type: z.enum(["audio", "document", "image", "sticker", "video"]),
460
+ media_id: z.string().optional(),
461
+ link: z.string().url().optional(),
462
+ caption: z.string().optional(),
463
+ filename: z.string().optional(),
464
+ phone_number_id: z.string().optional(),
465
+ context_message_id: z.string().optional()
466
+ }, async (args) => toToolResult(await handlers.sendMediaMessage(args)));
467
+ server.tool("whatsapp_send_raw_message", "Send a raw WhatsApp Cloud API message body for unsupported message variants.", {
468
+ phone_number_id: z.string().optional(),
469
+ body: z.record(z.string(), z.any())
470
+ }, async (args) => toToolResult(await handlers.sendRawMessage(args)));
471
+ server.tool("whatsapp_mark_message_as_read", "Mark a WhatsApp message as read.", {
472
+ message_id: z.string(),
473
+ phone_number_id: z.string().optional()
474
+ }, async (args) => toToolResult(await handlers.markMessageAsRead(args)));
475
+ server.tool("whatsapp_upload_media", "Upload a local media file to WhatsApp Cloud API for later reuse.", {
476
+ file_path: z.string(),
477
+ mime_type: z.string(),
478
+ phone_number_id: z.string().optional(),
479
+ filename: z.string().optional()
480
+ }, async (args) => toToolResult(await handlers.uploadMedia(args)));
481
+ server.tool("whatsapp_get_media_url", "Fetch metadata and download URL for an uploaded WhatsApp media asset.", {
482
+ media_id: z.string()
483
+ }, async (args) => toToolResult(await handlers.getMediaUrl(args)));
484
+ server.tool("whatsapp_delete_media", "Delete an uploaded WhatsApp media asset.", {
485
+ media_id: z.string(),
486
+ phone_number_id: z.string().optional()
487
+ }, async (args) => toToolResult(await handlers.deleteMedia(args)));
488
+ server.tool("whatsapp_get_recent_webhook_events", "Return recently received inbound messages and delivery status events kept in memory.", {
489
+ limit: z.number().int().positive().max(100).optional()
490
+ }, async (args) => toToolResult(await handlers.getRecentWebhookEvents(args)));
491
+ }
492
+ function registerAdditionalWhatsAppTools(server, client, config) {
493
+ const rawRequest = async (request) => toToolResult(formatToolResult(await client.safeRequest(request)));
494
+ const sendMessage = async (args) => rawRequest({
495
+ method: "POST",
496
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/messages`,
497
+ body: withContext(args.body, args.context_message_id)
498
+ });
499
+ const createTemplate = async (args) => rawRequest({
500
+ method: "POST",
501
+ path: `${resolveWabaId(config, args.waba_id)}/message_templates`,
502
+ body: {
503
+ name: args.name,
504
+ language: args.language,
505
+ category: args.category,
506
+ components: args.components,
507
+ ...(args.allow_category_change !== undefined ? { allow_category_change: args.allow_category_change } : {})
508
+ }
509
+ });
510
+ server.tool("whatsapp_get_shared_wabas", "List WhatsApp Business Accounts shared with the configured business.", {
511
+ business_id: z.string().optional()
512
+ }, async (args) => rawRequest({
513
+ path: `${resolveBusinessId(config, args.business_id)}/client_whatsapp_business_accounts`
514
+ }));
515
+ server.tool("whatsapp_deregister_phone", "Deregister a previously registered phone number.", {
516
+ phone_number_id: z.string().optional()
517
+ }, async (args) => rawRequest({
518
+ method: "POST",
519
+ path: `${resolvePhoneNumberId(config, args.phone_number_id)}/deregister`
520
+ }));
521
+ server.tool("whatsapp_get_phone_number_by_id", "Fetch a single business phone number by phone number ID.", {
522
+ phone_number_id: z.string().optional(),
523
+ fields: z.array(z.string()).optional()
524
+ }, async (args) => rawRequest({
525
+ path: resolvePhoneNumberId(config, args.phone_number_id),
526
+ query: args.fields && args.fields.length > 0 ? { fields: args.fields.join(",") } : undefined
527
+ }));
528
+ server.tool("whatsapp_get_display_name_status", "Fetch the beta display-name approval status for a phone number.", {
529
+ phone_number_id: z.string().optional()
530
+ }, async (args) => rawRequest({
531
+ path: resolvePhoneNumberId(config, args.phone_number_id),
532
+ query: {
533
+ fields: "name_status"
534
+ }
535
+ }));
536
+ server.tool("whatsapp_get_phone_numbers_with_filtering", "List WABA phone numbers using the filtering beta query parameters.", {
537
+ waba_id: z.string().optional(),
538
+ fields: z.string().optional(),
539
+ filtering: z.string().optional()
540
+ }, async (args) => rawRequest({
541
+ path: `${resolveWabaId(config, args.waba_id)}/phone_numbers`,
542
+ query: {
543
+ ...(args.fields ? { fields: args.fields } : {}),
544
+ ...(args.filtering ? { filtering: args.filtering } : {})
545
+ }
546
+ }));
547
+ server.tool("whatsapp_set_two_step_verification_code", "Change the two-step verification PIN for a phone number.", {
548
+ phone_number_id: z.string().optional(),
549
+ pin: z.string().regex(/^\d{6}$/)
550
+ }, async (args) => rawRequest({
551
+ method: "POST",
552
+ path: resolvePhoneNumberId(config, args.phone_number_id),
553
+ body: {
554
+ pin: args.pin
555
+ }
556
+ }));
557
+ server.tool("whatsapp_override_callback_url", "Subscribe a WABA with an override callback URL and verify token.", {
558
+ waba_id: z.string().optional(),
559
+ override_callback_uri: z.string().url(),
560
+ verify_token: z.string().min(1)
561
+ }, async (args) => rawRequest({
562
+ method: "POST",
563
+ path: `${resolveWabaId(config, args.waba_id)}/subscribed_apps`,
564
+ body: {
565
+ override_callback_uri: args.override_callback_uri,
566
+ verify_token: args.verify_token
567
+ }
568
+ }));
569
+ server.tool("whatsapp_send_reply_to_text_message", "Send a text reply to a previously received WhatsApp message.", {
570
+ to: z.string(),
571
+ body: z.string().min(1),
572
+ context_message_id: z.string(),
573
+ phone_number_id: z.string().optional()
574
+ }, async (args) => sendMessage({
575
+ phone_number_id: args.phone_number_id,
576
+ context_message_id: args.context_message_id,
577
+ body: {
578
+ messaging_product: "whatsapp",
579
+ recipient_type: "individual",
580
+ to: args.to,
581
+ type: "text",
582
+ text: { body: args.body }
583
+ }
584
+ }));
585
+ server.tool("whatsapp_send_text_message_with_preview_url", "Send a text message with URL previews enabled.", {
586
+ to: z.string(),
587
+ body: z.string().min(1),
588
+ phone_number_id: z.string().optional(),
589
+ context_message_id: z.string().optional()
590
+ }, async (args) => sendMessage({
591
+ phone_number_id: args.phone_number_id,
592
+ context_message_id: args.context_message_id,
593
+ body: {
594
+ messaging_product: "whatsapp",
595
+ recipient_type: "individual",
596
+ to: args.to,
597
+ type: "text",
598
+ text: { body: args.body, preview_url: true }
599
+ }
600
+ }));
601
+ server.tool("whatsapp_send_reply_with_reaction_message", "Send a reaction reply to an existing WhatsApp message.", {
602
+ to: z.string(),
603
+ reaction_message_id: z.string(),
604
+ emoji: z.string().min(1),
605
+ phone_number_id: z.string().optional()
606
+ }, async (args) => sendMessage({
607
+ phone_number_id: args.phone_number_id,
608
+ body: {
609
+ messaging_product: "whatsapp",
610
+ recipient_type: "individual",
611
+ to: args.to,
612
+ type: "reaction",
613
+ reaction: {
614
+ message_id: args.reaction_message_id,
615
+ emoji: args.emoji
616
+ }
617
+ }
618
+ }));
619
+ server.tool("whatsapp_send_image_message_by_id", "Send an image message using an uploaded media ID.", {
620
+ to: z.string(),
621
+ media_id: z.string(),
622
+ caption: z.string().optional(),
623
+ phone_number_id: z.string().optional(),
624
+ context_message_id: z.string().optional()
625
+ }, async (args) => sendMessage({
626
+ phone_number_id: args.phone_number_id,
627
+ context_message_id: args.context_message_id,
628
+ body: {
629
+ messaging_product: "whatsapp",
630
+ recipient_type: "individual",
631
+ to: args.to,
632
+ type: "image",
633
+ image: {
634
+ id: args.media_id,
635
+ ...(args.caption ? { caption: args.caption } : {})
636
+ }
637
+ }
638
+ }));
639
+ server.tool("whatsapp_send_reply_to_image_message_by_id", "Reply to a message with an uploaded image media ID.", {
640
+ to: z.string(),
641
+ media_id: z.string(),
642
+ context_message_id: z.string(),
643
+ caption: z.string().optional(),
644
+ phone_number_id: z.string().optional()
645
+ }, async (args) => sendMessage({
646
+ phone_number_id: args.phone_number_id,
647
+ context_message_id: args.context_message_id,
648
+ body: {
649
+ messaging_product: "whatsapp",
650
+ recipient_type: "individual",
651
+ to: args.to,
652
+ type: "image",
653
+ image: {
654
+ id: args.media_id,
655
+ ...(args.caption ? { caption: args.caption } : {})
656
+ }
657
+ }
658
+ }));
659
+ server.tool("whatsapp_send_image_message_by_url", "Send an image message using a public URL.", {
660
+ to: z.string(),
661
+ link: z.string().url(),
662
+ caption: z.string().optional(),
663
+ phone_number_id: z.string().optional(),
664
+ context_message_id: z.string().optional()
665
+ }, async (args) => sendMessage({
666
+ phone_number_id: args.phone_number_id,
667
+ context_message_id: args.context_message_id,
668
+ body: {
669
+ messaging_product: "whatsapp",
670
+ recipient_type: "individual",
671
+ to: args.to,
672
+ type: "image",
673
+ image: {
674
+ link: args.link,
675
+ ...(args.caption ? { caption: args.caption } : {})
676
+ }
677
+ }
678
+ }));
679
+ server.tool("whatsapp_send_reply_to_image_message_by_url", "Reply with an image using a public URL.", {
680
+ to: z.string(),
681
+ link: z.string().url(),
682
+ context_message_id: z.string(),
683
+ caption: z.string().optional(),
684
+ phone_number_id: z.string().optional()
685
+ }, async (args) => sendMessage({
686
+ phone_number_id: args.phone_number_id,
687
+ context_message_id: args.context_message_id,
688
+ body: {
689
+ messaging_product: "whatsapp",
690
+ recipient_type: "individual",
691
+ to: args.to,
692
+ type: "image",
693
+ image: {
694
+ link: args.link,
695
+ ...(args.caption ? { caption: args.caption } : {})
696
+ }
697
+ }
698
+ }));
699
+ server.tool("whatsapp_send_audio_message_by_id", "Send an audio message using an uploaded media ID.", {
700
+ to: z.string(),
701
+ media_id: z.string(),
702
+ phone_number_id: z.string().optional(),
703
+ context_message_id: z.string().optional()
704
+ }, async (args) => sendMessage({
705
+ phone_number_id: args.phone_number_id,
706
+ context_message_id: args.context_message_id,
707
+ body: {
708
+ messaging_product: "whatsapp",
709
+ recipient_type: "individual",
710
+ to: args.to,
711
+ type: "audio",
712
+ audio: { id: args.media_id }
713
+ }
714
+ }));
715
+ server.tool("whatsapp_send_audio_message_by_url", "Send an audio message using a public URL.", {
716
+ to: z.string(),
717
+ link: z.string().url(),
718
+ phone_number_id: z.string().optional(),
719
+ context_message_id: z.string().optional()
720
+ }, async (args) => sendMessage({
721
+ phone_number_id: args.phone_number_id,
722
+ context_message_id: args.context_message_id,
723
+ body: {
724
+ messaging_product: "whatsapp",
725
+ recipient_type: "individual",
726
+ to: args.to,
727
+ type: "audio",
728
+ audio: { link: args.link }
729
+ }
730
+ }));
731
+ server.tool("whatsapp_send_video_message_by_id", "Send a video message using an uploaded media ID.", {
732
+ to: z.string(),
733
+ media_id: z.string(),
734
+ caption: z.string().optional(),
735
+ phone_number_id: z.string().optional(),
736
+ context_message_id: z.string().optional()
737
+ }, async (args) => sendMessage({
738
+ phone_number_id: args.phone_number_id,
739
+ context_message_id: args.context_message_id,
740
+ body: {
741
+ messaging_product: "whatsapp",
742
+ recipient_type: "individual",
743
+ to: args.to,
744
+ type: "video",
745
+ video: {
746
+ id: args.media_id,
747
+ ...(args.caption ? { caption: args.caption } : {})
748
+ }
749
+ }
750
+ }));
751
+ server.tool("whatsapp_send_video_message_by_url", "Send a video message using a public URL.", {
752
+ to: z.string(),
753
+ link: z.string().url(),
754
+ caption: z.string().optional(),
755
+ phone_number_id: z.string().optional(),
756
+ context_message_id: z.string().optional()
757
+ }, async (args) => sendMessage({
758
+ phone_number_id: args.phone_number_id,
759
+ context_message_id: args.context_message_id,
760
+ body: {
761
+ messaging_product: "whatsapp",
762
+ recipient_type: "individual",
763
+ to: args.to,
764
+ type: "video",
765
+ video: {
766
+ link: args.link,
767
+ ...(args.caption ? { caption: args.caption } : {})
768
+ }
769
+ }
770
+ }));
771
+ server.tool("whatsapp_send_document_message_by_id", "Send a document message using an uploaded media ID.", {
772
+ to: z.string(),
773
+ media_id: z.string(),
774
+ caption: z.string().optional(),
775
+ filename: z.string().optional(),
776
+ phone_number_id: z.string().optional(),
777
+ context_message_id: z.string().optional()
778
+ }, async (args) => sendMessage({
779
+ phone_number_id: args.phone_number_id,
780
+ context_message_id: args.context_message_id,
781
+ body: {
782
+ messaging_product: "whatsapp",
783
+ recipient_type: "individual",
784
+ to: args.to,
785
+ type: "document",
786
+ document: {
787
+ id: args.media_id,
788
+ ...(args.caption ? { caption: args.caption } : {}),
789
+ ...(args.filename ? { filename: args.filename } : {})
790
+ }
791
+ }
792
+ }));
793
+ server.tool("whatsapp_send_document_message_by_url", "Send a document message using a public URL.", {
794
+ to: z.string(),
795
+ link: z.string().url(),
796
+ caption: z.string().optional(),
797
+ filename: z.string().optional(),
798
+ phone_number_id: z.string().optional(),
799
+ context_message_id: z.string().optional()
800
+ }, async (args) => sendMessage({
801
+ phone_number_id: args.phone_number_id,
802
+ context_message_id: args.context_message_id,
803
+ body: {
804
+ messaging_product: "whatsapp",
805
+ recipient_type: "individual",
806
+ to: args.to,
807
+ type: "document",
808
+ document: {
809
+ link: args.link,
810
+ ...(args.caption ? { caption: args.caption } : {}),
811
+ ...(args.filename ? { filename: args.filename } : {})
812
+ }
813
+ }
814
+ }));
815
+ server.tool("whatsapp_send_sticker_message_by_id", "Send a sticker message using an uploaded media ID.", {
816
+ to: z.string(),
817
+ media_id: z.string(),
818
+ phone_number_id: z.string().optional(),
819
+ context_message_id: z.string().optional()
820
+ }, async (args) => sendMessage({
821
+ phone_number_id: args.phone_number_id,
822
+ context_message_id: args.context_message_id,
823
+ body: {
824
+ messaging_product: "whatsapp",
825
+ recipient_type: "individual",
826
+ to: args.to,
827
+ type: "sticker",
828
+ sticker: { id: args.media_id }
829
+ }
830
+ }));
831
+ server.tool("whatsapp_send_sticker_message_by_url", "Send a sticker message using a public URL.", {
832
+ to: z.string(),
833
+ link: z.string().url(),
834
+ phone_number_id: z.string().optional(),
835
+ context_message_id: z.string().optional()
836
+ }, async (args) => sendMessage({
837
+ phone_number_id: args.phone_number_id,
838
+ context_message_id: args.context_message_id,
839
+ body: {
840
+ messaging_product: "whatsapp",
841
+ recipient_type: "individual",
842
+ to: args.to,
843
+ type: "sticker",
844
+ sticker: { link: args.link }
845
+ }
846
+ }));
847
+ server.tool("whatsapp_send_contact_message", "Send a contact card message.", {
848
+ to: z.string(),
849
+ contacts: z.array(z.record(z.string(), z.any())).min(1),
850
+ phone_number_id: z.string().optional(),
851
+ context_message_id: z.string().optional()
852
+ }, async (args) => sendMessage({
853
+ phone_number_id: args.phone_number_id,
854
+ context_message_id: args.context_message_id,
855
+ body: {
856
+ messaging_product: "whatsapp",
857
+ recipient_type: "individual",
858
+ to: args.to,
859
+ type: "contacts",
860
+ contacts: args.contacts
861
+ }
862
+ }));
863
+ server.tool("whatsapp_send_reply_to_contact_message", "Reply with a contact card message.", {
864
+ to: z.string(),
865
+ contacts: z.array(z.record(z.string(), z.any())).min(1),
866
+ context_message_id: z.string(),
867
+ phone_number_id: z.string().optional()
868
+ }, async (args) => sendMessage({
869
+ phone_number_id: args.phone_number_id,
870
+ context_message_id: args.context_message_id,
871
+ body: {
872
+ messaging_product: "whatsapp",
873
+ recipient_type: "individual",
874
+ to: args.to,
875
+ type: "contacts",
876
+ contacts: args.contacts
877
+ }
878
+ }));
879
+ server.tool("whatsapp_send_location_message", "Send a location message.", {
880
+ to: z.string(),
881
+ location: z.record(z.string(), z.any()),
882
+ phone_number_id: z.string().optional(),
883
+ context_message_id: z.string().optional()
884
+ }, async (args) => sendMessage({
885
+ phone_number_id: args.phone_number_id,
886
+ context_message_id: args.context_message_id,
887
+ body: {
888
+ messaging_product: "whatsapp",
889
+ recipient_type: "individual",
890
+ to: args.to,
891
+ type: "location",
892
+ location: args.location
893
+ }
894
+ }));
895
+ server.tool("whatsapp_send_reply_to_location_message", "Reply with a location message.", {
896
+ to: z.string(),
897
+ location: z.record(z.string(), z.any()),
898
+ context_message_id: z.string(),
899
+ phone_number_id: z.string().optional()
900
+ }, async (args) => sendMessage({
901
+ phone_number_id: args.phone_number_id,
902
+ context_message_id: args.context_message_id,
903
+ body: {
904
+ messaging_product: "whatsapp",
905
+ recipient_type: "individual",
906
+ to: args.to,
907
+ type: "location",
908
+ location: args.location
909
+ }
910
+ }));
911
+ server.tool("whatsapp_send_message_template_text", "Send a template message using a text-oriented template payload.", {
912
+ to: z.string(),
913
+ template: z.record(z.string(), z.any()),
914
+ phone_number_id: z.string().optional(),
915
+ context_message_id: z.string().optional()
916
+ }, async (args) => sendMessage({
917
+ phone_number_id: args.phone_number_id,
918
+ context_message_id: args.context_message_id,
919
+ body: {
920
+ messaging_product: "whatsapp",
921
+ recipient_type: "individual",
922
+ to: args.to,
923
+ type: "template",
924
+ template: args.template
925
+ }
926
+ }));
927
+ server.tool("whatsapp_send_message_template_media", "Send a template message using a media-oriented template payload.", {
928
+ to: z.string(),
929
+ template: z.record(z.string(), z.any()),
930
+ phone_number_id: z.string().optional(),
931
+ context_message_id: z.string().optional()
932
+ }, async (args) => sendMessage({
933
+ phone_number_id: args.phone_number_id,
934
+ context_message_id: args.context_message_id,
935
+ body: {
936
+ messaging_product: "whatsapp",
937
+ recipient_type: "individual",
938
+ to: args.to,
939
+ type: "template",
940
+ template: args.template
941
+ }
942
+ }));
943
+ server.tool("whatsapp_send_message_template_interactive", "Send a template message using an interactive template payload.", {
944
+ to: z.string(),
945
+ template: z.record(z.string(), z.any()),
946
+ phone_number_id: z.string().optional(),
947
+ context_message_id: z.string().optional()
948
+ }, async (args) => sendMessage({
949
+ phone_number_id: args.phone_number_id,
950
+ context_message_id: args.context_message_id,
951
+ body: {
952
+ messaging_product: "whatsapp",
953
+ recipient_type: "individual",
954
+ to: args.to,
955
+ type: "template",
956
+ template: args.template
957
+ }
958
+ }));
959
+ server.tool("whatsapp_send_list_message", "Send an interactive list message.", {
960
+ to: z.string(),
961
+ interactive: z.record(z.string(), z.any()),
962
+ phone_number_id: z.string().optional(),
963
+ context_message_id: z.string().optional()
964
+ }, async (args) => sendMessage({
965
+ phone_number_id: args.phone_number_id,
966
+ context_message_id: args.context_message_id,
967
+ body: {
968
+ messaging_product: "whatsapp",
969
+ recipient_type: "individual",
970
+ to: args.to,
971
+ type: "interactive",
972
+ interactive: args.interactive
973
+ }
974
+ }));
975
+ server.tool("whatsapp_send_reply_to_list_message", "Reply with an interactive list message.", {
976
+ to: z.string(),
977
+ interactive: z.record(z.string(), z.any()),
978
+ context_message_id: z.string(),
979
+ phone_number_id: z.string().optional()
980
+ }, async (args) => sendMessage({
981
+ phone_number_id: args.phone_number_id,
982
+ context_message_id: args.context_message_id,
983
+ body: {
984
+ messaging_product: "whatsapp",
985
+ recipient_type: "individual",
986
+ to: args.to,
987
+ type: "interactive",
988
+ interactive: args.interactive
989
+ }
990
+ }));
991
+ server.tool("whatsapp_send_reply_button", "Send an interactive reply-button message.", {
992
+ to: z.string(),
993
+ interactive: z.record(z.string(), z.any()),
994
+ phone_number_id: z.string().optional(),
995
+ context_message_id: z.string().optional()
996
+ }, async (args) => sendMessage({
997
+ phone_number_id: args.phone_number_id,
998
+ context_message_id: args.context_message_id,
999
+ body: {
1000
+ messaging_product: "whatsapp",
1001
+ recipient_type: "individual",
1002
+ to: args.to,
1003
+ type: "interactive",
1004
+ interactive: args.interactive
1005
+ }
1006
+ }));
1007
+ server.tool("whatsapp_send_single_product_message", "Send an interactive single-product message.", {
1008
+ to: z.string(),
1009
+ interactive: z.record(z.string(), z.any()),
1010
+ phone_number_id: z.string().optional(),
1011
+ context_message_id: z.string().optional()
1012
+ }, async (args) => sendMessage({
1013
+ phone_number_id: args.phone_number_id,
1014
+ context_message_id: args.context_message_id,
1015
+ body: {
1016
+ messaging_product: "whatsapp",
1017
+ recipient_type: "individual",
1018
+ to: args.to,
1019
+ type: "interactive",
1020
+ interactive: args.interactive
1021
+ }
1022
+ }));
1023
+ server.tool("whatsapp_send_multi_product_message", "Send an interactive multi-product message.", {
1024
+ to: z.string(),
1025
+ interactive: z.record(z.string(), z.any()),
1026
+ phone_number_id: z.string().optional(),
1027
+ context_message_id: z.string().optional()
1028
+ }, async (args) => sendMessage({
1029
+ phone_number_id: args.phone_number_id,
1030
+ context_message_id: args.context_message_id,
1031
+ body: {
1032
+ messaging_product: "whatsapp",
1033
+ recipient_type: "individual",
1034
+ to: args.to,
1035
+ type: "interactive",
1036
+ interactive: args.interactive
1037
+ }
1038
+ }));
1039
+ server.tool("whatsapp_send_catalog_message", "Send an interactive catalog message.", {
1040
+ to: z.string(),
1041
+ interactive: z.record(z.string(), z.any()),
1042
+ phone_number_id: z.string().optional(),
1043
+ context_message_id: z.string().optional()
1044
+ }, async (args) => sendMessage({
1045
+ phone_number_id: args.phone_number_id,
1046
+ context_message_id: args.context_message_id,
1047
+ body: {
1048
+ messaging_product: "whatsapp",
1049
+ recipient_type: "individual",
1050
+ to: args.to,
1051
+ type: "interactive",
1052
+ interactive: args.interactive
1053
+ }
1054
+ }));
1055
+ server.tool("whatsapp_send_catalog_template_message", "Send a template payload for a catalog-oriented template message.", {
1056
+ to: z.string(),
1057
+ template: z.record(z.string(), z.any()),
1058
+ phone_number_id: z.string().optional(),
1059
+ context_message_id: z.string().optional()
1060
+ }, async (args) => sendMessage({
1061
+ phone_number_id: args.phone_number_id,
1062
+ context_message_id: args.context_message_id,
1063
+ body: {
1064
+ messaging_product: "whatsapp",
1065
+ recipient_type: "individual",
1066
+ to: args.to,
1067
+ type: "template",
1068
+ template: args.template
1069
+ }
1070
+ }));
1071
+ server.tool("whatsapp_get_template_by_name_default_fields", "Fetch a template by name using the collection's default fields.", {
1072
+ waba_id: z.string().optional(),
1073
+ name: z.string()
1074
+ }, async (args) => rawRequest({
1075
+ path: `${resolveWabaId(config, args.waba_id)}/message_templates`,
1076
+ query: { name: args.name }
1077
+ }));
1078
+ server.tool("whatsapp_get_all_templates_default_fields", "Fetch all templates using the collection's default fields.", {
1079
+ waba_id: z.string().optional()
1080
+ }, async (args) => rawRequest({
1081
+ path: `${resolveWabaId(config, args.waba_id)}/message_templates`
1082
+ }));
1083
+ server.tool("whatsapp_get_namespace", "Fetch the message template namespace for a WABA.", {
1084
+ waba_id: z.string().optional()
1085
+ }, async (args) => rawRequest({
1086
+ path: resolveWabaId(config, args.waba_id),
1087
+ query: { fields: "message_template_namespace" }
1088
+ }));
1089
+ server.tool("whatsapp_create_auth_template_copy_code", "Create an authentication template with an OTP copy-code button payload.", {
1090
+ waba_id: z.string().optional(),
1091
+ name: z.string(),
1092
+ language: z.string(),
1093
+ category: z.string(),
1094
+ components: z.array(z.record(z.string(), z.any())),
1095
+ allow_category_change: z.boolean().optional()
1096
+ }, async (args) => createTemplate(args));
1097
+ server.tool("whatsapp_create_auth_template_one_tap_autofill", "Create an authentication template with an OTP one-tap autofill payload.", {
1098
+ waba_id: z.string().optional(),
1099
+ name: z.string(),
1100
+ language: z.string(),
1101
+ category: z.string(),
1102
+ components: z.array(z.record(z.string(), z.any())),
1103
+ allow_category_change: z.boolean().optional()
1104
+ }, async (args) => createTemplate(args));
1105
+ server.tool("whatsapp_create_catalog_template", "Create a catalog template payload.", {
1106
+ waba_id: z.string().optional(),
1107
+ name: z.string(),
1108
+ language: z.string(),
1109
+ category: z.string(),
1110
+ components: z.array(z.record(z.string(), z.any())),
1111
+ allow_category_change: z.boolean().optional()
1112
+ }, async (args) => createTemplate(args));
1113
+ server.tool("whatsapp_create_multi_product_template", "Create a multi-product template payload.", {
1114
+ waba_id: z.string().optional(),
1115
+ name: z.string(),
1116
+ language: z.string(),
1117
+ category: z.string(),
1118
+ components: z.array(z.record(z.string(), z.any())),
1119
+ allow_category_change: z.boolean().optional()
1120
+ }, async (args) => createTemplate(args));
1121
+ server.tool("whatsapp_create_template_text_header_quick_replies", "Create a template with text header, footer, and quick replies.", {
1122
+ waba_id: z.string().optional(),
1123
+ name: z.string(),
1124
+ language: z.string(),
1125
+ category: z.string(),
1126
+ components: z.array(z.record(z.string(), z.any())),
1127
+ allow_category_change: z.boolean().optional()
1128
+ }, async (args) => createTemplate(args));
1129
+ server.tool("whatsapp_create_template_image_header_cta", "Create a template with an image header and call-to-action buttons.", {
1130
+ waba_id: z.string().optional(),
1131
+ name: z.string(),
1132
+ language: z.string(),
1133
+ category: z.string(),
1134
+ components: z.array(z.record(z.string(), z.any())),
1135
+ allow_category_change: z.boolean().optional()
1136
+ }, async (args) => createTemplate(args));
1137
+ server.tool("whatsapp_create_template_location_header_website", "Create a template with a location header and website button.", {
1138
+ waba_id: z.string().optional(),
1139
+ name: z.string(),
1140
+ language: z.string(),
1141
+ category: z.string(),
1142
+ components: z.array(z.record(z.string(), z.any())),
1143
+ allow_category_change: z.boolean().optional()
1144
+ }, async (args) => createTemplate(args));
1145
+ server.tool("whatsapp_create_template_document_header_phone_url", "Create a template with a document header plus phone and URL buttons.", {
1146
+ waba_id: z.string().optional(),
1147
+ name: z.string(),
1148
+ language: z.string(),
1149
+ category: z.string(),
1150
+ components: z.array(z.record(z.string(), z.any())),
1151
+ allow_category_change: z.boolean().optional()
1152
+ }, async (args) => createTemplate(args));
1153
+ server.tool("whatsapp_edit_template", "Edit a template directly by template ID.", {
1154
+ template_id: z.string(),
1155
+ name: z.string().optional(),
1156
+ components: z.array(z.record(z.string(), z.any())).optional()
1157
+ }, async (args) => rawRequest({
1158
+ method: "POST",
1159
+ path: args.template_id,
1160
+ body: {
1161
+ ...(args.name ? { name: args.name } : {}),
1162
+ ...(args.components ? { components: args.components } : {})
1163
+ }
1164
+ }));
1165
+ server.tool("whatsapp_delete_template_by_id", "Delete a template by template ID and name.", {
1166
+ waba_id: z.string().optional(),
1167
+ hsm_id: z.string(),
1168
+ name: z.string()
1169
+ }, async (args) => rawRequest({
1170
+ method: "DELETE",
1171
+ path: `${resolveWabaId(config, args.waba_id)}/message_templates`,
1172
+ query: {
1173
+ hsm_id: args.hsm_id,
1174
+ name: args.name
1175
+ }
1176
+ }));
1177
+ }
1178
+ export function createWhatsAppMcpServer(client, config, eventStore) {
1179
+ const server = new McpServer({
1180
+ name: "whatsapp-cloud-api",
1181
+ version: "0.1.0"
1182
+ });
1183
+ registerWhatsAppTools(server, client, config, eventStore);
1184
+ registerAdditionalWhatsAppTools(server, client, config);
1185
+ return server;
1186
+ }
1187
+ //# sourceMappingURL=tools.js.map