Skip to main content
Glama

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

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.

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/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_call exists to explain exactly this. What IS possible: monitor incoming calls (whatsapp_recent_calls) and reject them (whatsapp_reject_call). (Future: Baileys v7 adds createCallLink — sending a tappable call link — tracked in docs/ARCHITECTURE.md.)

  • History is event-based. Chats/messages received after the server connects are available immediately; older history arrives via WhatsApp's messaging-history.set sync (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.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • F
    license
    -
    quality
    D
    maintenance
    An 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
  • A
    license
    -
    quality
    F
    maintenance
    MCP 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
  • F
    license
    -
    quality
    C
    maintenance
    WhatsApp MCP server that exposes messaging, groups, contacts, and profile management as tools and resources for AI agents, supporting Baileys and Meta Cloud API.
    19
  • A
    license
    -
    quality
    C
    maintenance
    MCP server that connects AI agents to WhatsApp using the multi-device API, enabling messaging, group management, and more as a regular user.
    8
    MIT

View all related MCP servers

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.

View all MCP Connectors

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/SaptodeepSarkar/whats-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server