whatsapp-sender-pro-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.
- package/README.md +162 -0
- package/package.json +49 -0
- package/src/index.js +730 -0
package/README.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# WhatsApp Sender Pro MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/whatsapp-sender-pro-mcp)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
Model Context Protocol (MCP) server for WhatsApp Sender Pro. This allows AI assistants like Claude to send WhatsApp messages, manage contacts, and run marketing campaigns on your behalf.
|
|
7
|
+
|
|
8
|
+
**Website:** https://whatsappsender.speedliv.com
|
|
9
|
+
**Chrome Extension:** [Install from Chrome Web Store](https://chromewebstore.google.com/detail/whatsapp-sender-pro/akaajmihnfkohfcpbohmephlldmlibok)
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
### Tools
|
|
14
|
+
- **send_whatsapp_message** - Send a message to a single contact
|
|
15
|
+
- **send_bulk_messages** - Send messages to multiple contacts with human-like delays
|
|
16
|
+
- **get_contacts** - Retrieve your saved contacts
|
|
17
|
+
- **add_contact** - Add a new contact
|
|
18
|
+
- **import_contacts** - Import multiple contacts at once
|
|
19
|
+
- **get_message_history** - View sent messages and their status
|
|
20
|
+
- **get_credits_balance** - Check your credits balance
|
|
21
|
+
- **get_analytics** - View messaging statistics
|
|
22
|
+
- **create_message_template** - Create reusable templates
|
|
23
|
+
- **authenticate** - Login to your account
|
|
24
|
+
|
|
25
|
+
### Resources
|
|
26
|
+
- `whatsapp://contacts` - All saved contacts
|
|
27
|
+
- `whatsapp://templates` - Message templates
|
|
28
|
+
- `whatsapp://stats` - Usage statistics
|
|
29
|
+
- `whatsapp://account` - Account information
|
|
30
|
+
|
|
31
|
+
### Prompts
|
|
32
|
+
- **send_marketing_campaign** - Create and send marketing campaigns
|
|
33
|
+
- **send_appointment_reminder** - Send appointment reminders
|
|
34
|
+
- **customer_followup** - Follow up with customers after purchase
|
|
35
|
+
- **event_invitation** - Send event invitations
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
### Option 1: NPX (No installation required)
|
|
40
|
+
```bash
|
|
41
|
+
npx whatsapp-sender-pro-mcp
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Option 2: NPM Global Install
|
|
45
|
+
```bash
|
|
46
|
+
npm install -g whatsapp-sender-pro-mcp
|
|
47
|
+
whatsapp-sender-mcp
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Option 3: From Source
|
|
51
|
+
```bash
|
|
52
|
+
git clone https://github.com/whatsapp-sender-pro/mcp-server
|
|
53
|
+
cd mcp-server
|
|
54
|
+
npm install
|
|
55
|
+
npm start
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Configuration
|
|
59
|
+
|
|
60
|
+
### For Claude Desktop
|
|
61
|
+
|
|
62
|
+
Add to your Claude Desktop configuration file:
|
|
63
|
+
|
|
64
|
+
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
65
|
+
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"mcpServers": {
|
|
70
|
+
"whatsapp-sender": {
|
|
71
|
+
"command": "npx",
|
|
72
|
+
"args": ["whatsapp-sender-pro-mcp"],
|
|
73
|
+
"env": {
|
|
74
|
+
"WHATSAPP_API_URL": "https://whatsapp-backend-prod.worksaas.workers.dev"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Or if installed globally:
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"mcpServers": {
|
|
85
|
+
"whatsapp-sender": {
|
|
86
|
+
"command": "whatsapp-sender-mcp",
|
|
87
|
+
"env": {
|
|
88
|
+
"WHATSAPP_API_URL": "https://whatsapp-backend-prod.worksaas.workers.dev"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### For Claude Code
|
|
96
|
+
|
|
97
|
+
Add to your project's `.claude/settings.json`:
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"mcpServers": {
|
|
102
|
+
"whatsapp-sender": {
|
|
103
|
+
"command": "npx",
|
|
104
|
+
"args": ["whatsapp-sender-pro-mcp"],
|
|
105
|
+
"env": {
|
|
106
|
+
"WHATSAPP_API_URL": "https://whatsapp-backend-prod.worksaas.workers.dev"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Usage Examples
|
|
114
|
+
|
|
115
|
+
### Authenticate First
|
|
116
|
+
```
|
|
117
|
+
Use the authenticate tool with my email and password to login
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Send a Single Message
|
|
121
|
+
```
|
|
122
|
+
Send a WhatsApp message to +1234567890 saying "Hello! Thanks for your interest in our product."
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Send Bulk Campaign
|
|
126
|
+
```
|
|
127
|
+
Get my contacts and send a promotional message about our 20% holiday sale to all of them
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Check Analytics
|
|
131
|
+
```
|
|
132
|
+
Show me my messaging statistics for the past week
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Use a Prompt
|
|
136
|
+
```
|
|
137
|
+
Use the send_marketing_campaign prompt to promote our new fitness app with a 30-day free trial offer
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Environment Variables
|
|
141
|
+
|
|
142
|
+
| Variable | Description | Default |
|
|
143
|
+
|----------|-------------|---------|
|
|
144
|
+
| `WHATSAPP_API_URL` | API server URL | `https://whatsapp-backend-prod.worksaas.workers.dev` |
|
|
145
|
+
| `WHATSAPP_API_TOKEN` | JWT authentication token | None (use authenticate tool) |
|
|
146
|
+
|
|
147
|
+
## Security
|
|
148
|
+
|
|
149
|
+
- Never share your API token
|
|
150
|
+
- The MCP server runs locally and communicates with the WhatsApp Sender API
|
|
151
|
+
- All messages are sent through your authenticated account
|
|
152
|
+
- Credits are deducted per message sent
|
|
153
|
+
|
|
154
|
+
## Support
|
|
155
|
+
|
|
156
|
+
- Website: https://whatsappsender.speedliv.com
|
|
157
|
+
- Chrome Extension: https://chromewebstore.google.com/detail/whatsapp-sender-pro/akaajmihnfkohfcpbohmephlldmlibok
|
|
158
|
+
- Email: support@speedliv.com
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "whatsapp-sender-pro-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP Server for WhatsApp Sender Pro - Send bulk WhatsApp messages via AI assistants like Claude",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"whatsapp-sender-mcp": "./src/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"start": "node src/index.js",
|
|
16
|
+
"dev": "node --watch src/index.js",
|
|
17
|
+
"prepublishOnly": "chmod +x src/index.js"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"model-context-protocol",
|
|
22
|
+
"whatsapp",
|
|
23
|
+
"whatsapp-sender",
|
|
24
|
+
"bulk-messaging",
|
|
25
|
+
"whatsapp-automation",
|
|
26
|
+
"claude",
|
|
27
|
+
"anthropic",
|
|
28
|
+
"ai",
|
|
29
|
+
"llm",
|
|
30
|
+
"marketing",
|
|
31
|
+
"messaging"
|
|
32
|
+
],
|
|
33
|
+
"author": "WhatsApp Sender Pro <support@speedliv.com>",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/whatsapp-sender-pro/mcp-server"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://whatsappsender.speedliv.com",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/whatsapp-sender-pro/mcp-server/issues"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18.0.0"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,730 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import {
|
|
6
|
+
CallToolRequestSchema,
|
|
7
|
+
ListToolsRequestSchema,
|
|
8
|
+
ListResourcesRequestSchema,
|
|
9
|
+
ReadResourceRequestSchema,
|
|
10
|
+
ListPromptsRequestSchema,
|
|
11
|
+
GetPromptRequestSchema,
|
|
12
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
13
|
+
|
|
14
|
+
// API Configuration
|
|
15
|
+
const API_BASE_URL = process.env.WHATSAPP_API_URL || "https://whatsapp-backend-prod.worksaas.workers.dev";
|
|
16
|
+
let API_TOKEN = process.env.WHATSAPP_API_TOKEN || "";
|
|
17
|
+
|
|
18
|
+
// Helper function for API calls
|
|
19
|
+
async function apiCall(endpoint, method = "GET", body = null) {
|
|
20
|
+
const headers = {
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
if (API_TOKEN) {
|
|
25
|
+
headers["Authorization"] = `Bearer ${API_TOKEN}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const options = {
|
|
29
|
+
method,
|
|
30
|
+
headers,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
if (body) {
|
|
34
|
+
options.body = JSON.stringify(body);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const response = await fetch(`${API_BASE_URL}${endpoint}`, options);
|
|
38
|
+
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
const error = await response.text();
|
|
41
|
+
throw new Error(`API Error: ${response.status} - ${error}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return response.json();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Create MCP Server
|
|
48
|
+
const server = new Server(
|
|
49
|
+
{
|
|
50
|
+
name: "whatsapp-sender-mcp",
|
|
51
|
+
version: "1.0.0",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
capabilities: {
|
|
55
|
+
tools: {},
|
|
56
|
+
resources: {},
|
|
57
|
+
prompts: {},
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// ==================== TOOLS ====================
|
|
63
|
+
|
|
64
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
65
|
+
return {
|
|
66
|
+
tools: [
|
|
67
|
+
{
|
|
68
|
+
name: "send_whatsapp_message",
|
|
69
|
+
description: "Send a WhatsApp message to a single contact. Requires phone number and message content.",
|
|
70
|
+
inputSchema: {
|
|
71
|
+
type: "object",
|
|
72
|
+
properties: {
|
|
73
|
+
phone: {
|
|
74
|
+
type: "string",
|
|
75
|
+
description: "Phone number with country code (e.g., +1234567890)",
|
|
76
|
+
},
|
|
77
|
+
message: {
|
|
78
|
+
type: "string",
|
|
79
|
+
description: "Message content to send",
|
|
80
|
+
},
|
|
81
|
+
contactName: {
|
|
82
|
+
type: "string",
|
|
83
|
+
description: "Optional name of the contact",
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
required: ["phone", "message"],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: "send_bulk_messages",
|
|
91
|
+
description: "Send WhatsApp messages to multiple contacts at once. Uses human-like delays to prevent bans.",
|
|
92
|
+
inputSchema: {
|
|
93
|
+
type: "object",
|
|
94
|
+
properties: {
|
|
95
|
+
contacts: {
|
|
96
|
+
type: "array",
|
|
97
|
+
items: {
|
|
98
|
+
type: "object",
|
|
99
|
+
properties: {
|
|
100
|
+
phone: { type: "string" },
|
|
101
|
+
name: { type: "string" },
|
|
102
|
+
},
|
|
103
|
+
required: ["phone"],
|
|
104
|
+
},
|
|
105
|
+
description: "Array of contacts with phone numbers",
|
|
106
|
+
},
|
|
107
|
+
message: {
|
|
108
|
+
type: "string",
|
|
109
|
+
description: "Message template. Use {name} for personalization.",
|
|
110
|
+
},
|
|
111
|
+
minDelay: {
|
|
112
|
+
type: "number",
|
|
113
|
+
description: "Minimum delay between messages in seconds (default: 3)",
|
|
114
|
+
},
|
|
115
|
+
maxDelay: {
|
|
116
|
+
type: "number",
|
|
117
|
+
description: "Maximum delay between messages in seconds (default: 8)",
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
required: ["contacts", "message"],
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "get_contacts",
|
|
125
|
+
description: "Retrieve all saved contacts from WhatsApp Sender Pro",
|
|
126
|
+
inputSchema: {
|
|
127
|
+
type: "object",
|
|
128
|
+
properties: {
|
|
129
|
+
limit: {
|
|
130
|
+
type: "number",
|
|
131
|
+
description: "Maximum number of contacts to retrieve (default: 100)",
|
|
132
|
+
},
|
|
133
|
+
search: {
|
|
134
|
+
type: "string",
|
|
135
|
+
description: "Search term to filter contacts by name or phone",
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: "add_contact",
|
|
142
|
+
description: "Add a new contact to WhatsApp Sender Pro",
|
|
143
|
+
inputSchema: {
|
|
144
|
+
type: "object",
|
|
145
|
+
properties: {
|
|
146
|
+
phone: {
|
|
147
|
+
type: "string",
|
|
148
|
+
description: "Phone number with country code",
|
|
149
|
+
},
|
|
150
|
+
name: {
|
|
151
|
+
type: "string",
|
|
152
|
+
description: "Contact name",
|
|
153
|
+
},
|
|
154
|
+
tags: {
|
|
155
|
+
type: "array",
|
|
156
|
+
items: { type: "string" },
|
|
157
|
+
description: "Tags for organizing contacts",
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
required: ["phone"],
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "import_contacts",
|
|
165
|
+
description: "Import multiple contacts at once",
|
|
166
|
+
inputSchema: {
|
|
167
|
+
type: "object",
|
|
168
|
+
properties: {
|
|
169
|
+
contacts: {
|
|
170
|
+
type: "array",
|
|
171
|
+
items: {
|
|
172
|
+
type: "object",
|
|
173
|
+
properties: {
|
|
174
|
+
phone: { type: "string" },
|
|
175
|
+
name: { type: "string" },
|
|
176
|
+
tags: { type: "array", items: { type: "string" } },
|
|
177
|
+
},
|
|
178
|
+
required: ["phone"],
|
|
179
|
+
},
|
|
180
|
+
description: "Array of contacts to import",
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
required: ["contacts"],
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: "get_message_history",
|
|
188
|
+
description: "Get message history and delivery status",
|
|
189
|
+
inputSchema: {
|
|
190
|
+
type: "object",
|
|
191
|
+
properties: {
|
|
192
|
+
limit: {
|
|
193
|
+
type: "number",
|
|
194
|
+
description: "Number of messages to retrieve (default: 50)",
|
|
195
|
+
},
|
|
196
|
+
status: {
|
|
197
|
+
type: "string",
|
|
198
|
+
enum: ["sent", "failed", "pending"],
|
|
199
|
+
description: "Filter by message status",
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: "get_credits_balance",
|
|
206
|
+
description: "Check current credits balance and usage",
|
|
207
|
+
inputSchema: {
|
|
208
|
+
type: "object",
|
|
209
|
+
properties: {},
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: "get_analytics",
|
|
214
|
+
description: "Get messaging analytics and statistics",
|
|
215
|
+
inputSchema: {
|
|
216
|
+
type: "object",
|
|
217
|
+
properties: {
|
|
218
|
+
period: {
|
|
219
|
+
type: "string",
|
|
220
|
+
enum: ["today", "week", "month"],
|
|
221
|
+
description: "Time period for analytics",
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: "create_message_template",
|
|
228
|
+
description: "Create a reusable message template",
|
|
229
|
+
inputSchema: {
|
|
230
|
+
type: "object",
|
|
231
|
+
properties: {
|
|
232
|
+
name: {
|
|
233
|
+
type: "string",
|
|
234
|
+
description: "Template name",
|
|
235
|
+
},
|
|
236
|
+
content: {
|
|
237
|
+
type: "string",
|
|
238
|
+
description: "Template content with variables like {name}, {company}",
|
|
239
|
+
},
|
|
240
|
+
category: {
|
|
241
|
+
type: "string",
|
|
242
|
+
description: "Template category (e.g., 'marketing', 'support')",
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
required: ["name", "content"],
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: "authenticate",
|
|
250
|
+
description: "Authenticate with WhatsApp Sender Pro API",
|
|
251
|
+
inputSchema: {
|
|
252
|
+
type: "object",
|
|
253
|
+
properties: {
|
|
254
|
+
email: {
|
|
255
|
+
type: "string",
|
|
256
|
+
description: "Account email",
|
|
257
|
+
},
|
|
258
|
+
password: {
|
|
259
|
+
type: "string",
|
|
260
|
+
description: "Account password",
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
required: ["email", "password"],
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
};
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
271
|
+
const { name, arguments: args } = request.params;
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
switch (name) {
|
|
275
|
+
case "authenticate": {
|
|
276
|
+
const result = await apiCall("/auth/login", "POST", {
|
|
277
|
+
email: args.email,
|
|
278
|
+
password: args.password,
|
|
279
|
+
});
|
|
280
|
+
API_TOKEN = result.token;
|
|
281
|
+
return {
|
|
282
|
+
content: [
|
|
283
|
+
{
|
|
284
|
+
type: "text",
|
|
285
|
+
text: `Successfully authenticated! Credits: ${result.user.credits}. You can now use all WhatsApp Sender features.`,
|
|
286
|
+
},
|
|
287
|
+
],
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
case "send_whatsapp_message": {
|
|
292
|
+
const result = await apiCall("/messages/send", "POST", {
|
|
293
|
+
phone: args.phone,
|
|
294
|
+
message: args.message,
|
|
295
|
+
contactName: args.contactName || "",
|
|
296
|
+
});
|
|
297
|
+
return {
|
|
298
|
+
content: [
|
|
299
|
+
{
|
|
300
|
+
type: "text",
|
|
301
|
+
text: `Message sent successfully to ${args.phone}. Message ID: ${result.messageId}. Credits used: 1.`,
|
|
302
|
+
},
|
|
303
|
+
],
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
case "send_bulk_messages": {
|
|
308
|
+
const result = await apiCall("/messages/bulk", "POST", {
|
|
309
|
+
contacts: args.contacts,
|
|
310
|
+
message: args.message,
|
|
311
|
+
minDelay: args.minDelay || 3,
|
|
312
|
+
maxDelay: args.maxDelay || 8,
|
|
313
|
+
});
|
|
314
|
+
return {
|
|
315
|
+
content: [
|
|
316
|
+
{
|
|
317
|
+
type: "text",
|
|
318
|
+
text: `Bulk messaging initiated. Sending to ${args.contacts.length} contacts. Campaign ID: ${result.campaignId}. Estimated completion: ${result.estimatedTime}.`,
|
|
319
|
+
},
|
|
320
|
+
],
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
case "get_contacts": {
|
|
325
|
+
const params = new URLSearchParams();
|
|
326
|
+
if (args.limit) params.append("limit", args.limit);
|
|
327
|
+
if (args.search) params.append("search", args.search);
|
|
328
|
+
|
|
329
|
+
const result = await apiCall(`/contacts?${params.toString()}`);
|
|
330
|
+
const contacts = result.contacts || [];
|
|
331
|
+
|
|
332
|
+
return {
|
|
333
|
+
content: [
|
|
334
|
+
{
|
|
335
|
+
type: "text",
|
|
336
|
+
text: `Found ${contacts.length} contacts:\n\n${contacts
|
|
337
|
+
.slice(0, 20)
|
|
338
|
+
.map((c, i) => `${i + 1}. ${c.name || "Unknown"} - ${c.phone}`)
|
|
339
|
+
.join("\n")}${contacts.length > 20 ? `\n\n... and ${contacts.length - 20} more` : ""}`,
|
|
340
|
+
},
|
|
341
|
+
],
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
case "add_contact": {
|
|
346
|
+
const result = await apiCall("/contacts", "POST", {
|
|
347
|
+
phone: args.phone,
|
|
348
|
+
name: args.name || "",
|
|
349
|
+
tags: args.tags || [],
|
|
350
|
+
});
|
|
351
|
+
return {
|
|
352
|
+
content: [
|
|
353
|
+
{
|
|
354
|
+
type: "text",
|
|
355
|
+
text: `Contact added successfully! ID: ${result.contact.id}, Phone: ${args.phone}, Name: ${args.name || "Not specified"}`,
|
|
356
|
+
},
|
|
357
|
+
],
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
case "import_contacts": {
|
|
362
|
+
const result = await apiCall("/contacts/import", "POST", {
|
|
363
|
+
contacts: args.contacts,
|
|
364
|
+
});
|
|
365
|
+
return {
|
|
366
|
+
content: [
|
|
367
|
+
{
|
|
368
|
+
type: "text",
|
|
369
|
+
text: `Import complete! Added: ${result.added}, Duplicates skipped: ${result.duplicates}, Failed: ${result.failed}`,
|
|
370
|
+
},
|
|
371
|
+
],
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
case "get_message_history": {
|
|
376
|
+
const params = new URLSearchParams();
|
|
377
|
+
if (args.limit) params.append("limit", args.limit);
|
|
378
|
+
if (args.status) params.append("status", args.status);
|
|
379
|
+
|
|
380
|
+
const result = await apiCall(`/messages/history?${params.toString()}`);
|
|
381
|
+
const messages = result.messages || [];
|
|
382
|
+
|
|
383
|
+
return {
|
|
384
|
+
content: [
|
|
385
|
+
{
|
|
386
|
+
type: "text",
|
|
387
|
+
text: `Message History (${messages.length} messages):\n\n${messages
|
|
388
|
+
.slice(0, 10)
|
|
389
|
+
.map(
|
|
390
|
+
(m) =>
|
|
391
|
+
`- To: ${m.contact_phone} | Status: ${m.status} | Date: ${new Date(m.sent_at).toLocaleString()}`
|
|
392
|
+
)
|
|
393
|
+
.join("\n")}`,
|
|
394
|
+
},
|
|
395
|
+
],
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
case "get_credits_balance": {
|
|
400
|
+
const result = await apiCall("/user/profile");
|
|
401
|
+
return {
|
|
402
|
+
content: [
|
|
403
|
+
{
|
|
404
|
+
type: "text",
|
|
405
|
+
text: `Credits Balance: ${result.user.credits}\nPlan: ${result.user.plan || "Free"}\nEmail: ${result.user.email}`,
|
|
406
|
+
},
|
|
407
|
+
],
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
case "get_analytics": {
|
|
412
|
+
const days = args.period === "today" ? 1 : args.period === "week" ? 7 : 30;
|
|
413
|
+
const result = await apiCall(`/messages/stats?period=${days}`);
|
|
414
|
+
|
|
415
|
+
return {
|
|
416
|
+
content: [
|
|
417
|
+
{
|
|
418
|
+
type: "text",
|
|
419
|
+
text: `Analytics (Last ${args.period || "week"}):\n\nTotal Sent: ${result.totals?.total_sent || 0}\nDelivered: ${result.totals?.total_delivered || 0}\nFailed: ${result.totals?.total_failed || 0}\nCredits Used: ${result.totals?.total_credits_used || 0}`,
|
|
420
|
+
},
|
|
421
|
+
],
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
case "create_message_template": {
|
|
426
|
+
const result = await apiCall("/templates", "POST", {
|
|
427
|
+
name: args.name,
|
|
428
|
+
content: args.content,
|
|
429
|
+
category: args.category || "general",
|
|
430
|
+
});
|
|
431
|
+
return {
|
|
432
|
+
content: [
|
|
433
|
+
{
|
|
434
|
+
type: "text",
|
|
435
|
+
text: `Template "${args.name}" created successfully! ID: ${result.template.id}`,
|
|
436
|
+
},
|
|
437
|
+
],
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
default:
|
|
442
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
443
|
+
}
|
|
444
|
+
} catch (error) {
|
|
445
|
+
return {
|
|
446
|
+
content: [
|
|
447
|
+
{
|
|
448
|
+
type: "text",
|
|
449
|
+
text: `Error: ${error.message}`,
|
|
450
|
+
},
|
|
451
|
+
],
|
|
452
|
+
isError: true,
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
// ==================== RESOURCES ====================
|
|
458
|
+
|
|
459
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
460
|
+
return {
|
|
461
|
+
resources: [
|
|
462
|
+
{
|
|
463
|
+
uri: "whatsapp://contacts",
|
|
464
|
+
mimeType: "application/json",
|
|
465
|
+
name: "All Contacts",
|
|
466
|
+
description: "List of all saved contacts in WhatsApp Sender Pro",
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
uri: "whatsapp://templates",
|
|
470
|
+
mimeType: "application/json",
|
|
471
|
+
name: "Message Templates",
|
|
472
|
+
description: "Saved message templates for quick sending",
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
uri: "whatsapp://stats",
|
|
476
|
+
mimeType: "application/json",
|
|
477
|
+
name: "Usage Statistics",
|
|
478
|
+
description: "Messaging statistics and analytics",
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
uri: "whatsapp://account",
|
|
482
|
+
mimeType: "application/json",
|
|
483
|
+
name: "Account Info",
|
|
484
|
+
description: "Current account information and credits balance",
|
|
485
|
+
},
|
|
486
|
+
],
|
|
487
|
+
};
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
491
|
+
const { uri } = request.params;
|
|
492
|
+
|
|
493
|
+
try {
|
|
494
|
+
switch (uri) {
|
|
495
|
+
case "whatsapp://contacts": {
|
|
496
|
+
const result = await apiCall("/contacts?limit=1000");
|
|
497
|
+
return {
|
|
498
|
+
contents: [
|
|
499
|
+
{
|
|
500
|
+
uri,
|
|
501
|
+
mimeType: "application/json",
|
|
502
|
+
text: JSON.stringify(result.contacts || [], null, 2),
|
|
503
|
+
},
|
|
504
|
+
],
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
case "whatsapp://templates": {
|
|
509
|
+
const result = await apiCall("/templates");
|
|
510
|
+
return {
|
|
511
|
+
contents: [
|
|
512
|
+
{
|
|
513
|
+
uri,
|
|
514
|
+
mimeType: "application/json",
|
|
515
|
+
text: JSON.stringify(result.templates || [], null, 2),
|
|
516
|
+
},
|
|
517
|
+
],
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
case "whatsapp://stats": {
|
|
522
|
+
const result = await apiCall("/messages/stats?period=30");
|
|
523
|
+
return {
|
|
524
|
+
contents: [
|
|
525
|
+
{
|
|
526
|
+
uri,
|
|
527
|
+
mimeType: "application/json",
|
|
528
|
+
text: JSON.stringify(result, null, 2),
|
|
529
|
+
},
|
|
530
|
+
],
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
case "whatsapp://account": {
|
|
535
|
+
const result = await apiCall("/user/profile");
|
|
536
|
+
return {
|
|
537
|
+
contents: [
|
|
538
|
+
{
|
|
539
|
+
uri,
|
|
540
|
+
mimeType: "application/json",
|
|
541
|
+
text: JSON.stringify(result.user, null, 2),
|
|
542
|
+
},
|
|
543
|
+
],
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
default:
|
|
548
|
+
throw new Error(`Unknown resource: ${uri}`);
|
|
549
|
+
}
|
|
550
|
+
} catch (error) {
|
|
551
|
+
throw new Error(`Failed to read resource: ${error.message}`);
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
// ==================== PROMPTS ====================
|
|
556
|
+
|
|
557
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
558
|
+
return {
|
|
559
|
+
prompts: [
|
|
560
|
+
{
|
|
561
|
+
name: "send_marketing_campaign",
|
|
562
|
+
description: "Create and send a marketing campaign to your contacts",
|
|
563
|
+
arguments: [
|
|
564
|
+
{
|
|
565
|
+
name: "product",
|
|
566
|
+
description: "Product or service to promote",
|
|
567
|
+
required: true,
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
name: "offer",
|
|
571
|
+
description: "Special offer or discount",
|
|
572
|
+
required: false,
|
|
573
|
+
},
|
|
574
|
+
],
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
name: "send_appointment_reminder",
|
|
578
|
+
description: "Send appointment reminders to clients",
|
|
579
|
+
arguments: [
|
|
580
|
+
{
|
|
581
|
+
name: "appointment_type",
|
|
582
|
+
description: "Type of appointment (e.g., 'meeting', 'consultation')",
|
|
583
|
+
required: true,
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
name: "date",
|
|
587
|
+
description: "Date and time of appointment",
|
|
588
|
+
required: true,
|
|
589
|
+
},
|
|
590
|
+
],
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
name: "customer_followup",
|
|
594
|
+
description: "Send follow-up messages to customers after purchase",
|
|
595
|
+
arguments: [
|
|
596
|
+
{
|
|
597
|
+
name: "product_purchased",
|
|
598
|
+
description: "Product that was purchased",
|
|
599
|
+
required: true,
|
|
600
|
+
},
|
|
601
|
+
],
|
|
602
|
+
},
|
|
603
|
+
{
|
|
604
|
+
name: "event_invitation",
|
|
605
|
+
description: "Send event invitations via WhatsApp",
|
|
606
|
+
arguments: [
|
|
607
|
+
{
|
|
608
|
+
name: "event_name",
|
|
609
|
+
description: "Name of the event",
|
|
610
|
+
required: true,
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
name: "event_date",
|
|
614
|
+
description: "Date and time of the event",
|
|
615
|
+
required: true,
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
name: "location",
|
|
619
|
+
description: "Event location or link",
|
|
620
|
+
required: true,
|
|
621
|
+
},
|
|
622
|
+
],
|
|
623
|
+
},
|
|
624
|
+
],
|
|
625
|
+
};
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
629
|
+
const { name, arguments: args } = request.params;
|
|
630
|
+
|
|
631
|
+
switch (name) {
|
|
632
|
+
case "send_marketing_campaign":
|
|
633
|
+
return {
|
|
634
|
+
messages: [
|
|
635
|
+
{
|
|
636
|
+
role: "user",
|
|
637
|
+
content: {
|
|
638
|
+
type: "text",
|
|
639
|
+
text: `Create a WhatsApp marketing campaign for "${args.product}"${args.offer ? ` with offer: "${args.offer}"` : ""}.
|
|
640
|
+
|
|
641
|
+
Steps:
|
|
642
|
+
1. First, use get_contacts to see my contact list
|
|
643
|
+
2. Create a compelling, personalized message (use {name} for personalization)
|
|
644
|
+
3. Send the campaign using send_bulk_messages with appropriate delays
|
|
645
|
+
|
|
646
|
+
Make the message friendly, concise, and include a clear call-to-action. Keep it under 500 characters for WhatsApp.`,
|
|
647
|
+
},
|
|
648
|
+
},
|
|
649
|
+
],
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
case "send_appointment_reminder":
|
|
653
|
+
return {
|
|
654
|
+
messages: [
|
|
655
|
+
{
|
|
656
|
+
role: "user",
|
|
657
|
+
content: {
|
|
658
|
+
type: "text",
|
|
659
|
+
text: `Send appointment reminders for ${args.appointment_type} scheduled on ${args.date}.
|
|
660
|
+
|
|
661
|
+
Create a professional reminder message that:
|
|
662
|
+
1. Greets the person by name
|
|
663
|
+
2. Confirms the appointment details
|
|
664
|
+
3. Asks for confirmation or rescheduling
|
|
665
|
+
4. Provides contact info for questions
|
|
666
|
+
|
|
667
|
+
Use the send_whatsapp_message tool to send to specific contacts.`,
|
|
668
|
+
},
|
|
669
|
+
},
|
|
670
|
+
],
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
case "customer_followup":
|
|
674
|
+
return {
|
|
675
|
+
messages: [
|
|
676
|
+
{
|
|
677
|
+
role: "user",
|
|
678
|
+
content: {
|
|
679
|
+
type: "text",
|
|
680
|
+
text: `Create a follow-up message campaign for customers who purchased "${args.product_purchased}".
|
|
681
|
+
|
|
682
|
+
The message should:
|
|
683
|
+
1. Thank them for their purchase
|
|
684
|
+
2. Ask if they're satisfied
|
|
685
|
+
3. Offer help if needed
|
|
686
|
+
4. Maybe suggest related products
|
|
687
|
+
|
|
688
|
+
Use get_contacts first, then send_bulk_messages with personalization.`,
|
|
689
|
+
},
|
|
690
|
+
},
|
|
691
|
+
],
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
case "event_invitation":
|
|
695
|
+
return {
|
|
696
|
+
messages: [
|
|
697
|
+
{
|
|
698
|
+
role: "user",
|
|
699
|
+
content: {
|
|
700
|
+
type: "text",
|
|
701
|
+
text: `Create WhatsApp invitations for "${args.event_name}" on ${args.event_date} at ${args.location}.
|
|
702
|
+
|
|
703
|
+
The invitation should:
|
|
704
|
+
1. Be exciting and engaging
|
|
705
|
+
2. Include all event details
|
|
706
|
+
3. Have a clear RSVP request
|
|
707
|
+
4. Mention any special instructions
|
|
708
|
+
|
|
709
|
+
Get contacts and send personalized invitations using send_bulk_messages.`,
|
|
710
|
+
},
|
|
711
|
+
},
|
|
712
|
+
],
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
default:
|
|
716
|
+
throw new Error(`Unknown prompt: ${name}`);
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
// Start the server
|
|
721
|
+
async function main() {
|
|
722
|
+
const transport = new StdioServerTransport();
|
|
723
|
+
await server.connect(transport);
|
|
724
|
+
console.error("WhatsApp Sender MCP Server running on stdio");
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
main().catch((error) => {
|
|
728
|
+
console.error("Fatal error:", error);
|
|
729
|
+
process.exit(1);
|
|
730
|
+
});
|