@daisyintel/whatsapp-cloud-mcp 0.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -62
- package/dist/src/bin/http.js +3 -0
- package/dist/src/bin/http.js.map +1 -0
- package/dist/src/config.js +16 -5
- package/dist/src/config.js.map +1 -1
- package/dist/src/graphClient.js.map +1 -1
- package/dist/src/http.js +33 -0
- package/dist/src/http.js.map +1 -0
- package/dist/src/index.js +4 -27
- package/dist/src/index.js.map +1 -1
- package/dist/src/tools.js +173 -161
- package/dist/src/tools.js.map +1 -1
- package/dist/src/webhook.js +32 -64
- package/dist/src/webhook.js.map +1 -1
- package/mcp.json.example +5 -7
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -1,99 +1,141 @@
|
|
|
1
1
|
# WhatsApp Cloud API MCP Server
|
|
2
2
|
|
|
3
|
-
TypeScript MCP server
|
|
3
|
+
TypeScript MCP server for the WhatsApp Cloud API with a config-driven account model. Each launched server process uses the Meta credentials supplied in the MCP client config or launch environment, so one running instance talks to one WhatsApp account context.
|
|
4
|
+
|
|
5
|
+
## How People Use It
|
|
6
|
+
|
|
7
|
+
The normal usage model is exactly like other MCP servers that accept credentials in the client config.
|
|
8
|
+
|
|
9
|
+
Example MCP config:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"mcpServers": {
|
|
14
|
+
"whatsapp-cloud": {
|
|
15
|
+
"command": "npx",
|
|
16
|
+
"args": ["--yes", "--package", "@daisyintel/whatsapp-cloud-mcp", "whatsapp-cloud-mcp"],
|
|
17
|
+
"env": {
|
|
18
|
+
"WHATSAPP_ACCESS_TOKEN": "replace-me",
|
|
19
|
+
"WHATSAPP_API_VERSION": "v23.0",
|
|
20
|
+
"WHATSAPP_BUSINESS_ID": "",
|
|
21
|
+
"WHATSAPP_WABA_ID": "",
|
|
22
|
+
"WHATSAPP_PHONE_NUMBER_ID": "",
|
|
23
|
+
"WHATSAPP_VERIFY_TOKEN": "",
|
|
24
|
+
"META_APP_SECRET": ""
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
That means:
|
|
32
|
+
|
|
33
|
+
- the MCP client launches the package
|
|
34
|
+
- that launched process uses the `WHATSAPP_*` credentials from `env`
|
|
35
|
+
- all tool calls in that process run against that one WhatsApp account
|
|
36
|
+
|
|
37
|
+
If someone wants to serve multiple downstream users, they should orchestrate multiple isolated instances, each with its own env configuration.
|
|
38
|
+
|
|
39
|
+
## Supported Modes
|
|
40
|
+
|
|
41
|
+
### `stdio` MCP Mode
|
|
42
|
+
|
|
43
|
+
This is the main MCP usage mode.
|
|
44
|
+
|
|
45
|
+
Required:
|
|
46
|
+
|
|
47
|
+
- `WHATSAPP_ACCESS_TOKEN`
|
|
48
|
+
|
|
49
|
+
Optional:
|
|
4
50
|
|
|
5
|
-
|
|
51
|
+
- `WHATSAPP_API_VERSION`
|
|
52
|
+
- `WHATSAPP_BUSINESS_ID`
|
|
53
|
+
- `WHATSAPP_WABA_ID`
|
|
54
|
+
- `WHATSAPP_PHONE_NUMBER_ID`
|
|
55
|
+
- `WHATSAPP_VERIFY_TOKEN`
|
|
56
|
+
- `META_APP_SECRET`
|
|
6
57
|
|
|
7
|
-
|
|
58
|
+
### Hosted HTTP Mode
|
|
59
|
+
|
|
60
|
+
The package also supports a single-account hosted HTTP server if someone wants to run their own MCP/webhook endpoint for one configured account.
|
|
61
|
+
|
|
62
|
+
Example PowerShell startup:
|
|
8
63
|
|
|
9
64
|
```powershell
|
|
10
|
-
$env:WHATSAPP_ACCESS_TOKEN="..."
|
|
65
|
+
$env:WHATSAPP_ACCESS_TOKEN="EAAG..."
|
|
11
66
|
$env:WHATSAPP_API_VERSION="v23.0"
|
|
12
|
-
$env:
|
|
13
|
-
$env:
|
|
14
|
-
$env:
|
|
15
|
-
$env:
|
|
16
|
-
$env:META_APP_SECRET="..."
|
|
67
|
+
$env:WHATSAPP_WABA_ID="123456789"
|
|
68
|
+
$env:WHATSAPP_PHONE_NUMBER_ID="987654321"
|
|
69
|
+
$env:WHATSAPP_VERIFY_TOKEN="my-verify-token"
|
|
70
|
+
$env:META_APP_SECRET="my-app-secret"
|
|
17
71
|
$env:PORT="3000"
|
|
72
|
+
$env:WHATSAPP_MAX_WEBHOOK_EVENTS="100"
|
|
18
73
|
$env:WHATSAPP_ALLOW_UNSIGNED_WEBHOOKS="false"
|
|
74
|
+
|
|
75
|
+
npx --yes --package @daisyintel/whatsapp-cloud-mcp whatsapp-cloud-mcp-http
|
|
19
76
|
```
|
|
20
77
|
|
|
21
|
-
|
|
78
|
+
Hosted endpoints:
|
|
22
79
|
|
|
23
|
-
|
|
80
|
+
- `GET /health`
|
|
81
|
+
- `POST /mcp`
|
|
82
|
+
- `GET /sse`
|
|
83
|
+
- `POST /messages?sessionId=...`
|
|
84
|
+
- `GET /webhook`
|
|
85
|
+
- `POST /webhook`
|
|
24
86
|
|
|
25
|
-
|
|
87
|
+
This hosted HTTP mode is still single-account per process. To handle many users with different Meta credentials, run many instances with different env vars.
|
|
26
88
|
|
|
27
|
-
|
|
28
|
-
- `whatsapp-cloud-mcp-inspect` starts MCP Inspector against the packaged server automatically
|
|
89
|
+
## Multi-User Orchestration Model
|
|
29
90
|
|
|
30
|
-
If
|
|
91
|
+
If a platform wants to serve many clients, the clean model is:
|
|
31
92
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
```
|
|
93
|
+
- client A launches one instance with client A credentials
|
|
94
|
+
- client B launches another instance with client B credentials
|
|
95
|
+
- client C launches another instance with client C credentials
|
|
36
96
|
|
|
37
|
-
|
|
97
|
+
So the scalability model is multiple isolated instances, not one shared token pool inside one process.
|
|
98
|
+
|
|
99
|
+
## Package Commands
|
|
100
|
+
|
|
101
|
+
Published CLIs:
|
|
102
|
+
|
|
103
|
+
- `whatsapp-cloud-mcp`
|
|
104
|
+
- `whatsapp-cloud-mcp-http`
|
|
105
|
+
- `whatsapp-cloud-mcp-inspect`
|
|
106
|
+
|
|
107
|
+
Typical npm usage:
|
|
38
108
|
|
|
39
109
|
```powershell
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
npm run inspect
|
|
110
|
+
npx --yes --package @daisyintel/whatsapp-cloud-mcp whatsapp-cloud-mcp
|
|
111
|
+
npx --yes --package @daisyintel/whatsapp-cloud-mcp whatsapp-cloud-mcp-http
|
|
112
|
+
npx --yes --package @daisyintel/whatsapp-cloud-mcp whatsapp-cloud-mcp-inspect
|
|
44
113
|
```
|
|
45
114
|
|
|
46
|
-
## Scripts
|
|
115
|
+
## Local Dev Scripts
|
|
47
116
|
|
|
48
117
|
```powershell
|
|
49
118
|
npm install
|
|
50
119
|
npm run build
|
|
51
120
|
npm test
|
|
52
|
-
npm
|
|
53
|
-
npm run
|
|
121
|
+
npm run test:package
|
|
122
|
+
npm run dev
|
|
123
|
+
npm run dev:http
|
|
54
124
|
npm run inspect:dev
|
|
55
125
|
```
|
|
56
126
|
|
|
57
127
|
## MCP Inspector
|
|
58
128
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
- `npm run inspect` launches Inspector against the built package server
|
|
62
|
-
- `npm run inspect:dev` launches Inspector directly against `src/index.ts`
|
|
63
|
-
- `whatsapp-cloud-mcp-inspect` does the same as the packaged built-server flow
|
|
64
|
-
|
|
65
|
-
Inspector opens a local UI, usually at `http://localhost:6274`, and proxies to the spawned MCP server. Before starting it, set the same WhatsApp environment variables shown above in your shell.
|
|
66
|
-
|
|
67
|
-
The installed Inspector version requires Node `>=22.7.5`. This machine is already compatible.
|
|
68
|
-
|
|
69
|
-
If you want a reusable client/server config, copy `mcp.json.example` to `mcp.json` and replace the placeholder env values.
|
|
70
|
-
|
|
71
|
-
## Webhook routes
|
|
72
|
-
|
|
73
|
-
- `GET /health`
|
|
74
|
-
- `GET /webhook`
|
|
75
|
-
- `POST /webhook`
|
|
76
|
-
|
|
77
|
-
## MCP transports
|
|
78
|
-
|
|
79
|
-
- `stdio` via the main MCP server process
|
|
80
|
-
- `streamable-http` at `http://127.0.0.1:3000/mcp`
|
|
81
|
-
- `sse` at `http://127.0.0.1:3000/sse` with POST messages to `http://127.0.0.1:3000/messages`
|
|
82
|
-
|
|
83
|
-
## Testing with MCP Inspector
|
|
84
|
-
|
|
85
|
-
To test the current `stdio` transport in Inspector:
|
|
129
|
+
To inspect the `stdio` server locally:
|
|
86
130
|
|
|
87
131
|
```powershell
|
|
88
|
-
$env:WHATSAPP_ACCESS_TOKEN="..."
|
|
89
|
-
$env:WHATSAPP_VERIFY_TOKEN="..."
|
|
132
|
+
$env:WHATSAPP_ACCESS_TOKEN="EAAG..."
|
|
90
133
|
npm run inspect:dev
|
|
91
134
|
```
|
|
92
135
|
|
|
93
|
-
To
|
|
136
|
+
To inspect the hosted HTTP server:
|
|
94
137
|
|
|
95
|
-
1. Start
|
|
96
|
-
2. Open MCP Inspector
|
|
97
|
-
3. Choose:
|
|
98
|
-
|
|
99
|
-
- `sse` with `http://127.0.0.1:3000/sse`
|
|
138
|
+
1. Start it with `npm run dev:http`.
|
|
139
|
+
2. Open MCP Inspector.
|
|
140
|
+
3. Choose `streamable-http` with `http://127.0.0.1:3000/mcp`.
|
|
141
|
+
4. Or choose `sse` with `http://127.0.0.1:3000/sse`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/bin/http.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,CAAC"}
|
package/dist/src/config.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { config as loadDotEnv } from "dotenv";
|
|
2
2
|
loadDotEnv();
|
|
3
|
-
const DEFAULT_API_VERSION = "v23.0";
|
|
4
|
-
const DEFAULT_PORT = 3000;
|
|
5
|
-
const DEFAULT_MAX_WEBHOOK_EVENTS = 100;
|
|
3
|
+
export const DEFAULT_API_VERSION = "v23.0";
|
|
4
|
+
export const DEFAULT_PORT = 3000;
|
|
5
|
+
export const DEFAULT_MAX_WEBHOOK_EVENTS = 100;
|
|
6
6
|
function parseIntWithDefault(rawValue, fallback, label) {
|
|
7
7
|
if (!rawValue) {
|
|
8
8
|
return fallback;
|
|
@@ -16,7 +16,7 @@ function parseIntWithDefault(rawValue, fallback, label) {
|
|
|
16
16
|
function parseBoolean(rawValue) {
|
|
17
17
|
return rawValue === "true" || rawValue === "1";
|
|
18
18
|
}
|
|
19
|
-
export function
|
|
19
|
+
export function loadAccountConfig(env = process.env) {
|
|
20
20
|
const accessToken = env.WHATSAPP_ACCESS_TOKEN;
|
|
21
21
|
if (!accessToken) {
|
|
22
22
|
throw new Error("WHATSAPP_ACCESS_TOKEN is required.");
|
|
@@ -28,10 +28,21 @@ export function loadConfig(env = process.env) {
|
|
|
28
28
|
wabaId: env.WHATSAPP_WABA_ID ?? env.WAB_ID,
|
|
29
29
|
phoneNumberId: env.WHATSAPP_PHONE_NUMBER_ID ?? env.PHONE_ID,
|
|
30
30
|
verifyToken: env.WHATSAPP_VERIFY_TOKEN,
|
|
31
|
-
appSecret: env.META_APP_SECRET
|
|
31
|
+
appSecret: env.META_APP_SECRET
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function loadServerConfig(env = process.env) {
|
|
35
|
+
return {
|
|
32
36
|
port: parseIntWithDefault(env.PORT, DEFAULT_PORT, "PORT"),
|
|
33
37
|
maxWebhookEvents: parseIntWithDefault(env.WHATSAPP_MAX_WEBHOOK_EVENTS, DEFAULT_MAX_WEBHOOK_EVENTS, "WHATSAPP_MAX_WEBHOOK_EVENTS"),
|
|
34
38
|
allowUnsignedWebhooks: parseBoolean(env.WHATSAPP_ALLOW_UNSIGNED_WEBHOOKS)
|
|
35
39
|
};
|
|
36
40
|
}
|
|
41
|
+
export function loadHostedConfig(env = process.env) {
|
|
42
|
+
return {
|
|
43
|
+
server: loadServerConfig(env),
|
|
44
|
+
account: loadAccountConfig(env)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export const loadConfig = loadHostedConfig;
|
|
37
48
|
//# sourceMappingURL=config.js.map
|
package/dist/src/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,QAAQ,CAAC;AAG9C,UAAU,EAAE,CAAC;AAEb,MAAM,mBAAmB,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,QAAQ,CAAC;AAG9C,UAAU,EAAE,CAAC;AAEb,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAO,CAAC;AAC3C,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC;AACjC,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAE9C,SAAS,mBAAmB,CAAC,QAA4B,EAAE,QAAgB,EAAE,KAAa;IACxF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC7C,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,gCAAgC,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,YAAY,CAAC,QAA4B;IAChD,OAAO,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,GAAG,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACpE,MAAM,WAAW,GAAG,GAAG,CAAC,qBAAqB,CAAC;IAC9C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IAED,OAAO;QACL,WAAW;QACX,UAAU,EAAE,GAAG,CAAC,oBAAoB,IAAI,mBAAmB;QAC3D,UAAU,EAAE,GAAG,CAAC,oBAAoB,IAAI,GAAG,CAAC,WAAW;QACvD,MAAM,EAAE,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,MAAM;QAC1C,aAAa,EAAE,GAAG,CAAC,wBAAwB,IAAI,GAAG,CAAC,QAAQ;QAC3D,WAAW,EAAE,GAAG,CAAC,qBAAqB;QACtC,SAAS,EAAE,GAAG,CAAC,eAAe;KAC/B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACnE,OAAO;QACL,IAAI,EAAE,mBAAmB,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC;QACzD,gBAAgB,EAAE,mBAAmB,CACnC,GAAG,CAAC,2BAA2B,EAC/B,0BAA0B,EAC1B,6BAA6B,CAC9B;QACD,qBAAqB,EAAE,YAAY,CAAC,GAAG,CAAC,gCAAgC,CAAC;KAC1E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACnE,OAAO;QACL,MAAM,EAAE,gBAAgB,CAAC,GAAG,CAAC;QAC7B,OAAO,EAAE,iBAAiB,CAAC,GAAG,CAAC;KAChC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,gBAAgB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphClient.js","sourceRoot":"","sources":["../../src/graphClient.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAGxB;IACA;IACA;IACA;IALlB,YACE,OAAe,EACC,QAAgB,EAChB,MAAe,EACf,SAAkB,EAClB,UAA0B;QAE1C,KAAK,CAAC,OAAO,CAAC,CAAC;QALC,aAAQ,GAAR,QAAQ,CAAQ;QAChB,WAAM,GAAN,MAAM,CAAS;QACf,cAAS,GAAT,SAAS,CAAS;QAClB,eAAU,GAAV,UAAU,CAAgB;QAG1C,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAED,SAAS,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"graphClient.js","sourceRoot":"","sources":["../../src/graphClient.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAGxB;IACA;IACA;IACA;IALlB,YACE,OAAe,EACC,QAAgB,EAChB,MAAe,EACf,SAAkB,EAClB,UAA0B;QAE1C,KAAK,CAAC,OAAO,CAAC,CAAC;QALC,aAAQ,GAAR,QAAQ,CAAQ;QAChB,WAAM,GAAN,MAAM,CAAS;QACf,cAAS,GAAT,SAAS,CAAS;QAClB,eAAU,GAAV,UAAU,CAAgB;QAG1C,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAED,SAAS,QAAQ,CAAC,MAA6B,EAAE,IAAY,EAAE,KAAoC;IACjG,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,8BAA8B,MAAM,CAAC,UAAU,IAAI,aAAa,EAAE,CAAC,CAAC;IAExF,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;QACvD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,QAAkB;IAC9C,IAAI,IAAa,CAAC;IAElB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAE,IAAgC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvG,MAAM,UAAU,GAAG,IAAI,EAAE,KAAK,CAAC;IAC/B,MAAM,UAAU,GACd,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,CAAC,CAAC,CAAE,UAAsC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE9G,OAAO;QACL,OAAO,EACL,OAAO,UAAU,EAAE,OAAO,KAAK,QAAQ;YACrC,CAAC,CAAC,UAAU,CAAC,OAAO;YACpB,CAAC,CAAC,wCAAwC,QAAQ,CAAC,MAAM,GAAG;QAChE,IAAI,EAAE,OAAO,UAAU,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QACxE,IAAI,EAAE,OAAO,UAAU,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QACxE,YAAY,EAAE,OAAO,UAAU,EAAE,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;QAClG,SAAS,EAAE,OAAO,UAAU,EAAE,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;QACzF,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,mBAAmB;IAEX;IACA;IAFnB,YACmB,MAA6B,EAC7B,YAA0B,KAAK;QAD/B,WAAM,GAAN,MAAM,CAAuB;QAC7B,cAAS,GAAT,SAAS,CAAsB;IAC/C,CAAC;IAEJ,KAAK,CAAC,OAAO,CAAI,OAA4B;QAC3C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QAElE,IAAI,IAA0B,CAAC;QAC/B,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC1B,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACtC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;YAChD,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;YAC9C,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;YAC/B,OAAO;YACP,IAAI;SACL,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,SAAS,CAAC;QACvE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,IAAI,iBAAiB,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QACpG,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,OAAO,SAAc,CAAC;QACxB,CAAC;QAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,WAAW,CAAI,OAA4B;QAC/C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAEhC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAI,OAAO,CAAC,CAAC;YAC5C,OAAO;gBACL,EAAE,EAAE,IAAI;gBACR,QAAQ;gBACR,IAAI;aACL,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;gBACvC,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,KAAK,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE;iBACtD,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,QAAQ;gBACR,KAAK,EAAE;oBACL,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B;oBAC5E,OAAO,EAAE,KAAK;iBACf;aACF,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|
package/dist/src/http.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { loadHostedConfig } from "./config.js";
|
|
2
|
+
import { InMemoryWebhookEventStore } from "./eventStore.js";
|
|
3
|
+
import { createWhatsAppMcpServer } from "./tools.js";
|
|
4
|
+
import { startHttpServer } from "./webhook.js";
|
|
5
|
+
async function main() {
|
|
6
|
+
const appConfig = loadHostedConfig();
|
|
7
|
+
const eventStore = new InMemoryWebhookEventStore(appConfig.server.maxWebhookEvents);
|
|
8
|
+
const createMcpServer = () => createWhatsAppMcpServer(appConfig.account, eventStore);
|
|
9
|
+
const httpServer = await startHttpServer(appConfig.server, appConfig.account, eventStore, createMcpServer);
|
|
10
|
+
console.error(`HTTP server listening on port ${appConfig.server.port}`);
|
|
11
|
+
console.error(`MCP streamable HTTP endpoint: http://127.0.0.1:${appConfig.server.port}/mcp`);
|
|
12
|
+
console.error(`MCP SSE endpoint: http://127.0.0.1:${appConfig.server.port}/sse`);
|
|
13
|
+
console.error(`Webhook endpoint: http://127.0.0.1:${appConfig.server.port}/webhook`);
|
|
14
|
+
const shutdown = async () => {
|
|
15
|
+
await new Promise((resolve, reject) => {
|
|
16
|
+
httpServer.close((error) => {
|
|
17
|
+
if (error) {
|
|
18
|
+
reject(error);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
resolve();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
process.exit(0);
|
|
25
|
+
};
|
|
26
|
+
process.on("SIGINT", () => void shutdown());
|
|
27
|
+
process.on("SIGTERM", () => void shutdown());
|
|
28
|
+
}
|
|
29
|
+
main().catch((error) => {
|
|
30
|
+
console.error(error instanceof Error ? error.stack : error);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC;IACrC,MAAM,UAAU,GAAG,IAAI,yBAAyB,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACpF,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,uBAAuB,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAErF,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;IAC3G,OAAO,CAAC,KAAK,CAAC,iCAAiC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACxE,OAAO,CAAC,KAAK,CAAC,kDAAkD,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,CAAC;IAC7F,OAAO,CAAC,KAAK,CAAC,sCAAsC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,CAAC;IACjF,OAAO,CAAC,KAAK,CAAC,sCAAsC,SAAS,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,CAAC;IAErF,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACzB,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,CAAC,KAAK,CAAC,CAAC;oBACd,OAAO;gBACT,CAAC;gBAED,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/src/index.js
CHANGED
|
@@ -1,36 +1,13 @@
|
|
|
1
1
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
2
|
-
import {
|
|
2
|
+
import { DEFAULT_MAX_WEBHOOK_EVENTS, loadAccountConfig } from "./config.js";
|
|
3
3
|
import { InMemoryWebhookEventStore } from "./eventStore.js";
|
|
4
|
-
import { WhatsAppGraphClient } from "./graphClient.js";
|
|
5
4
|
import { createWhatsAppMcpServer } from "./tools.js";
|
|
6
|
-
import { startHttpServer } from "./webhook.js";
|
|
7
5
|
async function main() {
|
|
8
|
-
const
|
|
9
|
-
const eventStore = new InMemoryWebhookEventStore(
|
|
10
|
-
const
|
|
11
|
-
const createMcpServer = () => createWhatsAppMcpServer(client, config, eventStore);
|
|
12
|
-
const httpServer = await startHttpServer(config, eventStore, createMcpServer);
|
|
13
|
-
console.error(`HTTP server listening on port ${config.port}`);
|
|
14
|
-
console.error(`MCP streamable HTTP endpoint: http://127.0.0.1:${config.port}/mcp`);
|
|
15
|
-
console.error(`MCP SSE endpoint: http://127.0.0.1:${config.port}/sse`);
|
|
16
|
-
console.error(`Webhook endpoint: http://127.0.0.1:${config.port}/webhook`);
|
|
17
|
-
const stdioServer = createMcpServer();
|
|
6
|
+
const account = loadAccountConfig();
|
|
7
|
+
const eventStore = new InMemoryWebhookEventStore(DEFAULT_MAX_WEBHOOK_EVENTS);
|
|
8
|
+
const stdioServer = createWhatsAppMcpServer(account, eventStore);
|
|
18
9
|
const transport = new StdioServerTransport();
|
|
19
10
|
await stdioServer.connect(transport);
|
|
20
|
-
const shutdown = async () => {
|
|
21
|
-
await new Promise((resolve, reject) => {
|
|
22
|
-
httpServer.close((error) => {
|
|
23
|
-
if (error) {
|
|
24
|
-
reject(error);
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
resolve();
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
process.exit(0);
|
|
31
|
-
};
|
|
32
|
-
process.on("SIGINT", () => void shutdown());
|
|
33
|
-
process.on("SIGTERM", () => void shutdown());
|
|
34
11
|
}
|
|
35
12
|
main().catch((error) => {
|
|
36
13
|
console.error(error instanceof Error ? error.stack : error);
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAErD,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,UAAU,GAAG,IAAI,yBAAyB,CAAC,0BAA0B,CAAC,CAAC;IAC7E,MAAM,WAAW,GAAG,uBAAuB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,MAAM,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACvC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|