Skip to main content
Glama
BusinessNone

WhatsApp MCP Stream

by BusinessNone

WhatsApp MCP Stream

CI

Streamable HTTP 전송을 기반으로 하는 WhatsApp MCP 서버로, Baileys를 사용해 WhatsApp에 연결하며, 웹 관리자 UI와 양방향 미디어 흐름(업로드 + 다운로드)을 제공합니다.

주요 특징:

  • 전송: /mcp에 제공되는 Streamable HTTP

  • 엔진: Baileys

  • 관리자 UI: QR, 상태, 로그아웃, 런타임 설정, 대화 기록 뷰어

  • 미디어: 업로드 엔드포인트 + /media 호스팅 + MCP 다운로드 도구

빠른 시작 (Docker)

# build and run

docker compose build

docker compose up -d

서버는 다음 주소에서 사용할 수 있습니다:

  • 관리자 UI: http://localhost:3003/admin

  • MCP 엔드포인트: http://localhost:3003/mcp

  • 미디어 파일: http://localhost:3003/media/<filename>

Related MCP server: WhatsApp Business API MCP Server

--iptables=false가 설정된 호스트의 DNS

일부 NAS/강화된 호스트에서는(예: dockerd --iptables=false를 사용하는 Synology) Docker의 내장 DNS 프록시(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은 오버라이드를 자동으로 적용합니다.

런타임 설정

설정은 관리자 UI에서 편집할 수 있으며 SETTINGS_PATH(기본값: MEDIA_DIR/settings.json)에 저장됩니다.

관리자 UI

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 전송

서버는 /mcp에서 Streamable HTTP를 제공합니다.

일반적인 흐름:

  1. JSON-RPC initialize을 사용하여 POST /mcp

  2. 후속 요청에는 서버가 반환한 mcp-session-id 헤더를 사용

  3. 도구 호출을 위해 POST /mcp 사용

참고: 클라이언트는 initialize 요청 시 Accept: application/json, text/event-stream 헤더를 보내야 합니다.

스모크 테스트

MCP 도구용 빠른 회균 스모크 테스트:

npm run smoke:mcp

선택 사항: 사용자 지정 타겟:

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

MCP 도구

인증

도구

설명

get_qr_code

인증용 최신 WhatsApp QR 코드를 이미지로 가져옵니다.

check_auth_status

WhatsApp 클라이언트가 인증되었고 사용할 준비가 되었는지 확인합니다.

logout

WhatsApp에서 로그아웃하고 현재 세션을 지웁니다.

연락처

도구

설명

search_contacts

이름 또는 전화번호로 연락처를 검색합니다.

resolve_contact

이름 또는 전화번호로 연락처를 확인합니다(가장 가까운 결과).

get_contact_by_id

JID로 연락처 세부 정보를 가져옵니다.

get_profile_pic

JID에 대한 프로필 사진 URL을 가져옵니다.

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_path를 send_media의 media_path에 사용하며, URL 소스 때 base64를 피할 수 있고(서버가 직접 다운로드), 파일을 여러 수신자에게 재업로드 없이 보낼 수 있습니다.

download_media

메시지에서 미디어를 다운로드합니다.

유틸리티

도구

설명

ping

상태 확인 도구.

복구 참고 사항

이 서비스에는 Baileys/WhatsApp 세션 상태 손상에 대한 의도적인 복구 우회 장치가 포함되어 있습니다.

이 기능이 필요한 이유:

  • 프로덕션에서 컨테이너는 살아 있고 MCP도 응답하지만 WhatsApp 세션이 기능적으로 손상된 사례를 관찰했습니다.

  • 대부분의 경우 Baileys 오류인 failed to find some ...로 나타났습니다.
    — Wait, actually the exact phrase: failed to find key ... to decode mutation — corrected below.

  • 그 상태에서 수동으로 컨테이너를 재시작하면 서비스가 복구되는 경우가 많았습니다.

현재 동작:

  • 앱 상태 손상 신호가 감지되면 서비스는 먼저 forceResync()로 소프트 복구를 시도합니다.

  • 같은 오류가 시간 간격 안에 반복되면 내부 WhatsApp 클라이언트를 재시작하는 수준으로 확대됩니다.

  • Connection Terminated 같은 연결 끊김이 발생하면 서비스는 연결 끊김 감시자를 예약하고, 시간 안에 소쉘이 open 상태로 되돌아오지 않으면 자동 재시작을 수행합니다.

  • 재연결 라이프사이클은 중복되는 잠금 교착(deadlock)을 방지하도록 보호되어, 수동으로 컨테이너를 재시작하지 않아도 연결 복구가 완료될 수 있습니다.

  • 최근 운영 관찰에서 반복된 소쉣 연결 끊김(428 Connection Terminated, 503 Stream Terminated)이 자동으로 복구되어 open 상태로 되돌아갔습니다.

  • 전용 /healthz 엔드포인트는 서비스가 실제로 허용된 복구 시간 내에서 벗어나 멈췄을 때만 503을 반환합니다.

  • 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

강제 재동기화 후 재연결 전 지연 시간(ms)입니다.

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

이 창 내에서 동일한 JID로 전송되는 정확히 중복된 send_message 요청을 억제합니다.

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으로 설정하면 비활성화됩니다. 시간 초과 시 throw하므로 복구가 멈추지 않고 재시도할 수 있습니다.

WA_AUTO_DOWNLOAD_CONCURRENCY

3

최대 병렬 자동 다운로드 수입니다. 자동 다운로드는 프로세스 내부의 크기 제한 큐를 통해 실행되므로 대량의 인바운드 미디어가 I/O를 포화시키지 못합니다.

WA_AUTO_DOWNLOAD_QUEUE_MAX

200

대기 가능한 최대 자동 다운로드 작업 수입니다. 초과분은 경고 로그와 함께 FIFO(가장 오래된 것부터)로 폐기되며, 최근 메시지가 우선순위를 유지합니다.

MCP_HTTP_ENABLE_JSON_RESPONSE

1

Streamable HTTP POST 요청에 기본적으로 직접 JSON 응답을 사용합니다. 0으로 설정하면 기존 SSE 스타일 POST 응답 처리를 강제합니다.

추가 전송 진단:

  • 이제 /mcp POST 요청은 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 — 채팅의 페이지네이션된 메시지 목록(최신순)입니다.

두 엔드포인트 모두 관리자 UI의 채팅 탭에서 사용됩니다.

내보내기

채팅을 내보내기:

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

include_media=true이면 ZIP에는 download_media를 통해 이미 다운로드된 파일이 포함됩니다. 누락된 미디어를 WhatsApp에서 가져오지는 않습니다.

Related MCP Connectors

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