@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.
- package/README.md +133 -0
- package/api/index.js +3 -0
- package/dist/api-client.d.ts +10 -0
- package/dist/api-client.js +100 -0
- package/dist/api-client.js.map +1 -0
- package/dist/cli-setup.d.ts +1 -0
- package/dist/cli-setup.js +74 -0
- package/dist/cli-setup.js.map +1 -0
- package/dist/config.d.ts +18 -0
- package/dist/config.js +88 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/quota-guard.d.ts +19 -0
- package/dist/lib/quota-guard.js +101 -0
- package/dist/lib/quota-guard.js.map +1 -0
- package/dist/resources/index.d.ts +2 -0
- package/dist/resources/index.js +62 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.js +364 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/analytics.d.ts +2 -0
- package/dist/tools/analytics.js +42 -0
- package/dist/tools/analytics.js.map +1 -0
- package/dist/tools/auth.d.ts +2 -0
- package/dist/tools/auth.js +113 -0
- package/dist/tools/auth.js.map +1 -0
- package/dist/tools/auto-replies.d.ts +2 -0
- package/dist/tools/auto-replies.js +117 -0
- package/dist/tools/auto-replies.js.map +1 -0
- package/dist/tools/broadcasts.d.ts +2 -0
- package/dist/tools/broadcasts.js +58 -0
- package/dist/tools/broadcasts.js.map +1 -0
- package/dist/tools/chats.d.ts +2 -0
- package/dist/tools/chats.js +77 -0
- package/dist/tools/chats.js.map +1 -0
- package/dist/tools/contacts.d.ts +2 -0
- package/dist/tools/contacts.js +79 -0
- package/dist/tools/contacts.js.map +1 -0
- package/dist/tools/flows.d.ts +2 -0
- package/dist/tools/flows.js +148 -0
- package/dist/tools/flows.js.map +1 -0
- package/dist/tools/messages.d.ts +2 -0
- package/dist/tools/messages.js +149 -0
- package/dist/tools/messages.js.map +1 -0
- package/dist/tools/shopify.d.ts +2 -0
- package/dist/tools/shopify.js +66 -0
- package/dist/tools/shopify.js.map +1 -0
- package/dist/tools/templates.d.ts +2 -0
- package/dist/tools/templates.js +160 -0
- package/dist/tools/templates.js.map +1 -0
- package/dist/web-app.d.ts +1 -0
- package/dist/web-app.js +845 -0
- package/dist/web-app.js.map +1 -0
- package/package.json +42 -0
- package/src/api-client.ts +112 -0
- package/src/cli-setup.ts +87 -0
- package/src/config.ts +111 -0
- package/src/index.ts +66 -0
- package/src/lib/quota-guard.ts +138 -0
- package/src/resources/index.ts +70 -0
- package/src/server.ts +408 -0
- package/src/tools/analytics.ts +58 -0
- package/src/tools/auth.ts +136 -0
- package/src/tools/auto-replies.ts +144 -0
- package/src/tools/broadcasts.ts +73 -0
- package/src/tools/chats.ts +100 -0
- package/src/tools/contacts.ts +99 -0
- package/src/tools/flows.ts +192 -0
- package/src/tools/messages.ts +177 -0
- package/src/tools/shopify.ts +80 -0
- package/src/tools/templates.ts +193 -0
- package/src/web-app.ts +844 -0
- package/tsconfig.json +18 -0
- package/vercel.json +10 -0
package/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# 🚀 Messegy WhatsApp Model Context Protocol (MCP) Server
|
|
2
|
+
|
|
3
|
+
Official Model Context Protocol (MCP) Server for the **Messegy WhatsApp Business Cloud Platform**.
|
|
4
|
+
|
|
5
|
+
Connect any AI Assistant (**Claude Desktop**, **Cursor IDE**, **Antigravity**, **Windsurf**, or custom LLM agents) directly to your WhatsApp Business Cloud API to send messages, manage templates, query live chats, launch broadcasts, and automate customer engagement using natural language.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 📦 Installation & Quickstart
|
|
10
|
+
|
|
11
|
+
### 1. Run via npx (No install needed)
|
|
12
|
+
```bash
|
|
13
|
+
npx @messegy/mcp
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### 2. Local Setup
|
|
17
|
+
```bash
|
|
18
|
+
cd mcp
|
|
19
|
+
npm install
|
|
20
|
+
npm run build
|
|
21
|
+
npm start
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## ⚙️ Configuration & Environment Variables
|
|
27
|
+
|
|
28
|
+
| Variable | Description | Required | Default |
|
|
29
|
+
| :--- | :--- | :--- | :--- |
|
|
30
|
+
| `MESSEGY_API_KEY` | Your Messegy Workspace API Key / Bearer Token | **Yes** | - |
|
|
31
|
+
| `MESSEGY_PROJECT_KEY` | Your Active Project / Workspace Key | Optional | - |
|
|
32
|
+
| `MESSEGY_BASE_URL` | Base URL of the Messegy API service | Optional | `https://backend.messegy.com/api` |
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 🔑 Zero-Config Interactive Authentication
|
|
37
|
+
|
|
38
|
+
You **do NOT need to hardcode API keys** into JSON files if you don't want to!
|
|
39
|
+
|
|
40
|
+
1. Simply add the server with `command: "npx"` and `args: ["-y", "@messegy/mcp"]`.
|
|
41
|
+
2. Start chatting with your AI:
|
|
42
|
+
> *"Claude, connect my Messegy account"*
|
|
43
|
+
3. The AI will ask for your API Key, validate it with the server, and securely save it in `~/.messegy/config.json`.
|
|
44
|
+
4. To switch accounts or workspaces later, simply say:
|
|
45
|
+
> *"Disconnect my Messegy account"* or *"Connect with new API key <key>"*
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 🤖 Connect to AI Assistants
|
|
50
|
+
|
|
51
|
+
### 1. Claude Desktop Setup (Zero-Config)
|
|
52
|
+
Add this configuration to your Claude Desktop config file:
|
|
53
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
54
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"messegy": {
|
|
60
|
+
"command": "node",
|
|
61
|
+
"args": ["/ABSOLUTE/PATH/TO/mcp/dist/index.js"]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
*(Optional: You can still provide `"env": { "MESSEGY_API_KEY": "..." }` if you prefer static configuration).*
|
|
67
|
+
|
|
68
|
+
### 2. Cursor IDE / Antigravity Setup
|
|
69
|
+
Add under `Settings` -> `Features` -> `MCP Servers`:
|
|
70
|
+
- **Name**: `messegy-whatsapp`
|
|
71
|
+
- **Type**: `stdio`
|
|
72
|
+
- **Command**: `node /ABSOLUTE/PATH/TO/mcp/dist/index.js`
|
|
73
|
+
- **Env**: (Leave blank for interactive login or set `MESSEGY_API_KEY=your_key`)
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 🛠️ Available MCP Tools
|
|
78
|
+
|
|
79
|
+
### 💬 Messaging & Live Chat
|
|
80
|
+
* **`messegy_send_whatsapp_message`**: Send a direct WhatsApp text or media (image, video, PDF, audio) message to any phone number.
|
|
81
|
+
* **`messegy_send_interactive_buttons`**: Send clickable quick-reply buttons (up to 3 buttons).
|
|
82
|
+
* **`messegy_send_list_menu`**: Send structured interactive list menus with sections and selectable rows.
|
|
83
|
+
* **`messegy_list_chats`**: Retrieve active customer WhatsApp threads with unread indicators.
|
|
84
|
+
* **`messegy_get_chat_history`**: Fetch full message history of a customer conversation.
|
|
85
|
+
* **`messegy_reply_to_chat`**: Send an agent/AI reply to an active chat thread.
|
|
86
|
+
|
|
87
|
+
### 📄 WhatsApp Templates (Meta Approved)
|
|
88
|
+
* **`messegy_list_templates`**: List all approved, pending, and rejected WhatsApp templates.
|
|
89
|
+
* **`messegy_send_template_message`**: Send pre-approved templates with dynamic body parameters (`{{1}}`, `{{2}}`) and media headers.
|
|
90
|
+
* **`messegy_create_template`**: Draft and submit new templates directly to Meta for instant review.
|
|
91
|
+
|
|
92
|
+
### 👥 CRM & Contacts
|
|
93
|
+
* **`messegy_search_contacts`**: Find leads and contacts by phone, name, or assigned tags.
|
|
94
|
+
* **`messegy_create_contact`**: Add new leads with custom fields and metadata.
|
|
95
|
+
* **`messegy_add_tag_to_contact`**: Tag contacts (e.g. `VIP`, `Hot-Lead`, `Pending-Payment`).
|
|
96
|
+
|
|
97
|
+
### 🚀 Broadcast Campaigns
|
|
98
|
+
* **`messegy_create_broadcast`**: Launch bulk promotional or utility broadcasts to segmented tags or recipient lists.
|
|
99
|
+
* **`messegy_get_broadcast_stats`**: Check real-time campaign delivery, read, and failure metrics.
|
|
100
|
+
|
|
101
|
+
### 📈 Business Health, Plan Quotas & Analytics
|
|
102
|
+
* **`messegy_get_account_overview`**: Check WhatsApp Phone Number health, Meta quality rating (`GREEN`/`YELLOW`/`RED`), messaging tier limit, and wallet balance.
|
|
103
|
+
* **`messegy_get_plan_limits_and_usage`**: Inspect active subscription plan quotas, message balance, Auto-Reply rule counts, and WhatsApp Flow limits to avoid overages.
|
|
104
|
+
|
|
105
|
+
### 🤖 Auto-Replies & Keyword Bots
|
|
106
|
+
* **`messegy_list_auto_replies`**: List all keyword triggers, welcome bots, and away messages.
|
|
107
|
+
* **`messegy_create_auto_reply`**: Create keyword-based auto-responders (e.g. "PRICE", "HOURS", "SUPPORT") with text, templates, or buttons.
|
|
108
|
+
* **`messegy_update_auto_reply`**: Edit keywords, modify response text, or toggle active/inactive status.
|
|
109
|
+
* **`messegy_delete_auto_reply`**: Remove an auto-reply rule.
|
|
110
|
+
|
|
111
|
+
### 📋 WhatsApp Flows (Native Interactive Forms & Surveys)
|
|
112
|
+
* **`messegy_list_flows`**: List all WhatsApp Flows (DRAFT, PUBLISHED, DEPRECATED).
|
|
113
|
+
* **`messegy_get_flow_details`**: Retrieve full schema, screens, and fields of a WhatsApp Flow.
|
|
114
|
+
* **`messegy_create_flow`**: Create a new native WhatsApp Flow for lead generation, surveys, or booking.
|
|
115
|
+
* **`messegy_publish_flow`**: Publish a flow to Meta for live customer access.
|
|
116
|
+
* **`messegy_send_flow_message`**: Send an interactive flow message with a native form/survey action button to a customer.
|
|
117
|
+
* **`messegy_get_flow_submissions`**: Retrieve submitted form responses, lead details, and survey answers.
|
|
118
|
+
|
|
119
|
+
### 🛍️ Shopify & E-commerce Triggers
|
|
120
|
+
* **`messegy_trigger_shopify_abandoned_cart`**: Trigger abandoned checkout recovery messages with auto-applied discount links.
|
|
121
|
+
* **`messegy_send_order_notification`**: Send order confirmation or fulfillment tracking WhatsApp updates.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 📚 Dynamic Resources
|
|
126
|
+
|
|
127
|
+
* **`messegy://templates`**: Real-time list of all approved WhatsApp templates for AI prompt context.
|
|
128
|
+
* **`messegy://account-status`**: Real-time health, verified name, and messaging limits of the WhatsApp account.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 📄 License
|
|
133
|
+
MIT © Messegy Platform
|
package/api/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare class MessegyApiClient {
|
|
2
|
+
private getHeaders;
|
|
3
|
+
private checkAuth;
|
|
4
|
+
get<T = any>(endpoint: string, params?: Record<string, any>, skipAuthCheck?: boolean): Promise<T>;
|
|
5
|
+
post<T = any>(endpoint: string, data?: Record<string, any>, skipAuthCheck?: boolean): Promise<T>;
|
|
6
|
+
put<T = any>(endpoint: string, data?: Record<string, any>): Promise<T>;
|
|
7
|
+
delete<T = any>(endpoint: string, params?: Record<string, any>): Promise<T>;
|
|
8
|
+
private handleError;
|
|
9
|
+
}
|
|
10
|
+
export declare const api: MessegyApiClient;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { getConfig } from './config.js';
|
|
3
|
+
export class MessegyApiClient {
|
|
4
|
+
getHeaders() {
|
|
5
|
+
const config = getConfig();
|
|
6
|
+
const headers = {
|
|
7
|
+
'Content-Type': 'application/json',
|
|
8
|
+
Accept: 'application/json',
|
|
9
|
+
};
|
|
10
|
+
if (config.apiKey) {
|
|
11
|
+
headers['Authorization'] = `Bearer ${config.apiKey}`;
|
|
12
|
+
headers['x-api-key'] = config.apiKey;
|
|
13
|
+
}
|
|
14
|
+
if (config.projectKey) {
|
|
15
|
+
headers['x-project-key'] = config.projectKey;
|
|
16
|
+
}
|
|
17
|
+
return headers;
|
|
18
|
+
}
|
|
19
|
+
checkAuth() {
|
|
20
|
+
const config = getConfig();
|
|
21
|
+
if (!config.apiKey) {
|
|
22
|
+
throw new Error('⚠️ No Messegy account connected! Please provide your Messegy API Key by calling the "messegy_connect_account" tool or by saying: "Connect my Messegy account with API Key <your_key>".');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async get(endpoint, params, skipAuthCheck = false) {
|
|
26
|
+
if (!skipAuthCheck)
|
|
27
|
+
this.checkAuth();
|
|
28
|
+
const config = getConfig();
|
|
29
|
+
try {
|
|
30
|
+
const response = await axios.get(`${config.baseUrl}${endpoint}`, {
|
|
31
|
+
params,
|
|
32
|
+
headers: this.getHeaders(),
|
|
33
|
+
timeout: 15000,
|
|
34
|
+
});
|
|
35
|
+
return response.data;
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
this.handleError(err, `GET ${endpoint}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async post(endpoint, data, skipAuthCheck = false) {
|
|
42
|
+
if (!skipAuthCheck)
|
|
43
|
+
this.checkAuth();
|
|
44
|
+
const config = getConfig();
|
|
45
|
+
try {
|
|
46
|
+
const response = await axios.post(`${config.baseUrl}${endpoint}`, data, {
|
|
47
|
+
headers: this.getHeaders(),
|
|
48
|
+
timeout: 15000,
|
|
49
|
+
});
|
|
50
|
+
return response.data;
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
this.handleError(err, `POST ${endpoint}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async put(endpoint, data) {
|
|
57
|
+
this.checkAuth();
|
|
58
|
+
const config = getConfig();
|
|
59
|
+
try {
|
|
60
|
+
const response = await axios.put(`${config.baseUrl}${endpoint}`, data, {
|
|
61
|
+
headers: this.getHeaders(),
|
|
62
|
+
timeout: 15000,
|
|
63
|
+
});
|
|
64
|
+
return response.data;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
this.handleError(err, `PUT ${endpoint}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async delete(endpoint, params) {
|
|
71
|
+
this.checkAuth();
|
|
72
|
+
const config = getConfig();
|
|
73
|
+
try {
|
|
74
|
+
const response = await axios.delete(`${config.baseUrl}${endpoint}`, {
|
|
75
|
+
params,
|
|
76
|
+
headers: this.getHeaders(),
|
|
77
|
+
timeout: 15000,
|
|
78
|
+
});
|
|
79
|
+
return response.data;
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
this.handleError(err, `DELETE ${endpoint}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
handleError(error, action) {
|
|
86
|
+
if (axios.isAxiosError(error)) {
|
|
87
|
+
const axiosErr = error;
|
|
88
|
+
const status = axiosErr.response?.status;
|
|
89
|
+
const responseData = axiosErr.response?.data;
|
|
90
|
+
const message = responseData?.message || responseData?.error || axiosErr.message;
|
|
91
|
+
if (status === 401 || status === 403) {
|
|
92
|
+
throw new Error(`🔒 Authentication Failed (Status ${status}): Invalid or expired Messegy API Key. Please reconnect using "messegy_connect_account" with a valid key.`);
|
|
93
|
+
}
|
|
94
|
+
throw new Error(`Messegy API Error during [${action}]: (Status ${status || 'Unknown'}) ${message}`);
|
|
95
|
+
}
|
|
96
|
+
throw new Error(`Messegy Network Error during [${action}]: ${error.message}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export const api = new MessegyApiClient();
|
|
100
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runInteractiveCliSetup(): Promise<void>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import readline from 'readline';
|
|
5
|
+
function getClaudeConfigPath() {
|
|
6
|
+
const home = os.homedir();
|
|
7
|
+
if (process.platform === 'darwin') {
|
|
8
|
+
return path.join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
9
|
+
}
|
|
10
|
+
else if (process.platform === 'win32') {
|
|
11
|
+
const appData = process.env.APPDATA || path.join(home, 'AppData', 'Roaming');
|
|
12
|
+
return path.join(appData, 'Claude', 'claude_desktop_config.json');
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
return path.join(home, '.config', 'Claude', 'claude_desktop_config.json');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export async function runInteractiveCliSetup() {
|
|
19
|
+
const rl = readline.createInterface({
|
|
20
|
+
input: process.stdin,
|
|
21
|
+
output: process.stdout,
|
|
22
|
+
});
|
|
23
|
+
const question = (query) => new Promise((resolve) => rl.question(query, resolve));
|
|
24
|
+
console.log('\n======================================================');
|
|
25
|
+
console.log(' 🚀 Messegy WhatsApp MCP 1-Click Auto-Setup');
|
|
26
|
+
console.log('======================================================\n');
|
|
27
|
+
try {
|
|
28
|
+
const apiKey = (await question('🔑 Enter your Messegy API Key (from Messegy Portal -> Settings): ')).trim();
|
|
29
|
+
if (!apiKey) {
|
|
30
|
+
console.log('\n❌ Error: API Key is required. Setup cancelled.\n');
|
|
31
|
+
rl.close();
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
const projectKey = (await question('📁 Enter Project Key (Optional, press Enter to skip): ')).trim();
|
|
35
|
+
const configPath = getClaudeConfigPath();
|
|
36
|
+
const configDir = path.dirname(configPath);
|
|
37
|
+
if (!fs.existsSync(configDir)) {
|
|
38
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
let existingConfig = {};
|
|
41
|
+
if (fs.existsSync(configPath)) {
|
|
42
|
+
try {
|
|
43
|
+
const raw = fs.readFileSync(configPath, 'utf-8');
|
|
44
|
+
existingConfig = JSON.parse(raw);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
existingConfig = {};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (!existingConfig.mcpServers) {
|
|
51
|
+
existingConfig.mcpServers = {};
|
|
52
|
+
}
|
|
53
|
+
existingConfig.mcpServers.messegy = {
|
|
54
|
+
command: 'npx',
|
|
55
|
+
args: ['-y', '@messegy/mcp'],
|
|
56
|
+
env: {
|
|
57
|
+
MESSEGY_API_KEY: apiKey,
|
|
58
|
+
...(projectKey ? { MESSEGY_PROJECT_KEY: projectKey } : {}),
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
fs.writeFileSync(configPath, JSON.stringify(existingConfig, null, 2), 'utf-8');
|
|
62
|
+
console.log('\n✅ SUCCESS! Messegy MCP Server has been configured automatically.');
|
|
63
|
+
console.log(`📂 Updated Config: ${configPath}`);
|
|
64
|
+
console.log('\n👉 Next Step: Open or Restart Claude Desktop, and start chatting with your WhatsApp business!\n');
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
console.error('\n❌ Setup failed:', err.message);
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
rl.close();
|
|
71
|
+
process.exit(0);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=cli-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-setup.js","sourceRoot":"","sources":["../src/cli-setup.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface MessegyConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
projectKey?: string;
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function getConfig(): MessegyConfig;
|
|
7
|
+
/**
|
|
8
|
+
* Save new credentials interactively and persist to ~/.messegy/config.json
|
|
9
|
+
*/
|
|
10
|
+
export declare function saveConfig(newConfig: {
|
|
11
|
+
apiKey: string;
|
|
12
|
+
projectKey?: string;
|
|
13
|
+
baseUrl?: string;
|
|
14
|
+
}): MessegyConfig;
|
|
15
|
+
/**
|
|
16
|
+
* Disconnect & remove saved credentials
|
|
17
|
+
*/
|
|
18
|
+
export declare function clearConfig(): void;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
dotenv.config();
|
|
6
|
+
const CONFIG_DIR = path.join(os.homedir(), '.messegy');
|
|
7
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
8
|
+
// In-memory configuration cache
|
|
9
|
+
let activeConfig = null;
|
|
10
|
+
function ensureConfigDir() {
|
|
11
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
12
|
+
try {
|
|
13
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
catch { }
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function loadSavedFileConfig() {
|
|
19
|
+
try {
|
|
20
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
21
|
+
const data = fs.readFileSync(CONFIG_FILE, 'utf-8');
|
|
22
|
+
return JSON.parse(data);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
console.error('Error reading saved Messegy config:', err);
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
export function getConfig() {
|
|
31
|
+
if (activeConfig) {
|
|
32
|
+
return activeConfig;
|
|
33
|
+
}
|
|
34
|
+
const fileConfig = loadSavedFileConfig();
|
|
35
|
+
const apiKey = process.env.MESSEGY_API_KEY ||
|
|
36
|
+
fileConfig?.apiKey ||
|
|
37
|
+
'';
|
|
38
|
+
const projectKey = process.env.MESSEGY_PROJECT_KEY ||
|
|
39
|
+
fileConfig?.projectKey ||
|
|
40
|
+
undefined;
|
|
41
|
+
const baseUrl = (process.env.MESSEGY_BASE_URL ||
|
|
42
|
+
fileConfig?.baseUrl ||
|
|
43
|
+
'https://backend.messegy.com/api').replace(/\/$/, '');
|
|
44
|
+
activeConfig = {
|
|
45
|
+
apiKey,
|
|
46
|
+
projectKey,
|
|
47
|
+
baseUrl,
|
|
48
|
+
};
|
|
49
|
+
return activeConfig;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Save new credentials interactively and persist to ~/.messegy/config.json
|
|
53
|
+
*/
|
|
54
|
+
export function saveConfig(newConfig) {
|
|
55
|
+
ensureConfigDir();
|
|
56
|
+
const updated = {
|
|
57
|
+
apiKey: newConfig.apiKey.trim(),
|
|
58
|
+
projectKey: newConfig.projectKey?.trim() || undefined,
|
|
59
|
+
baseUrl: (newConfig.baseUrl || 'https://backend.messegy.com/api').replace(/\/$/, ''),
|
|
60
|
+
};
|
|
61
|
+
try {
|
|
62
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(updated, null, 2), 'utf-8');
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
console.error('Failed to write ~/.messegy/config.json:', err);
|
|
66
|
+
}
|
|
67
|
+
activeConfig = updated;
|
|
68
|
+
return updated;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Disconnect & remove saved credentials
|
|
72
|
+
*/
|
|
73
|
+
export function clearConfig() {
|
|
74
|
+
try {
|
|
75
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
76
|
+
fs.unlinkSync(CONFIG_FILE);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
console.error('Failed to delete ~/.messegy/config.json:', err);
|
|
81
|
+
}
|
|
82
|
+
activeConfig = {
|
|
83
|
+
apiKey: '',
|
|
84
|
+
projectKey: undefined,
|
|
85
|
+
baseUrl: 'https://backend.messegy.com/api',
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { runInteractiveCliSetup } from './cli-setup.js';
|
|
5
|
+
import { startHttpMcpServer } from './server.js';
|
|
6
|
+
import { registerAuthTools } from './tools/auth.js';
|
|
7
|
+
import { registerMessageTools } from './tools/messages.js';
|
|
8
|
+
import { registerTemplateTools } from './tools/templates.js';
|
|
9
|
+
import { registerChatTools } from './tools/chats.js';
|
|
10
|
+
import { registerContactTools } from './tools/contacts.js';
|
|
11
|
+
import { registerBroadcastTools } from './tools/broadcasts.js';
|
|
12
|
+
import { registerAnalyticsTools } from './tools/analytics.js';
|
|
13
|
+
import { registerAutoReplyTools } from './tools/auto-replies.js';
|
|
14
|
+
import { registerFlowTools } from './tools/flows.js';
|
|
15
|
+
import { registerShopifyTools } from './tools/shopify.js';
|
|
16
|
+
import { registerResources } from './resources/index.js';
|
|
17
|
+
async function main() {
|
|
18
|
+
const args = process.argv.slice(2);
|
|
19
|
+
if (args.includes('init') || args.includes('--init') || args.includes('setup') || args.includes('--setup')) {
|
|
20
|
+
await runInteractiveCliSetup();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (args.includes('server') || args.includes('--server') || args.includes('--http') || process.env.MESSEGY_MCP_MODE === 'http') {
|
|
24
|
+
const port = process.env.PORT || 3001;
|
|
25
|
+
startHttpMcpServer(port);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// Initialize official Messegy MCP Server
|
|
29
|
+
const server = new McpServer({
|
|
30
|
+
name: 'messegy-whatsapp',
|
|
31
|
+
version: '1.0.0',
|
|
32
|
+
});
|
|
33
|
+
// Register interactive Auth & Account Switching tools (1st priority)
|
|
34
|
+
registerAuthTools(server);
|
|
35
|
+
// Register all tool suites
|
|
36
|
+
registerMessageTools(server);
|
|
37
|
+
registerTemplateTools(server);
|
|
38
|
+
registerChatTools(server);
|
|
39
|
+
registerContactTools(server);
|
|
40
|
+
registerBroadcastTools(server);
|
|
41
|
+
registerAutoReplyTools(server);
|
|
42
|
+
registerFlowTools(server);
|
|
43
|
+
registerAnalyticsTools(server);
|
|
44
|
+
registerShopifyTools(server);
|
|
45
|
+
// Register dynamic LLM context resources
|
|
46
|
+
registerResources(server);
|
|
47
|
+
// Connect via standard input/output transport
|
|
48
|
+
const transport = new StdioServerTransport();
|
|
49
|
+
await server.connect(transport);
|
|
50
|
+
console.error('🚀 Messegy WhatsApp MCP Server is running on stdio');
|
|
51
|
+
}
|
|
52
|
+
main().catch((error) => {
|
|
53
|
+
console.error('Fatal error in Messegy MCP server:', error);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface PlanUsageInfo {
|
|
2
|
+
planName: string;
|
|
3
|
+
status: string;
|
|
4
|
+
messagesRemaining: number;
|
|
5
|
+
dailyTierLimit: number;
|
|
6
|
+
maxAutoReplies: number;
|
|
7
|
+
currentAutoReplies: number;
|
|
8
|
+
maxFlows: number;
|
|
9
|
+
currentFlows: number;
|
|
10
|
+
isTrial: boolean;
|
|
11
|
+
trialDaysLeft?: number;
|
|
12
|
+
expiresAt?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function fetchCurrentPlanUsage(forceRefresh?: boolean): Promise<PlanUsageInfo>;
|
|
15
|
+
/**
|
|
16
|
+
* Validates requested action against plan quotas before executing.
|
|
17
|
+
* Throws friendly user error if limit exceeded.
|
|
18
|
+
*/
|
|
19
|
+
export declare function enforcePlanQuota(action: 'send_message' | 'send_broadcast' | 'create_auto_reply' | 'create_flow', quantity?: number): Promise<void>;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { api } from '../api-client.js';
|
|
2
|
+
let cachedUsage = null;
|
|
3
|
+
const CACHE_TTL_MS = 30000; // 30 seconds cache to keep tools fast
|
|
4
|
+
export async function fetchCurrentPlanUsage(forceRefresh = false) {
|
|
5
|
+
const now = Date.now();
|
|
6
|
+
if (!forceRefresh && cachedUsage && now - cachedUsage.timestamp < CACHE_TTL_MS) {
|
|
7
|
+
return cachedUsage.data;
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
const [planRes, dashRes] = await Promise.all([
|
|
11
|
+
api.get('/billing/my-plan').catch(() => null),
|
|
12
|
+
api.get('/dashboard').catch(() => null),
|
|
13
|
+
]);
|
|
14
|
+
const plan = planRes?.data?.plan || planRes?.plan || planRes?.data || {};
|
|
15
|
+
const dash = dashRes?.data || dashRes || {};
|
|
16
|
+
const meta = dash?.meta || {};
|
|
17
|
+
const stats = dash?.stats || {};
|
|
18
|
+
const planName = plan?.name || meta?.plan_name || 'Starter Plan';
|
|
19
|
+
const isTrial = Boolean(dash?.trial_days_left && dash.trial_days_left > 0);
|
|
20
|
+
const usage = {
|
|
21
|
+
planName,
|
|
22
|
+
status: plan?.status || 'active',
|
|
23
|
+
messagesRemaining: typeof stats?.messages_remaining === 'number' ? stats.messages_remaining : (plan?.message_limit ?? 1000),
|
|
24
|
+
dailyTierLimit: parseTierLimit(meta?.throughput || meta?.tier),
|
|
25
|
+
maxAutoReplies: plan?.max_auto_replies ?? (planName.toLowerCase().includes('enterprise') ? 9999 : planName.toLowerCase().includes('pro') ? 50 : 5),
|
|
26
|
+
currentAutoReplies: typeof stats?.active_auto_replies === 'number' ? stats.active_auto_replies : 0,
|
|
27
|
+
maxFlows: plan?.max_flows ?? (planName.toLowerCase().includes('enterprise') ? 9999 : planName.toLowerCase().includes('pro') ? 20 : 2),
|
|
28
|
+
currentFlows: typeof stats?.active_flows === 'number' ? stats.active_flows : 0,
|
|
29
|
+
isTrial,
|
|
30
|
+
trialDaysLeft: dash?.trial_days_left,
|
|
31
|
+
expiresAt: plan?.expires_at || plan?.renewal_date,
|
|
32
|
+
};
|
|
33
|
+
cachedUsage = { data: usage, timestamp: now };
|
|
34
|
+
return usage;
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
// Fallback safe limits if billing API is unreachable
|
|
38
|
+
return {
|
|
39
|
+
planName: 'Standard Plan',
|
|
40
|
+
status: 'active',
|
|
41
|
+
messagesRemaining: 500,
|
|
42
|
+
dailyTierLimit: 1000,
|
|
43
|
+
maxAutoReplies: 10,
|
|
44
|
+
currentAutoReplies: 0,
|
|
45
|
+
maxFlows: 5,
|
|
46
|
+
currentFlows: 0,
|
|
47
|
+
isTrial: false,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function parseTierLimit(throughputOrTier) {
|
|
52
|
+
if (typeof throughputOrTier === 'number')
|
|
53
|
+
return throughputOrTier;
|
|
54
|
+
const str = String(throughputOrTier || '').toLowerCase();
|
|
55
|
+
if (str.includes('100k') || str.includes('tier 3'))
|
|
56
|
+
return 100000;
|
|
57
|
+
if (str.includes('10k') || str.includes('tier 2'))
|
|
58
|
+
return 10000;
|
|
59
|
+
if (str.includes('1k') || str.includes('tier 1'))
|
|
60
|
+
return 1000;
|
|
61
|
+
return 1000; // default Meta tier 1
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Validates requested action against plan quotas before executing.
|
|
65
|
+
* Throws friendly user error if limit exceeded.
|
|
66
|
+
*/
|
|
67
|
+
export async function enforcePlanQuota(action, quantity = 1) {
|
|
68
|
+
const usage = await fetchCurrentPlanUsage();
|
|
69
|
+
// Check if account status is active
|
|
70
|
+
if (usage.status.toLowerCase() === 'expired' || usage.status.toLowerCase() === 'suspended') {
|
|
71
|
+
throw new Error(`🚫 Action Blocked: Your Messegy subscription [${usage.planName}] is currently ${usage.status.toUpperCase()}. Please renew your plan on the Messegy Billing portal.`);
|
|
72
|
+
}
|
|
73
|
+
// 1. Message sending check
|
|
74
|
+
if (action === 'send_message') {
|
|
75
|
+
if (usage.messagesRemaining <= 0) {
|
|
76
|
+
throw new Error(`🚫 Message Limit Reached: You have 0 messages remaining on your [${usage.planName}]. Please top up message credits on Messegy Dashboard.`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// 2. Broadcast bulk recipient check
|
|
80
|
+
if (action === 'send_broadcast') {
|
|
81
|
+
if (quantity > usage.messagesRemaining) {
|
|
82
|
+
throw new Error(`🚫 Broadcast Quota Exceeded: You are trying to send ${quantity} messages, but your current plan [${usage.planName}] only has ${usage.messagesRemaining} credits remaining. Please reduce recipient count or purchase additional credits.`);
|
|
83
|
+
}
|
|
84
|
+
if (quantity > usage.dailyTierLimit) {
|
|
85
|
+
throw new Error(`⚠️ Meta Daily Tier Limit Warning: Your current WhatsApp number tier allows max ${usage.dailyTierLimit.toLocaleString()} messages/day. Batch size ${quantity} exceeds this limit.`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// 3. Auto-reply rule limit check
|
|
89
|
+
if (action === 'create_auto_reply') {
|
|
90
|
+
if (usage.currentAutoReplies >= usage.maxAutoReplies) {
|
|
91
|
+
throw new Error(`🚫 Auto-Reply Rule Limit Reached: Your [${usage.planName}] allows a maximum of ${usage.maxAutoReplies} automated rules (${usage.currentAutoReplies}/${usage.maxAutoReplies} used). Please upgrade your plan or delete unused rules.`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// 4. WhatsApp Flow creation limit check
|
|
95
|
+
if (action === 'create_flow') {
|
|
96
|
+
if (usage.currentFlows >= usage.maxFlows) {
|
|
97
|
+
throw new Error(`🚫 WhatsApp Flow Limit Reached: Your [${usage.planName}] allows a maximum of ${usage.maxFlows} active flows (${usage.currentFlows}/${usage.maxFlows} used). Please upgrade your plan on Messegy Dashboard to create more flows.`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=quota-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota-guard.js","sourceRoot":"","sources":["../../src/lib/quota-guard.ts"],"names":[],"mappings":"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"}
|