Allows sending WhatsApp text messages and files to yourself, contacts, or groups through a linked companion device session, with support for captions, document mode, delivery status checks, pairing via QR code, and access through CLI, local HTTP API, or MCP tools.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
whatsapp-headless
Send WhatsApp messages and files from scripts, cron jobs and AI agents — no browser, no window, nothing on screen.
It links your account as an ordinary companion device (same protocol WhatsApp Web/Desktop use) with Baileys, keeps the keys in a local folder, and exposes three ways to send:
Surface | Use it for |
CLI | one-off sends, cron jobs, shell scripts |
Local HTTP API | any language / agent that can do a |
MCP server (stdio) | Antigravity, Claude Desktop, Cursor, VS Code, Hermes, any MCP client |
Once paired, sending never opens a GUI — not even a hidden one. There is no Chromium, no Puppeteer, no CDP.
Why not drive WhatsApp Web?
WhatWeb automation needs a visible/hidden Chrome, a cloned profile and cookies that Google/Meta now bind to the device (DBSC), so it breaks constantly and leaks a browser process per send. A linked device speaks the real protocol over a websocket: lighter, stable, and genuinely headless.
Related MCP server: AItomation MCP relay
Requirements
Node.js 18+
A phone with WhatsApp (to scan one QR code)
Install
git clone https://github.com/<you>/whatsapp-headless.git
cd whatsapp-headless
npm installPair once
npm run loginA QR appears in the terminal (and as auth/qr.png). On the phone:
WhatsApp → Settings → Linked devices → Link a device → scan.
The session is stored in auth/ (WA_AUTH_DIR to change it). Treat that folder as a password: anyone with it can send as that account. It is git-ignored.
Send
# text to yourself
node src/cli.js send me --text "backup finished"
# any file to yourself (images/videos/audio go inline, the rest as a document)
node src/cli.js send me --file ./report.pdf --caption "monthly report"
# to someone else: any phone format works
node src/cli.js send "+55 11 91234-5678" --file ./invoice.pdf
# group by jid
node src/cli.js send "120363000000000000@g.us" --text "deploy done"
# force document mode (no inline preview for images)
node src/cli.js send me --file ./shot.png --documentstatus shows pairing and connection state, logout wipes the local session.
Local HTTP API
WA_PORT=8787 WA_TOKEN=optional-secret npm run serveOpen http://127.0.0.1:8787/ for the pairing page: it shows the QR, renews it automatically (Baileys rotates the code every ~20 s), flips to "paired" as soon as the phone confirms, and has a send box for quick tests.
curl -s localhost:8787/health
curl -s localhost:8787/qr -o qr.png # only while unpaired
curl -s -X POST localhost:8787/send \
-H 'content-type: application/json' \
-H "x-api-key: $WA_TOKEN" \
-d '{"to":"me","file":"C:/path/report.pdf","caption":"done"}'Method | Path | Body / notes |
GET |
| pairing page with self-renewing QR |
GET |
| Server-Sent Events stream: state pushed the instant it changes |
GET |
| pairing, connection, jid |
GET |
| PNG of the pairing QR ( |
GET |
| delivery receipt of a message id returned by |
GET |
| status panel: service, WhatsApp, browser sessions, API keys |
GET |
| pid, uptime, version, auth dir, last sends |
GET |
| platforms with an active login ( |
GET/POST |
|
|
POST |
|
|
Pairing detection
The page never guesses: /events pushes phase transitions.
| meaning | page shows |
| waiting for the scan, a fresh QR is on screen | QR + instructions |
| phone approved the code, session syncing | "Carregando…" |
| ready, | paired ✓ |
Because it is a push stream, the switch to "loading" happens in the same instant the phone confirms — no polling interval to wait for. If EventSource is unavailable the page falls back to /health polling on its own.
The server binds 127.0.0.1 by default (WA_HOST, WA_PORT) and reconnects on its own.
Status panel and desktop shortcut
/status keeps everything an operator needs on a single page: WhatsApp pairing state (live over
/events, with the QR inline while it is not paired), service pid / uptime / version, the last
sends with their delivery receipt, the platforms that still hold a logged-in session, and the API
keys found inside that session — always masked.
# Windows: puts "Status do WhatsApp" on the Desktop
powershell -NoProfile -ExecutionPolicy Bypass -File desktop\install-shortcut.ps1The shortcut runs desktop/status.vbs, which
checks whether
127.0.0.1:8787already answers,if not, starts
node src/server.jswithout any window and waits up to 30 s for it,opens the panel in the default browser.
One double click is enough to bring the service back after a reboot. The hidden start logs to
%LOCALAPPDATA%\whatsapp-headless.log. Uninstall = delete the shortcut (and the project folder).
The right-hand side of the panel is optional and reads from a separate local tool of your own,
configured in config.local.json (git-ignored):
{ "csDir": "C:/path/to/your-session-tool" }That folder must be a Python project exposing status and scan subcommands that print JSON
(module defaults to chromesession.cli; override with CS_DIR, CS_PYTHON or csModule).
Without it the card says "não configurado" and the rest keeps working. A scan takes ~2 minutes, so
it runs on demand, in the background, with the page polling for the result.
MCP server (Antigravity, Claude Desktop, Cursor, ...)
Add to the client's MCP config:
{
"mcpServers": {
"whatsapp": {
"command": "node",
"args": ["C:/path/to/whatsapp-headless/src/mcp.js"],
"env": { "WA_AUTH_DIR": "C:/path/to/whatsapp-headless/auth" }
}
}
}Tools exposed: wa_status, wa_send_text, wa_send_file, wa_pair.
wa_send_file example arguments: { "to": "me", "file": "C:/tmp/report.pdf", "caption": "done" }.
How it works
src/client.js— socket, auth state, jid resolution, media kind detection by MIME.src/cli.js— terminal surface.src/server.js— HTTP surface, single long-lived socket, auto-reconnect.src/status.html— status panel (service, WhatsApp, sessions, keys).src/keys.js— optional bridge to an external session/key tool; masks every secret.desktop/status.vbs+desktop/install-shortcut.ps1— desktop shortcut and hidden cold start.src/mcp.js— MCP stdio JSON-RPC 2.0 (no SDK dependency).
to accepts me/self, any phone format (+55 11 9..., 5511...), or a full jid (...@s.whatsapp.net, ...@g.us).
Caveats
@whiskeysockets/baileysis currently published as7.0.0-rc.x; pin it if you need stability.This is an unofficial client. WhatsApp's Terms forbid unofficial clients and automated bulk messaging; accounts can be limited or banned. Use it on your own account, for your own automation, at human-ish rates.
One device slot is used (WhatsApp allows 4‑5 linked devices).
Sending to a number that is not on WhatsApp fails — catch the error.
Português
Envia mensagens e arquivos pelo WhatsApp sem navegador e sem janela nenhuma: pareia uma vez pelo QR (npm run login) e depois use CLI, API HTTP local ou o servidor MCP. A sessão fica em auth/ (trate como senha, já está no .gitignore). to: "me" manda para você mesmo.
License
MIT — see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Drive WhatsApp from any MCP client: pair devices, send text and media, manage contacts and groups.
An authenticated remote MCP server for user-owned devices and one-shot capability invocation.
MCP connector for iMessage & Contacts via a local Mac agent + Vercel relay
Use your Pronto feed, Spaces, Posts, Artifacts, and agents from any MCP client.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables reading, sending, and managing iMessage conversations on macOS through MCP.1MIT
- AlicenseNot gradedqualityCmaintenanceEnables external AI applications to access MCP tools by providing a user-hosted HTTPS endpoint that forwards requests to a paired desktop client.MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to read, search, and send personal WhatsApp messages and files through a locally linked device.29 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables local MCP clients to inspect WeChat chats, retrieve and search indexed messages, and submit tracked send-message tasks through native desktop automation on macOS and Windows.Apache 2.0