wwebjs-mcp
Provides tools for interacting with WhatsApp Web, enabling AI agents to send and receive messages, manage chats, groups, contacts, and more via the wwebjs-api.
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., "@wwebjs-mcpsend a WhatsApp message to +1234567890 saying 'Hello'"
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.
wwebjs-mcp
MCP server that exposes the wwebjs-api
(WhatsApp Web REST API) as Model Context Protocol tools. It runs as a Docker
container, is configured entirely through .env, and all ~149 API endpoints
are exposed automatically — the tools are generated at startup from the
upstream swagger.json, so new endpoints appear with no code changes.
How it works
MCP client ──MCP (stdio | HTTP/SSE)──▶ wwebjs-mcp ──REST (x-api-key)──▶ wwebjs-api ──▶ WhatsApp WebOn startup the server reads
swagger.jsonand turns every operation into an MCP tool (session_start,client_sendMessage,message_react,groupChat_addParticipants, …).Path parameters (
{sessionId}), query params, and JSON body fields are all derived from the spec and validated via each tool's JSON Schema.The
x-api-keyheader is injected on every call fromWWEBJS_API_KEY.Binary responses (QR image, page screenshot) are returned as MCP image content.
Related MCP server: WA MCP
Prerequisites
Docker Engine and Docker Compose v2 (
docker compose versionshould print something; if you only have the olddocker-composebinary, upgrade Docker Desktop/Engine).Either an existing wwebjs-api instance you can reach (→ Scenario A), or none at all — this repo can run one for you too (→ Scenario B).
Get the code
git clone https://github.com/victor-halla/wwebjs-mcp.git
cd wwebjs-mcp(SSH clone: git clone git@github.com:victor-halla/wwebjs-mcp.git, if you
have a deploy key or your own key registered on GitHub.)
Then continue with whichever scenario matches your setup below. Both end with the same two commands:
docker compose up --build -d # builds the image and starts the container(s)
curl http://localhost:8080/health # -> {"status":"ok"} once it's upScenario A — connect to an existing wwebjs-api container
Use this when you already run wwebjs-api, with its API_KEY set and a
session (a logged-in WhatsApp number) already created.
You need three things from the running instance:
Base URL — how this MCP container reaches the wwebjs-api container.
API key — the value of
API_KEYon the wwebjs-api server.Session ID — the id of the already-configured session. Confirm it with:
curl -H "x-api-key: <API_KEY>" http://<host>:3000/session/getSessions curl -H "x-api-key: <API_KEY>" http://<host>:3000/session/status/<sessionId>A ready session returns a connected/authenticated state — no QR needed.
1. Pick the right WWEBJS_API_URL (container networking)
How wwebjs-api runs |
|
Its own container on a shared Docker network |
|
A container publishing port 3000 on the host |
|
A remote server |
|
To share a network with an existing container, find/create the network and attach this service to it:
docker network ls # find the existing network name
docker inspect <wwebjs-container> --format '{{json .NetworkSettings.Networks}}'Then in docker-compose.yml add (external = the network already created by your
wwebjs-api stack):
services:
wwebjs-mcp:
networks: [wa-net]
networks:
wa-net:
external: true
name: <existing-network-name>…and set WWEBJS_API_URL=http://<wwebjs-container-name>:3000 in .env.
2. Configure .env and start
cp .env.example .envWWEBJS_API_URL=http://wwebjs-api:3000 # or host.docker.internal:3000
WWEBJS_API_KEY=<the API_KEY of your wwebjs-api>
MCP_TRANSPORT=http
MCP_HTTP_PORT=8080
MCP_AUTH_TOKEN=<optional token AI clients must present>docker compose up --build -d
curl http://localhost:8080/health # -> {"status":"ok"}The MCP endpoint is now at http://localhost:8080/mcp (Streamable HTTP).
The session id is not an env var — it is passed as the
sessionIdargument on each tool call by the AI client (e.g.session_status,client_sendMessage). Just tell your AI agent whichsessionIdto use.
Scenario B — set up everything from scratch
Use this when you have no wwebjs-api yet. Run both containers together.
In
docker-compose.yml, uncomment thewwebjs-apiservice at the bottom and set in.env:WWEBJS_API_URL=http://wwebjs-api:3000 WWEBJS_API_KEY=<choose-a-strong-key> MCP_TRANSPORT=httpStart the stack:
docker compose up --build -dCreate and log in a session (pick any id, e.g.
main). Either drive it via your AI client's tools (session_start→session_qr_image→ scan), or by curl directly against wwebjs-api:curl -H "x-api-key: $WWEBJS_API_KEY" http://localhost:3000/session/start/main # open the QR image in a browser and scan it with WhatsApp > Linked devices: # http://localhost:3000/session/qr/main/image (send x-api-key header) curl -H "x-api-key: $WWEBJS_API_KEY" http://localhost:3000/session/status/mainAlternatively use phone pairing via the
session_requestPairingCodetool.Once
statusreports connected, the session persists on disk (thesessionsvolume) and is reused on restart. From then on it behaves like Scenario A.
Authentication
The HTTP transport supports an optional bearer token: set MCP_AUTH_TOKEN in
.env and every client must send Authorization: Bearer <token> on /mcp,
or the server replies 401. Generate a strong token with:
openssl rand -hex 32Leave MCP_AUTH_TOKEN empty only for local, loopback-only testing. Always
set it before exposing the server outside localhost (e.g. via the
Cloudflare Tunnel below) — without it, anyone who can reach the URL gets full
access to every WhatsApp session.
Connecting an AI client (OpenClaw, Claude Code, VS Code, etc.)
The container speaks Streamable HTTP MCP at POST/GET /mcp. Point any
MCP-capable client at it.
Claude Code
Project-scoped, via .mcp.json in the repo root of the project you want the
tools available in:
{
"mcpServers": {
"whatsapp": {
"type": "http",
"url": "http://<mcp-host>:8080/mcp",
"headers": { "Authorization": "Bearer <MCP_AUTH_TOKEN>" }
}
}
}Or register it with the CLI instead of hand-editing JSON:
claude mcp add --transport http whatsapp http://<mcp-host>:8080/mcp \
--header "Authorization: Bearer <MCP_AUTH_TOKEN>"VS Code
Create .vscode/mcp.json in the workspace (note: VS Code uses a top-level
servers key, not mcpServers):
{
"servers": {
"whatsapp": {
"type": "http",
"url": "http://<mcp-host>:8080/mcp",
"headers": { "Authorization": "Bearer <MCP_AUTH_TOKEN>" }
}
}
}Then enable it from the Command Palette (MCP: List Servers / MCP: Add Server) if it isn't picked up automatically. Check your VS Code version's MCP docs if the schema has moved since this was written.
Generic / any other MCP client
Most clients follow the same shape as Claude Code above (mcpServers map with
type: "http", url, optional headers). Point url at /mcp and, if
MCP_AUTH_TOKEN is set, include the Authorization: Bearer header.
Omit the
headersblock ifMCP_AUTH_TOKENis empty.If the AI tool runs in its own container, use a URL it can reach the MCP container by (shared Docker network name, or
host.docker.internal:8080).Tell the agent which session id to operate on; it passes
sessionIdon every tool call. See thewwebjs-mcpskill for the usage playbook.
stdio transport (local process instead of HTTP) — set MCP_TRANSPORT=stdio
and have the client launch node dist/index.js with the same env vars.
Using the included Claude Code skill
This repo ships a Claude Code skill at
.claude/skills/wwebjs-mcp/SKILL.md.
It's a task-oriented playbook for the agent using the tools (not for
building this server): connecting a session (QR/pairing code), sending
text/media/location/poll messages, resolving chatId/messageId correctly,
managing chats/groups/contacts/labels/channels, and which actions to confirm
with the user before calling (session_terminateAll, chat_delete, …).
Skills are project-scoped, and you'll normally be using the WhatsApp tools from a different project than this one (this repo's job is just to run the server). Copy the skill folder wherever you need it:
# Available only in one project:
mkdir -p /path/to/your-project/.claude/skills
cp -r .claude/skills/wwebjs-mcp /path/to/your-project/.claude/skills/
# Or available to Claude Code in every project on this machine:
mkdir -p ~/.claude/skills
cp -r .claude/skills/wwebjs-mcp ~/.claude/skills/Once the skill is in place and the MCP server is connected (previous
section), Claude Code loads it automatically — no manual setup beyond
copying the folder. It triggers on its own whenever you ask for something
WhatsApp-related ("send a WhatsApp message to...", "list my WhatsApp
chats..."), or you can invoke it explicitly with /wwebjs-mcp.
Exposing over HTTPS (Cloudflare Tunnel)
To reach this server from outside your network (e.g. a hosted AI client that can't reach your LAN) without opening an inbound port, run it behind a Cloudflare Tunnel:
In the Cloudflare Zero Trust dashboard, create a tunnel and add a public hostname pointing at service
http://wwebjs-mcp:8080(the Docker service name —cloudflaredreaches it over the compose network, no host port needed).Copy the tunnel token into
.env:CLOUDFLARE_TUNNEL_TOKEN=<token from the dashboard>Set
MCP_AUTH_TOKEN(see Authentication above) — the tunnel makes/mcpreachable from the public internet.Uncomment the
cloudflaredservice at the bottom ofdocker-compose.ymland start it:docker compose up -d cloudflaredPoint your MCP client's
urlathttps://<your-tunnel-hostname>/mcpinstead of the local address.
No other code changes are needed — the server already sets Express's
trust proxy, so it correctly reads the original client's protocol/IP from
the X-Forwarded-* headers Cloudflare adds. /health stays reachable without
the bearer token (used by the container's own Docker healthcheck); every
/mcp call still requires it.
Configuration (.env)
Variable | Default | Purpose |
|
| Base URL of the wwebjs-api server |
| – | Sent as |
|
| Per-request timeout |
|
|
|
|
| HTTP bind address |
| – | Optional bearer token for MCP clients |
| – | Only expose these tools (comma sep.) |
| – | Hide these tools (e.g. |
|
|
|
| – | Token for the optional |
Development
npm install
npm run build
MCP_TRANSPORT=stdio WWEBJS_API_URL=http://localhost:3000 WWEBJS_API_KEY=... npm startRefresh the endpoint list from upstream at any time:
npm run fetch-swagger # re-downloads swagger.jsonTool naming
Tools are named <segments> joined by _, dropping path params:
Endpoint | Tool |
|
|
|
|
|
|
|
|
When two methods share a path (e.g. GET/POST /client/getChats), the second
is prefixed with its method (post_client_getChats).
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.
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/victor-halla/wwebjs-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server