mcpField
E
Evolution WhatsApp

Evolution WhatsApp

Local
github.comCommunication0Updated 4d ago

About Evolution WhatsApp

Evolution WhatsApp is a locally run MCP server that lets MCP clients read and send WhatsApp messages and manage connections through the Evolution API. It stores no messages and supports read-only mode, number allowlists and write confirmations.

Key features

  1. 01Send text and media messages
  2. 02List chats and read message history
  3. 03Create instances and retrieve pairing QR codes
  4. 04Check connection status and configure webhooks
  5. 05Apply read-only, number and write-confirmation limits

Use cases

  1. 01Send WhatsApp notifications through an MCP client
  2. 02Review conversations and read message history
  3. 03Link a WhatsApp number and check instance status

MCP support

The server exposes nine WhatsApp tools to MCP clients over stdio and calls the Evolution API over HTTP. It supports read-only mode, an allowed-number list and human confirmation for write operations.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"ewertonslv-evolution-whatsapp": {
"command": "npx",
"args": [
"-y",
"evolution-whatsapp-mcp"
],
"env": {
"EVOLUTION_API_URL": "<EVOLUTION_API_URL>",
"EVOLUTION_API_KEY": "<EVOLUTION_API_KEY>",
"EVOLUTION_DEFAULT_INSTANCE": "<EVOLUTION_DEFAULT_INSTANCE>",
"EVOLUTION_TIMEOUT_MS": "<EVOLUTION_TIMEOUT_MS>",
"EVOLUTION_READ_ONLY": "<EVOLUTION_READ_ONLY>",
"EVOLUTION_CONFIRM_WRITES": "<EVOLUTION_CONFIRM_WRITES>",
"EVOLUTION_ALLOWED_NUMBERS": "<EVOLUTION_ALLOWED_NUMBERS>"
}
}
}
}
Run commandnpx -y evolution-whatsapp-mcp
Environment variables to set
EVOLUTION_API_URLBase URL of your Evolution API server, e.g. http://localhost:8080. Use https outside localhost.
EVOLUTION_API_KEYSecretEvolution API key, sent as the apikey header.
EVOLUTION_DEFAULT_INSTANCEDefault instance used when a tool call omits the instance argument.
EVOLUTION_TIMEOUT_MSPer-request timeout in milliseconds (default 30000).
EVOLUTION_READ_ONLYSet to true to hide every tool that sends or changes state (send_text, send_media, create_instance, disconnect_instance, configure_webhook).
EVOLUTION_CONFIRM_WRITESSet to true to require a human confirmation (elicitation dialog) before send_text, send_media, create_instance, disconnect_instance or configure_webhook run. Clients that can show no dialog are refused. Default false; an unrecognised value counts as true and prints a warning.
EVOLUTION_ALLOWED_NUMBERSComma-separated phone numbers that send_text and send_media may reach. Empty means no restriction.

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
npmevolution-whatsapp-mcp0.3.1

Tools

9

Saved tool list · updated 4d ago

ParameterTypeRequiredDescription
textstringYesMessage body.
numberstringYesRecipient phone, e.g. "+55 11 99999-9999".
instancestringNoEvolution instance name. Falls back to EVOLUTION_DEFAULT_INSTANCE.

Details

From the project README

evolution-whatsapp-mcp

An MCP server that lets Claude (and any MCP client) use WhatsApp. It sends and reads messages, sends media, and manages connections through the Evolution API. Add it to Claude Desktop/Code and your agent can connect a WhatsApp number and talk to people.

CI Node License: MIT

The client code comes from the WhatsApp integration of a multi-tenant clinic SaaS. All nine tools were last checked against a real Evolution API 2.3.7 server in October 2026.

Architecture & where it runs

Claude (Desktop/Code)        evolution-whatsapp-mcp          Evolution API        WhatsApp
     [MCP client]   ──stdio──►   (this package)    ──HTTP──►   (gateway)  ──────►  (phone)
  • This MCP server runs locally, on demand. You don't host it. Your MCP client (Claude Desktop/Code) spawns it as a child process over stdio (npx evolution-whatsapp-mcp); it starts when the client needs it and exits when the client closes. No open ports, no deployment.
  • The Evolution API is the part that must stay running, because it holds the WhatsApp session (like WhatsApp Web: if it goes down, the number disconnects). Run it locally via Docker to try things out, or on a small VPS if you need it online 24/7 (e.g. to receive messages via webhook). This server only needs its URL + API key.
  • The server is stateless. It has no database and stores no messages. It only forwards calls from your MCP client to the Evolution API.

Tools

ToolDescription
send_textSend a text message to a phone number
send_mediaSend an image / video / document / audio (URL or base64)
find_chatsList the conversations on the instance (limit, default 50, max 200)
find_messagesRead a chat's message history (by phone or JID), with limit (default 50, max 200) and page
create_instanceCreate a new instance (a WhatsApp connection slot)
get_qrcodeGet the QR code (base64) to link a WhatsApp number
connection_statusCheck whether the instance is connected
disconnect_instanceLog the WhatsApp number out of the instance
configure_webhookPoint the instance webhook to a public URL

Every tool takes an optional instance argument; if omitted it falls back to EVOLUTION_DEFAULT_INSTANCE.

Tools carry MCP annotations: the read tools are marked read-only, and disconnect_instance and configure_webhook are marked destructive so clients can ask for confirmation first.

find_messages accepts a Brazilian number with or without the ninth digit. WhatsApp stores some chats under the short form, so the tool tries the other form when the first one has no messages.

Prerequisites

A running Evolution API server (v2.x) and its API key. The quickest way to run one locally is the example docker-compose.yml (Evolution API v2 with the Postgres and Redis it needs). Use local Docker to try it out, or a VPS for 24/7 operation:

EVOLUTION_API_KEY=my-secret-key docker compose up -d

It listens on http://localhost:8080. Use the same value for EVOLUTION_API_KEY when you plug in the MCP server (see above). The compose file is a starting point, not a production setup.

Install & configure

One line for Claude Code:

claude mcp add evolution-whatsapp \
  -e EVOLUTION_API_URL=http://localhost:8080 \
  -e EVOLUTION_API_KEY=your-evolution-api-key \
  -- npx -y evolution-whatsapp-mcp

For other clients, add it to the MCP client config. For Claude Desktop / Claude Code (mcpServers config):

{
  "mcpServers": {
    "whatsapp": {
      "command": "npx",
      "args": ["-y", "evolution-whatsapp-mcp"],
      "env": {
        "EVOLUTION_API_URL": "http://localhost:8080",
        "EVOLUTION_API_KEY": "your-evolution-api-key",
        "EVOLUTION_DEFAULT_INSTANCE": "my-whatsapp"
      }
    }
  }
}
Env varRequiredDescription
EVOLUTION_API_URLyesBase URL of your Evolution API server
EVOLUTION_API_KEYyesEvolution API key (sent as the apikey header)
EVOLUTION_DEFAULT_INSTANCEnoDefault instance when a tool omits instance
EVOLUTION_TIMEOUT_MSnoPer-request timeout in milliseconds (default 30000)
EVOLUTION_READ_ONLYnotrue, 1 or yes (any case) hides send_text, send_media, create_instance, disconnect_instance and configure_webhook. Anything else leaves them on
EVOLUTION_CONFIRM_WRITESnotrue, 1 or yes (any case) makes send_text, send_media, create_instance, disconnect_instance and configure_webhook wait for a human to confirm. A client that can show no confirmation is refused and nothing is sent. false, 0, no or empty is off (default). Any other value (a typo such as ture or on) counts as on and prints a warning on stderr
EVOLUTION_ALLOWED_NUMBERSnoComma-separated numbers send_text and send_media may reach (e.g. 5511999999999,5521988887777). Empty means no restriction. Brazilian numbers match with or without the ninth digit; group JIDs are refused when the list is set

Because an LLM drives these tools, a prompt injected through a received message could ask it to send something. EVOLUTION_READ_ONLY and EVOLUTION_ALLOWED_NUMBERS limit what it can do.

Built-in limits: find_chats and find_messages take limit (1-200, default 50); any response over 100,000 characters is truncated with a notice; get_qrcode drops an oversized base64 image and keeps the pairing code. configure_webhook only accepts https URLs (plain http is allowed for localhost, 127.0.0.1 and [::1]). The server prints a warning on stderr if EVOLUTION_API_URL is neither https nor localhost, since the API key would travel unencrypted.

Confirm before writing

Tool descriptions are advice, not a lock: a model can still call disconnect_instance to "restart the connection". With EVOLUTION_CONFIRM_WRITES=true the server holds each write (send_text, send_media, create_instance, disconnect_instance, configure_webhook) until a person confirms it through the client, a channel the model does not control. It is off by default, so headless automation keeps working; turn it on when a person is in the loop.

What the person sees is a short preview: the action, the recipient with the number masked (+55 11 9****-9999), and up to 200 characters of the text. Media content and webhook paths or query strings are never shown. The dialog defaults to "no" and waits 120 seconds; anything other than an explicit yes (decline, cancel, timeout, error) sends nothing.

Client declaresResult
Form elicitation (elicitation, as in Claude Code)A yes/no dialog before each write
Anything else (no capabilities, URL-only elicitation, MCP Apps only)The write is refused with isError and nothing is sent

A confirmation card for MCP Apps clients is not part of this release. Claude Code does not render MCP Apps (client matrix at modelcontextprotocol/modelcontextprotocol, 2026-11-03), so it uses the dialog. Some Claude Code versions have been reported to auto-decline elicitation forms; in that case the write is refused, never sent.

It combines with the other limits: EVOLUTION_ALLOWED_NUMBERS is checked first (a number outside the list is refused without asking), and with EVOLUTION_READ_ONLY on there are no write tools to confirm.

Example flow (end to end)

Ask Claude:

  1. "Create a WhatsApp instance called my-whatsapp and show me the QR code." → create_instance + get_qrcode (scan it with your phone).
  2. "Is it connected?" → connection_status.
  3. "Send 'Your appointment is confirmed' to +55 11 99999-9999." → send_text.
  4. "What did they reply?" → find_messages.

Troubleshooting

SymptomCause and fix
HTTP 401 / UnauthorizedEVOLUTION_API_KEY does not match the server's AUTHENTICATION_API_KEY.
Timeout / fetch failedThe URL is wrong or the Evolution API is down. Open EVOLUTION_API_URL in a browser; raise EVOLUTION_TIMEOUT_MS for slow servers.
Sends fail, instance not openThe instance is not connected. Run connection_status, then get_qrcode and scan it from the phone (WhatsApp > Linked devices).
find_messages returns nothing for a Brazilian numberWhatsApp may store the chat with or without the ninth digit. The tool tries both; check the number has the country code (55).
number must be a phone with 8 to 15 digitsPass the full number with country code, or a JID containing @.
Webhook URL refusedconfigure_webhook requires https (http only for localhost, 127.0.0.1, [::1]). Look-alike hosts such as localhost.evil.com are refused.
send_text is missing from the tool listEVOLUTION_READ_ONLY is on. Unset it or set it to false.
Recipient is not in EVOLUTION_ALLOWED_NUMBERSThe number is not on the allowlist. Add it, or leave the variable empty.
Response ends with truncated: use limit/pageThe payload was over 100,000 characters. Lower limit or read page by page.

Directory listings

Metadata for the official MCP registry is in server.json and for Smithery in smithery.yaml. Glama indexes public GitHub MCP servers from this README and package.json, so keep both accurate.

Development

npm install
npm run build      # tsc → dist/
npm test           # vitest (mocks the Evolution API; no server needed)
npm run lint       # tsc --noEmit

Inspect the server locally with the MCP Inspector:

EVOLUTION_API_URL=http://localhost:8080 EVOLUTION_API_KEY=key \
  npx @modelcontextprotocol/inspector node dist/index.js

How it works

A thin REST client (src/evolution.ts) wraps the Evolution endpoints and authenticates with the apikey header. src/tools.ts registers each operation as an MCP tool with a zod input schema; src/index.ts serves them over stdio.

License

MIT © Ewerton Silva

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.