@messegy/mcp 1.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.
Files changed (77) hide show
  1. package/README.md +133 -0
  2. package/api/index.js +3 -0
  3. package/dist/api-client.d.ts +10 -0
  4. package/dist/api-client.js +100 -0
  5. package/dist/api-client.js.map +1 -0
  6. package/dist/cli-setup.d.ts +1 -0
  7. package/dist/cli-setup.js +74 -0
  8. package/dist/cli-setup.js.map +1 -0
  9. package/dist/config.d.ts +18 -0
  10. package/dist/config.js +88 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.js +56 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/lib/quota-guard.d.ts +19 -0
  16. package/dist/lib/quota-guard.js +101 -0
  17. package/dist/lib/quota-guard.js.map +1 -0
  18. package/dist/resources/index.d.ts +2 -0
  19. package/dist/resources/index.js +62 -0
  20. package/dist/resources/index.js.map +1 -0
  21. package/dist/server.d.ts +10 -0
  22. package/dist/server.js +364 -0
  23. package/dist/server.js.map +1 -0
  24. package/dist/tools/analytics.d.ts +2 -0
  25. package/dist/tools/analytics.js +42 -0
  26. package/dist/tools/analytics.js.map +1 -0
  27. package/dist/tools/auth.d.ts +2 -0
  28. package/dist/tools/auth.js +113 -0
  29. package/dist/tools/auth.js.map +1 -0
  30. package/dist/tools/auto-replies.d.ts +2 -0
  31. package/dist/tools/auto-replies.js +117 -0
  32. package/dist/tools/auto-replies.js.map +1 -0
  33. package/dist/tools/broadcasts.d.ts +2 -0
  34. package/dist/tools/broadcasts.js +58 -0
  35. package/dist/tools/broadcasts.js.map +1 -0
  36. package/dist/tools/chats.d.ts +2 -0
  37. package/dist/tools/chats.js +77 -0
  38. package/dist/tools/chats.js.map +1 -0
  39. package/dist/tools/contacts.d.ts +2 -0
  40. package/dist/tools/contacts.js +79 -0
  41. package/dist/tools/contacts.js.map +1 -0
  42. package/dist/tools/flows.d.ts +2 -0
  43. package/dist/tools/flows.js +148 -0
  44. package/dist/tools/flows.js.map +1 -0
  45. package/dist/tools/messages.d.ts +2 -0
  46. package/dist/tools/messages.js +149 -0
  47. package/dist/tools/messages.js.map +1 -0
  48. package/dist/tools/shopify.d.ts +2 -0
  49. package/dist/tools/shopify.js +66 -0
  50. package/dist/tools/shopify.js.map +1 -0
  51. package/dist/tools/templates.d.ts +2 -0
  52. package/dist/tools/templates.js +160 -0
  53. package/dist/tools/templates.js.map +1 -0
  54. package/dist/web-app.d.ts +1 -0
  55. package/dist/web-app.js +845 -0
  56. package/dist/web-app.js.map +1 -0
  57. package/package.json +42 -0
  58. package/src/api-client.ts +112 -0
  59. package/src/cli-setup.ts +87 -0
  60. package/src/config.ts +111 -0
  61. package/src/index.ts +66 -0
  62. package/src/lib/quota-guard.ts +138 -0
  63. package/src/resources/index.ts +70 -0
  64. package/src/server.ts +408 -0
  65. package/src/tools/analytics.ts +58 -0
  66. package/src/tools/auth.ts +136 -0
  67. package/src/tools/auto-replies.ts +144 -0
  68. package/src/tools/broadcasts.ts +73 -0
  69. package/src/tools/chats.ts +100 -0
  70. package/src/tools/contacts.ts +99 -0
  71. package/src/tools/flows.ts +192 -0
  72. package/src/tools/messages.ts +177 -0
  73. package/src/tools/shopify.ts +80 -0
  74. package/src/tools/templates.ts +193 -0
  75. package/src/web-app.ts +844 -0
  76. package/tsconfig.json +18 -0
  77. package/vercel.json +10 -0
@@ -0,0 +1,117 @@
1
+ import { z } from 'zod';
2
+ import { api } from '../api-client.js';
3
+ import { enforcePlanQuota } from '../lib/quota-guard.js';
4
+ export function registerAutoReplyTools(server) {
5
+ /**
6
+ * 1. List Auto-Reply Rules
7
+ */
8
+ server.tool('messegy_list_auto_replies', 'List all keyword-based auto-replies, automated greetings, away messages, and bot trigger rules configured in your Messegy account', {
9
+ status: z.enum(['ALL', 'ACTIVE', 'INACTIVE']).default('ALL').describe('Filter by rule status'),
10
+ search: z.string().optional().describe('Search keyword or trigger title'),
11
+ }, async (params) => {
12
+ const queryParams = {};
13
+ if (params.status !== 'ALL') {
14
+ queryParams.status = params.status.toLowerCase();
15
+ }
16
+ if (params.search) {
17
+ queryParams.search = params.search;
18
+ }
19
+ const result = await api.get('/auto-replies', queryParams);
20
+ const rules = result.data || result.auto_replies || result;
21
+ return {
22
+ content: [
23
+ {
24
+ type: 'text',
25
+ text: `🤖 Found ${Array.isArray(rules) ? rules.length : 0} Auto-Reply rules:\n\n${JSON.stringify(rules, null, 2)}`,
26
+ },
27
+ ],
28
+ };
29
+ });
30
+ /**
31
+ * 2. Create Auto-Reply Rule
32
+ */
33
+ server.tool('messegy_create_auto_reply', 'Create an automated WhatsApp auto-responder triggered by incoming keywords (e.g. "PRICE", "HELLO", "SUPPORT", "HOURS") with custom reply text, interactive buttons, or templates', {
34
+ name: z.string().describe('Rule name / title (e.g. "Price Inquiry Bot", "Welcome Greeting")'),
35
+ trigger_keywords: z.array(z.string()).min(1).describe('Keywords that trigger this auto-reply (e.g. ["price", "cost", "pricing", "rate"])'),
36
+ match_type: z.enum(['EXACT', 'CONTAINS', 'STARTS_WITH', 'FUZZY']).default('CONTAINS').describe('Keyword matching condition'),
37
+ reply_type: z.enum(['TEXT', 'TEMPLATE', 'BUTTONS', 'FLOW']).default('TEXT').describe('Response format'),
38
+ reply_text: z.string().describe('Response message content sent to the customer'),
39
+ template_name: z.string().optional().describe('Approved template name if reply_type is TEMPLATE'),
40
+ buttons: z
41
+ .array(z.object({
42
+ id: z.string(),
43
+ title: z.string(),
44
+ }))
45
+ .optional()
46
+ .describe('Optional quick-reply buttons (max 3) if reply_type is BUTTONS'),
47
+ status: z.enum(['ACTIVE', 'INACTIVE']).default('ACTIVE').describe('Rule initial status'),
48
+ }, async (params) => {
49
+ // 1. Quota & Rule Limit Check
50
+ await enforcePlanQuota('create_auto_reply');
51
+ const payload = {
52
+ name: params.name,
53
+ keywords: params.trigger_keywords,
54
+ match_type: params.match_type.toLowerCase(),
55
+ reply_type: params.reply_type.toLowerCase(),
56
+ response_text: params.reply_text,
57
+ template_name: params.template_name,
58
+ buttons: params.buttons,
59
+ is_active: params.status === 'ACTIVE',
60
+ };
61
+ const result = await api.post('/auto-replies', payload);
62
+ return {
63
+ content: [
64
+ {
65
+ type: 'text',
66
+ text: `✅ Auto-Reply rule "${params.name}" created successfully!\n\n${JSON.stringify(result, null, 2)}`,
67
+ },
68
+ ],
69
+ };
70
+ });
71
+ /**
72
+ * 3. Update Auto-Reply Rule
73
+ */
74
+ server.tool('messegy_update_auto_reply', 'Update, edit keywords, modify response text, or toggle active/inactive status of an existing Auto-Reply rule', {
75
+ rule_id: z.string().describe('Auto-Reply Rule ID'),
76
+ name: z.string().optional().describe('Updated rule title'),
77
+ trigger_keywords: z.array(z.string()).optional().describe('Updated keyword list'),
78
+ reply_text: z.string().optional().describe('Updated response text'),
79
+ status: z.enum(['ACTIVE', 'INACTIVE']).optional().describe('Toggle active / inactive state'),
80
+ }, async (params) => {
81
+ const payload = {};
82
+ if (params.name)
83
+ payload.name = params.name;
84
+ if (params.trigger_keywords)
85
+ payload.keywords = params.trigger_keywords;
86
+ if (params.reply_text)
87
+ payload.response_text = params.reply_text;
88
+ if (params.status)
89
+ payload.is_active = params.status === 'ACTIVE';
90
+ const result = await api.put(`/auto-replies/${encodeURIComponent(params.rule_id)}`, payload);
91
+ return {
92
+ content: [
93
+ {
94
+ type: 'text',
95
+ text: `🔄 Auto-Reply rule [${params.rule_id}] updated successfully!\n\n${JSON.stringify(result, null, 2)}`,
96
+ },
97
+ ],
98
+ };
99
+ });
100
+ /**
101
+ * 4. Delete Auto-Reply Rule
102
+ */
103
+ server.tool('messegy_delete_auto_reply', 'Delete a keyword auto-reply rule from your account', {
104
+ rule_id: z.string().describe('Auto-Reply Rule ID to delete'),
105
+ }, async (params) => {
106
+ const result = await api.delete(`/auto-replies/${encodeURIComponent(params.rule_id)}`);
107
+ return {
108
+ content: [
109
+ {
110
+ type: 'text',
111
+ text: `🗑️ Auto-Reply rule [${params.rule_id}] deleted successfully!\n\n${JSON.stringify(result, null, 2)}`,
112
+ },
113
+ ],
114
+ };
115
+ });
116
+ }
117
+ //# sourceMappingURL=auto-replies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-replies.js","sourceRoot":"","sources":["../../src/tools/auto-replies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerBroadcastTools(server: McpServer): void;
@@ -0,0 +1,58 @@
1
+ import { z } from 'zod';
2
+ import { api } from '../api-client.js';
3
+ import { enforcePlanQuota } from '../lib/quota-guard.js';
4
+ export function registerBroadcastTools(server) {
5
+ /**
6
+ * 1. Create and Launch WhatsApp Broadcast Campaign
7
+ */
8
+ server.tool('messegy_create_broadcast', 'Launch or schedule a bulk WhatsApp marketing / utility broadcast campaign to a list of recipients or a contact tag segment', {
9
+ campaign_name: z.string().describe('Descriptive name for the broadcast campaign'),
10
+ template_name: z.string().describe('Name of the approved template to send'),
11
+ recipients: z.array(z.string()).optional().describe('List of recipient phone numbers with country code'),
12
+ target_tag: z.string().optional().describe('Target contact tag instead of explicit list (e.g. "VIP", "Festival-Leads")'),
13
+ schedule_time: z.string().optional().describe('Optional ISO 8601 timestamp to schedule in the future (e.g. "2026-11-01T10:00:00Z")'),
14
+ }, async (params) => {
15
+ if (!params.recipients?.length && !params.target_tag) {
16
+ return {
17
+ content: [{ type: 'text', text: 'Error: Either "recipients" list or "target_tag" must be provided.' }],
18
+ isError: true,
19
+ };
20
+ }
21
+ // Check quota & daily tier limits
22
+ const count = params.recipients?.length || 1;
23
+ await enforcePlanQuota('send_broadcast', count);
24
+ const payload = {
25
+ name: params.campaign_name,
26
+ template_name: params.template_name,
27
+ recipients: params.recipients?.map((r) => r.replace(/[^\d]/g, '')),
28
+ target_tag: params.target_tag,
29
+ scheduled_at: params.schedule_time,
30
+ };
31
+ const result = await api.post('/v1/broadcasts', payload);
32
+ return {
33
+ content: [
34
+ {
35
+ type: 'text',
36
+ text: `🚀 Broadcast campaign "${params.campaign_name}" created successfully!\n\n${JSON.stringify(result, null, 2)}`,
37
+ },
38
+ ],
39
+ };
40
+ });
41
+ /**
42
+ * 2. Get Broadcast Campaign Analytics
43
+ */
44
+ server.tool('messegy_get_broadcast_stats', 'Fetch real-time analytics (Sent, Delivered, Read, Failed count, Cost) for a WhatsApp broadcast campaign', {
45
+ campaign_id: z.string().describe('Unique ID of the broadcast campaign'),
46
+ }, async (params) => {
47
+ const result = await api.get(`/v1/broadcasts/${encodeURIComponent(params.campaign_id)}`);
48
+ return {
49
+ content: [
50
+ {
51
+ type: 'text',
52
+ text: `📊 Campaign Stats for [${params.campaign_id}]:\n\n${JSON.stringify(result, null, 2)}`,
53
+ },
54
+ ],
55
+ };
56
+ });
57
+ }
58
+ //# sourceMappingURL=broadcasts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcasts.js","sourceRoot":"","sources":["../../src/tools/broadcasts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD;;OAEG;IACH,MAAM,CAAC,IAAI,CACT,0BAA0B,EAC1B,4HAA4H,EAC5H;QACE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;QACjF,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;QAC3E,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;QACxG,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4EAA4E,CAAC;QACxH,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qFAAqF,CAAC;KACrI,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACrD,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,mEAAmE,EAAE,CAAC;gBACtG,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,kCAAkC;QAClC,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,CAAC;QAC7C,MAAM,gBAAgB,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QAEhD,MAAM,OAAO,GAAG;YACd,IAAI,EAAE,MAAM,CAAC,aAAa;YAC1B,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAClE,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,YAAY,EAAE,MAAM,CAAC,aAAa;SACnC,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACzD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,0BAA0B,MAAM,CAAC,aAAa,8BAA8B,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACpH;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF;;OAEG;IACH,MAAM,CAAC,IAAI,CACT,6BAA6B,EAC7B,yGAAyG,EACzG;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;KACxE,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,kBAAkB,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACzF,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,0BAA0B,MAAM,CAAC,WAAW,SAAS,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBAC7F;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerChatTools(server: McpServer): void;
@@ -0,0 +1,77 @@
1
+ import { z } from 'zod';
2
+ import { api } from '../api-client.js';
3
+ export function registerChatTools(server) {
4
+ /**
5
+ * 1. List Recent WhatsApp Chats / Inbox
6
+ */
7
+ server.tool('messegy_list_chats', 'Get a list of active WhatsApp customer chats in the inbox with last message preview and unread status', {
8
+ limit: z.number().min(1).max(50).default(20).describe('Number of chats to fetch'),
9
+ unread_only: z.boolean().default(false).describe('If true, only returns chats with unread customer messages'),
10
+ search: z.string().optional().describe('Search by customer name or phone number'),
11
+ }, async (params) => {
12
+ const queryParams = {
13
+ limit: params.limit,
14
+ };
15
+ if (params.unread_only) {
16
+ queryParams.unread = 'true';
17
+ }
18
+ if (params.search) {
19
+ queryParams.search = params.search;
20
+ }
21
+ const result = await api.get('/v1/chats', queryParams);
22
+ const chats = result.data || result.chats || result;
23
+ return {
24
+ content: [
25
+ {
26
+ type: 'text',
27
+ text: `💬 Fetched ${Array.isArray(chats) ? chats.length : 0} conversation threads:\n\n${JSON.stringify(chats, null, 2)}`,
28
+ },
29
+ ],
30
+ };
31
+ });
32
+ /**
33
+ * 2. Get Chat History of a Customer Thread
34
+ */
35
+ server.tool('messegy_get_chat_history', 'Retrieve the full chronological message history of a specific customer WhatsApp conversation', {
36
+ chat_id: z.string().describe('Unique Chat ID or Customer Phone Number'),
37
+ limit: z.number().min(1).max(100).default(30).describe('Number of recent messages to fetch'),
38
+ }, async (params) => {
39
+ const result = await api.get(`/v1/chats/${encodeURIComponent(params.chat_id)}/messages`, {
40
+ limit: params.limit,
41
+ });
42
+ const messages = result.data || result.messages || result;
43
+ return {
44
+ content: [
45
+ {
46
+ type: 'text',
47
+ text: `📜 Message history for chat [${params.chat_id}]:\n\n${JSON.stringify(messages, null, 2)}`,
48
+ },
49
+ ],
50
+ };
51
+ });
52
+ /**
53
+ * 3. Reply to an Active Chat Thread
54
+ */
55
+ server.tool('messegy_reply_to_chat', 'Send an agent or AI reply message to an ongoing customer WhatsApp chat thread', {
56
+ chat_id: z.string().describe('Chat ID or recipient phone number'),
57
+ text: z.string().describe('Reply message content'),
58
+ attachment_url: z.string().url().optional().describe('Optional media attachment URL'),
59
+ }, async (params) => {
60
+ const payload = {
61
+ message: params.text,
62
+ };
63
+ if (params.attachment_url) {
64
+ payload.attachment_url = params.attachment_url;
65
+ }
66
+ const result = await api.post(`/v1/chats/${encodeURIComponent(params.chat_id)}/reply`, payload);
67
+ return {
68
+ content: [
69
+ {
70
+ type: 'text',
71
+ text: `✅ Reply sent to chat [${params.chat_id}]!\n\n${JSON.stringify(result, null, 2)}`,
72
+ },
73
+ ],
74
+ };
75
+ });
76
+ }
77
+ //# sourceMappingURL=chats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chats.js","sourceRoot":"","sources":["../../src/tools/chats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerContactTools(server: McpServer): void;
@@ -0,0 +1,79 @@
1
+ import { z } from 'zod';
2
+ import { api } from '../api-client.js';
3
+ export function registerContactTools(server) {
4
+ /**
5
+ * 1. Search Contacts & Leads
6
+ */
7
+ server.tool('messegy_search_contacts', 'Search your Messegy WhatsApp CRM contacts by phone number, name, email, or assigned tags', {
8
+ query: z.string().optional().describe('Search query (phone number, name, or email)'),
9
+ tag: z.string().optional().describe('Filter by specific tag (e.g. "VIP", "Hot-Lead")'),
10
+ limit: z.number().min(1).max(100).default(25).describe('Max contacts to return'),
11
+ }, async (params) => {
12
+ const queryParams = {
13
+ limit: params.limit,
14
+ };
15
+ if (params.query)
16
+ queryParams.search = params.query;
17
+ if (params.tag)
18
+ queryParams.tag = params.tag;
19
+ const result = await api.get('/v1/contacts', queryParams);
20
+ const contacts = result.data || result.contacts || result;
21
+ return {
22
+ content: [
23
+ {
24
+ type: 'text',
25
+ text: `👥 Found contacts:\n\n${JSON.stringify(contacts, null, 2)}`,
26
+ },
27
+ ],
28
+ };
29
+ });
30
+ /**
31
+ * 2. Create / Upsert Contact
32
+ */
33
+ server.tool('messegy_create_contact', 'Add a new contact or update existing lead in Messegy CRM with name, phone number, and custom attributes', {
34
+ phone_number: z.string().describe('Phone number with country code (e.g. 919876543210)'),
35
+ name: z.string().optional().describe('Customer full name'),
36
+ email: z.string().email().optional().describe('Customer email address'),
37
+ tags: z.array(z.string()).optional().describe('List of tags to assign (e.g. ["Website-Lead", "Qualified"])'),
38
+ custom_fields: z.record(z.any()).optional().describe('Key-value custom attributes (e.g. {"city": "Mumbai", "deal_value": 50000})'),
39
+ }, async (params) => {
40
+ const cleanPhone = params.phone_number.replace(/[^\d]/g, '');
41
+ const payload = {
42
+ phone_number: cleanPhone,
43
+ name: params.name,
44
+ email: params.email,
45
+ tags: params.tags,
46
+ custom_fields: params.custom_fields,
47
+ };
48
+ const result = await api.post('/v1/contacts', payload);
49
+ return {
50
+ content: [
51
+ {
52
+ type: 'text',
53
+ text: `✅ Contact +${cleanPhone} created/updated successfully!\n\n${JSON.stringify(result, null, 2)}`,
54
+ },
55
+ ],
56
+ };
57
+ });
58
+ /**
59
+ * 3. Add Tag to Contact
60
+ */
61
+ server.tool('messegy_add_tag_to_contact', 'Assign a tag (e.g. "VIP", "Hot-Lead", "Payment-Pending") to a customer for segmentation and broadcast targeting', {
62
+ phone_number: z.string().describe('Customer phone number'),
63
+ tag: z.string().describe('Tag name to assign'),
64
+ }, async (params) => {
65
+ const cleanPhone = params.phone_number.replace(/[^\d]/g, '');
66
+ const result = await api.post(`/v1/contacts/${cleanPhone}/tags`, {
67
+ tag: params.tag,
68
+ });
69
+ return {
70
+ content: [
71
+ {
72
+ type: 'text',
73
+ text: `🏷️ Tag "${params.tag}" added to contact +${cleanPhone}!\n\n${JSON.stringify(result, null, 2)}`,
74
+ },
75
+ ],
76
+ };
77
+ });
78
+ }
79
+ //# sourceMappingURL=contacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contacts.js","sourceRoot":"","sources":["../../src/tools/contacts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAEvC,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD;;OAEG;IACH,MAAM,CAAC,IAAI,CACT,yBAAyB,EACzB,0FAA0F,EAC1F;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;QACpF,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;QACtF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,wBAAwB,CAAC;KACjF,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,WAAW,GAAwB;YACvC,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB,CAAC;QACF,IAAI,MAAM,CAAC,KAAK;YAAE,WAAW,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;QACpD,IAAI,MAAM,CAAC,GAAG;YAAE,WAAW,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QAE7C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC;QAE1D,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,yBAAyB,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACnE;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF;;OAEG;IACH,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,yGAAyG,EACzG;QACE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;QACvF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QAC1D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;QACvE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6DAA6D,CAAC;QAC5G,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4EAA4E,CAAC;KACnI,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG;YACd,YAAY,EAAE,UAAU;YACxB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,aAAa,EAAE,MAAM,CAAC,aAAa;SACpC,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,cAAc,UAAU,qCAAqC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACrG;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF;;OAEG;IACH,MAAM,CAAC,IAAI,CACT,4BAA4B,EAC5B,iHAAiH,EACjH;QACE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QAC1D,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;KAC/C,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,gBAAgB,UAAU,OAAO,EAAE;YAC/D,GAAG,EAAE,MAAM,CAAC,GAAG;SAChB,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,YAAY,MAAM,CAAC,GAAG,uBAAuB,UAAU,QAAQ,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACvG;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerFlowTools(server: McpServer): void;
@@ -0,0 +1,148 @@
1
+ import { z } from 'zod';
2
+ import { api } from '../api-client.js';
3
+ import { enforcePlanQuota } from '../lib/quota-guard.js';
4
+ export function registerFlowTools(server) {
5
+ /**
6
+ * 1. List WhatsApp Flows
7
+ */
8
+ server.tool('messegy_list_flows', 'List all WhatsApp Flows (native interactive forms, surveys, appointment booking, lead gen forms) in your account with status (DRAFT, PUBLISHED, DEPRECATED)', {
9
+ status: z.enum(['ALL', 'DRAFT', 'PUBLISHED', 'DEPRECATED']).default('ALL').describe('Filter by flow status'),
10
+ }, async (params) => {
11
+ const queryParams = {};
12
+ if (params.status !== 'ALL') {
13
+ queryParams.status = params.status;
14
+ }
15
+ const result = await api.get('/flows', queryParams);
16
+ const flows = result.data || result.flows || result;
17
+ return {
18
+ content: [
19
+ {
20
+ type: 'text',
21
+ text: `📋 WhatsApp Flows (${Array.isArray(flows) ? flows.length : 0} found):\n\n${JSON.stringify(flows, null, 2)}`,
22
+ },
23
+ ],
24
+ };
25
+ });
26
+ /**
27
+ * 2. Get Flow Details & Screen Structure
28
+ */
29
+ server.tool('messegy_get_flow_details', 'Retrieve full schema, screens, and configuration details for a specific WhatsApp Flow', {
30
+ flow_id: z.string().describe('Unique WhatsApp Flow ID'),
31
+ }, async (params) => {
32
+ const result = await api.get(`/flows/${encodeURIComponent(params.flow_id)}`);
33
+ return {
34
+ content: [
35
+ {
36
+ type: 'text',
37
+ text: `🔍 Flow Details for [${params.flow_id}]:\n\n${JSON.stringify(result, null, 2)}`,
38
+ },
39
+ ],
40
+ };
41
+ });
42
+ /**
43
+ * 3. Create New WhatsApp Flow
44
+ */
45
+ server.tool('messegy_create_flow', 'Create a new native WhatsApp Flow for lead capture, customer survey, registration, or appointment booking', {
46
+ name: z.string().describe('Flow name (e.g. "Diwali Customer Survey", "Lead Gen Form 2026")'),
47
+ categories: z
48
+ .array(z.enum([
49
+ 'SIGN_UP',
50
+ 'SIGN_IN',
51
+ 'APPOINTMENT_BOOKING',
52
+ 'LEAD_GENERATION',
53
+ 'CONTACT_US',
54
+ 'CUSTOMER_SUPPORT',
55
+ 'SURVEY',
56
+ 'OTHER',
57
+ ]))
58
+ .default(['LEAD_GENERATION'])
59
+ .describe('Categories of the flow'),
60
+ }, async (params) => {
61
+ // 1. Quota & Flow Limit Check
62
+ await enforcePlanQuota('create_flow');
63
+ const payload = {
64
+ name: params.name,
65
+ categories: params.categories,
66
+ };
67
+ const result = await api.post('/flows', payload);
68
+ return {
69
+ content: [
70
+ {
71
+ type: 'text',
72
+ text: `🚀 Flow "${params.name}" created successfully!\n\n${JSON.stringify(result, null, 2)}`,
73
+ },
74
+ ],
75
+ };
76
+ });
77
+ /**
78
+ * 4. Publish WhatsApp Flow to Meta
79
+ */
80
+ server.tool('messegy_publish_flow', 'Publish a DRAFT WhatsApp Flow to Meta so it becomes live and can be sent to customers', {
81
+ flow_id: z.string().describe('WhatsApp Flow ID to publish'),
82
+ }, async (params) => {
83
+ const result = await api.post(`/flows/${encodeURIComponent(params.flow_id)}/publish`);
84
+ return {
85
+ content: [
86
+ {
87
+ type: 'text',
88
+ text: `🎉 Flow [${params.flow_id}] published live to Meta!\n\n${JSON.stringify(result, null, 2)}`,
89
+ },
90
+ ],
91
+ };
92
+ });
93
+ /**
94
+ * 5. Send Interactive Flow Message to Customer
95
+ */
96
+ server.tool('messegy_send_flow_message', 'Send an interactive WhatsApp Flow message to a customer containing a native form/survey action button', {
97
+ to: z.string().describe('Recipient phone number with country code'),
98
+ flow_id: z.string().describe('Published WhatsApp Flow ID'),
99
+ cta_button_text: z.string().max(20).describe('Label on the CTA button (e.g. "Fill Form", "Book Slot", "Start Survey")'),
100
+ body_text: z.string().describe('Introductory message text displayed above the flow button'),
101
+ header_text: z.string().optional().describe('Optional message header'),
102
+ footer_text: z.string().optional().describe('Optional small footer text'),
103
+ flow_token: z.string().optional().describe('Optional unique tracking token for this flow session'),
104
+ initial_screen_id: z.string().optional().describe('Screen ID to open first (default is first screen in flow)'),
105
+ }, async (params) => {
106
+ const cleanTo = params.to.replace(/[^\d]/g, '');
107
+ const payload = {
108
+ to: cleanTo,
109
+ flow_id: params.flow_id,
110
+ body: params.body_text,
111
+ header: params.header_text,
112
+ footer: params.footer_text,
113
+ cta_text: params.cta_button_text,
114
+ flow_token: params.flow_token || `token_${Date.now()}`,
115
+ first_screen: params.initial_screen_id,
116
+ };
117
+ const result = await api.post(`/flows/${encodeURIComponent(params.flow_id)}/send`, payload);
118
+ return {
119
+ content: [
120
+ {
121
+ type: 'text',
122
+ text: `✅ WhatsApp Flow sent to +${cleanTo}!\n\n${JSON.stringify(result, null, 2)}`,
123
+ },
124
+ ],
125
+ };
126
+ });
127
+ /**
128
+ * 6. Get Flow Form Submissions & Responses Data
129
+ */
130
+ server.tool('messegy_get_flow_submissions', 'Retrieve customer submitted form answers, lead data, survey responses, and appointment bookings collected by a WhatsApp Flow', {
131
+ flow_id: z.string().describe('WhatsApp Flow ID'),
132
+ limit: z.number().min(1).max(100).default(25).describe('Number of recent submissions to fetch'),
133
+ }, async (params) => {
134
+ const result = await api.get(`/flows/${encodeURIComponent(params.flow_id)}/submissions`, {
135
+ limit: params.limit,
136
+ });
137
+ const submissions = result.data || result.submissions || result;
138
+ return {
139
+ content: [
140
+ {
141
+ type: 'text',
142
+ text: `📊 Flow Submissions for [${params.flow_id}] (${Array.isArray(submissions) ? submissions.length : 0} responses):\n\n${JSON.stringify(submissions, null, 2)}`,
143
+ },
144
+ ],
145
+ };
146
+ });
147
+ }
148
+ //# sourceMappingURL=flows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flows.js","sourceRoot":"","sources":["../../src/tools/flows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerMessageTools(server: McpServer): void;