WhatsApp MCP on Cloudflare Workers – Read‑Only AI‑Powered Message Access

TL;DR – What WhatsApp MCP does and why it matters

WhatsApp MCP is a self‑hosted, read‑only server that runs on Cloudflare Workers and lets an AI agent (e.g., Claude Code) search and read your own WhatsApp chats without sending messages. It stores messages in a private SQLite database inside a Durable Object, keeping the data under your control while exposing a standard MCP interface.


Core functionality – AI agents can query your chat history

  • Search and read: Agents can run search_messages across all chats or within a specific conversation, and get_messages to page through a chat.
  • Chat discovery: list_chats returns recent chats, optionally filtered by name or number.
  • Naming assistance: unnamed_chats surfaces chats that only have phone numbers; agents can call set_contact_names to attach human‑readable names.
  • On‑demand sync: sync_now forces an immediate pull from WhatsApp if the stored copy is older than ten minutes.
  • Read‑only guarantee: The server never sends messages; it only reads what WhatsApp provides to a linked device.

Architecture – How the system stays private and lightweight

  • Durable Object as single source of truth: All messages, contacts, and Baileys authentication data live in a SQLite DB inside one Durable Object (WhatsAppStore).
  • Stateless Cloudflare Worker: The Worker handles HTTP/MCP routing, OAuth, and a daily cron that triggers a pull. It holds no message data itself.
  • Baileys library: An open‑source WhatsApp Web client library is used to emulate a linked device. The code includes three shims (ws‑shim.ts, vendor‑bridge.mjs, polyfills.ts) to make Baileys run on Cloudflare’s workerd runtime.
  • OAuth protection: A password (OWNER_PASSWORD) or optional email‑based login protects the /mcp endpoint. Tokens are stored in a KV namespace (OAUTH_KV).
  • No external storage: Apart from Cloudflare KV for OAuth tokens, all data stays inside the Durable Object; nothing is sent to third‑party storage.

Deployment steps – From zero to a working endpoint

  1. Prerequisites: Cloudflare account on the Workers Paid plan, Node 20+, and a phone with WhatsApp.
  2. Clone and install:
    git clone https://github.com/finereli/whatsapp-mcp
    cd whatsapp-mcp
    npm install
    
  3. Create KV namespace for OAuth tokens:
    npx wrangler kv namespace create OAUTH_KV
    
  4. Set a strong owner password (12+ characters):
    npx wrangler secret put OWNER_PASSWORD
    
  5. Deploy:
    npm run deploy
    
    Wrangler prints a URL like https://whatsapp-mcp.<your‑name>.workers.dev.
  6. Link WhatsApp: Open the URL, scan the QR code from WhatsApp → Settings → Linked Devices. The first link imports whatever history WhatsApp provides.
  7. Connect an MCP client (e.g., Claude Code):
    claude mcp add --transport http whatsapp https://<your‑url>/mcp
    
    Then run /mcp and sign in with the password.

Operational notes – What you need to know before using or modifying the project

  • Terms of Service risk: The project uses the same reverse‑engineered protocol as WhatsApp Web, which is against WhatsApp’s TOS. The practical risk is low for a read‑only linked device, but it is non‑zero.
  • Import limits: The initial history import can exceed the default CPU limit on Workers; the repo’s wrangler.jsonc raises the limit, which requires a paid plan.
  • Data completeness: WhatsApp only sends the portion of history it deems appropriate for a new device. To fill gaps, you must relink the device.
  • Unnamed chats: Many one‑off contacts appear only as phone numbers. Agents can resolve these by calling unnamed_chats and then set_contact_names with data from your own contacts store.
  • Media handling: Media files are not downloaded; they appear as placeholders like [image] or [voice note 12s].
  • Single‑user design: Each deployment is tied to one WhatsApp account; multi‑user support would require redesigning the Durable Object keying.

Extending the server – Adding tools or changing auth

  • Add a new MCP tool: Register it in src/mcp.ts and implement any required SQL in src/store.ts. Keep read‑only tools idempotent.
  • Swap authentication mode: src/auth.ts supports password or email‑based login. Adding another identity provider only requires a new mode and callback route; the rest of the code sees an opaque bearer token.
  • Multi‑user scaling: Replace the fixed Durable Object name (owner) with a per‑user identifier derived from the signed‑in identity, and adjust the OAuth payload accordingly.
  • Custom name ingestion: Any external process that can produce { jid, name } rows can call store.setCustomNames. This enables CSV uploads, CardDAV syncs, or scheduled jobs without exposing credentials to the server.
  • Sending messages: The project deliberately omits write capability. Adding it would require careful security review because it would turn the linked device into a fully functional bot, increasing the risk of account bans.

Debugging and testing – Built‑in diagnostics

With the optional PIN secret set, the following endpoints return JSON for troubleshooting (include header x‑pin: <PIN>):

  • /debug – shows session phase, linked status, and recent events.
  • /debug/pull – forces an immediate pull.
  • /debug/* – various read‑only queries (chats, messages, search, unnamed, sql).
  • /debug/logout – triggers the same flow as relink.

Local development can be run with npm run dev and a .dev.vars file containing OWNER_PASSWORD. This spins up a local Durable Object with empty storage, allowing you to test the QR pairing flow without affecting a production deployment.

Community reaction – Highlights from Hacker News discussion

"AI built me an Android gateway that can send/read text messages… zero SaaS, 3rd party, or purchases after the software was built." – @pizzafeelsright

"What bothers me is exposing the other side of conversations to a 3rd‑party AI company… people you are messaging never consented." – @SchemaLoad

"I've experimented with WhatsApp‑web hacks and sometimes get banned; it’s inconvenient if WA is the universal contact channel." – @taldo

"Sounds like the free plan might not be enough; the repo notes a paid plan is required for the initial import." – @calmingsolitude

"I was banned after linking a secondary device; WhatsApp can permanently block accounts that add unofficial linked devices." – @lgleason

These comments underline the privacy, legal, and reliability concerns that accompany any unofficial WhatsApp integration.


Bottom line

WhatsApp MCP demonstrates that a personal, read‑only AI assistant can be built on top of Cloudflare Workers without storing data off‑site. It offers a concrete example of how to combine the MCP protocol, Baileys, and Cloudflare Durable Objects to give AI agents contextual access to your own messages—while also surfacing the legal and operational trade‑offs of reverse‑engineered WhatsApp integrations.

Sources

Related

  • Project
  • Dispatch
  • Project
  • Project
  • Project