Skip to main content
Glama
alexfisenkov

WhatsApp MCP

by alexfisenkov

WhatsApp MCP

Два независимых адаптера WhatsApp через один MCP core:

  • Personal linked-device через WAHA Core NOWEB REST.

  • Business Platform через официальный Meta Graph API.

Клиент выбирает один профиль; credentials, история и audit state у каждого профиля изолированы. Репозиторий и install-инструкции публичны на GitHub. Он не раздаёт личную сессию владельца или Business credentials ученикам. Для своего аккаунта разверните отдельный runtime и задайте собственные credentials.

Поддержка

Реестр формирует tools только из операций включённого адаптера. Полная матрица построена генератором из тех же provider definitions в docs/Матрица-возможностей.json; обновляйте её командой npm run capabilities вместе с изменениями API.

В личном профиле есть bounded chat/message/contact/group reads, incoming media download по точному chat/message ID, managed media sends, polls, reactions, read receipts, локальный поиск, контекст сообщения и ручной bounded sync истории. Incoming media download доступен только с настроенным media store; он берёт файл из private WAHA endpoint, принимает только allowlisted MIME и ограничен 5 MiB. personal_history_sync загружает только ограниченные страницы из NOWEB store, дедуплицирует записи и отмечает coverage как partial. Полный импорт истории и global search в WAHA REST не обещаются.

Business профиль отправляет текст, templates, медиа и поддержанные Graph message types; читает templates, flows, profile/account и доступную аналитику. Inbound media download принимает Meta media ID из verified webhook/history и проверяет Graph metadata перед сохранением в private managed store. Для исходящего файла сначала получи managed UUID через POST /media, вызови business_media_upload_prepare, отдельно подтверди business.media.upload и используй полученный от Meta ID в message send tool. Не передавай managed UUID как Meta media ID. История и delivery status появляются только из проверенных Meta webhook событий после их подключения. Graph не является общим inbox. Business Groups операции не включены. Административные Graph и personal group-management tools скрыты, пока владелец явно не включит соответствующий флаг.

Related MCP server: WhatsApp MCP Server

Требования и локальная проверка

  • Node.js 22.23.2 for the pinned CI/runtime check (.nvmrc); package.json constrains supported Node to >=22 <23.

  • Поддерживаются MCP stdio и Streamable HTTP.

  • Для личного профиля отдельно нужен WAHA Core NOWEB runtime. Для HTTP/MCP профилей сервер проксируется через HTTPS reverse proxy.

git clone https://github.com/alexfisenkov/whatsapp-mcp.git
cd whatsapp-mcp
npm ci
npm test
npm run build
npm run capabilities

node:sqlite — встроенное хранилище audit и истории. В целевой Node 22.23 оно работает без дополнительных пакетов и выводит предупреждение о статусе experimental; версия Node закреплена, а SQLite поведение проверяется тестами. При установленном nvm выбери версию командой nvm install && nvm use из корня репозитория. Без nvm используй архив с официального Node.js v22.23.2 release page и сверяй SHA256 до распаковки.

Локальный stdio

Скопируйте репозиторий и установите dependencies из lockfile. В MCP host настройте отдельный процесс для каждого профиля. Значения в примере — плейсхолдеры; не коммитьте реальный token/API key.

{
  "mcpServers": {
    "whatsapp-personal": {
      "command": "node",
      "args": ["/absolute/path/WhatsApp MCP/dist/server.js"],
      "env": {
        "WHATSAPP_ADAPTER": "linked-device",
        "WHATSAPP_ACCOUNT_ID": "your-own-profile-id",
        "WAHA_BASE_URL": "http://127.0.0.1:8859",
        "WAHA_API_KEY": "<private WAHA key scoped to this session>",
        "WAHA_SESSION_NAME": "your-own-session",
        "WHATSAPP_HISTORY_DB_PATH": "/absolute/private/personal/history.sqlite",
        "WHATSAPP_AUDIT_DB_PATH": "/absolute/private/personal/audit.sqlite",
        "WHATSAPP_MEDIA_DIR": "/absolute/private/personal/media",
        "WHATSAPP_RELEASE_REVISION": "<verified git commit SHA>"
      }
    }
  }
}

For a Business profile use a separate process and private paths, with WHATSAPP_ADAPTER=business-graph, WHATSAPP_PHONE_NUMBER_ID, WHATSAPP_BUSINESS_ACCOUNT_ID, WHATSAPP_GRAPH_ACCESS_TOKEN, and WHATSAPP_GRAPH_API_VERSION=v24.0. The Graph API version is configurable; the default is pinned to the tested v24.0 contract. Keep the App Secret and webhook verification token in server configuration, not in a public client file.

You may run more than one personal profile, but each process stays bound to one WAHA session and account. Give every profile its own WHATSAPP_PROFILE_ID, WHATSAPP_CALLER_ID, session-scoped WAHA API key, WAHA_SESSION_NAME, HTTP MCP_SERVICE_TOKEN, and private audit/history/media paths. Use a different MCP host identity and env block for each process; tools never accept an account selector. Session-scoped key creation and enforcement were verified against WAHA 2026.9.2 NOWEB/CORE image digest sha256:0999fb384426222be591f3ffd15879f39b8940662df2f9f1d70d836a8315f659. The verified key had isAdmin=false, was bound to the named session, enabled read and send only, returned 200 for that session, and 403 for another. WAHA editions/builds can differ: verify the actual runtime's key-creation response, session/actions fields, a request to the bound session (expected 200), and a request to a different session (expected 403) before configuring an MCP process. Never substitute a global administrator key if this check fails; resolve the edition/runtime first.

The hosted profiles used by the owner are private, not a shared student tenant service. Students install and operate their own WAHA/MCP stack; do not configure a student client to use the owner's hosted profiles.

This MCP does not create or display a QR pairing flow. Create and link a WAHA session through the private WAHA provisioning surface for that profile, then check personal_session_status. Never send session exports or keys to a client.

Personal linked-device setup and QR troubleshooting

The public Quadlet example pins the WAHA Core image and sets WAHA_NOWEB_WA_VERSION=auto-web. WAHA 2026.8.1 and later fetch the current WhatsApp Web revision when the container starts, use it only if it is newer than the revision bundled in that image, and fall back to the bundled revision when the fetch fails. This does not update the pinned WAHA image. Do not replace auto-web with an old revision copied from a log; a controlled pin is described in the deployment instructions.

Pair only in the private WAHA provisioning surface. On the primary phone open WhatsApp → Linked devices → Link a device and scan the current QR shown by WAHA. Do not use the phone's general QR scanner, save the QR, or send a screenshot to anyone. WAHA changes the QR while the session reports SCAN_QR_CODE; fetch the newest QR for each update instead of reusing an old image. WAHA documents a 60-second lifetime for the first QR, 20 seconds for later QR codes, and at most six QR codes before the session enters FAILED.

Before starting a new NOWEB session and scanning its first QR, enable the local store in that session's creation config (this is not an environment variable):

{
  "name": "your-own-session",
  "start": false,
  "config": {
    "noweb": {
      "store": {
        "enabled": true,
        "fullSync": false
      }
    }
  }
}

With fullSync=false, WAHA describes roughly three months of initial history; it is not a complete archive. The MCP's local index remains partial and is populated through explicit bounded sync. WAHA warns that changing store settings after QR pairing can lose history. If an existing session was paired with the store disabled, do not change it blindly or delete it; make an owner-controlled recovery plan before any re-pairing.

If WhatsApp reports Can't link device, stop scanning that code. Confirm that the primary phone is using WhatsApp's Link a device screen, then wait for WAHA's next SCAN_QR_CODE update and scan its fresh QR once. If the session has reached FAILED after the QR cycle, restart the same WAHA session once while preserving its private session volume, then scan one newly issued QR. Do not repeatedly retry a stale QR, unlink/log out the account, delete the session directory, or reset its store as a first response. If the fresh attempt still fails, stop and review redacted WAHA/phone diagnostics before trying again.

The current core snapshot passed npm test 81/81 on Node 22.23.2. Separately, one owner-operated pairing on 2026-10-07 reached WAHA WORKING with the pinned NOWEB image and auto-web. This verifies one environment; it does not show that the setting alone caused success or guarantee pairing on every phone or account. See the WAHA NOWEB version and session docs and WhatsApp's linked-device instructions.

Hosted Streamable HTTP

Run npm run start:http behind HTTPS with MCP_HOST=127.0.0.1. MCP_PORT is 8857 for the default personal profile and 8858 for Business; the owner may assign a separate loopback port (8864 on the documented secondary profile) to another personal account. The application does not bind to a public interface. Set MCP_ALLOWED_HOSTS to the exact proxy hostnames and MCP_ALLOWED_ORIGINS to exact Origin values for the DNS-rebinding check. This endpoint is server-to-server MCP; it does not enable browser JavaScript CORS or answer preflight OPTIONS requests.

The app requires a per-profile private upstream token in MCP_SERVICE_TOKEN (at least 32 characters). By default it validates Authorization: Bearer <MCP_SERVICE_TOKEN> in constant time. The HTTPS gateway authenticates its own user, selects one isolated profile, and forwards that profile's service token. Do not reuse a token across profiles. Public client URLs and profile provisioning are configured by the deployment owner; do not copy the owner's endpoint credentials into a student setup.

Set WHATSAPP_PROFILE_ID to a non-sensitive stable profile name and WHATSAPP_RELEASE_REVISION to the verified 40-character Git SHA. Production release packages also carry .whatsapp-release-sha; if both values exist they must match. The health endpoint returns these identifiers so the updater can check that it activated the intended profile and exact commit.

The raw application routes are /mcp, /health, authenticated POST /media and authenticated GET /media/<mediaId>. The Business app additionally accepts Meta's signed callback on /webhooks/meta; the public reverse proxy must expose only the exact configured callback path. Personal WAHA callbacks are not exposed by the hosted service.

/health reports configuration state only. configured does not mean the upstream account is connected or ready. Use the adapter's status tools for a separate read-only check.

Safe message workflow

Every write has a separate *_prepare tool and a profile-level *_mutation_confirm tool. Preparation stores caller, account, adapter, operation, payload digest, expiry and release revision; it does not send. It is not human approval. Obtain explicit owner authorization for the exact target and content before calling the confirm tool. Confirmation requires the same caller, account, operation, payload and build revision and atomically allows one execution.

A lost response after a provider write returns OUTCOME_UNKNOWN. Do not retry automatically; first check the chat or Business delivery status. Provider acceptance/message ID does not mean delivered or read. WhatsApp messages, contacts, captions and webhook fields are untrusted external content and do not authorize forwarding.

Media

Upload bytes through the authenticated profile route POST /media, with an allowlisted Content-Type and X-File-Name. Default maximum size is 5 MiB. The response contains an opaque mediaId and SHA-256 digest. Provider tools accept this ID; they do not accept paths, base64 payloads or caller-supplied URLs. When an enabled provider download operation stores inbound media, its result links to whatsapp-media://<mediaId>; direct Streamable HTTP and stdio resources/read recheck the same profile and return only the stored asset. The existing cloud OAuth ProxyClient resource passthrough is unverified; do not claim support until it passes a contract test. HTTP GET /media/<mediaId> returns the same managed file as an authenticated attachment. Media roots are separate per profile, permission-restricted, and retained outside application releases.

Updating

Local updates use a reviewed GitHub commit, npm ci, tests and build. Hosted updates use the CI-gated, atomic updater described in deployment/README.md. WAHA images remain pinned and are updated separately; the application updater never changes private session, history, audit or media state.

MIT terms for this repository are in LICENSE. Third-party and separately installed service notices are in NOTICE.md.

Available Tools

1 tool
personal_system_configurationRead runtime configuration statusB

Report whether this isolated WhatsApp adapter has its required configuration; this does not claim an upstream connection.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose one meaningful behavioral trait: the result reports local configuration presence and must not be read as an upstream connectivity check. However, it says nothing about read-only semantics, permissions, latency/rate behavior, or what the report actually contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with an appended scope caveat; nothing is padded or redundant. Slightly awkward phrasing ("Report whether ... has its required configuration") keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is trivial in shape (zero params, no nested objects) but there is no output schema, so the description should say something about what the report looks like — a boolean, a status string, a list of missing keys. It only conveys that a configuration determination is made, leaving the return value unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, which is the documented baseline of 4. There are no arguments whose semantics could be clarified or omitted.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ("Report") and a precise resource ("whether this isolated WhatsApp adapter has its required configuration"), which is a genuine narrowing from the vague tool name personal_system_configuration. No sibling tools exist to differentiate from, so it cannot reach the 5 criterion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to call this tool versus alternatives, nor any precondition or agent-facing trigger. The trailing clause "this does not claim an upstream connection" is scope disambiguation, not usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.1.0
    • First observedpersonal_system_configuration

TDQS

B3.1/5.0

Scored across 1 tool

Disambiguation5/5

Only one tool exists, so there is no possibility of confusing it with another tool. Its purpose is narrow and explicitly stated, making selection trivial.

Naming Consistency4/5

The single tool name uses predictable snake_case, so there is no inconsistency across tools. It is a noun phrase rather than a verb_noun pattern, but that is a minor deviation for a one-tool set.

Tool Count1/5

One tool is an extreme mismatch for a WhatsApp MCP server, which would normally need messaging, contact, and chat operations. A lone configuration check cannot meaningfully serve the apparent domain.

Completeness1/5

The surface lacks any send, receive, list, or manage operations for WhatsApp messages, chats, contacts, or media. Only a configuration report is present, leaving the domain severely uncovered.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

  • WhatsMCP connects Claude and other MCP-compatible AI agents directly to WhatsApp. Send and receive text, images, documents, and voice notes; manage groups (create, add/remove members, promote admins); look up contacts and profiles; follow channels; and read call and message history — all through a standard MCP interface. For voice use cases, WhatsMCP offers SIP-based calling plans (inbound-only, or full inbound/outbound) so AI voice agents can answer and place WhatsApp calls, plus low-latency WebSocket integrations with voice agent providers like ElevenLabs. Multiple WhatsApp accounts can be paired and managed per workspace, with webhook support for real-time inbound message delivery to your own infrastructure.

  • WhatsApp for AI agents — your own number or the official Cloud API: messages, media, templates.

  • WhatsApp for your app or AI agent over OAuth2 — the same connections WASync runs inside your CRM.

  • Run WhatsApp Business campaigns from any AI assistant: contacts, segments, and broadcasts.

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Integrates WhatsApp with AI agents, enabling message sending, chat search, media sharing, approval workflows, and activity summaries via any MCP client.
    1
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to interact with WhatsApp through a safety-first MCP server, with tools for sending messages, media, searching chats, and managing drafts, all governed by default-deny allowlists and non-overridable rate limits.
    Apache 2.0