@daisyintel/whatsapp-cloud-mcp 0.1.0 → 2.0.0

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