Skip to main content
Glama

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 install

Create .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 dev

Wrangler 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

bun run generate

Regenerate src/generated/endpoints.ts from the Postman collection

bun run dev

Run the Worker locally with wrangler dev

bun run deploy

Deploy to Cloudflare

bun run typecheck

tsc --noEmit

bun test

Run the test suite

bun run cf-typegen

Regenerate worker-configuration.d.ts from wrangler.jsonc + .dev.vars

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 deploy

The 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

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