whatsapp-mcp
Provides tools for interacting with WhatsApp, including sending and receiving messages, managing chats and contacts, reacting to messages, and downloading media, enabling agents to monitor and participate in conversations.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@whatsapp-mcpsend a WhatsApp message to Mom saying I'll be home by 6"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
WhatsApp MCP Server
WhatsApp as an MCP server. Runs as a long-lived Docker daemon, accessed over HTTPS with Bearer auth, and pushes ntfy notifications when your session needs attention (QR expired, connection dropped). Built on Baileys via the @amiticia/baileys-client wrapper.
Who this is for
You want your personal WhatsApp account reachable as a set of tools from Claude Code, Claude Desktop, Cursor, or any custom MCP/HTTP client — from any machine — with the WhatsApp connection surviving client restarts, multiple clients sharing one socket, and a push telling you on your phone when you need to re-scan a QR.
Related MCP server: whatsapp-mcp
Features
HTTP MCP endpoint (
httpStreamtransport) — connect from anywhere, share the session across multiple clients without Baileys fighting for the socketBearer-token auth on the MCP endpoint
Public QR web page (protected by paired-number check) — tap the ntfy push and scan directly from your phone browser
ntfy push on: first QR after disconnect, every 2min while still waiting, connection drop, reconnect after drop, and unexpected pairings
Bad-pairing protection — if someone else scans the public QR, the app auto-logs out and purges credentials (
EXPECTED_WA_NUMBER)23 MCP tools — search contacts/messages, list chats, send text/media, react, delete, mark read, download media, plus reactive monitoring (cursor delta, long-poll, a
follow_chatWebSocket stream) and webhook subscriptions for real-time inbound push (see table below)Persistent SQLite (chats/messages/contacts) and Baileys multi-file auth stored in a Docker volume
Architecture
flowchart LR
subgraph clients[MCP clients]
CC[Claude Code / Desktop / Cursor / custom agents]
end
PB[Phone browser]
CC -- "https + Bearer" --> T[Traefik]
PB -- "https (public)" --> T
T -- ":39001" --> MCP[FastMCP httpStream]
T -- ":39002" --> QR[QR page]
subgraph container[whatsapp-mcp container]
MCP
QR
BA[Baileys]
end
MCP --> BA
QR --> BA
BA -- "WA Web API" --> WA[(WhatsApp servers)]
container -- "outbound POST" --> NT[ntfy.sh] -- push --> PH[Your phone]One container exposes two HTTP servers on different ports. Traefik terminates TLS (Let's Encrypt) and routes by hostname.
Quick start for MCP clients
A deployment exposes two hostnames of your choosing (example.com below — substitute your own):
https://mcp.example.com/mcp— MCP endpoint, requiresAuthorization: Bearer <MCP_AUTH_TOKEN>https://wa.example.com/— QR web page
Claude Code
Edit ~/.claude.json, in the top-level mcpServers object:
"whatsapp": {
"type": "http",
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer ${MCP_AUTH_TOKEN}"
}
}Export MCP_AUTH_TOKEN in your shell (or put the token literally — ~/.claude.json is 0600). Restart Claude Code, run /mcp — should show whatsapp: ✓ Connected.
Claude Desktop
~/.config/Claude/claude_desktop_config.json (Linux) / ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"whatsapp": {
"type": "http",
"url": "https://mcp.example.com/mcp",
"headers": { "Authorization": "Bearer your-token-here" }
}
}
}Cursor
~/.cursor/mcp.json — same shape as Claude Desktop above.
Other clients / custom code
See examples/ for a raw HTTPS JSON-RPC transcript (curl), a Python client, and a custom TypeScript agent using StreamableHTTPClientTransport.
MCP tools
The server exposes 23 tools. Full reference: docs/tools.md.
Category | Tools |
Connection / Auth |
|
Contacts |
|
Messages |
|
Reactive monitoring |
|
Chats |
|
Groups |
|
Sending |
|
Actions |
|
Media |
|
Webhooks |
|
Deployment
Full deploy / update / rotate-secrets / troubleshoot runbook: deploy/README.md. The production compose file is deploy/docker-compose.yaml; hostnames and the send policy come from deploy/.env (template: deploy/.env.example).
This repo depends on its sibling baileys-client (link:../baileys-client), so clone both side by side. Build recipe (BuildKit):
git clone https://github.com/eusoubrasileiro/baileys-client.git
git clone https://github.com/eusoubrasileiro/whatsapp-mcp.git
cd whatsapp-mcp
DOCKER_BUILDKIT=1 docker build \
--build-context baileys=../baileys-client \
-t whatsapp-mcp:latest .Local development
For development without Docker, keep the default stdio transport. Build the sibling baileys-client checkout first (see Deployment):
(cd ../baileys-client && pnpm install && pnpm build)
pnpm install
pnpm test # vitest — git hooks enforce it on every commit
pnpm typecheck
pnpm start # node --experimental-strip-types src/main.tsRequires Node.js 24 (.nvmrc; engines asks for >= 24) for --experimental-strip-types and native better-sqlite3.
For local HTTP mode (same as production minus Traefik):
MCP_TRANSPORT=httpstream MCP_AUTH_TOKEN=dev pnpm start
# then: curl -H 'Authorization: Bearer dev' http://127.0.0.1:39001/mcp ...See scripts/smoke-test.sh for the auth matrix, and docs/development.md for tests, hooks and conventions.
Environment variables
Full table: docs/configuration.md. Highlights:
Variable | Purpose |
| Bearer token required by the HTTP MCP endpoint (mandatory in production) |
| Unset = no push notifications; set to enable |
| Prefix allowed to pair; wrong scan → auto-logout + purge (strongly recommended whenever the QR page is public) |
| Base dir for |
| Powers |
| Transcription route: |
| OpenRouter model for image description (default |
Data storage & privacy
Credentials:
WHATSAPP_MCP_DATA_DIR/auth_info/(Baileys multi-file auth state)Messages / chats / contacts:
WHATSAPP_MCP_DATA_DIR/data/whatsapp.db(SQLite via Drizzle +better-sqlite3)Media: served from a RustFS sidecar in the same compose stack, behind Traefik at
https://mcp.example.com/media/<key>. Thedownload_mediatool returns an MCPresource_linkpointing at that URL (publicly fetchable, no Bearer needed) plus inlineimageContent/audioContenton the first call. Cache hits return the URL only.Audio → text: by default,
download_mediaon an audio/ptt message transcribes via OpenRouter Whisper (openai/whisper-large-v3) after preprocessing to 16 kHz mono FLAC. The response is wrapped in an<transcription>XML block. Passtranscribe: falseto get raw audio bytes instead. RequiresOPENROUTER_API_KEY. Groq and OpenAI remain as rollback routes viaAUDIO_PROVIDER(each needs its own key).Image → text: opt-in via
download_media({ ..., describe: true }). Sends the image to an OpenRouter vision model (VISION_MODEL, defaultopenai/gpt-6-luna); response wrapped in an<image_description>XML block. RequiresOPENROUTER_API_KEY.Logs:
WHATSAPP_MCP_DATA_DIR/{wa,mcp}-logs.txt(pino JSON lines)
Everything stays on the VPS (Docker bind mount in production, filesystem in dev). Data leaves the VPS only when an MCP client explicitly invokes a tool.
All data directories are .gitignored. Treat them as sensitive — anyone with auth_info/ can impersonate your WhatsApp session.
Credits
Conceptual origin: lharries/whatsapp-mcp (Go + Python).
Fork history: started from
jlucaso1/whatsapp-mcp-ts, since heavily rewritten (HTTP transport, send guards, media plane, reactive monitoring).Maintained by eusoubrasileiro.
License
MIT — see LICENSE, which also carries the ISC notice for the portions derived from jlucaso1/whatsapp-mcp-ts.
Not affiliated with WhatsApp or Meta. Baileys is an unofficial WhatsApp Web client; automating a WhatsApp account can get it restricted — read docs/account-restrictions.md before sending from a number you care about.
This server cannot be deployed
Maintenance
Related MCP Connectors
WhatsMCP connects Claude and other MCP-compatible AI agents directly to WhatsApp. Send and receive text, images, documents, and voice notes; manage groups (create, add/remove members, promote admins); look up contacts and profiles; follow channels; and read call and message history — all through a standard MCP interface. For voice use cases, WhatsMCP offers SIP-based calling plans (inbound-only, or full inbound/outbound) so AI voice agents can answer and place WhatsApp calls, plus low-latency WebSocket integrations with voice agent providers like ElevenLabs. Multiple WhatsApp accounts can be paired and managed per workspace, with webhook support for real-time inbound message delivery to your own infrastructure.
Drive WhatsApp from any MCP client: pair devices, send text and media, manage contacts and groups.
Your own WhatsApp as an MCP server: read, search and send from any MCP client.
WhatsApp (Web + Business API), SMS, contacts, and call records via 2Chat's MCP server.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI clients to interact with WhatsApp via MCP tools for searching contacts, sending/receiving messages, and managing chats, running in a Docker container with HTTP/SSE transport.-
- AlicenseNot gradedqualityDmaintenanceEnables sending WhatsApp messages from MCP clients using a personal WhatsApp account via WebSocket protocol, without needing the Business API or browser automation.36 npmMIT
- AlicenseNot gradedqualityBmaintenanceMCP server that turns WhatsApp into agent-callable tools, enabling search contacts, send/receive messages, read chats, handle media, and monitor calls via the WhatsApp Web multi-device protocol.6 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables connecting a personal WhatsApp number to any MCP client, providing tools to send, search, and manage WhatsApp messages, with an optional auto-reply feature.23 PyPI4MIT