whatsmcp
whatsmcp
An MCP server on Cloudflare Workers that exposes the
Z-API WhatsApp REST API as tools, served over Streamable HTTP at
https://whatsmcp.unfld.dev/mcp.
Tools are generated at build time from postman.json, so the tool surface tracks
the collection rather than being hand-maintained. Three meta-tools (zapi_list_endpoints,
zapi_describe_endpoint, zapi_request) are always registered, so no endpoint is ever unreachable
even when the toolset filter narrows what gets exposed.
Z-API does not keep message bodies. This Worker also accepts Z-API webhooks, stores events in
Cloudflare D1, and exposes whatsmcp_history_list / whatsmcp_history_get /
whatsmcp_history_search so clients can read inbound replies. Chat tags from
GET /chats (optional string etiqueta ids) are snapshotted separately; filter
history with whatsmcp_history_list tag= after whatsmcp_chats_sync or a
webhook on that chat. Image/audio/document/video links from received webhooks
are stored as mediaUrl (Z-API hosted, ~30 days; not copied to R2).
Setup
bun installCreate .dev.vars in the repo root (gitignored) with your Z-API credentials:
MCP_AUTH_TOKEN=...
WEBHOOK_AUTH_TOKEN=...
ZAPI_INSTANCE_ID=...
ZAPI_INSTANCE_TOKEN=...
ZAPI_CLIENT_TOKEN=...ZAPI_INSTANCE_ID and ZAPI_INSTANCE_TOKEN build the instance base URL; ZAPI_CLIENT_TOKEN is sent
as the Client-Token header. MCP_AUTH_TOKEN is the static bearer token clients must present.
WEBHOOK_AUTH_TOKEN is the query token on webhook URLs (?token=).
Local run
bun run devWrangler serves the Worker at http://localhost:8787. The MCP endpoint is
http://127.0.0.1:8787/mcp. Clients must send one of:
Authorization: Bearer <MCP_AUTH_TOKEN>
Authorization: <MCP_AUTH_TOKEN>GET /health is public and returns { "ok": true, "name": "whatsmcp" }.
GET /icon.png and GET /icon.svg are also public (the MCP server advertises them
as its icons).
Webhook ingest (HTTPS only; Z-API will not call local http://):
POST /webhooks/on-message-sent?token=<WEBHOOK_AUTH_TOKEN>
POST /webhooks/on-message-received?token=<WEBHOOK_AUTH_TOKEN>
POST /webhooks/on-disconnect?token=<WEBHOOK_AUTH_TOKEN>
POST /webhooks/on-connect?token=<WEBHOOK_AUTH_TOKEN>
POST /webhooks/on-message-status-received?token=<WEBHOOK_AUTH_TOKEN>
POST /webhooks/on-chat-presence?token=<WEBHOOK_AUTH_TOKEN>Register those six URLs separately (the whatsmcp_register_webhooks tool does this).
Also enable Notificar as enviadas por mim também on the received webhook (the register
tool turns this on) so messages you send are stored with fromMe: true and show up in
history next to inbound replies.
Do not use Z-API update-every-webhooks — it points every event type at one URL.
Scripts
Script | What it does |
| Regenerate |
| Run the Worker locally with |
| Deploy to Cloudflare |
|
|
| Run the test suite |
| Regenerate |
Rerun bun run cf-typegen after changing bindings or vars in wrangler.jsonc.
Configuration
ZAPI_TOOLSETS (a plain var in wrangler.jsonc, default *) selects which Z-API categories
register as tools — for example instance,messages,groups. The meta-tools ignore this filter.
Deploying
Secrets are not stored in wrangler.jsonc. Set them once per environment:
wrangler secret put MCP_AUTH_TOKEN
wrangler secret put WEBHOOK_AUTH_TOKEN
wrangler secret put ZAPI_INSTANCE_ID
wrangler secret put ZAPI_INSTANCE_TOKEN
wrangler secret put ZAPI_CLIENT_TOKEN
wrangler d1 migrations apply whatsmcp --remote
wrangler deployThe whatsmcp.unfld.dev custom domain is declared in wrangler.jsonc and is provisioned by
Cloudflare on first deploy.
Connecting a client
{
"mcpServers": {
"whatsmcp": {
"url": "https://whatsmcp.unfld.dev/mcp",
"headers": { "Authorization": "Bearer <MCP_AUTH_TOKEN>" }
}
}
}Both Authorization: Bearer <MCP_AUTH_TOKEN> and the bare
Authorization: <MCP_AUTH_TOKEN> form are accepted. GET /health is public
and unauthenticated for uptime checks. The server icon is at
https://whatsmcp.unfld.dev/icon.png (SVG at /icon.svg).
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/pedrogmbh/whatsmcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server