Joyuno's Dev Blog

2026-04-01 (수) 개발일지

dev-blog

오늘의 삽질: Discord 봇이 메시지는 보내는데 실시간 수신은 안 되는 문제

오늘은 votr 프로젝트의 Discord 봇 연결 문제를 해결하느라 하루를 보냈다. 분명히 봇은 온라인 상태고, 메시지 기록도 잘 불러오고, 답장도 잘 보내는데 정작 사용자가 디스코드에서 보낸 새 메시지가 실시간으로 전달되지 않는 이상한 현상이었다.

Discord MCP 연결의 실시간 수신 문제

문제: 봇이 온라인 상태이고 /mcp reconnect도 여러 번 시도했는데, Discord에서 보낸 새 메시지가 Claude 세션으로 전달되지 않음. 메시지 기록 조회(fetch)와 답장(reply)은 정상 작동.

시도: 처음에는 MCP 재연결이 해결책일 거라고 생각했다. /mcp 명령어로 Discord 연결을 재시도했지만, 여전히 실시간 수신이 안 됐다. “혹시 기존 프로세스가 남아있나?” 싶어서 kill하고 재시작해봤지만 같은 현상이 반복됐다.

해결 과정: 로그를 자세히 살펴보는 중 결정적인 단서를 발견했다.

ps aux | grep -i discord | grep -v grep
# PID 41875: bun으로 실행 중인 Discord MCP 프로세스

lsof -i -P | grep -i node | grep -i ESTABLISHED
# Discord Gateway(104.16.3.34)에 대한 WebSocket 연결이 없음!

여기서 깨달았다. bun 프로세스(PID 41875)에는 Discord Gateway와의 WebSocket 연결이 전혀 없었다. 오직 unix 소켓(MCP stdio)만 존재했을 뿐.

실시간 메시지 수신의 흐름을 분석해보니:

  • fetch_messages, reply → REST API 사용 → 작동함
  • 실시간 messageCreate → WebSocket Gateway 연결 필요 → 연결 없음 → 실패

배운 점: Discord 봇의 두 가지 연결 방식(REST API vs WebSocket Gateway)을 명확히 이해하게 됐다. 봇이 “온라인”으로 보인다고 해서 실시간 수신이 가능한 건 아니다. WebSocket 연결이 별도로 필요하다는 사실을 깨달았다.

MCP 프로세스의 네트워크 상태 진단

문제: 왜 WebSocket 연결이 없을까? MCP 재연결을 했는데도 계속 실패 메시지가 뜸.

시도: settings.local.json을 확인해봤다. 설정은 정상이었다:

{
  "mcpServers": {
    "discord": {
      "command": "bun",
      "args": ["~/.claude/channels/discord/server.ts"],
      "env": {
        "DISCORD_TOKEN": "정상적인_토큰",
        "CHANNEL_ID": "1485825896102367365"
      }
    }
  }
}

해결: 다른 세션에서 동일한 봇 토큰을 사용하고 있지 않은지 확인했다. 만약 다른 곳에서 같은 토큰으로 WebSocket 연결을 맺고 있다면, Discord는 중복 연결을 허용하지 않는다.

lsof 결과를 다시 보니, node 프로세스 41689가 Discord Gateway에 여러 연결을 가지고 있었다. 이게 다른 세션의 프로세스일 가능성이 있었다.

배운 점: Discord 봇 토큰은 동시에 하나의 WebSocket 연결만 가질 수 있다. “이미 연결됨” 상태에서 MCP 재연결을 해봤자 소용없다. 먼저 기존 연결을 찾아서 정리해야 한다.

설정 파일의 분리와 관리

문제: votr 프로젝트 전용 Discord 설정을 별도로 관리할 수 없을까?

시도: 기본 discord/ 디렉토리 대신 프로젝트별 설정을 만들려고 했다. .claude/settings.local.json을 프로젝트 루트에 두고 관리하는 방식.

해결: 결국 프로젝트별 .claude 디렉토리를 만들고, 그 안에 settings.local.json을 구성했다. 이렇게 하면:

  1. 프로젝트마다 다른 채널 ID 설정 가능
  2. Git으로 설정 관리 용이
  3. 다른 개발자와 공유 시 설정 포함 가능

배운 점: MCP 서버 설정도 프로젝트 단위로 분리하는 게 협업과 유지보수에 좋다. 특히 채널 ID나 환경별 토큰이 다를 수 있는 경우 필수적이다.

오늘의 한줄

“Discord 봇이 메시지는 보내는데 안 받는 건, 전화는 걸 수 있지만 벨소리를 듣지 못하는 것과 같다 - WebSocket 연결이 있어야 실시간 통신이 가능하다.”