Skip to main content
Glama
MAASAI-Labs

WhatsApp Community Manager MCP

by MAASAI-Labs
README.md
# WhatsApp Community Manager MCP

**Live MCP URL (Streamable HTTP):** `https://whatsapp-community-mcp.vercel.app/mcp`  
Health check: `https://whatsapp-community-mcp.vercel.app/health`

Run your WhatsApp groups from any MCP client. It can list groups, read recent messages, summarise activity, draft posts, and post or schedule them.

It is **generic and bring-your-own-credentials**: every user connects **their own** [Green API](https://green-api.com) instance, and can optionally add their own WhatsApp Cloud API number. The server ships with no shared account.

> **Safety:** every tool that sends something (`post_message`, `schedule_post`, `run_due_posts`) returns a **preview only** unless it is called with `confirm: true`. The assistant should only set `confirm: true` after the user approves that exact text and destination. Message text read from groups is treated as untrusted data, never as instructions.

## Tools
| Tool | Purpose | Sends? |
|---|---|---|
| `connection_status` | Shows which providers are configured and the Green API instance state. Credentials are never shown | No |
| `list_groups` | Lists the groups you're in, with their chat ids | No |
| `group_info` | Group name, description, participant and admin count | No |
| `read_group_messages` | Last N messages, oldest first | No |
| `summarise_activity` | Message volume, top posters, busiest hours (in your timezone), keywords, questions that look unanswered, links shared | No |
| `draft_post` | Announcement, event, reminder, poll, welcome or rules post with WhatsApp formatting, built from your facts | No |
| `post_message` | Sends text, or a file/image from a URL with a caption | **Only with `confirm: true`** |
| `schedule_post` | Queues a post 1 min to 90 days ahead | **Only with `confirm: true`** |
| `list_scheduled_posts` / `cancel_scheduled_post` | Manage the queue | No |
| `run_due_posts` | Sends posts that are due. Call it from a cron | **Only with `confirm: true`** |

## Credentials (yours, never shared)
| Variable / HTTP header | Meaning |
|---|---|
| `GREEN_API_ID_INSTANCE` / `x-green-api-id-instance` | Your Green API idInstance |
| `GREEN_API_TOKEN_INSTANCE` / `x-green-api-token-instance` | Your apiTokenInstance |
| `GREEN_API_URL` / `x-green-api-url` | Your instance's apiUrl from the console, e.g. `https://7103.api.greenapi.com`. Default: `https://api.green-api.com`. Only Green API hosts are accepted |
| `WHATSAPP_CLOUD_TOKEN`, `WHATSAPP_PHONE_NUMBER_ID` (optional) | Meta WhatsApp Cloud API. It can send to individuals only: it can't read group history or post to these groups, and outside the 24 h window it needs approved templates |

On a hosted deployment, each user should send their own credentials as the HTTP headers above. Nothing is stored. Environment variables are a fallback for single-user or stdio setups. If you set them on a shared deployment, every caller acts as that account.

## Example prompts
- "List my WhatsApp groups."
- "Summarise the last 200 messages in Lagos Devs, Africa/Lagos time. Which questions went unanswered?"
- "Draft an event post for our meetup on Sat 18 Oct, 2pm at Yaba, then show me the preview."
- "Schedule that reminder for Friday 9am Lagos time." (The assistant previews it, you approve, then it schedules with confirm.)

## Run locally
```bash
npm install && npm run build
GREEN_API_ID_INSTANCE=... GREEN_API_TOKEN_INSTANCE=... GREEN_API_URL=https://XXXX.api.greenapi.com npm start   # http://localhost:3000/mcp
npm run start:stdio
npm test        # 14 mocked tests: no network, no sends
npm run smoke   # HTTP smoke with credentials stripped: sends nothing
```

Claude Desktop config:
```json
{ "mcpServers": { "whatsapp-community": { "command": "node", "args": ["/path/dist/main-stdio.js"], "env": { "GREEN_API_ID_INSTANCE": "…", "GREEN_API_TOKEN_INSTANCE": "…", "GREEN_API_URL": "https://XXXX.api.greenapi.com" } } } }
```

## Deploy to Vercel
1. Import the repo. `api/mcp.ts` and `vercel.json` are already set up, and the endpoint is `/mcp`.
2. Don't set shared credentials. Users send theirs as headers.
3. **Scheduling on serverless:** the queue is a JSON file under `DATA_DIR`. The default is `~/.whatsapp-community-mcp`, or `/tmp` on Vercel, which does **not** persist. For production scheduling, run the server somewhere with a durable `DATA_DIR`, or swap `src/store.ts` for a KV store. Then trigger `run_due_posts` with `confirm: true` from a cron you control.

## Marketplace reviewer test
1. `npm install && npm run build && npm test`: 14 tests pass. All provider calls are mocked, and the tests show that no request is made without `confirm: true`.
2. `npm run smoke`: 6/6. Previews work, and tools that need credentials fail cleanly.
3. To test with your own number, start with `connection_status`, `list_groups` and then `post_message` **without** confirm. Check the preview, then post to a test group with `confirm: true`.

## Limitations
- Polls are drafted as numbered text, not native WhatsApp polls.
- The summary is statistical. The assistant writes the prose on top of it.
- Green API rate and plan limits apply; HTTP 466 is reported as a quota error.

MIT License © 2026 Segun Cole


## Storage and tenant isolation

- **Hosted:** data is kept in a private **Vercel Blob** store (free Hobby quota) when `BLOB_READ_WRITE_TOKEN` is set, at `<app>/<tenant>/<file>.json`, with ETag-based optimistic concurrency.
- **Tenant key:** a one-way SHA-256 hash of the caller's own credential headers, or of an `x-user-key` header if you send one (recommended if your token rotates). Secrets are never stored and tenants can't see each other's data. Callers with no credentials and no `x-user-key` share a `public-demo` space, so don't put real data there.
- **Local / self-hosted:** without a Blob token it falls back to JSON files under `DATA_DIR` (default `~/.whatsapp-community-mcp/<tenant>/`).

## Scheduled posts and cron

`vercel.json` registers a Vercel Cron job (`/api/cron`, daily at 07:00 UTC: Hobby allows cron jobs at most once a day). It needs a `CRON_SECRET` env var, which Vercel sends as `Authorization: Bearer …`, and it only sends due posts for the **operator's own** credentials set as env vars (a single-tenant, self-hosted deployment). On the shared hosted server no operator credentials are set, so the cron does nothing. Each user's client calls `run_due_posts` (with `confirm: true`) instead. For minute-level timing, upgrade to Pro cron, or call `run_due_posts` from your own scheduler.

TDQS

A3.6/5.0

Scored across 11 tools

Disambiguation5/5

Each tool targets a distinct action/resource: raw reads (read_group_messages) vs. aggregation (summarise_activity), drafting (draft_post) vs. sending (post_message), and the scheduling lifecycle is cleanly split into schedule/list/cancel/run. The draft/schedule/run tools all describe their preview-without-confirm behavior consistently, so an agent can reliably pick the right one.

Naming Consistency4/5

Almost all names follow a predictable verb_noun snake_case pattern (list_groups, read_group_messages, post_message, schedule_post, cancel_scheduled_post). A few are noun-only (connection_status, group_info), which is a minor deviation but still readable and unambiguous.

Tool Count5/5

11 tools is well-scoped for a WhatsApp community manager: connection, group discovery, reading, summarising, drafting, sending, and a full scheduling sub-lifecycle. Every tool earns its place with no redundant entries.

Completeness4/5

The messaging and scheduling lifecycle is well covered (draft, send, schedule, list, cancel, run due), with read and summary operations for groups. However, group/community administration is absent: no tools to add/remove participants, promote/demote admins, or create/manage groups, which are notable gaps for a 'community manager' server.

Maintenance

ActivityMaintained
ResponsivenessNo issues