주요 콘텐츠로 건너뛰기
AI 튜토리얼

whatsapp-mcp로 비공개 WhatsApp 메시지 검색 서버 구축하기

whatsapp-mcp를 Cloudflare에 배포하고 WhatsApp 계정을 연결한 뒤, Claude 또는 다른 MCP 클라이언트와 연동해 메시지를 검색하고 읽는 방법을 알아보세요. 이름이 없는 연락처를 확인하고, 메시지 데이터를 자신의 계정에 보관하면서 동기화 문제를 해결하는 방법도 설명합니다.

whatsapp-mcp로 비공개 WhatsApp 메시지 검색 서버 구축하기

whatsapp-mcp의 기능

whatsapp-mcp는 MCP 호환 AI 에이전트가 WhatsApp 메시지를 읽고 검색할 수 있게 해 주는 소형 서버입니다. 이 서버는 사용자의 Cloudflare 계정에서 실행되며, WhatsApp Web 방식의 연결된 기기로 휴대폰에 연결됩니다.

초기 설정을 완료하면 Claude Code, Claude Desktop 또는 다른 MCP 애플리케이션과 같은 클라이언트가 다음과 같은 질문에 답할 수 있습니다.

  • Dana가 항공편에 대해 뭐라고 말했나요?
  • 모든 채팅에서 임대 계약을 언급한 메시지를 찾아 줘.
  • 이번 주 가족 그룹에서 내가 놓친 내용을 요약해 줘.

이 서버는 의도적으로 읽기 전용으로 동작합니다. 메시지를 수집하고 검색하고 표시할 수 있지만 WhatsApp 메시지를 보낼 수는 없습니다.

시스템 작동 방식

데이터의 기준은 계속 사용자의 휴대폰입니다. Cloudflare 배포 환경은 연결된 기기로 작동하며, 데이터를 동기화해야 할 때 또는 계정을 연결할 때만 WhatsApp에 연결합니다.

에이전트가 정보를 요청하면 서버에 저장된 복사본이 10분보다 오래된 경우 WhatsApp에서 대기 중인 업데이트를 가져옵니다. 예약된 가져오기도 하루에 한 번 실행됩니다. 메시지를 수집한 후 서버는 다시 연결을 해제합니다. 휴대폰은 정상적으로 계속 작동하며 알림도 계속 수신합니다.

메시지는 사용자의 계정에 있는 Cloudflare Durable Object 내부의 SQLite 데이터베이스에 저장됩니다. 서버는 메시지 기록을 외부 스토리지 서비스로 전송하지 않습니다.

사전 요구 사항

설치하기 전에 다음을 준비하세요.

  • Workers 유료 요금제의 Cloudflare 계정
  • Node.js 20 이상
  • 연결하려는 WhatsApp 계정이 있는 휴대폰
  • Claude Code 또는 Claude Desktop과 같은 MCP 클라이언트

Workers 유료 요금제가 필요한 이유는 대규모 WhatsApp 기록을 가져올 때 기본 CPU 제한을 초과할 수 있기 때문입니다. 저장소의 wrangler.jsonc에서 해당 제한을 높이며, Cloudflare는 더 높은 제한을 사용하려면 유료 요금제를 요구합니다.

설치 및 배포

저장소를 복제하고, 종속성을 설치하고, 필요한 KV 네임스페이스를 만들고, 소유자 비밀번호를 저장한 다음 Worker를 배포합니다.

git clone https://github.com/finereli/whatsapp-mcp
cd whatsapp-mcp
npm install

npx wrangler kv namespace create OAUTH_KV
npx wrangler secret put OWNER_PASSWORD
npm run deploy

비밀번호는 12자 이상이어야 합니다. 배포가 완료되면 Wrangler가 https://whatsapp-mcp.your-name.workers.dev와 비슷한 URL을 출력합니다. 해당 URL을 열어 설정을 계속 진행하세요.

사용자 지정 도메인을 사용하려면 wrangler.jsonc 하단의 주석을 따르세요.

WhatsApp 계정 연결

배포 페이지에 나머지 설정 단계가 표시됩니다.

  1. WhatsApp 연결 옵션을 선택합니다.
  2. 휴대폰에서 WhatsApp을 열고 설정, 연결된 기기, 기기 연결로 이동합니다.
  3. 서버에 표시된 QR 코드를 스캔합니다. 같은 휴대폰을 사용 중이라 화면을 스캔할 수 없다면 전화번호 연결 옵션을 대신 사용하세요.
  4. 첫 연결에서 WhatsApp이 새 기기에 제공하는 기록을 가져오는 동안 기다립니다.

페이지에 가져오기 진행률이 표시되며, 가져오기가 계속되는 동안 페이지를 닫아도 됩니다. 새로 연결된 기기에 제공할 기록을 WhatsApp이 결정하므로 초기 가져오기에 모든 과거 메시지가 포함되지 않을 수 있습니다.

MCP 클라이언트 연결

Claude Code에서 /mcp 엔드포인트를 사용해 배포된 서버를 등록합니다.

claude mcp add --transport http whatsapp https://your-url/mcp

그런 다음 Claude Code에서 /mcp를 실행하고 소유자 비밀번호로 로그인합니다. 다른 MCP 클라이언트도 동일한 URL로 설정해야 합니다.

https://your-url/mcp

인증이 완료되면 에이전트에게 채팅 목록 표시, 메시지 조회 또는 기록 검색을 요청할 수 있습니다.

사용 가능한 도구

MCP 서버는 로컬 메시지 복사본을 읽고 관리하기 위한 기능별 도구를 제공합니다.

  • list_chats는 최신 채팅부터 채팅을 나열하며, 이름 또는 번호로 선택적으로 필터링할 수 있습니다.
  • get_messages는 한 채팅의 메시지를 읽으며 날짜를 기준으로 이전 또는 이후 메시지를 페이지 단위로 조회할 수 있습니다.
  • search_messages는 모든 채팅 또는 선택한 채팅에서 전문 검색을 수행합니다.
  • unnamed_chats는 전화번호로만 식별되는 채팅을 찾고, 활동량이 많은 채팅을 우선 표시하며 상대방이 보낸 최신 메시지도 보여 줍니다.
  • set_contact_names는 전화번호에 이름을 저장하므로 그룹 채팅에서도 이름이 올바르게 표시됩니다.
  • sync_now는 새 메시지를 즉시 가져옵니다.
  • link_status는 계정 연결 여부, 마지막 동기화 시점 및 저장된 데이터의 양을 보여 줍니다.
  • relink는 현재 연결을 제거하고 연결 절차를 다시 시작합니다. 저장된 메시지는 계속 사용할 수 있습니다.

저장된 복사본이 10분보다 오래된 경우 읽기 도구가 먼저 자동으로 동기화합니다. 따라서 모든 검색 전에 sync_now를 수동으로 호출하지 않고도 자연어로 요청할 수 있습니다.

전화번호로만 표시되는 채팅 확인

WhatsApp이 모든 연결된 기기에 연락처 이름을 제공하지 않기 때문에 일부 채팅은 전화번호로 표시됩니다. 일회성 대화나 WhatsApp 연락처에 저장되지 않은 사람의 경우 이러한 일이 흔합니다.

에이전트에게 다음과 같이 요청하세요.

이름이 없는 채팅의 이름을 찾아 줘.

에이전트는 unnamed_chats를 호출하고, 이미 연결된 연락처 연동 기능으로 번호를 대조한 다음 set_contact_names를 통해 일치하는 이름을 저장할 수 있습니다. 예를 들어 Google Contacts 또는 Gmail 커넥터가 일치하는 이름을 제공할 수 있습니다. 서버 자체는 연락처 서비스에 로그인하지 않습니다.

저장된 이름은 전화번호에 연결되므로 그룹 대화에서도 사용할 수 있습니다. 일치하는 연락처가 없으면 일부 번호는 이름 없이 남습니다.

미디어 및 메시지 기록 이해하기

미디어 파일은 다운로드되지 않습니다. 이미지, 음성 메모, 문서는 [image] 또는 [voice note 12s]와 같은 레이블로 표시됩니다. WhatsApp에서 캡션을 제공하는 경우 캡션은 유지되지만 음성 메시지는 텍스트로 변환되지 않습니다.

첫 번째 연결은 WhatsApp이 보내기로 선택한 기록을 가져옵니다. 기록은 일반적으로 연결마다 한 번만 전송됩니다. 가져오기가 불완전한 경우 연결을 다시 설정하면 이미 저장된 메시지를 유지하면서 다른 가져오기를 요청할 수 있습니다. 수집 과정은 멱등성을 고려해 설계되었으므로 다시 가져와도 의도적으로 중복 행이 생성되지 않습니다.

계정 다시 연결하기

WhatsApp에서 기기가 제거되었다고 알리거나 페어링 과정을 다시 시작하려는 경우 다시 연결하세요. 에이전트에게 relink를 실행하도록 요청하거나 /setup을 열고 연결 해제 후 다시 스캔을 선택하세요.

메시지가 표시되면 새 QR 코드를 스캔하세요. 기존에 저장된 메시지는 유지되며, 새 연결을 통해 누락된 기록을 보완할 수 있습니다.

고급 구성

기본 배포는 비밀번호 인증을 사용합니다. 주요 구성 값은 다음과 같습니다.

  • OWNER_PASSWORD: 소유자 비밀번호이며, 최소 길이는 12자입니다.
  • OWNER_EMAIL: 로그인 서비스 모드를 사용할 때 허용되는 유일한 이메일 주소입니다.
  • OPERATOR_NAME: 개인정보 보호 페이지에 표시할 수 있는 선택적 이름입니다.
  • DEFAULT_COUNTRY_CODE: 에이전트가 국가 코드 없이 번호를 저장할 때 사용하는 숫자만 포함된 국가 코드입니다.
  • LOGIN_ORIGIN: 배포를 로그인 서비스 모드로 전환합니다.
  • ALLOWED_ORIGINS: 로그인 서비스 토큰에 허용되는 출처입니다.
  • PIN: x-pin 헤더를 통해 보호된 디버그 경로를 활성화하는 선택적 32자 이상의 값입니다.
  • OAUTH_KV 및 WA: 애플리케이션에서 사용하는 KV 및 Durable Object 바인딩입니다.

도메인, KV ID, 이메일과 같은 배포별 값은 gitignore에 등록된 wrangler.local.jsonc 파일에 보관하세요. 다음 명령으로 로컬 구성을 배포합니다.

npm run deploy:local

동기화 문제 디버깅

PIN을 구성하면 서버에서 보호된 진단 엔드포인트를 제공합니다. x-pin 헤더에 PIN을 전송하세요.

  • /debug는 세션 단계, 연결 상태, 개수 및 최근 세션 이벤트를 보여줍니다.
  • /debug/pull은 즉시 동기화를 시작합니다.
  • /debug/chats?q=, /debug/messages?chat=, /debug/search?q= 및 /debug/types는 저장된 데이터를 검사합니다.
  • /debug/unnamed는 unnamed_chats가 반환한 채팅을 보여줍니다.
  • /debug/sql?q=은 저장소에 대해 읽기 전용 SELECT 쿼리 하나를 실행합니다.
  • /debug/logout은 다시 연결하는 것과 동일한 작업을 수행합니다.

배포가 성공한 후 유용한 확인 순서는 /debug에서 유휴 세션과 연결된 계정을 보고하는지 확인하고, /debug/pull을 실행한 다음 채팅 목록, 메시지 조회, 전문 검색, 이름 없는 채팅 처리 및 연락처 이름 지정을 테스트하는 것입니다.

로컬에서 개발하기

로컬 개발을 위해 충분히 긴 비밀번호가 포함된 .dev.vars 파일을 만들고 Worker를 시작하세요.

OWNER_PASSWORD=your-12-character-or-longer-password

npm run dev

로컬 개발은 빈 저장소가 있는 별도의 Durable Object를 사용합니다. 로그인 흐름을 실행하고 실제 QR 코드를 표시할 수 있지만, 로컬에서 휴대폰을 연결하면 연결된 기기가 하나 더 생성됩니다.

코드 변경 사항을 제출하기 전에 다음을 실행하세요.

npm run typecheck
npm test

테스트 모음은 Node 22.13 이상에서 Node 내장 SQLite를 사용해 저장소 코드를 실행합니다. 해당 SQLite 환경에서는 전문 검색을 다루지 않으므로 배포 후에도 검색을 테스트하세요.

중요한 보안 및 플랫폼 고려 사항

이 프로젝트는 공식 WhatsApp 연동이 아닙니다. WhatsApp은 개인 메시지를 읽기 위한 API를 제공하지 않으며, 이 프로젝트는 오픈 소스 Baileys 라이브러리를 통해 WhatsApp Web과 동일한 프로토콜을 사용합니다. 이러한 사용은 WhatsApp 약관을 위반할 수 있습니다. 자신의 계정에서만 사용하고, 읽기 전용 연결 기기의 실질적인 위험은 낮지만 0은 아니라는 점을 기억하세요.

하나의 배포는 한 사람과 하나의 WhatsApp 계정을 대상으로 합니다. 각 배포에는 전체 메시지 기록과 활성 계정 로그인이 저장되므로 하나를 공유하기보다 사용자별로 별도의 배포를 실행해야 합니다.

메시지는 Durable Object의 SQLite 저장소 내부에 남아 있지만, 배포 자격 증명이나 소유자 인증에 접근할 수 있는 사람은 저장된 기록에 접근할 수 있습니다. 비밀번호, Cloudflare 계정, 시크릿 및 디버그 PIN을 주의 깊게 보호하세요.

결론

whatsapp-mcp는 WhatsApp의 연결된 기기 프로토콜과 MCP 클라이언트 사이를 연결하는 실용적인 브리지입니다. Cloudflare에 배포하고, 휴대폰을 한 번 연결한 다음, 에이전트를 /mcp에 연결하면 search_messages, get_messages, set_contact_names와 같은 도구를 사용해 자신의 메시지 보관함을 탐색할 수 있습니다. 읽기 전용 설계, 비공개 Durable Object 저장소, 예약된 동기화 및 명시적인 재연결 흐름을 갖추고 있어 배포를 직접 관리하면서 개인 메시지를 검색하는 데 적합합니다.