Skip to main content
Glama

whatsapp-mcp

Give your AI agents your WhatsApp.

MCP server Runs on Cloudflare Workers License: GPL-3.0

Deploy to Cloudflare

whatsapp-mcp lets an AI assistant like Claude read your WhatsApp chats, search them and send messages for you. It connects to your account the same way WhatsApp Web does, as a linked device, and keeps a searchable copy of your chats.

It speaks MCP, the standard way AI apps connect to tools, so it works with Claude, ChatGPT, Claude Code, Cursor and other MCP clients. It runs on your own Cloudflare account, so your messages stay with you.

Once it is set up, you ask in plain words and your assistant calls the tools for you:

Get started

You need a Cloudflare account, a GitHub account and your phone with WhatsApp.

1. Deploy

Click Deploy to Cloudflare above. Cloudflare copies this project to your GitHub, builds it and puts it online at an address like https://whatsapp-mcp.<your-name>.workers.dev.

During the setup it asks for a SECRET. That is the password of your server, at least 16 characters. Generate a strong one in a terminal with openssl rand -hex 32, or use a password manager, and keep it safe. Anyone who has it can read and send your messages.

Open this address in your browser and sign in with your SECRET:

https://whatsapp-mcp.<your-name>.workers.dev/accounts/personal

Select Link WhatsApp. On your phone, open WhatsApp, go to Settings → Linked devices → Link a device and point the camera at the code. The page then counts your chats as they arrive.

personal is a name you choose. Each name is a separate WhatsApp account, so one server can hold several.

3. Connect your AI assistant

Add this address as a custom connector in Claude or ChatGPT, or as a remote MCP server in any other client:

https://whatsapp-mcp.<your-name>.workers.dev/accounts/personal/mcp

The app opens your server in the browser. Sign in with your SECRET and select Allow. In Claude Code that is:

claude mcp add --transport http whatsapp https://whatsapp-mcp.<your-name>.workers.dev/accounts/personal/mcp

In pi, add it and sign in from the terminal:

pi mcp add whatsapp --url https://whatsapp-mcp.<your-name>.workers.dev/accounts/personal/mcp
pi mcp login whatsapp

Scripts and clients that can set a header can skip the browser and send Authorization: Bearer <SECRET> instead.

Related MCP server: WhatsApp Cloud API MCP Server

What your assistant can do

Tool

What it does

get_status

Connection state and how much of your history is saved

list_chats

Chats in the order your phone shows them, with unread counts

find_chats

Chats by any name or phone number

find_people

People by any name or phone, including group members

get_messages

A chat's messages, with voice messages transcribed

get_message_context

A message and the conversation around it

view_media

Shows an image, a video's preview or a voice message's text

search_messages

Search all chats by words, including transcribed voice messages

send_message

Sends text, as a reply or with mentions, never twice on retries

react_to_message

Adds or removes a reaction

edit_message

Edits a message you sent

delete_message

Deletes a message for everyone

mark_as_read

Marks a chat as read

save_contact

Saves or renames someone in your address book, on every device

remove_contact

Removes someone from your address book, on every device

load_older_messages

Asks your phone for older history

check_numbers

Which phone numbers have WhatsApp

get_group_info

A group's details and members

get_profile

Someone's name, About text and picture

Tools that send or change something tell your assistant so, and most assistants ask you before using them.

How it works

flowchart LR
  agent["AI assistant"] -- "MCP + OAuth" --> worker["Worker"]
  worker -- "RPC" --> account
  subgraph account["Durable Object, one per WhatsApp account"]
    socket["WhatsApp session<br/>whatsapp-rust in WASM"]
    archive[("SQLite archive<br/>full-text search")]
    socket --> archive
  end
  socket <-- "WebSocket" --> whatsapp["WhatsApp"]
  account -- "voice messages, images" --> ai["Workers AI<br/>speech to text, vision"]

Each WhatsApp account lives in its own Durable Object, a small server that Cloudflare keeps running with its own SQLite database. The WhatsApp session inside it is baileyrs, whose protocol core is whatsapp-rust compiled to WebAssembly. An alarm every 30 seconds keeps the object in memory and reconnects it after deploys.

WhatsApp sends your recent history once, when you link, and the archive keeps every message after that. Search finds people by any name they have used, and treats a person's phone number and their anonymous WhatsApp ID (LID) as the same person.

Say Marina sends you a 30-second voice message about the trip. WhatsApp transcribes it on your phone, but that text never leaves the phone, so the server makes its own. It waits until your assistant first reads the chat. Then it downloads the audio, sends it to Workers AI and saves the text in the archive. After that, a search for "hotel" finds what Marina said, and no read pays for it again. A voice message nobody reads costs nothing. One read transcribes at most 10 voice messages, newest first, and waits up to 8 seconds for them. Any that take longer finish in the background, and the next read shows them.

Images wait longer. A read lists them only by caption and size, because each image would cost your assistant more than 1,000 tokens of context. Your assistant asks for one with view_media. If Marina also sends a photo of the hotel booking, the server downloads it then and passes it on as WhatsApp sent it, without resizing. The first time, a Workers AI vision model also describes the photo and copies the text in it, like the hotel's name and the dates. The archive keeps that description, so the next search for the hotel finds the photo too. A video shows the small preview that comes inside the message, and the server downloads nothing. It also sends that preview when WhatsApp no longer has an image, or when the image is over 3.75 MB, because Claude rejects anything over 5 MB once it's base64 encoded.

The server never opens view-once media. When someone deletes a message for everyone, the server deletes its transcript or description too.

Configuration

Name

Kind

Purpose

SECRET

Secret

The password of your server, at least 16 characters

AUTH_MODE

Variable

How MCP clients get in: oauth, api_key or both. both if unset

TIMEZONE

Variable

Time zone for dates, like America/Sao_Paulo. UTC if unset

TRANSCRIBE_MODEL

Variable

@cf/openai/whisper-large-v3-turbo (default), @cf/deepgram/nova-3 or off

DESCRIBE_MODEL

Variable

@cf/mistralai/mistral-small-3.1-24b-instruct (default), @cf/meta/llama-4-scout-17b-16e-instruct or off

TRANSCRIBE_LANGUAGE

Variable

Language of most voice messages, like pt. Detected per message if empty

DESCRIBE_LANGUAGE

Variable

Language of image descriptions, like pt. English if empty

With oauth, an app connects after you sign in with SECRET in the browser and allow it. With api_key, clients send Authorization: Bearer <SECRET> on every request. The pairing page asks for SECRET in every mode, and allows five attempts per minute.

Change the variables in wrangler.jsonc, or pass --var TIMEZONE:<zone> to wrangler deploy. OAuth grants live in a KV namespace that the first deploy creates. The pairing page also uses a small REST API under /accounts/:id: status, start, send and logout.

Costs

One personal account running 24/7 costs $5 per month, the price of Workers Paid. Its included usage covers everything one account does:

One account, per month

Workers Paid includes

Time in memory

324,000 GB-s

400,000 GB-s

Requests

90,000, plus your assistant's calls

1 million

Written rows

260,000 once to link, then 90,000 plus new messages

50 million

The object stays in memory all day, and Cloudflare bills that time as if it used the full 128 MB, however busy the account is. It also wakes every 30 seconds, which explains the 90,000 requests and rows. Linking saves the whole history at once: an account with about 30,000 messages wrote 258,000 rows in its first hour. Going past the included usage would take about 30,000 assistant calls or 100,000 new messages a day.

More accounts share the same plan. Cloudflare bills extra time in blocks of 1 million GB-s at $12.50, so two to four accounts cost $17.50 per month.

Workers AI bills transcription per audio minute, $0.0005 with Whisper and $0.0052 with Nova-3. A thousand 30-second voice messages cost about $0.26 with Whisper. The 10,000 free neurons a day cover about 200 minutes of Whisper. An image description costs about $0.0004 with Mistral Small 3.1, so a thousand viewed images cost about $0.40.

Workers Free is not enough, even for one account.

WARNING

Workers Free allows 100,000 written rows per day, fewer than the first sync writes. When an account crosses that limit, Cloudflare blocks every write until 00:00 UTC, so the server can't save new messages or schedule its heartbeat. Upgrading to Workers Paid lifts the block.

See Workers pricing, Durable Objects pricing and limits for current numbers.

Is it safe?

Your session and your messages stay in your Cloudflare account. The server talks to WhatsApp, and sends the voice messages your assistant reads and the images it views to Workers AI in the same Cloudflare account. Only someone who knows your SECRET can use it or allow an app in.

This is an unofficial WhatsApp client, not affiliated with WhatsApp or Meta, and WhatsApp can ban accounts that use one. Link a number you can afford to lose, and keep your assistant asking before it sends messages.

Development

You need Bun. Wrangler comes with the project.

bun install
printf 'SECRET=%s\n' "$(openssl rand -hex 32)" > .dev.vars   # see .dev.vars.example
bun run dev     # http://localhost:8787/accounts/dev
bun run check   # types, lint, format and tests

To deploy from your machine, run bunx wrangler secret put SECRET once and then bun run deploy.

Built on baileyrs and whatsapp-rust. Message rendering and identity rules follow mautrix-whatsapp. Licensed under GPL-3.0.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to interact with your personal WhatsApp account, allowing them to search messages and contacts, retrieve chat history, and send messages to individuals or groups. Uses WhatsApp Web API with local data storage for privacy and security.
    16 npm
    ISC
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI assistants to manage WhatsApp: list chats, send and receive messages, download media, and transcribe voice notes via the unofficial Baileys library.
    71 npm
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    Enables AI agents to control WhatsApp, including sending messages and media, reading chats, managing groups and communities, with QR/pairing auth and session persistence.
    14
    19 npm
    2
    MIT