카카오톡을 Claude가 직접 다루게 만들기 — Hyper-V + MCP 자동화 사례
API가 없는 카카오톡 PC를 Hyper-V 가상 컴퓨터에 격리하고, Win32·클립보드·OCR로 조작하는 MCP 서버를 붙여 Claude가 메시지를 읽고 보내게 만든 과정과 시행착오.

카카오톡을 Claude가 직접 다루게 만들기
Hyper-V 가상 컴퓨터 + MCP 서버로 만든 카카오톡 자동화, 그리고 그 과정의 시행착오
왜 만들었나
카카오톡에는 개인 계정용 공개 API가 없습니다. 그래서 "이 방 대화를 정리해 줘", "이 키워드가 나오면 알려 줘" 같은 일을 AI에게 맡기려면, 사람이 하듯 PC 카카오톡 화면을 직접 조작하는 수밖에 없습니다.
이 글은 그 일을 MCP(Model Context Protocol) 서버로 만들어, Claude가 도구 호출 한 번으로 카카오톡 메시지를 읽고 보내게 만든 사례입니다. 공개된 오픈소스 kronenz/kakaotalk-mcp(MIT)를 바탕으로 기능을 크게 늘렸고, 확장판 코드는 farrar142/kakaotalk-mcp에 공개해 두었습니다. 이 글의 스크린샷도 Claude가 직접 메시지를 보내고 화면을 찍어 만들었습니다.
시연: 도구 호출 한 번이 카카오톡 메시지가 되기까지

① Claude Code가 kakao_send_message를 호출하고 ② 몇 초 뒤 VM 속 카카오톡 PC의 나와의 채팅에 그 메시지가 도착합니다. 왼쪽 카드는 실제 호출 인자와 응답을 그대로 옮긴 것이고, 오른쪽은 VM 화면 캡처입니다.
시연: 카카오톡 화면이 구조화된 데이터가 되기까지

읽기는 반대 방향입니다. ① MCP 서버가 채팅 목록을 Ctrl+A로 전체 선택(말풍선이 어둡게 보이는 이유)해 복사하고, ② 그 텍스트를 보낸 사람·날짜·시각·본문으로 나눠 Claude에게 돌려줍니다. 여러 줄 메시지도 한 레코드로 유지됩니다.
전체 구조
- ClaudeOAuth 2.1로 인증
claude.ai 커스텀 커넥터나 Claude Code가 도구를 호출
- 리버스 프록시SSE 때문에 버퍼링 끔
Nginx Proxy Manager가 TLS를 끝내고 VM으로 전달
- MCP 서버프록시 호스트만 방화벽 허용
Hyper-V VM 안의 Python 서버(streamable-http)
- 카카오톡 PC대화 기록은 SQLite
Win32 API·키보드·클립보드·OCR로 조작
왜 Hyper-V 가상 컴퓨터인가
카카오톡 PC 자동화는 실제로 로그인한 데스크톱에서, 창을 맨 앞으로 올려야만 동작합니다. 서비스나 SSH로는 띄울 수 없고, 키 입력과 클립보드를 씁니다.
이걸 평소 쓰는 PC에서 돌리면 자동화가 마우스·키보드·클립보드를 사람과 빼앗아 씁니다. 그래서 카카오톡과 MCP 서버를 Hyper-V 가상 컴퓨터 하나에 통째로 격리했습니다.
- 로그온하면 시작프로그램의 작은 supervisor(pythonw)가 서버를 띄우고, 죽으면 다시 띄웁니다. 처음엔 숨긴 PowerShell 반복문이었는데 로그온 중 콘솔이 넘어가며 멈춰서 바꿨습니다.
- 운영 제약도 남습니다. VM 화면이 렌더링되지 않으면(창 최소화, 화면 잠금) 키 입력이 갈 곳을 잃기 때문에, 가상 컴퓨터 연결 창은 열어 둬야 합니다.

실제 VM 데스크톱. 카카오톡 창들과 MCP 서버를 관리하는 Claude 세션 터미널이 한 화면에서 돌아갑니다. 개인정보 보호를 위해 나와의 채팅 외에는 흐리게 처리했습니다.
Claude가 쓰는 도구
| 분류 | 도구 | 하는 일 |
|---|---|---|
| 방 | kakao_list_open_rooms · kakao_open_room · kakao_leave_room | 열린 방 목록, 방 열기(검색창 입력), 나가기 |
| 읽기 | kakao_read_messages · kakao_read_board · kakao_extract_links | 메시지를 발신자·시각·날짜로 구조화해 읽기, 톡게시판, 링크 추출 |
| 보내기 | kakao_send_message · kakao_send_mention · kakao_send_image · kakao_send_bulk | 텍스트, @멘션, 이미지, 여러 방 일괄 전송 |
| 오픈채팅 | kakao_openchat_search · kakao_openchat_join · kakao_openchat_create | 검색·참여·개설 (참여 코드, 동의 창 처리 포함) |
| 기록·감시 | kakao_history_* · kakao_start_monitor | 방별 주기 수집과 검색, 키워드 감시 |
- 도구마다 읽기·보내기·방 관리 스코프가 나뉘고, 호출은 감사 로그에 남습니다(메시지 본문은 남기지 않음).
화면을 어떻게 읽고 쓰나
카카오톡 PC는 UI 대부분을 직접 그립니다(EVA_* 창 클래스). 접근성 API로는 거의 보이지 않아서 여러 방법을 섞었습니다.
- 방 찾기: 채팅방은 제목이 방 이름인 최상위 창입니다(EnumWindows). 없으면 메인 창 검색창에 WM_CHAR로 이름을 넣고 Enter.
- 보내기: 입력창(RICHEDIT50W)에 클립보드로 붙여 넣고 Enter. 붙여 넣기 전후 입력창 내용을 비교해 실제로 들어갔는지, 전송 뒤 비었는지 확인합니다. 한글은 IME를 거치지 않도록 WM_CHAR나 붙여 넣기로만 넣습니다.
- 읽기: 메시지 목록에 포커스를 주고 Ctrl+A, Ctrl+C. 복사본은 레코드가 CRLF, 메시지 안 줄바꿈이 LF라서 이걸로 메시지를 나누고 날짜 구분선과 입장·퇴장 줄을 떼어 냅니다.
- 오픈채팅·게시판: 결과 목록·메뉴·다이얼로그가 전부 그려진 화면이라 캡처해서 Windows 내장 OCR(한국어)로 읽습니다. 1px 구분선 픽셀로 항목을 나누고, 글자 밝기로 제목(검정)과 설명(회색)을 가립니다.
- 기록: 카카오톡은 메시지 ID를 주지 않아서 (방, 날짜, 시각, 보낸 사람, 내용, 같은 분 안 순번)으로 중복을 막아 SQLite에 쌓습니다.
부딪힌 문제와 해결
1. 포커스를 잡으려다 링크를 눌렀다
읽기 전에 메시지 목록 가운데를 클릭했더니 링크나 사진이 눌려 「이 링크에 연결할까요?」 모달이 떴습니다. 모달 때문에 방 창이 앞으로 오지 못해 그 방 수집이 계속 실패했습니다.
→ 클릭하지 않습니다. AttachThreadInput + SetFocus로 키보드 포커스만 옮기고, 작업 전후 최상위 창 목록을 비교해 새로 열린 브라우저 창·탭·확인 창을 닫습니다. WM_CLOSE는 비동기라 창이 실제로 사라질 때까지 기다린 뒤 포커스를 돌려야 엉뚱한 창이 앞으로 오지 않습니다.
2. 다른 방 대화가 섞여 저장됐다
클립보드와 포커스는 프로세스 사이에 공유되는데 잠금은 프로세스 안에서만 걸려 있었습니다. 별도 프로세스의 테스트가 서버의 주기 수집과 겹치면서 한 방의 대화가 다른 방 이름으로 저장됐습니다. 클립보드 소유자는 어느 방이든 카톡 메인 창이라 출처 확인에도 못 썼습니다.
→ 이름 있는 뮤텍스로 모든 UI 작업을 프로세스 간 직렬화하고, 복사 직후 그 방 창이 여전히 앞에 있는지 확인합니다. 저장 전에는 최근 메시지가 다른 한 방에만 이미 있으면 저장을 거부합니다.
3. 빈 복사
대화가 많은 방에서는 Ctrl+A 선택이 끝나기 전에 Ctrl+C가 들어가 아무것도 복사되지 않았습니다. → 선택 대기를 0.3초, 1초, 2초로 늘려 가며 재시도합니다.
4. 오픈채팅 입장 중 멈춤
커뮤니티 방의 「커뮤니티 시작하기」 동의 창, 제목조차 없는 세이프봇 동의 창이 입장을 막았습니다. → OCR로 창을 알아보고, 명시적으로 동의 옵션을 줬을 때만 「동의」, 기본은 「취소」하고 이유를 돌려줍니다. 사용자 결정이 필요한 동의라 일부러 기본값을 거절로 뒀습니다.
5. OCR은 숫자를 자주 틀린다
작은 글씨는 2~3배 확대해야 하고, 시각의 콜론이 빠지거나 「톡게시판」을 「특기시단」으로 읽습니다. 메뉴는 글자 대신 "「채팅방 서랍」 바로 아래 항목"처럼 위치로 찾습니다.
여러 Claude 세션이 함께 일한다
지금은 서버 하나를 여러 Claude 세션이 같이 씁니다. 도구를 쓰는 세션이 문제를 발견하면 서버를 고치는 세션에 메시지로 알리고, 그쪽이 고쳐 재배포합니다.
이 글도 그렇게 만들었습니다. 글을 쓰는 세션이 프로필 사진 변경을 부탁하고, 시연 메시지를 보내고 읽다가 읽기 버그 두 개를 찾아 알렸습니다.
- 빈 방 오보고: 메시지가 없는 방을 읽으면 "창을 앞으로 가져올 수 없음" 오류가 났습니다. → 빈 방은 0건 성공으로 돌려주도록 고쳤습니다.
- 마지막 메시지 누락: 메시지가 2건이면 1건, 3건이면 2건만 읽혔습니다. Ctrl+A 직후 너무 일찍 Ctrl+C를 누르면 선택이 앞쪽 말풍선까지만 잡힌 채 굳어서, 두 번 복사해 비교해도 둘 다 같은 부분 복사가 나왔기 때문입니다. → 매번 Ctrl+A부터 다시 선택하고 대기를 0.5→1→2→3초로 늘려, 연속한 두 번의 「전체 선택 후 복사」가 같아야 받아들이도록 바꿨습니다. 읽기 한 번이 2~4.5초로 느려진 대신, 1,000건이 넘는 방도 여러 번 읽어 모두 일치했습니다.
큰 방에서는 다음 수집 때 빠진 메시지가 채워져서 티가 나지 않던 버그였습니다. 메시지가 세 개뿐인 나와의 채팅에서 시연하다 보니 바로 드러났습니다.
좌표는 카카오톡 PC 26.9, 배율 100% 기준이라 버전이나 배율이 바뀌면 다시 맞춰야 합니다. 화면 자동화는 결국 그런 유지보수를 감수하는 선택입니다. 그래도 API가 없는 도구를 AI의 손에 쥐여 줄 수 있다는 점에서, 충분히 해 볼 만한 일이었습니다.