Claude Code에서 /mcp를 열었더니 Slack MCP가 빨간 X와 함께 failed. 분명 설정했는데 왜 안 되지? 원인 찾기부터 해결까지의 기록.
증상
Manage MCP servers
3 servers
Project MCPs (/Users/elon/.../contents_hub/.mcp.json)
contents-hub · ✅ connected
User MCPs (/Users/elon/.claude.json)
context7 · ✅ connected
slack · ❌ failed
context7은 되는데 slack만 안 된다.
첫 번째 삽질: 설정 파일을 못 찾다
"Slack MCP 설정 확인해줘"라고 했더니, Claude가 열심히 찾아본 결과:
- 프로젝트
.mcp.json— contents-hub만 있음 ~/.claude/plugins/installed_plugins.json— slack 항목 없음- 마켓플레이스 플러그인 정의 — SSE 방식(
https://mcp.slack.com/sse)만 있음
결론: "설치되어 있지 않습니다"
그런데 /mcp 화면에는 분명히 slack이 보인다. User MCPs라고 적혀 있고, 경로는 /Users/elon/.claude.json.
진짜 설정 위치: ~/.claude.json
Claude Code의 User-level MCP 설정은 ~/.claude.json 파일 안의 mcpServers 섹션에 있다.
{
"mcpServers": {
"context7": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"],
"env": {}
},
"slack": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": {
"SLACK_BOT_TOKEN": "xoxb-..."
}
}
}
}
이 파일은 5만 토큰이 넘는 거대한 JSON이라 전체 읽기가 안 되고, grep slack으로 찾아야 했다.
원인: SLACK_TEAM_ID 누락
@modelcontextprotocol/server-slack 패키지는 두 가지 환경변수가 둘 다 필요하다:
| 환경변수 | 용도 | 상태 |
|---|---|---|
SLACK_BOT_TOKEN |
Bot 인증 | 설정됨 |
SLACK_TEAM_ID |
워크스페이스 식별 | 누락 |
토큰만 넣고 Team ID를 안 넣어서 서버 초기화에 실패한 것.
Team ID 찾기
Bot Token이 유효한지부터 확인:
curl -s -H "Authorization: Bearer xoxb-..." https://slack.com/api/auth.test
{
"ok": true,
"url": "https://chequer.slack.com/",
"team": "QueryPie AI",
"team_id": "T03L6852Y",
"user": "claudenotification",
"bot_id": "B0ADT281XK4"
}
토큰은 살아있고, Team ID는 T03L6852Y.
해결
~/.claude.json의 slack MCP 설정에 SLACK_TEAM_ID 추가:
"slack": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": {
"SLACK_BOT_TOKEN": "xoxb-...",
"SLACK_TEAM_ID": "T03L6852Y"
}
}
Claude Code 재시작 후 /mcp 확인 — slack · ✅ connected.
SSE vs stdio: 어떤 방식이 좋을까
Slack MCP에는 두 가지 연결 방식이 있다.
SSE (Server-Sent Events) — 공식
{
"slack": {
"type": "sse",
"url": "https://mcp.slack.com/sse"
}
}
Slack이 직접 운영하는 원격 서버. 별도 토큰 설정 없이 OAuth 브라우저 인증.
stdio — 커뮤니티
{
"slack": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": {
"SLACK_BOT_TOKEN": "xoxb-...",
"SLACK_TEAM_ID": "T..."
}
}
}
로컬에서 subprocess로 실행. Bot Token을 직접 관리.
비교
| SSE (공식) | HTTP (OAuth) | stdio (커뮤니티) | |
|---|---|---|---|
| 안정성 | Slack 서버 의존 | Slack 서버 의존 | 로컬 실행 |
| 인증 | OAuth (DCR) | OAuth (Client ID) | Bot 토큰 설정 |
| CLI 지원 | DCR 미지원으로 실패 | Redirect URL 불일치로 실패 | 동작함 |
| 채널 접근 | 사용자 전체 | 사용자 전체 | Bot 초대 필요 |
개인 프로젝트에서는 stdio 방식이 편하다. 토큰 한 번 설정하면 끝이고, 오프라인에서도 동작하니까.
실제로 SSE를 시도해봤다
stdio가 연결된 후, "SSE로 바꾸면 Bot 초대 없이 내가 가입한 모든 채널을 읽을 수 있지 않을까?" 하는 욕심이 생겼다. Bot은 초대된 채널만 접근 가능하지만, SSE는 사용자 본인의 OAuth 인증이니까.
설정을 변경하고 Claude Code를 재시작했더니:
Slack MCP Server
Status: ❌ failed
Auth: ❌ not authenticated
URL: https://mcp.slack.com/sse
Error: Incompatible auth server: does not support dynamic client registration
SSE 방식은 Claude Code CLI에서 작동하지 않는다. dynamic client registration을 지원하지 않기 때문.
그럼 HTTP + OAuth는?
DCR 문제를 우회할 수 있는 방법이 있었다. Claude Code v2.1.30+에서 --client-id/--client-secret 플래그 지원:
claude mcp remove slack
MCP_CLIENT_SECRET="your-secret" claude mcp add --transport http slack https://mcp.slack.com/mcp \
--client-id YOUR_SLACK_CLIENT_ID \
--client-secret \
--callback-port 8976
설정은 성공. /mcp에서 Authenticate를 누르면 브라우저가 열리면서 Slack OAuth 화면이 나온다. 그런데:
redirect_uri did not match any configured URIs.
Passed URI: http://localhost:8976/callback
Claude Code는 콜백에 항상 HTTP를 사용하는데, Slack App의 Redirect URL에는 HTTPS만 등록 가능했다. https://localhost:8976/callback은 등록되지만, Claude Code가 보내는 건 http://라서 불일치.
--callback-scheme, --https 같은 옵션? 없다. claude mcp add --help에 HTTP 콜백을 HTTPS로 바꾸는 방법은 존재하지 않는다.
결론: HTTP(OAuth) 방식도 현재로서는 사용 불가. stdio로 복원.
Bot의 채널 접근 제한
stdio 방식의 한 가지 제약: Bot은 초대된 채널만 접근할 수 있다.
/invite @Claude-Notification # 각 채널에서 실행
Private 채널도 읽으려면 Slack App에 추가 scope가 필요:
groups:history— private 채널 메시지 읽기groups:read— private 채널 목록 조회
Scope 추가 후 Slack App 설정 페이지에서 Reinstall to Workspace 클릭.
Slack Bot 필요 권한 (Scopes)
Slack App의 OAuth & Permissions에서 아래 Bot Token Scopes가 필요:
channels:history— 채널 메시지 읽기channels:read— 채널 목록 조회chat:write— 메시지 보내기reactions:read— 이모지 리액션 읽기users:read— 사용자 정보 조회
추가로 유용한 scope:
incoming-webhook— 웹훅으로 메시지 전송
Private 채널 접근용 (필요 시):
groups:history— private 채널 메시지 읽기groups:read— private 채널 목록 조회
교훈
- Claude Code MCP 설정 위치는 3곳: 프로젝트(
.mcp.json), 유저(~/.claude.json), 플러그인(~/.claude/plugins/) ~/.claude.json은 거대하다: 전체 읽기보다 grep으로 검색- 환경변수 하나가 전체를 막는다:
SLACK_TEAM_ID하나 빠졌을 뿐인데 failed auth.testAPI로 토큰 검증: 토큰 유효성 + Team ID를 한 번에 확인- SSE는 CLI에서 안 된다:
dynamic client registration미지원 에러 - HTTP(OAuth)도 안 된다: Claude Code 콜백이 HTTP인데, Slack은 HTTPS만 허용
- stdio가 유일한 선택 (2026-02 기준): 3가지 방식 중 CLI에서 동작하는 건 stdio뿐
- Private 채널은 추가 scope 필요:
groups:history,groups:read+ 앱 재설치