Skip to main content
Glama
README.md
# πŸš€ Slack MCP Server

FastMCPλ₯Ό μ‚¬μš©ν•œ μ™„μ „ν•œ Slack 톡합 MCP μ„œλ²„μž…λ‹ˆλ‹€. Cursor IDEμ—μ„œ Slack API의 λͺ¨λ“  κΈ°λŠ₯을 μžμ—°μ–΄λ‘œ μ‚¬μš©ν•  수 있게 ν•΄μ€λ‹ˆλ‹€.

## πŸ“‹ λͺ©μ°¨

- [νŠΉμ§•](#-νŠΉμ§•)
- [μš”κ΅¬μ‚¬ν•­](#-μš”κ΅¬μ‚¬ν•­)
- [λΉ λ₯Έ μ„€μΉ˜](#-λΉ λ₯Έ-μ„€μΉ˜)
- [μˆ˜λ™ μ„€μΉ˜](#-μˆ˜λ™-μ„€μΉ˜)
- [μ‚¬μš©λ²•](#-μ‚¬μš©λ²•)
- [μ‚¬μš© κ°€λŠ₯ν•œ 도ꡬ](#-μ‚¬μš©-κ°€λŠ₯ν•œ-도ꡬ)
- [ν”„λ‘œμ νŠΈ ꡬ쑰](#-ν”„λ‘œμ νŠΈ-ꡬ쑰)
- [개발자 κ°€μ΄λ“œ](#-개발자-κ°€μ΄λ“œ)
- [문제 ν•΄κ²°](#-문제-ν•΄κ²°)
- [λΌμ΄μ„ μŠ€](#-λΌμ΄μ„ μŠ€)

## ✨ νŠΉμ§•

### ν•„μˆ˜ κΈ°λŠ₯ (과제 μš”κ΅¬μ‚¬ν•­)
- βœ… **λ©”μ‹œμ§€ 전솑**: 채널에 λ©”μ‹œμ§€ 전솑
- βœ… **채널 λͺ©λ‘ 쑰회**: μ ‘κ·Ό κ°€λŠ₯ν•œ λͺ¨λ“  채널 쑰회
- βœ… **채널 νžˆμŠ€ν† λ¦¬ 쑰회**: μ§€μ •λœ μ±„λ„μ˜ λ©”μ‹œμ§€ νžˆμŠ€ν† λ¦¬
- βœ… **λ‹€μ΄λ ‰νŠΈ λ©”μ‹œμ§€**: 1:1 λ©”μ‹œμ§€ 전솑

### μΆ”κ°€ κΈ°λŠ₯
- βœ… **μ‚¬μš©μž λͺ©λ‘ 쑰회**: μ›Œν¬μŠ€νŽ˜μ΄μŠ€ μ‚¬μš©μž 정보
- βœ… **λ°˜μ‘ μΆ”κ°€**: λ©”μ‹œμ§€μ— 이λͺ¨μ§€ λ°˜μ‘ μΆ”κ°€
- βœ… **λ©”μ‹œμ§€ 검색**: ν‚€μ›Œλ“œ 기반 λ©”μ‹œμ§€ 검색
- βœ… **μ—°κ²° ν…ŒμŠ€νŠΈ**: API μ—°κ²° μƒνƒœ 확인

### 기술적 νŠΉμ§•
- πŸš€ **FastMCP 기반**: μ΅œμ‹  MCP ν”„λ ˆμž„μ›Œν¬ μ‚¬μš©
- ⚑ **비동기 처리**: aiohttpλ₯Ό μ΄μš©ν•œ κ³ μ„±λŠ₯ API 호좜
- πŸ›‘οΈ **μ™„μ „ν•œ μ—λŸ¬ 처리**: μƒμ„Έν•œ 였λ₯˜ λ©”μ‹œμ§€μ™€ 볡ꡬ κ°€λŠ₯ν•œ μ˜ˆμ™Έ 처리
- πŸ“ **νƒ€μž… 힌트**: μ™„μ „ν•œ νƒ€μž… μ•ˆμ •μ„±
- πŸ§ͺ **포괄적 ν…ŒμŠ€νŠΈ**: μžλ™ν™”λœ ν…ŒμŠ€νŠΈ μŠ€μœ„νŠΈ
- πŸ“Š **λ‘œκΉ…**: κ΅¬μ‘°ν™”λœ λ‘œκΉ… μ‹œμŠ€ν…œ
- πŸ”§ **μžλ™ μ„€μΉ˜**: 원클릭 μ„€μΉ˜ 슀크립트

## πŸ“‹ μš”κ΅¬μ‚¬ν•­

- **Python 3.8+**
- **pip** (νŒ¨ν‚€μ§€ κ΄€λ¦¬μž)
- **Cursor IDE** (MCP ν΄λΌμ΄μ–ΈνŠΈ)
- **Slack Bot Token** (xoxb-둜 μ‹œμž‘)

### Slack Bot κΆŒν•œ

Slack 앱에 λ‹€μŒ κΆŒν•œμ΄ ν•„μš”ν•©λ‹ˆλ‹€:

```
Bot Token Scopes:
- channels:history    # 채널 λ©”μ‹œμ§€ 읽기
- channels:read       # 채널 정보 쑰회
- chat:write          # λ©”μ‹œμ§€ 전솑
- groups:history      # λΉ„κ³΅κ°œ κ·Έλ£Ή λ©”μ‹œμ§€ 읽기
- groups:read         # λΉ„κ³΅κ°œ κ·Έλ£Ή 정보 쑰회
- im:history          # DM λ©”μ‹œμ§€ 읽기
- im:read             # DM 정보 쑰회
- im:write            # DM 전솑
- mpim:history        # λ©€ν‹°νŒŒν‹° DM λ©”μ‹œμ§€ 읽기
- mpim:read           # λ©€ν‹°νŒŒν‹° DM 정보 쑰회
- mpim:write          # λ©€ν‹°νŒŒν‹° DM 전솑
- reactions:write     # λ°˜μ‘ μΆ”κ°€
- search:read         # λ©”μ‹œμ§€ 검색
- users:read          # μ‚¬μš©μž 정보 쑰회
```

## πŸš€ λΉ λ₯Έ μ„€μΉ˜

### 1. μžλ™ μ„€μΉ˜ (ꢌμž₯)

```bash
cd slack-mcp
python install.py
```

μ„€μΉ˜ μŠ€ν¬λ¦½νŠΈκ°€ λ‹€μŒμ„ μžλ™μœΌλ‘œ μ²˜λ¦¬ν•©λ‹ˆλ‹€:
- νŒ¨ν‚€μ§€ μ„€μΉ˜
- ν™˜κ²½ λ³€μˆ˜ μ„€μ •
- Cursor MCP μ„€μ • μ—…λ°μ΄νŠΈ
- μ„€μΉ˜ ν…ŒμŠ€νŠΈ μ‹€ν–‰

### 2. Cursor μž¬μ‹œμž‘

μ„€μΉ˜ μ™„λ£Œ ν›„ Cursorλ₯Ό μž¬μ‹œμž‘ν•˜λ©΄ Slack MCP 도ꡬλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

## πŸ”§ μˆ˜λ™ μ„€μΉ˜

### 1. μ €μž₯μ†Œ 클둠

```bash
git clone <repository-url>
cd slack-mcp
```

### 2. νŒ¨ν‚€μ§€ μ„€μΉ˜

```bash
pip install -r requirements.txt
```

### 3. ν™˜κ²½ λ³€μˆ˜ μ„€μ •

`.env` 파일 생성:

```bash
# Slack Bot Token (xoxb-둜 μ‹œμž‘ν•˜λŠ” 토큰)
SLACK_BOT_TOKEN=xoxb-your-bot-token-here

# 선택적: 둜그 레벨 μ„€μ •
LOG_LEVEL=INFO
```

### 4. Cursor MCP μ„€μ •

`~/.cursor/mcp.json` νŒŒμΌμ— λ‹€μŒ μΆ”κ°€:

```json
{
  "mcpServers": {
    "slack": {
      "command": "python",
      "args": ["/path/to/slack-mcp/slack_mcp_server.py"],
      "env": {
        "SLACK_BOT_TOKEN": "xoxb-your-bot-token-here"
      }
    }
  }
}
```

### 5. ν…ŒμŠ€νŠΈ μ‹€ν–‰

```bash
python test_slack_mcp.py
```

## πŸ“– μ‚¬μš©λ²•

Cursorμ—μ„œ μƒˆ μ±„νŒ…μ„ μ‹œμž‘ν•˜κ³  λ‹€μŒκ³Ό 같이 μžμ—°μ–΄λ‘œ Slack κΈ°λŠ₯을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

### λ©”μ‹œμ§€ 전솑
```
#general 채널에 "μ•ˆλ…•ν•˜μ„Έμš”!"λΌλŠ” λ©”μ‹œμ§€λ₯Ό λ³΄λ‚΄μ£Όμ„Έμš”
```

### 채널 정보 쑰회
```
μ‚¬μš© κ°€λŠ₯ν•œ Slack 채널 λͺ©λ‘μ„ λ³΄μ—¬μ£Όμ„Έμš”
```

### λ©”μ‹œμ§€ νžˆμŠ€ν† λ¦¬
```
#general μ±„λ„μ˜ 졜근 λ©”μ‹œμ§€ 10개λ₯Ό κ°€μ Έμ™€μ£Όμ„Έμš”
```

### λ‹€μ΄λ ‰νŠΈ λ©”μ‹œμ§€
```
μ‚¬μš©μž U1234567890μ—κ²Œ "회의 μ€€λΉ„ μ™„λ£Œ"λΌλŠ” DM을 λ³΄λ‚΄μ£Όμ„Έμš”
```

### λ©”μ‹œμ§€ 검색
```
"ν”„λ‘œμ νŠΈ"λΌλŠ” ν‚€μ›Œλ“œκ°€ ν¬ν•¨λœ λ©”μ‹œμ§€λ₯Ό κ²€μƒ‰ν•΄μ£Όμ„Έμš”
```

## πŸ› οΈ μ‚¬μš© κ°€λŠ₯ν•œ 도ꡬ

| 도ꡬ | μ„€λͺ… | νŒŒλΌλ―Έν„° |
|------|------|----------|
| `send_slack_message` | 채널에 λ©”μ‹œμ§€ 전솑 | `channel`, `text` |
| `get_slack_channels` | 채널 λͺ©λ‘ 쑰회 | μ—†μŒ |
| `get_slack_channel_history` | 채널 νžˆμŠ€ν† λ¦¬ 쑰회 | `channel_id`, `limit` |
| `send_slack_direct_message` | λ‹€μ΄λ ‰νŠΈ λ©”μ‹œμ§€ 전솑 | `user_id`, `text` |
| `get_slack_users` | μ‚¬μš©μž λͺ©λ‘ 쑰회 | μ—†μŒ |
| `add_slack_reaction` | λ©”μ‹œμ§€μ— λ°˜μ‘ μΆ”κ°€ | `channel`, `timestamp`, `name` |
| `search_slack_messages` | λ©”μ‹œμ§€ 검색 | `query`, `count` |
| `test_slack_connection` | μ—°κ²° ν…ŒμŠ€νŠΈ | μ—†μŒ |

## πŸ“ ν”„λ‘œμ νŠΈ ꡬ쑰

```
slack-mcp/
β”œβ”€β”€ πŸ“„ README.md                 # 이 파일
β”œβ”€β”€ πŸ“„ requirements.txt          # Python νŒ¨ν‚€μ§€ μ˜μ‘΄μ„±
β”œβ”€β”€ πŸ“„ slack_api.py              # Slack API ν΄λΌμ΄μ–ΈνŠΈ
β”œβ”€β”€ πŸ“„ slack_mcp_server.py       # FastMCP μ„œλ²„ κ΅¬ν˜„
β”œβ”€β”€ πŸ“„ test_slack_mcp.py         # ν…ŒμŠ€νŠΈ 슀크립트
β”œβ”€β”€ πŸ“„ install.py                # μžλ™ μ„€μΉ˜ 슀크립트
β”œβ”€β”€ πŸ“„ mcp_config.json          # MCP μ„€μ • ν…œν”Œλ¦Ώ
β”œβ”€β”€ πŸ“„ env_example.txt          # ν™˜κ²½ λ³€μˆ˜ ν…œν”Œλ¦Ώ
└── πŸ“„ .gitignore               # Git λ¬΄μ‹œ 파일
```

## πŸ‘¨β€πŸ’» 개발자 κ°€μ΄λ“œ

### 개발 ν™˜κ²½ μ„€μ •

```bash
# 개발 λͺ¨λ“œλ‘œ νŒ¨ν‚€μ§€ μ„€μΉ˜
pip install -r requirements.txt

# ν™˜κ²½ λ³€μˆ˜ μ„€μ •
cp env_example.txt .env
# .env νŒŒμΌμ„ νŽΈμ§‘ν•˜μ—¬ μ‹€μ œ 토큰 μž…λ ₯

# ν…ŒμŠ€νŠΈ μ‹€ν–‰
python test_slack_mcp.py
```

### μƒˆλ‘œμš΄ 도ꡬ μΆ”κ°€

1. `slack_api.py`에 API λ©”μ„œλ“œ μΆ”κ°€
2. `slack_mcp_server.py`에 MCP 도ꡬ λ°μ½”λ ˆμ΄ν„° μΆ”κ°€
3. `test_slack_mcp.py`에 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ μΆ”κ°€

### λ‘œκΉ…

μ„œλ²„λŠ” λ‹€μŒ μœ„μΉ˜μ— 둜그λ₯Ό κΈ°λ‘ν•©λ‹ˆλ‹€:
- **μ½˜μ†” 좜λ ₯**: μ‹€μ‹œκ°„ 둜그 확인
- **파일 둜그**: `slack_mcp.log`

### 디버깅

```bash
# 상세 λ‘œκ·Έμ™€ ν•¨κ»˜ ν…ŒμŠ€νŠΈ μ‹€ν–‰
LOG_LEVEL=DEBUG python test_slack_mcp.py

# μ„œλ²„ 직접 μ‹€ν–‰ (λ””λ²„κΉ…μš©)
python slack_mcp_server.py
```

## πŸ” 문제 ν•΄κ²°

### 자주 λ°œμƒν•˜λŠ” 문제

#### 1. "SLACK_BOT_TOKEN ν™˜κ²½ λ³€μˆ˜κ°€ μ„€μ •λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€"

**ν•΄κ²°μ±…:**
- `.env` νŒŒμΌμ— μ˜¬λ°”λ₯Έ 토큰이 μžˆλŠ”μ§€ 확인
- 토큰이 `xoxb-`둜 μ‹œμž‘ν•˜λŠ”μ§€ 확인

#### 2. "invalid_auth" μ—λŸ¬

**ν•΄κ²°μ±…:**
- Slack Bot Token이 μœ νš¨ν•œμ§€ 확인
- 토큰이 μ˜¬λ°”λ₯Έ μ›Œν¬μŠ€νŽ˜μ΄μŠ€μš©μΈμ§€ 확인
- ν•„μš”ν•œ κΆŒν•œμ΄ λͺ¨λ‘ λΆ€μ—¬λ˜μ—ˆλŠ”μ§€ 확인

#### 3. "channel_not_found" μ—λŸ¬

**ν•΄κ²°μ±…:**
- 채널 IDκ°€ μ˜¬λ°”λ₯Έμ§€ 확인
- 봇이 ν•΄λ‹Ή 채널에 μΆ”κ°€λ˜μ—ˆλŠ”μ§€ 확인
- 곡개 채널인지 λ˜λŠ” 봇이 μ΄ˆλŒ€λ˜μ—ˆλŠ”μ§€ 확인

#### 4. Cursorμ—μ„œ MCP 도ꡬ가 보이지 μ•ŠμŒ

**ν•΄κ²°μ±…:**
- Cursorλ₯Ό μ™„μ „νžˆ μž¬μ‹œμž‘
- `~/.cursor/mcp.json` μ„€μ • 파일 확인
- 파일 κ²½λ‘œκ°€ μ˜¬λ°”λ₯Έμ§€ 확인

### 둜그 확인

```bash
# μ„œλ²„ 둜그 확인
tail -f slack_mcp.log

# ν…ŒμŠ€νŠΈ λ‘œκ·Έμ™€ ν•¨κ»˜ μ‹€ν–‰
python test_slack_mcp.py 2>&1 | tee debug.log
```

### μˆ˜λ™ μ—°κ²° ν…ŒμŠ€νŠΈ

```bash
# Pythonμ—μ„œ 직접 ν…ŒμŠ€νŠΈ
python -c "
import asyncio
from slack_api import get_slack_client
import os
from dotenv import load_dotenv

load_dotenv()
token = os.getenv('SLACK_BOT_TOKEN')
client = get_slack_client(token)

async def test():
    result = await client.test_connection()
    print(result)

asyncio.run(test())
"
```

## πŸ“‹ 과제 μš”κ΅¬μ‚¬ν•­ λŒ€λΉ„ ν˜„ν™©

| μš”κ΅¬μ‚¬ν•­ | μƒνƒœ | κ΅¬ν˜„ μœ„μΉ˜ |
|----------|------|-----------|
| **ν•„μˆ˜ κΈ°λŠ₯** |
| λ©”μ‹œμ§€ 전솑 | βœ… μ™„λ£Œ | `send_slack_message` |
| 채널 λͺ©λ‘ 쑰회 | βœ… μ™„λ£Œ | `get_slack_channels` |
| 채널 νžˆμŠ€ν† λ¦¬ 쑰회 | βœ… μ™„λ£Œ | `get_slack_channel_history` |
| λ‹€μ΄λ ‰νŠΈ λ©”μ‹œμ§€ | βœ… μ™„λ£Œ | `send_slack_direct_message` |
| **선택 κΈ°λŠ₯** |
| μ‚¬μš©μž λͺ©λ‘ 쑰회 | βœ… μ™„λ£Œ | `get_slack_users` |
| λ°˜μ‘ μΆ”κ°€ | βœ… μ™„λ£Œ | `add_slack_reaction` |
| λ©”μ‹œμ§€ 검색 | βœ… μ™„λ£Œ | `search_slack_messages` |
| **기술 μš”κ΅¬μ‚¬ν•­** |
| FastMCP μ‚¬μš© | βœ… μ™„λ£Œ | `slack_mcp_server.py` |
| μ—λŸ¬ 처리 | βœ… μ™„λ£Œ | λͺ¨λ“  도ꡬ에 try-catch |
| νƒ€μž… 힌트 | βœ… μ™„λ£Œ | λͺ¨λ“  ν•¨μˆ˜μ— νƒ€μž… 힌트 |
| λ‘œκΉ… | βœ… μ™„λ£Œ | κ΅¬μ‘°ν™”λœ λ‘œκΉ… μ‹œμŠ€ν…œ |
| ν…ŒμŠ€νŠΈ | βœ… μ™„λ£Œ | `test_slack_mcp.py` |
| λ¬Έμ„œν™” | βœ… μ™„λ£Œ | 이 README 및 μ½”λ“œ 주석 |

## πŸ† μΆ”κ°€ κ΅¬ν˜„ 사항

과제 μš”κ΅¬μ‚¬ν•­μ„ λ„˜μ–΄μ„œ λ‹€μŒ κΈ°λŠ₯듀을 μΆ”κ°€λ‘œ κ΅¬ν˜„ν–ˆμŠ΅λ‹ˆλ‹€:

- πŸ”„ **μžλ™ μ„€μΉ˜ μ‹œμŠ€ν…œ**: 원클릭 μ„€μΉ˜ 슀크립트
- πŸ§ͺ **포괄적 ν…ŒμŠ€νŠΈ**: λͺ¨λ“  κΈ°λŠ₯에 λŒ€ν•œ μžλ™ν™”λœ ν…ŒμŠ€νŠΈ
- πŸ“Š **μƒμ„Έν•œ 응닡 ν¬λ§·νŒ…**: κ΅¬μ‘°ν™”λœ 성곡/μ‹€νŒ¨ 응닡
- ⚑ **비동기 HTTP ν΄λΌμ΄μ–ΈνŠΈ**: κ³ μ„±λŠ₯ aiohttp μ‚¬μš©
- πŸ›‘οΈ **μ„Έμ…˜ 관리**: HTTP μ„Έμ…˜ μž¬μ‚¬μš©μœΌλ‘œ μ„±λŠ₯ μ΅œμ ν™”
- πŸ”§ **개발자 도ꡬ**: 디버깅 및 문제 ν•΄κ²° 도ꡬ
- πŸ“ **μ™„μ „ν•œ ν”„λ‘œμ νŠΈ ꡬ쑰**: 생산 μ€€λΉ„ μ™„λ£Œλœ μ½”λ“œ ꡬ쑰

## πŸ“„ λΌμ΄μ„ μŠ€

MIT License - μžμ„Έν•œ λ‚΄μš©μ€ [LICENSE](LICENSE) νŒŒμΌμ„ μ°Έμ‘°ν•˜μ„Έμš”.

---

## πŸš€ μ‹œμž‘ν•˜κΈ°

```bash
# 1. ν”„λ‘œμ νŠΈ 클둠
git clone <repository-url>
cd slack-mcp

# 2. μžλ™ μ„€μΉ˜ μ‹€ν–‰
python install.py

# 3. Cursor μž¬μ‹œμž‘
# 이제 Cursorμ—μ„œ Slack MCP 도ꡬλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€!
```

**λ¬Έμ œκ°€ μžˆμœΌμ‹œλ©΄ [Issues](../../issues)에 λ³΄κ³ ν•΄μ£Όμ„Έμš”.**