Evolution WhatsApp

Official registry Other

Send and read WhatsApp messages, send media and manage instances via the Evolution API.

Install

Add this to your client's MCP configuration (Claude Desktop: claude_desktop_config.json; Cursor: .cursor/mcp.json; VS Code and others use the same "mcpServers" shape).

NPM package evolution-whatsapp-mcp
Claude Code
claude mcp add evolution-whatsapp -e 'EVOLUTION_API_URL=<EVOLUTION_API_URL>' -e 'EVOLUTION_API_KEY=<your evolution_api_key>' -e 'EVOLUTION_DEFAULT_INSTANCE=<EVOLUTION_DEFAULT_INSTANCE>' -e 'EVOLUTION_TIMEOUT_MS=<EVOLUTION_TIMEOUT_MS>' -e 'EVOLUTION_READ_ONLY=<EVOLUTION_READ_ONLY>' -e 'EVOLUTION_CONFIRM_WRITES=false' -e 'EVOLUTION_ALLOWED_NUMBERS=<EVOLUTION_ALLOWED_NUMBERS>' -- npx -y evolution-whatsapp-mcp@0.3.1
JSON configuration (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "evolution-whatsapp": {
            "command": "npx",
            "args": [
                "-y",
                "evolution-whatsapp-mcp@0.3.1"
            ],
            "env": {
                "EVOLUTION_API_URL": "<EVOLUTION_API_URL>",
                "EVOLUTION_API_KEY": "<your evolution_api_key>",
                "EVOLUTION_DEFAULT_INSTANCE": "<EVOLUTION_DEFAULT_INSTANCE>",
                "EVOLUTION_TIMEOUT_MS": "<EVOLUTION_TIMEOUT_MS>",
                "EVOLUTION_READ_ONLY": "<EVOLUTION_READ_ONLY>",
                "EVOLUTION_CONFIRM_WRITES": "false",
                "EVOLUTION_ALLOWED_NUMBERS": "<EVOLUTION_ALLOWED_NUMBERS>"
            }
        }
    }
}

Environment variables

  • EVOLUTION_API_URL required Base URL of your Evolution API server, e.g. http://localhost:8080. Use https outside localhost.
  • EVOLUTION_API_KEY required secret Evolution API key, sent as the apikey header.
  • EVOLUTION_DEFAULT_INSTANCE Default instance used when a tool call omits the instance argument.
  • EVOLUTION_TIMEOUT_MS Per-request timeout in milliseconds (default 30000).
  • EVOLUTION_READ_ONLY Set to true to hide every tool that sends or changes state (send_text, send_media, create_instance, disconnect_instance, configure_webhook).
  • EVOLUTION_CONFIRM_WRITES Set 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_NUMBERS Comma-separated phone numbers that send_text and send_media may reach. Empty means no restriction.

Documentation

From the project's README on GitHub, refreshed weekly. Links open on GitHub.

Contents
  1. evolution-whatsapp-mcp
  2. Architecture & where it runs
  3. Tools
  4. Prerequisites
  5. Install & configure
  6. Confirm before writing
  7. Example flow (end to end)
  8. Troubleshooting
  9. Directory listings
  10. Development
  11. How it works
  12. License

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.

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

Frequently asked questions

What is Evolution WhatsApp?

Send and read WhatsApp messages, send media and manage instances via the Evolution API.

How do I install Evolution WhatsApp?

It runs on your machine. In Claude Code: claude mcp add evolution-whatsapp -e 'EVOLUTION_API_URL=<EVOLUTION_API_URL>' -e 'EVOLUTION_API_KEY=<your evolution_api_key>' -e 'EVOLUTION_DEFAULT_INSTANCE=<EVOLUTION_DEFAULT_INSTANCE>' -e 'EVOLUTION_TIMEOUT_MS=<EVOLUTION_TIMEOUT_MS>' -e 'EVOLUTION_READ_ONLY=<EVOLUTION_READ_ONLY>' -e 'EVOLUTION_CONFIRM_WRITES=false' -e 'EVOLUTION_ALLOWED_NUMBERS=<EVOLUTION_ALLOWED_NUMBERS>' -- npx -y evolution-whatsapp-mcp@0.3.1. For other clients, paste the JSON configuration from this page into their MCP settings.

Does Evolution WhatsApp need an API key?

Yes. It expects EVOLUTION_API_URL, EVOLUTION_API_KEY, which you set in its configuration.

Is Evolution WhatsApp open source?

Yes. Its code is on GitHub under the MIT license.

Who maintains Evolution WhatsApp?

It is published by Ewertonslv. AI.tn lists it but does not maintain or endorse it.

From the official MCP Registry. Listing is not an endorsement: review a server's code and permissions before giving it access to your data.