Skip to main content
Glama
BusinessNone

WhatsApp MCP Stream

by BusinessNone

WhatsApp MCP Stack Stream

CI

Сервер WhatsApp MCP, построенный на транспорте Streamable HTTP, с использованием Baileys для подключения к WhatsApp, с веб-интерфейсом администрирования и двунаправленным потоком медиа (загрузка и скачивание).

Ключевые особенности:

  • Транспорт: Streamable HTTP на /mcp

  • Движок: Baileys

  • Админ-панель: QR, статус, выход, настройки времени выполнения, просмотр истории чатов

  • Медиа: эндпоинты загрузки + хостинг /media + MCP-инструмент скачивания

Быстрый старт (Docker)

# build and run

docker compose build

docker compose up -d

Сервер будет доступен по адресам:

  • Админ-панель: http://localhost:3003/admin

  • MCP-эндпоинт: http://localhost:3003/mcp

  • Медиа-файлы: http://localhost:3003/media/<filename>

Related MCP server: WhatsApp Business API MCP Server

DNS на хостах с --iptables=false

На некоторых NAS и усиленных хостах (например, Synology с dockerd --iptables=false) встроенный DNS-прокси Docker (127.0.0.11) не имеет правил iptables DNAT и отказывает в соединениях внутри контейнеров.

Решение: скопируйте resolv.conf.example в resolv.conf и добавьте в том переопределение:

cp resolv.conf.example resolv.conf

Затем добавьте в локальный docker-compose.override.yml (не коммитьте его):

services:
  mcp-whatsapp:
    volumes:
      - ./resolv.conf:/etc/resolv.conf:ro

docker compose up автоматически подхватит переопределение.

Настройки выполнения

Настройки можно изменять в админ-панели; они сохраняются в SETTINGS_PATH (по умолчанию — MEDIA_DIR/settings.json).

Админ-панель

Admin UI Админ-консоль с настройками времени выполнения, привязкой по QR, просмотрщиком истории чатов, экспортом и статусом.

Поддерживаемые настройки:

  • media_public_base_url

  • upload_max_mb

  • upload_enabled

  • max_files_per_upload

  • require_upload_token

  • upload_token

  • auto_download_media

  • auto_download_max_mb

Аутентификация

Встроенная аутентификация ещё не реализована. В продакшене используйте шлюз с принудительной проверкой подлинности. Проект хорошо работает за authmcp-gateway:

https://github.com/loglux/authmcp-gateway

API загрузки медиа

Base64 JSON:

curl -X POST http://localhost:3003/api/upload \
  -H "Content-Type: application/json" \
  -d {filename:photo.jpg,mime_type:image/jpeg,data:<base64>}

Multipart (рекомендуется для больших файлов):

curl -X POST http://localhost:3003/api/upload-multipart \
  -F "file=@/path/to/file.jpg"

Оба метода возвращают url и (если настроено) publicUrl.

Отправка локальных файлов через send_media

Каталог ./files/ в корне проекта монтируется в контейнер по пути /app/files. Положите туда любой файл и сразу используйте его — перезапуск контейнера не нужен:

# On host:
cp report.pdf /path/to/whatsapp-mcp-stream/files/

# In send_media:
media_path: /app/files/report.pdf

Для источника в виде URL передайте media_url напрямую в send_media или stage_media — сервер сам скачает файл, без base64.

Авторизация загрузки (необязательно)

Если require_upload_token=true, передавайте токен одним из способов:

  • x-upload-token: <token>

  • Authorization: Bearer <token>

MCP-транспорт

Сервер представляет Streamable HTTP на /mcp.

Типовый поток:

  1. POST /mcp с JSON-RPC initialize

  2. Используйте возвращаемый заголовок IDs-session-id для последующих запросов

  3. POST /mcp для вызова инструментов

Примечание: клиенты должны отправлять Accept: application/json, text/event-stream при initialize.

Смоук-тест

Быстрый регрессионный смоук-тест MCP-инструментов:

npm run smoke:mcp

Необязательная целевая цель:

MCP_BASE_URL=http://localhost:3003 npm run smoke:mcp

Инструменты MCP

Аутентификация

Инструмент

Описание

get_qr_code

Получить последний QR-код WhatsApp в виде изображения для аутентификации.

check_auth_status

Проверить, аутентифицирован ли WhatsApp-клиент и готов ли он к работе.

logout

Выйти из WhatsApp и очистка текущей сессии.

Контакты

Инструмент

Описание

search_contacts

Искать контакты по имени или номеру телефона.

resolve_contact

Определить контакт по имени или номеру телефона (лучшие совпадения).

get_contact_by_id

Получить данные о контакте по JID.

get_profile_pic

Получить URL фотографии профиля для JID.

get_group_info

Получить метаданные группы и список участников по JID.

Чаты

Инструмент

Описание

list_chats

Списал чаты с метаданными и, опционально, с последним сообщением.

get_chat_by_id

Получить метаданные чата по JID.

list_groups

Получить только групповые чаты.

get_direct_chat_by_contact_number

Найти JID личного чата по номеру телефона.

get_chat_by_contact

Найти контакт по имени или номеру и вернуть метаданные чата.

analyze_group_overlaps

Найти участников, встречающихся в нескольких группах.

find_members_without_direct_chat

Найти участников группы, у которых нет личного чата.

find_members_not_in_contacts

Найти участников группы, отсутствующих в контактах.

run_group_audit

Выполнить комплексный аудит групп как одну операцию.

Сообщения

Инструмент

Описание

list_messages

Получить сообщения из конкретного чата.

search_messages

Искать сообщения по тексту (опционально ограничиваясь одним чата).

get_message_by_id

Получить конкретное сообщение по ID (jid:id).

get_message_context

Получить сообщение вокруг конкретного сообщения.

get_last_interaction

Получить последнее сообщение для JID.

send_message

Отправить текстовое сообщение человеку или группе. Поддерживает опциональный idempotency_key.

Медиа

Инструмент

Описание

send_media

Отправить медиа (изображение/видео/документ/аудио). Принимает media_path, media_url или media_content (base64). Поддерживает опциональный idempotency_key.

stage_media

Сохраника файл в медиакаталог сервера и возвращает его локальный путь. Используйте возвращаемый saved_start в send_media (media_path) — избегает base64, когда источник — URL (сервер скачивает сам), или позволяет отправить один и тот же файл нескольким получателям без повторной загрузки.

download_media

Скачать медиа из сообщения.

Дополнительно

Инструмент

Описание

ping

Инструмент проверки здоровья.

Заметки о восстановлении

В этом сервисе есть намеренный обходной механизм для восстановления состояния сессии Baileys/WhatsApp.

Почему он существует:

  • В продакшене мы наблюдали случаи, когда контейнер оставался живым, MCP продолжал отвечать, но сессия WhatsApp была фактически полностью уничтожена.

  • Самыми распространёнными индикаторами были ошибки Baileys: failed to find key ... to decode mutation и failed to sync state from version.

  • В таком состоянии ручной перезапуск контейнера часто восстанавливал работоспособность.

Текущее поведение:

  • При сигнале повреждения состояния приложения, сервис сначала пробует мягкое восстановление через forceResync().

  • Если повторяется однотипный сбой в течение временного интервала, происходит эскалация до внутреннего перезапуска WhatsApp-клиента.

  • При отключениях, таких как Connection Terminated, сервис запускает сторожевой таймер и, если сокет не вернулся в состояние open, эскалирует до внутреннего перезапуска.

  • Цикл перезапуска защищён от вложенных блокировок, поэтому отключения могут быть автоматически восстановлены без ручного перезапуска и необходим.

  • Недавние наблюдения в проде показывают повторные отключения сокета (428 Connection Terminated, 503 Stream Errored) автоматически возвращаются в состояние open.

  • Отдельный эндпоинт /healthz возвращает 503 только когда сервис по-настоящему застрял вне допустимого окна восстановления.

  • Healthcheck Docker использует /healthz, поэтому контейнер перезапускается только после того, как внутреннее восстановление получит шанс сработать.

Эти механизмы сокращают необходимость вмешательства оператора и повышают устойчивость к часто встречающимся сбоям сессий WhatsApp/Baileys.

Лицензия

MIT

Персистентность

Чаты и сообщения сохраняются в локальную базу данных SQLite, размещённую вместе с сессией.

Переменные окружения:

Переменная

По умолчанию

Описание

DB_PATH

<SESSION_DIR>/store.sqlite

Путь к базе данных SQLite для хранения чатов и сообщений.

WA_EVENT_LOG

0

Включить подробные журналы событий WhatsApp.

WA_EVENT_STREAM

0

Записывать необработанный поток событий Baileys в файл для глубокой отладки.

WA_EVENT_STREAM_PATH

/app/logs/wa-events.log

Путь к файлу журнала потока событий.

WA_RESYNC_RECONNECT

1

Включить страховочное переподключение после принудительной ресинхронизации.

WA_RESYNC_RECONNECT_DELAY_MS

15000

Задержка перед переподключением после принудительной ресинхронизации (мс).

WA_SYNC_RECOVERY_COOLDOWN_MS

300000

Минимальная задержка между автоматическими восстановлениями состояния приложения.

WA_SYNC_RECOVERY_WINDOW_MS

900000

Временное окно для подсчёта повторяющихся сбоев повреждения состояния приложения.

WA_SYNC_SOFT_RECOVERY_LIMIT

2

Количество мягких восстановлений до перехода к внутреннему перезапуску.

WA_READINESS_GRACE_MS

180000

Период отсрочки во время восстановления/отключения, прежде чем /healthz перейдёт в состояние нездоров.

WA_DISCONNECT_RECOVERY_DELAY_MS

30000

Сколько ждать после закрытия сокета, прежде чем сторожевой механизм отключения принудительно выполнит переподключение/перезапуск.

WA_DISCONNECT_RECOVERY_RESTART_CODES

428

Коды статусов отключения через запятую, которые должны немедленно передаваться внутреннему сторожевому механизму перезапуска.

WA_SEND_DEDUP_WINDOW_MS

45000

Подавлять точные дубликаты запросов send_message к тому же JID в рамках этого окна.

WA_IDEMPOTENCY_TTL_MS

86400000

Сколько времени записи идемпотентности завершённых send_message хранятся в SQLite для безопасных повторных попыток.

WA_MESSAGE_INDEX_MAX

20000

Макс. количество записей индекса сообщений в памяти (jid:id -> необработанное сообщение).

WA_MESSAGE_KEY_INDEX_MAX

20000

Макс. количество записей индекса ключей сообщений в памяти (id -> необработанное сообщение).

WA_INITIALIZE_TIMEOUT_MS

120000

Ограничить инициализацию клиента WhatsApp этим сроком; установите 0, чтобы отключить. При тайм-ауте выбрасывается ошибка, чтобы восстановление могло повторить попытку, а не зависнуть.

WA_AUTO_DOWNLOAD_CONCURRENCY

3

Максимум параллельных автозагрузок. Автозагрузка выполняется через ограниченную внутрипроцессную очередь, поэтому всплеск входящих медиафайлов не может перегрузить ввод-вывод.

WA_AUTO_DOWNLOAD_QUEUE_MAX

200

Максимум заданий автозагрузки в очереди. Излишки отбрасываются в порядке FIFO (сначала старые) с предупреждением в журнале; недавние сообщения остаются приоритетными.

MCP_HTTP_ENABLE_JSON_RESPONSE

1

Использовать прямые JSON-ответы для Streamable HTTP POST-запросов по умолчанию. Установите 0, чтобы принудительно включить прежнюю обработку POST-ответов в стиле SSE.

Дополнительная диагностика транспорта:

  • POST-запросы /mcp теперь записывают события жизненного цикла запроса в logs/mcp-whatsapp.log

  • сюда входят поступление запроса, диспетчеризация транспорта, завершение transport.handleRequest, а также HTTP finish / close

  • по этим журналам можно определить, возникает ли задержка до того, как ответ покидает whatsapp-mcp-stream, или уже после — на стороне шлюза/клиента

API истории чатов

Просматривайте сохранённые чаты и сообщения через:

GET /api/chats?limit=50&offset=0&q=<search> — постраничный список чатов, опционально фильтруется по имени.

GET /api/chats/:jid/messages?limit=50&offset=0 — постраничные сообщения чата (сначала новые).

Оба эндпоинта используются вкладкой Чаты в админ-интерфейсе.

Экспорт

Экспортируйте чат (JSON + необязательно скачанные медиафайлы) через:

GET /api/export/chat/:jid?include_media=true

Если include_media=true, ZIP-архив включает файлы, уже скачанные через download_media. Он не загружает недостающие медиафайлы из WhatsApp.

Related MCP Connectors

  • WhatsApp (Web + Business API), SMS, contacts, and call records via 2Chat's MCP server.

  • Drive WhatsApp from any MCP client: pair devices, send text and media, manage contacts and groups.

  • 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.

  • Let Claude or ChatGPT search, read and send your WhatsApp messages over MCP. OAuth sign-in.

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Enables WhatsApp automation through MCP protocol, allowing users to manage sessions, send messages, handle groups/communities, and access contacts through natural language interactions with AI agents.
    4 npm
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables connecting a personal or business WhatsApp account via QR pairing and then sending/reading messages, managing chats, contacts, groups, and searching message history through MCP tools.
    MIT