whats-mcp
Provides tools for interacting with WhatsApp, including sending and receiving messages, managing contacts, reading chats and unread messages, sending media, and monitoring incoming calls.
Click on "Install 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., "@whats-mcpSend a WhatsApp message to John: see you at 5"
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.
whats-mcp
MCP server that turns your WhatsApp into agent-callable tools.
Link your WhatsApp account once by scanning a QR code (the official "Linked Devices" flow — your phone keeps working normally), and the server keeps the session alive across restarts. Then any MCP-capable agent (Claude Desktop, Hermes, Cursor, …) can search your contacts, send messages, read chats, read unread messages, mark things read, send media, and monitor incoming calls.
Built on Baileys 6.7.24 (the WhatsApp Web multi-device protocol) — a pure Node.js implementation. No browser, no Puppeteer, no Chromium.
⚠️ Unofficial client disclaimer: this uses WhatsApp's Web protocol via an unofficial library. WhatsApp/Meta can ban accounts that abuse unofficial clients. Use it for your own account, at normal human volumes, and avoid bulk/spammy automation. No warranty — use at your own risk.
Features
Area | Tools |
Linking |
|
Contacts |
|
Sending |
|
Reading |
|
Calls |
|
Key properties:
Persistent session — auth lives in
auth_info/(git-ignored). Restart the server → reconnects with no re-scan.Persistent indexes — contacts (
contacts.json) and unread messages (unread.json) are saved to the auth dir, so a daemon restart loses nothing.Auto-reconnect — exponential backoff on drops; only a logout stops it.
No browser — pure WebSocket protocol implementation.
Stdio-safe — QR codes are returned as tool results (raw + ASCII), never printed to stdout; all logs go to stderr so the JSON-RPC stream stays clean.
Related MCP server: lingtai-whatsapp
Quick start
Full step-by-step install guide for Windows, macOS and Linux (Node setup, QR linking, 24/7 service for each OS): docs/INSTALL.md.
# 1. install
npm install
# 2. run the server (or: npm start)
node src/index.js
# 3. ask your MCP client to link the device:
# call whatsapp_get_qr → scan the QR in WhatsApp → Settings →
# Linked devices → Link a device
# (or call whatsapp_get_pairing_code with your number and type the code)The server connects to WhatsApp immediately on boot. While unlinked it keeps
a fresh QR ready. Once linked, creds.json is persisted — every later start
reconnects automatically.
Registering in an MCP client
Standard mcpServers config (Claude Desktop / Cursor / etc.):
{
"mcpServers": {
"whatsapp": {
"command": "node",
"args": ["/absolute/path/to/whats-mcp/src/index.js"],
"env": {
"WHATSAPP_AUTH_DIR": "/absolute/path/to/whats-mcp/auth_info"
}
}
}
}Hermes Agent
Connect Hermes to the daemon over HTTP (recommended — the systemd service owns the WhatsApp connection, see below):
hermes config set mcp_servers.whatsapp.url http://127.0.0.1:8787/mcpor spawn the server per Hermes session (stdio):
hermes config set mcp_servers.whatsapp.command node
hermes config set mcp_servers.whatsapp.args '["/absolute/path/to/whats-mcp/src/index.js"]'
hermes config set mcp_servers.whatsapp.env.WHATSAPP_AUTH_DIR /absolute/path/to/whats-mcp/auth_infoThen restart Hermes — tools appear as mcp_whatsapp_whatsapp_get_qr, etc.
(One instance per auth dir: either the daemon or a spawned child, never
both — the single-instance lock enforces this.)
24/7 daemon (systemd)
Keep the WhatsApp connection alive across reboots and logins:
# 1. install the unit (see ~/.config/systemd/user/whats-mcp.service in this repo's setup)
systemctl --user daemon-reload
systemctl --user enable --now whats-mcp
loginctl enable-linger "$USER" # start at boot, even before loginThe daemon serves MCP on http://127.0.0.1:8787/mcp (plus GET /health),
logs to journald (journalctl --user -u whats-mcp -f), and never unlinks the
device on shutdown. Contacts and unread-message state are persisted inside the
auth dir, so restarts lose nothing.
Environment variables
Variable | Default | Purpose |
|
| Where the linked-device credentials live (keep private!) |
|
|
|
|
|
|
| (unset) | Set to run as a daemon: StreamableHTTP on |
|
| Seconds send/read tools wait for the connection to be open |
Tool reference
whatsapp_get_qr
Returns the current linking QR as a raw string and an ASCII rendering, plus seconds until it rotates. Scan with WhatsApp → Settings → Linked devices → Link a device. QR rotates every ~20–60s — scan promptly.
whatsapp_get_pairing_code
phone (digits with country code, e.g. 919876543210) → returns an 8-digit
code. On the phone: Link a device → Link with phone number instead, then
enter the code. Fails gracefully if the account doesn't support pairing.
whatsapp_get_status
Connection state, linked flag, QR availability, contact/chat/unread counts, last disconnect reason. Use this first whenever something seems off.
whatsapp_search_contacts
query (name substring or number digits, empty = list all) + limit →
matches with jid, name, notify, number. The jid can be passed to any
tool that takes a contact.
whatsapp_send_message
contact + text, optional quoted_message_id (reply). contact is
resolved in order: full JID → phone number (verified via onWhatsApp) →
saved contact name.
whatsapp_send_media
contact + media_type (image | audio | document) + source (local
path or http(s) URL), optional caption, file_name, as_voice_note.
whatsapp_read_chat
contact + limit → most recent messages seen for that chat (since server
start), plus its unread count.
whatsapp_read_unread
per_chat + max_chats → chats with unreadCount > 0, sorted by unread
count, with the newest incoming messages for each.
whatsapp_mark_read
contact → sends read receipts for that chat's tracked messages (respects
the account's read-receipt privacy setting).
whatsapp_recent_calls / whatsapp_reject_call
Incoming call events (offer/ringing/accept/reject/timeout, with
video flag) since server start; reject a live call by id.
whatsapp_logout
Removes the linked device from your account (like tapping "Log out" on the phone). The auth folder is kept; scan a fresh QR to re-link.
Limitations (read this — it's honest)
Voice/video calls cannot be placed. This is a hard WhatsApp protocol limitation: call media flows over a separate signaling path that the linked-device (Web) protocol does not expose. Verified against the Baileys 6.7.24 API surface — there is no send-side call content; missed-call "bubbles" are inbound-only server constructs.
whatsapp_callexists to explain exactly this. What IS possible: monitor incoming calls (whatsapp_recent_calls) and reject them (whatsapp_reject_call). (Future: Baileys v7 addscreateCallLink— sending a tappable call link — tracked indocs/ARCHITECTURE.md.)History is event-based. Chats/messages received after the server connects are available immediately; older history arrives via WhatsApp's
messaging-history.setsync (contacts + chat metadata, unread counts).Message content: text, captions and file names are extracted; media blobs are not downloaded (yet).
4 linked devices max (phone + 3). Scanning a 5th bumps the oldest.
The phone must keep WhatsApp installed; uninstalling or renaming the number kills the linked session.
Project layout
whats-mcp/
├── src/
│ ├── index.js # entry: boot client, expose over MCP stdio
│ ├── server.js # MCP tool definitions (zod schemas)
│ └── whatsapp.js # Baileys wrapper: QR, auth, reconnect, indexes
├── scripts/
│ └── smoke-test.mjs # stdio end-to-end test (npm run smoke)
├── docs/
│ ├── ARCHITECTURE.md # design decisions + upgrade paths
│ └── AGENTS.md # conventions for agent contributors
├── .env.example
├── package.json
└── LICENSE (MIT)Testing
npm run smoke # spawns the real server over stdio, asserts handshake+toolsLicense
MIT — see LICENSE. Baileys is MIT; the MCP SDK is MIT.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityDmaintenanceAn MCP (Multi-Agent Conversation Protocol) Server that enables interaction with the WhatsApp Business API, allowing agents to send messages, manage media, and perform other WhatsApp business operations through natural language.1

lingtai-whatsappofficial
Alicense-qualityFmaintenanceMCP server for interacting with the official Meta WhatsApp Business Platform/Cloud API, enabling sending messages, managing contacts, templates, and handling webhook callbacks.Apache 2.0- Flicense-qualityCmaintenanceWhatsApp MCP server that exposes messaging, groups, contacts, and profile management as tools and resources for AI agents, supporting Baileys and Meta Cloud API.19
- Alicense-qualityCmaintenanceMCP server that connects AI agents to WhatsApp using the multi-device API, enabling messaging, group management, and more as a regular user.8MIT
Related MCP Connectors
Hosted MCP server for the Wavix telecom platform: SMS, voice, 2FA, SIP, numbers, 10DLC, CDRs.
Official MCP server for OmniDimension. Drive voice agents, dispatch calls, and run bulk campaigns.
Managed LinkedIn MCP server for AI agents: search, connect, message and enrich on accounts you own.
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/SaptodeepSarkar/whats-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server