Whats
FreeNot checkedMCP server that turns WhatsApp into agent-callable tools, enabling search contacts, send/receive messages, read chats, handle media, and monitor calls via the W
About
MCP 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.
README
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 | whatsapp_get_qr (scan to link), whatsapp_get_pairing_code (link without QR), whatsapp_get_status, whatsapp_logout |
| Contacts | whatsapp_search_contacts (by name or number) |
| Sending | whatsapp_send_message (text / reply), whatsapp_send_media (image, audio/voice note, document) |
| Reading | whatsapp_read_chat (recent messages), whatsapp_read_unread (unread chats + messages), whatsapp_mark_read (one chat), whatsapp_list_chats, whatsapp_mark_all_read (batch read receipts, clears phone badges) |
| Calls | whatsapp_recent_calls, whatsapp_reject_call, whatsapp_call (honest explainer — see Limitations) |
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.
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/mcp
or 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_info
Then 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 login
The 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 |
|---|---|---|
WHATSAPP_AUTH_DIR |
./auth_info |
Where the linked-device credentials live (keep private!) |
WHATSAPP_LOG_LEVEL |
warn |
silent | error | warn | info | debug — always to stderr |
WHATSAPP_MARK_ONLINE |
true |
false = don't mark online (phone keeps receiving its own push notifications) |
WHATSAPP_MCP_PORT |
(unset) | Set to run as a daemon: StreamableHTTP on 127.0.0.1:<port>/mcp instead of stdio |
WHATSAPP_CONNECT_TIMEOUT |
30 |
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+tools
License
MIT — see LICENSE. Baileys is MIT; the MCP SDK is MIT.
Installing Whats
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/SaptodeepSarkar/whats-mcpFAQ
Is Whats MCP free?
Yes, Whats MCP is free — one-click install via Unyly at no cost.
Does Whats need an API key?
No, Whats runs without API keys or environment variables.
Is Whats hosted or self-hosted?
A hosted option is available: Unyly runs the server in the cloud, no local setup required.
How do I install Whats in Claude Desktop, Claude Code or Cursor?
Open Whats on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
ARA
Generate images, video and audio from any AI agent — one connector.
by ARAOmni Video
An MCP server that transforms LLM-enabled IDEs into professional video editors by pre-processing footage into text proxies, generating motion graphics via HTML/
by buildwithtazaYouTube
Transcripts, channel stats, search
by YouTubeEverArt
AI image generation using various models.
by modelcontextprotocolgpu-bridge/mcp-server
Unified GPU inference API with 30 AI services (LLM, image gen, video, TTS, whisper, embeddings, reranking, OCR) as MCP tools. Pay-per-use via x402 USDC or API k
by gpu-bridgehamflx/imagen3-mcp
A powerful image generation tool using Google's Imagen 3.0 API through MCP. Generate high-quality images from text prompts with advanced photography, artistic,
by hamflxmerterbak/Grok-MCP
MCP server for xAI's [Grok API](https://docs.x.ai/docs/overview) with agentic tool calling, image generation, vision, and file support.
by merterbakSureScaleAI/openai-gpt-image-mcp
OpenAI GPT image generation/editing MCP server.
by SureScaleAIYangLiangwei/PersonalizationMCP
Comprehensive personal data aggregation MCP server with Steam, YouTube, Bilibili, Spotify, Reddit and other platforms integrations. Features OAuth2 authenticati
by YangLiangweiAceDataCloud/MCPFlux
Flux AI image generation and editing (Black Forest Labs) via Ace Data Cloud API.
by AceDataCloudCompare Whats with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All media MCPs
