<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>MCP on To the Moon</title><link>https://junstellar.github.io/tags/mcp/</link><description>Recent content in MCP on To the Moon</description><generator>Hugo -- gohugo.io</generator><language>ko-kr</language><lastBuildDate>Tue, 14 Jul 2026 12:00:00 +0900</lastBuildDate><atom:link href="https://junstellar.github.io/tags/mcp/index.xml" rel="self" type="application/rss+xml"/><item><title>@멘션 한 번이면 클로드가 답한다 — 디스코드로 만든 팀 AI 비서</title><link>https://junstellar.github.io/p/discord-claude-mention-bot/</link><pubDate>Tue, 14 Jul 2026 12:00:00 +0900</pubDate><guid>https://junstellar.github.io/p/discord-claude-mention-bot/</guid><description>&lt;h2 id="시작은-슬랙이었다"&gt;시작은 슬랙이었다
&lt;/h2&gt;&lt;p&gt;팀 프로젝트 관리용으로 &amp;ldquo;메신저에서 클로드를 태그로 불러 쓰는&amp;rdquo; 환경을 만들고 싶었다.
슬랙에 클로드를 붙이는 공식 기능(Claude in Slack, 이른바 클로드 태그)이 이미 있어서
그걸 쓰려고 했는데 — &lt;strong&gt;팀 플랜을 요구했다.&lt;/strong&gt; 혼자 쓰거나 소규모로 굴리는 입장에선
기능 하나 때문에 요금제를 통째로 올리는 게 납득이 안 됐다.&lt;/p&gt;
&lt;p&gt;그래서 &amp;ldquo;그럼 내가 쓰는 메신저에 직접 붙이자&amp;quot;로 방향을 틀었고, 후보를 좁혔다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;카카오톡&lt;/strong&gt; — 탈락. 일반 채팅방에 붙일 봇 API가 아예 없다.
오픈빌더는 1:1 채널 챗봇 전용이고, 비공식 자동화는 계정 정지 위험이 있다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;텔레그램&lt;/strong&gt; — 공식 봇 API가 가장 간단하고 진입장벽이 낮다. 다만 대화가 한 줄기라
여러 주제를 동시에 굴리면 금방 뒤엉킨다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;디스코드&lt;/strong&gt; — 최종 선택.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;디스코드를 고른 이유는 명확했다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;스레드 구조.&lt;/strong&gt; 멘션 하나에 스레드가 하나 생기니 주제별로 문맥이 자연스럽게 분리된다.
이게 뒤에 나올 &lt;code&gt;--resume&lt;/code&gt; 세션 매핑과 정확히 맞아떨어진다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;채널 분리.&lt;/strong&gt; 업무/메모/일정처럼 용도별 채널을 나눠 쓸 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;첨부파일과 코드블록을 제대로 다룬다.&lt;/strong&gt; 파일 올리고 바로 &amp;ldquo;이거 분석해줘&amp;quot;가 된다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;봇 권한을 세밀하게 준다.&lt;/strong&gt; 어떤 채널에서 뭘 할 수 있는지 서버 단위로 통제된다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;슬래시 명령이 1급 시민.&lt;/strong&gt; &lt;code&gt;/일정등록&lt;/code&gt; 같은 걸 자동완성·인자 검증까지 붙여 만들 수 있다.&lt;/li&gt;
&lt;li&gt;무료이고, PC·모바일 클라이언트가 다 있어서 나가서도 그대로 쓴다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="핵심-아키텍처"&gt;핵심 아키텍처
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;디스코드 @멘션 → discord.py 봇 → claude -p (headless Claude Code) → 응답 전송
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;claude -p --output-format json&lt;/code&gt;은 응답과 함께 &lt;code&gt;session_id&lt;/code&gt;를 돌려준다.
이걸 디스코드 스레드 ID와 매핑해 저장해두고, 다음 메시지에 &lt;code&gt;--resume &amp;lt;session_id&amp;gt;&lt;/code&gt;를
붙이면 &lt;strong&gt;스레드마다 대화 문맥이 유지&lt;/strong&gt;된다.&lt;/li&gt;
&lt;li&gt;Claude Code에 구독(Pro/Max) 로그인이 되어 있으면 &lt;code&gt;claude -p&lt;/code&gt;는 구독량으로 처리되어
&lt;strong&gt;Anthropic API 결제가 필요 없다.&lt;/strong&gt; 슬랙 쪽에서 막혔던 요금 문제가 여기서 사라진다.&lt;/li&gt;
&lt;li&gt;headless 모드에서도 그 PC에 설정된 &lt;strong&gt;MCP 서버와 스킬을 전부 그대로 인식한다.&lt;/strong&gt;
내 PC에서 쓰던 환경이 그대로 디스코드로 나오는 셈이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="예상-못-한-수확-로컬-메모-동기화가-같이-풀렸다"&gt;예상 못 한 수확: 로컬 메모 동기화가 같이 풀렸다
&lt;/h2&gt;&lt;p&gt;옵시디언처럼 &lt;strong&gt;메모를 로컬 파일로 쌓아두고 있었는데&lt;/strong&gt;, 이걸 폰에서도 보려면
어느 서비스든 결국 유료 동기화 플랜을 권한다. 슬랙 때와 똑같은 벽이다.&lt;/p&gt;
&lt;p&gt;그런데 이 봇을 붙이고 나니 그 문제가 통째로 사라졌다.
메모 파일은 계속 내 PC에 로컬로 있고, 디스코드에서 멘션 한 번이면
클로드가 그 파일들을 읽어서 답한다. &lt;strong&gt;동기화를 할 필요가 없다 —
파일을 옮기는 게 아니라, 파일이 있는 곳에 질문을 보내는 구조이기 때문이다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;여기에 MCP를 얹으면 더 좋아진다. 레드마인 같은 사내 시스템을 MCP로 물려두면,
봇이 일정과 이슈를 조회해서 &lt;strong&gt;디스코드 채팅에 보기 좋게 정리해 뿌려준다.&lt;/strong&gt;
로컬 메모 + MCP 데이터를 한 자리에서 묶어 요약해주니, 별도 대시보드를 안 만들어도
&amp;ldquo;오늘 뭐 있지&amp;quot;가 채팅 한 줄로 끝난다.&lt;/p&gt;
&lt;h2 id="봇-기능"&gt;봇 기능
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;멘션 → 스레드 자동 생성 후 답변&lt;/li&gt;
&lt;li&gt;첨부파일 자동 다운로드 후 클로드가 Read 도구로 분석&lt;/li&gt;
&lt;li&gt;슬래시 명령(&lt;code&gt;/일정등록&lt;/code&gt;, &lt;code&gt;/일정목록&lt;/code&gt;, &lt;code&gt;/일정삭제&lt;/code&gt;)으로 일정 알림
(마감 전날 1회 + 당일 매시간 반복, 삭제 = 완료 처리)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="디스코드에서 슬래시 명령으로 일정을 등록하고, 봇이 마감일과 D-day를 정리해 보여주는 화면" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://junstellar.github.io/images/discord-bot/claudetag-schedule-ko.png"&gt;&lt;/p&gt;
&lt;h2 id="보안-설계"&gt;보안 설계
&lt;/h2&gt;&lt;p&gt;봇이 있는 서버의 &lt;strong&gt;모든 멤버가 내 PC의 클로드를 쓰게 되므로&lt;/strong&gt; 도구를 잠가야 한다.
&lt;code&gt;--allowedTools&lt;/code&gt;를 읽기/검색 계열(Read, Glob, Grep, WebSearch, WebFetch)과
허용할 MCP 도구(&lt;code&gt;mcp__redmine__list_issues&lt;/code&gt; 등)로만 제한하고,
Bash·Write·Edit 같은 실행/쓰기 도구는 막았다.&lt;/p&gt;
&lt;h2 id="디스코드-봇-등록-절차"&gt;디스코드 봇 등록 절차
&lt;/h2&gt;&lt;p&gt;개발자 포털에서:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;New Application → Bot 메뉴에서 토큰 발급&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MESSAGE CONTENT INTENT 스위치 켜기&lt;/strong&gt; — 안 켜면 봇이 메시지를 못 읽는다. 최다 실수 포인트.&lt;/li&gt;
&lt;li&gt;OAuth2 URL Generator에서 &lt;code&gt;bot&lt;/code&gt; 스코프 + 필요한 권한 체크&lt;/li&gt;
&lt;li&gt;생성된 URL로 서버 초대&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;다른 클로드 구독자도 자기 토큰과 자기 구독으로 돌릴 수 있게
zip(봇 코드 + &lt;code&gt;.env.example&lt;/code&gt; + 설치 가이드 + &lt;code&gt;setup.bat&lt;/code&gt;)으로 묶어뒀다.
setup.bat이 Python(winget)·discord.py 설치와 설정 파일 생성까지 자동화하고,
계정이 필요한 부분(디스코드 토큰 발급, 클로드 로그인)만 수동으로 남는다.&lt;/p&gt;
&lt;h2 id="막혔던-점과-해결"&gt;막혔던 점과 해결
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;스토어(MSIX) 설치 Python은 AppData가 가상화&lt;/strong&gt;되어 &lt;code&gt;%APPDATA%\Claude\claude-code\&lt;/code&gt;의
claude.exe를 못 읽는다 (PowerShell에선 보이는데 Python에선 FileNotFoundError).
→ claude.exe를 AppData 밖 폴더로 복사해서 해결. 단독 실행파일이라 복사만으로 동작.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;배치 파일에 한글을 넣으면 cmd가 명령을 깨뜨린다&lt;/strong&gt; (&lt;code&gt;chcp 65001&lt;/code&gt; 이후 파서가 바이트
오프셋을 잘못 읽어 &lt;code&gt;'laudeBot'은(는)...&lt;/code&gt; 같은 유령 오류 발생). → bat 파일은 ASCII만 사용.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PowerShell 파이프로 한글을 넘기면 인코딩이 깨진다.&lt;/strong&gt; → 파이썬 subprocess에서
UTF-8 바이트로 stdin에 직접 쓰면 안전. 파이썬 실행도 &lt;code&gt;-u&lt;/code&gt;(unbuffered) + &lt;code&gt;PYTHONUTF8=1&lt;/code&gt; 필수
(안 하면 print가 버퍼에 갇혀 로그가 안 보이거나 이모지 출력에서 죽는다).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;봇을 AI 세션의 백그라운드 프로세스로 띄우면 세션이 끝날 때 봇도 같이 죽는다.&lt;/strong&gt;
→ bat 더블클릭으로 독립 콘솔에서 실행해야 한다. 콘솔 창 닫으면 봇 종료, 최소화는 OK.&lt;/li&gt;
&lt;li&gt;같은 봇 토큰으로 프로세스를 2개 띄우면 게이트웨이에 둘 다 붙어서 &lt;strong&gt;답장이 중복&lt;/strong&gt;된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="메모생각"&gt;메모/생각
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;결국 세 번의 &amp;ldquo;유료 플랜을 쓰세요&amp;quot;를 같은 방법 하나로 넘겼다.
슬랙 클로드 태그(팀 플랜), 메모 동기화(구독), API 결제 —
&lt;strong&gt;내 PC에서 도는 봇 하나&lt;/strong&gt;로 셋 다 정리됐다.&lt;/li&gt;
&lt;li&gt;핵심은 클로드를 어디 올려두는 게 아니라, 이미 내 PC에 갖춰둔 환경(MCP·스킬·로컬 파일)에
&lt;strong&gt;메신저라는 입구를 하나 뚫어준 것&lt;/strong&gt;이다. 그래서 새로 설정할 게 거의 없었다.&lt;/li&gt;
&lt;li&gt;다음에 해볼 것: 부팅 시 자동 시작 등록, 스레드별 도구 권한 분리.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Redmine MCP 서버 직접 만들기 — 일주일의 기록</title><link>https://junstellar.github.io/p/redmine-mcp-server/</link><pubDate>Mon, 29 Jun 2026 22:00:00 +0900</pubDate><guid>https://junstellar.github.io/p/redmine-mcp-server/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;💻 &lt;strong&gt;바로 설치:&lt;/strong&gt; &lt;code&gt;pipx install git+https://github.com/junstellar/redmine-mcp-jun.git&lt;/code&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;Claude Code가 사내 Redmine을 직접 읽고 쓰게 만들고 싶었다. 그런데 우리 Redmine은 사설망에 있어 Atlassian·GitHub 같은 외부 SaaS 커넥터를 못 쓴다. 그래서 내 PC에서만 도는 로컬 MCP 서버를 직접 만들었다. 단일 파일에서 시작해 pip 패키지로 키운 일주일의 기록이다.&lt;/p&gt;
&lt;h2 id="mcp가-뭔지-도구를-어떻게-짰나"&gt;MCP가 뭔지, 도구를 어떻게 짰나
&lt;/h2&gt;&lt;p&gt;MCP(Model Context Protocol)는 &amp;lsquo;AI와 외부 도구를 잇는&amp;rsquo; 표준이다. USB처럼, 표준만 맞추면 어떤 도구든 LLM에 꽂아 쓸 수 있다.&lt;/p&gt;
&lt;p&gt;서버를 클라이언트에 붙이는 방식은 크게 둘이다. &lt;strong&gt;stdio&lt;/strong&gt;는 서버를 사용자 PC에서 로컬 프로세스로 띄워 같은 PC 안에서만 주고받는 방식이고, **HTTP(원격)**는 서버를 따로 호스팅해 네트워크로 붙는 방식이다. 원격 방식은 한 번 띄워두면 여러 명이 같이 쓰기 좋지만, 서버 운영과 인증·키 관리를 따로 챙겨야 한다. 나는 사내에서 내가 직접 설치해 쓸 거라, 키가 내 PC 밖으로 안 나가고 설치도 간단한 &lt;strong&gt;stdio 방식&lt;/strong&gt;으로 했다.&lt;/p&gt;
&lt;p&gt;내가 만들 Redmine 연동에서 코드보다 먼저 한 일은 &amp;ldquo;LLM이 이걸로 뭘 할 수 있어야 하나&amp;quot;를 적어보는 거였다. 막상 적어보니 평소 Redmine에서 하는 일이 그리 많지 않았다 — 내 일감 확인, 이슈 검색·열람, 이슈 만들기, 댓글 달기, 위키 보고 고치기 정도. 거기에 맞춰 도구 10개를 추렸다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;도구&lt;/th&gt;
					&lt;th&gt;역할&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;list_projects&lt;/code&gt; / &lt;code&gt;list_issues&lt;/code&gt; / &lt;code&gt;get_issue&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;프로젝트·이슈 조회&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;create_issue&lt;/code&gt; / &lt;code&gt;add_comment&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;이슈 생성·댓글&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;list_wiki_pages&lt;/code&gt; / &lt;code&gt;get_wiki&lt;/code&gt; / &lt;code&gt;update_wiki&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;위키&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;get_my_today&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&amp;lsquo;오늘 내 일감&amp;rsquo; 단축&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;list_enumerations&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;우선순위·상태 ID&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;여기서 하나 배웠다. &lt;code&gt;get_my_today&lt;/code&gt;처럼 자주 쓰는 흐름은 전용 도구로 빼두면 LLM이 훨씬 잘 골라 쓴다. 그리고 만들면서 챙긴 세 가지 — 도구 설명은 풍부하게(짧으면 엉뚱한 걸 부른다), 입력 스키마는 빡빡하게, 응답은 JSON 그대로 넘기기.&lt;/p&gt;
&lt;h2 id="진짜-어려운-건-코드가-아니라-배포였다"&gt;진짜 어려운 건 코드가 아니라 배포였다
&lt;/h2&gt;&lt;p&gt;처음엔 파일 하나(약 420줄)로 빠르게 동작부터 확인했다. 정작 시간을 잡아먹은 건 &amp;ldquo;남 PC에 어떻게 깔지&amp;quot;였다. OS별 경로 분기에, Python 3.12의 PEP 668로 &lt;code&gt;pip install&lt;/code&gt;이 막히는 환경까지 겹쳤다. 결국 pip 패키지로 갈아엎고 pipx 설치로 정리하니, 어느 OS든 두 줄로 끝났다.&lt;/p&gt;
&lt;p&gt;가장 신경 쓴 건 Claude 설정 파일(&lt;code&gt;.claude.json&lt;/code&gt;)을 건드리는 부분이었다. 다른 MCP 설정도 같이 든 공유 파일이라, 수정 전 무조건 백업을 뜨게 했다(실제로 한 번 사고 났는데 바로 복구됐다). 실행 경로도 &lt;code&gt;python&lt;/code&gt; 대신 절대경로로 박아 파이썬 버전이 바뀌어도 안 깨지게 했다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;막힘&lt;/th&gt;
					&lt;th&gt;해결&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;PEP 668로 &lt;code&gt;pip install&lt;/code&gt; 거부&lt;/td&gt;
					&lt;td&gt;pipx로 전환&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;파이썬 업그레이드 후 MCP 안 뜸&lt;/td&gt;
					&lt;td&gt;실행 명령을 절대경로로&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;설정 머지하다 다른 항목 날림&lt;/td&gt;
					&lt;td&gt;수정 전 백업 강제&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;LLM이 단축 도구 안 부르고 우회&lt;/td&gt;
					&lt;td&gt;description에 키워드 보강&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="정리"&gt;정리
&lt;/h2&gt;&lt;p&gt;MCP 서버 만들기 자체는 의외로 쉽다(파이썬 400줄). 어려운 건 &lt;em&gt;배포&lt;/em&gt;, &lt;em&gt;키 관리&lt;/em&gt;, 그리고 &lt;em&gt;LLM이 잘 골라 쓰게 만드는 description 튜닝&lt;/em&gt; — 이 셋이다. 미리 고민하고 들어가면 며칠이면 된다.&lt;/p&gt;
&lt;p&gt;필요한 사람을 위해 코드는 레포에 올려뒀으니(&lt;a class="link" href="https://github.com/junstellar/redmine-mcp-jun" target="_blank" rel="noopener"
 &gt;github.com/junstellar/redmine-mcp-jun&lt;/a&gt;, MIT) 받아 써도 된다. 그래도 한 번쯤은 &lt;strong&gt;직접 만들어보는 걸 추천한다.&lt;/strong&gt; 새 일감이 등록되면 알려주는 알림, 들어온 일감을 자동으로 분석해 회신 댓글을 다는 봇처럼 — 자기한테 필요한 걸 직접 붙여보면 훨씬 많이 남는다.&lt;/p&gt;</description></item></channel></rss>