소개
교육생들에게 온라인으로 3주간 실습을 진행하는 프로그램을 기획하고 있습니다.
매주 안내할 내용이 달라질텐데요, 그때그때 지식 파일이 변경되어 다른 응답을 해줄 수 있는 챗봇을 만들 수 있으면 좋겠다는 아이디어를 떠올렸습니다.
진행 방법
우선 노션 링크를 읽어오는 챗봇 만들기
Dify 지식 업로드를 할 때 '노션 동기화' 기능이 있습니다.
동기화 누르면 노션 로그인하고 내가 운영하고 있는 페이지는 동기화할 수 있습니다.
노션에 포함되어 있는 내용은 잘 답변을 합니다. 그런데 노션 페이지가 수정될 때 실시간으로 응답이 바뀌는지 궁금했습니다.
테스트해본 것
노션에 없는 '실습 시간'에 대한 질문을 테스트해보니 역시 모른다고 합니다.
노션에 실습 시간에 대한 정보를 추가해봄
여전히 실습 시간 정보를 못 가져옵니다.
지식 파일로 다시 들어가서 '동기화'를 누르면 정보를 가져오게 됩니다. 번 파일 재업로드보다는 편하지만 아주 편하진 않네요.
Dify를 탈출하다....
수강생 정보를 csv로 주면 노드로 name | email 필드를 분리하고 메일을 발송하는 기능까지 모두 Dify에서 구현을 하려고 했는데
기본적인 csv 파일도 분리가 쉽지 않더라고요. ChatGPT, 클로드코드에게 물어가면서 Dify의 코드 노드를 써봤는데 계속 실패했습니다.
이러느니 차라리 dify MCP를 설치해서 클로드코드에서 dify 구현한 앱을 가져다 쓰기로 전략을 선회했습니다.
글 가장 하단에 dify MCP 설치 방법 첨부할게요.
클로드코드로 개발 시작
원하는 기획을 챗지피티와 대화하고 PRD.md로 만들어서 개발 전 첨부하는건 이제 기본이쥬?
수강생들에게 줄 '유튜브 VOD 링크' '실습 체크리스트'를 첨부하면
자동으로 이메일이 발송되고, 여기에 주차별로 다른 응답을 할 수 있는 챗봇을 함께 삽입하는게 목표입니다.
만들어달라고하니까 파이썬으로 뚱땅뚱땅 개발하고, 이를 웹으로 확인할 수 있게 요청하여 이런 화면이 나왔습니다. PRD를 꼼꼼히 안 봤더니 제가 의도했던 기능보다 과하게 나왔습니다.
메인 페이지
주차별로 콘텐츠를 제출하는 페이지
이제 dify의 지식 파일이 실습 체크리스트(구글 문서)를 읽고 답변을 잘 해주게 해야합니다.
클로드코드 왈 knowledge API 어쩌고가 있어서 이걸 활용하면 매주차별로 다른 답변을 해줄 수 있다고 합니다.
제가 개발을 뭘 알겠습니까 처음부터 끝까지 클로드 코드한테 다 해달라고 했어요.
Dify에서 외부 지식 API 생성하기
dify는 외부 지식을 호출해올 수 있게 API 생성이 가능한데요, 통신할 수 있도록 ngrok라는 것으로 엔드포인트를 만들고 (내가 안 만들고 클로드코드가 만듬)
이 링크를 API 지식 추가에 넣으면 API 연결이 됩니다.
이제 매주 다른 정보를 읽어올 수 있게 되겠죠? 라고 기대를 했지만 아직은 잘 안되네요 허허헠
시간 관계상 다음주까지는 꼭 성공해서 돌아오겠습니다. 금방 고칠 수 있을 것 같아요?
보너스 - Dify MCP 연결 가이드
# Dify MCP 연결 가이드
Claude Code와 로컬 Dify 서버를 MCP(Model Context Protocol)로 연결하는 방법을 설명합니다.
## 📋 목차
- [사전 요구사항](#사전-요구사항)
- [앱 유형별 설정](#앱-유형별-설정)
- [MCP 서버 등록](#mcp-서버-등록)
- [연결 테스트](#연결-테스트)
- [문제 해결](#문제-해결)
## 🔧 사전 요구사항
### 1. Dify 서버 실행
```bash
# Dify 도커 컨테이너들이 실행되어 있어야 함
docker ps | grep dify
```
### 2. Claude Code 설치
- Claude Code CLI가 설치되어 있어야 함
### 3. 필수 도구
```bash
# uvx 설치 확인
uvx --version
# 또는 uv 설치
curl -LsSf https://astral.sh/uv/install.sh | sh
```
## 📱 앱 유형별 설정
### 🤖 챗봇 앱 (Chatbot)
#### 1. 앱 생성 및 설정
1. Dify 대시보드에서 **챗봇** 유형으로 앱 생성
2. LLM 모델 설정 (GPT-4, Claude 등)
3. 프롬프트 및 대화 설정 구성
4. **게시(Publish)** 버튼 클릭
#### 2. API 키 생성
1. 앱 설정 → **API 액세스** 탭
2. **Service API** 키 생성 및 복사
3. 키 형식: `app-xxxxxxxxxxxxxxxxx`
#### 3. API 엔드포인트
```bash
POST http://localhost/v1/chat-messages
Content-Type: application/json
Authorization: Bearer app-xxxxxxxxxxxxxxxxx
{
"inputs": {},
"query": "사용자 메시지",
"response_mode": "streaming", # 또는 "blocking"
"conversation_id": "", # 대화 연속성을 위한 ID
"user": "user-123"
}
```
#### 4. MCP 설정 (챗봇)
```json
{
"mcpServers": {
"dify-chatbot": {
"command": "uvx",
"args": [
"--from", "git+https://github.com/YanxingLiu/dify-mcp-server",
"dify_mcp_server"
],
"env": {
"DIFY_BASE_URL": "http://localhost/v1",
"DIFY_APP_SKS": "app-YOUR_CHATBOT_API_KEY"
}
}
}
}
```
### 🔄 워크플로우 앱 (Workflow)
#### 1. 앱 생성 및 설정
1. Dify 대시보드에서 **워크플로우** 유형으로 앱 생성
2. 워크플로우 노드 구성:
- **Start 노드**: 입력 변수 정의
- **LLM 노드**: AI 모델 설정
- **End 노드**: 출력 변수 정의
3. 워크플로우 테스트 및 **게시(Publish)**
#### 2. API 키 생성
1. 앱 설정 → **API 액세스** 탭
2. **Service API** 키 생성 및 복사
3. 키 형식: `app-xxxxxxxxxxxxxxxxx`
#### 3. API 엔드포인트
```bash
POST http://localhost/v1/workflows/run
Content-Type: application/json
Authorization: Bearer app-xxxxxxxxxxxxxxxxx
{
"inputs": {
"input_variable": "입력 값", # 워크플로우에서 정의한 변수들
"another_var": "다른 값"
},
"response_mode": "blocking", # 워크플로우는 주로 blocking 모드
"user": "user-123"
}
```
#### 4. MCP 설정 (워크플로우)
```json
{
"mcpServers": {
"dify-workflow": {
"command": "uvx",
"args": [
"--from", "git+https://github.com/YanxingLiu/dify-mcp-server",
"dify_mcp_server"
],
"env": {
"DIFY_BASE_URL": "http://localhost/v1",
"DIFY_APP_SKS": "app-YOUR_WORKFLOW_API_KEY"
}
}
}
}
```
### 📝 텍스트 생성 앱 (Text Generator)
#### 1. 앱 생성 및 설정
1. Dify 대시보드에서 **텍스트 생성** 유형으로 앱 생성
2. 프롬프트 템플릿 작성 (변수 포함 가능)
3. LLM 모델 설정
4. **게시(Publish)** 버튼 클릭
#### 2. API 엔드포인트
```bash
POST http://localhost/v1/completion-messages
Content-Type: application/json
Authorization: Bearer app-xxxxxxxxxxxxxxxxx
{
"inputs": {
"variable1": "값1", # 프롬프트에서 정의한 변수들
"variable2": "값2"
},
"response_mode": "blocking",
"user": "user-123"
}
```
## ⚙️ MCP 서버 등록
### 1. 설정 파일 위치
```bash
~/.config/claude-code/mcp_settings.json
```
### 2. 완전한 설정 예시
```json
{
"mcpServers": {
"dify-chatbot": {
"command": "uvx",
"args": [
"--from", "git+https://github.com/YanxingLiu/dify-mcp-server",
"dify_mcp_server"
],
"env": {
"DIFY_BASE_URL": "http://localhost/v1",
"DIFY_APP_SKS": "app-chatbot-api-key"
}
},
"dify-workflow": {
"command": "uvx",
"args": [
"--from", "git+https://github.com/YanxingLiu/dify-mcp-server",
"dify_mcp_server"
],
"env": {
"DIFY_BASE_URL": "http://localhost/v1",
"DIFY_APP_SKS": "app-workflow-api-key"
}
}
}
}
```
### 3. 여러 앱 동시 사용
```json
{
"mcpServers": {
"dify-assistant": {
"command": "uvx",
"args": [
"--from", "git+https://github.com/YanxingLiu/dify-mcp-server",
"dify_mcp_server"
],
"env": {
"DIFY_BASE_URL": "http://localhost/v1",
"DIFY_APP_SKS": "app-chatbot-key,app-workflow-key,app-completion-key"
}
}
}
}
```
## 🧪 연결 테스트
### 1. MCP 서버 상태 확인
```bash
claude mcp list
```
### 2. API 직접 테스트
```bash
# 챗봇 테스트
curl -X POST "http://localhost/v1/chat-messages" \
-H "Authorization: Bearer app-YOUR-API-KEY" \
-H "Content-Type: application/json" \
-d '{
"inputs": {},
"query": "안녕하세요",
"response_mode": "blocking",
"user": "test-user"
}'
# 워크플로우 테스트
curl -X POST "http://localhost/v1/workflows/run" \
-H "Authorization: Bearer app-YOUR-API-KEY" \
-H "Content-Type: application/json" \
-d '{
"inputs": {"input": "테스트 입력"},
"response_mode": "blocking",
"user": "test-user"
}'
```
### 3. MCP 프로토콜 테스트
```python
import json
import subprocess
import os
os.environ['DIFY_BASE_URL'] = 'http://localhost/v1'
os.environ['DIFY_APP_SKS'] = 'app-YOUR-API-KEY'
mcp_request = {
'jsonrpc': '2.0',
'id': 1,
'method': 'initialize',
'params': {
'protocolVersion': '2024-11-05',
'capabilities': {},
'clientInfo': {'name': 'test-client', 'version': '1.0.0'}
}
}
proc = subprocess.Popen([
'uvx', '--from', 'git+https://github.com/YanxingLiu/dify-mcp-server', 'dify_mcp_server'
], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
request_line = json.dumps(mcp_request) + '\n'
stdout, stderr = proc.communicate(input=request_line, timeout=10)
print('Response:', stdout)
```
## 🔧 문제 해결
### 1. 연결 실패 시 체크리스트
#### ❌ "App unavailable" 오류
- [ ] 앱이 게시(Published) 되었는지 확인
- [ ] API 키가 올바른지 확인
- [ ] 앱 유형과 API 엔드포인트가 일치하는지 확인
#### ❌ "Bad Request" 오류
- [ ] 요청 JSON 형식이 올바른지 확인
- [ ] 필수 필드가 누락되지 않았는지 확인
- [ ] Authorization 헤더가 올바른지 확인
#### ❌ "Not chat app" 오류
- [ ] 챗봇 앱이 아닌데 `/chat-messages` 엔드포인트 사용
- [ ] 올바른 앱 유형의 API 엔드포인트 사용 필요
#### ❌ "Workflow not published" 오류
- [ ] 워크플로우를 게시했는지 확인
- [ ] 워크플로우에 오류가 없는지 확인
### 2. 로그 확인
```bash
# Dify 컨테이너 로그 확인
docker logs docker-api-1
# MCP 서버 수동 실행으로 디버깅
DIFY_BASE_URL="http://localhost/v1" DIFY_APP_SKS="app-YOUR-KEY" \
uvx --from "git+https://github.com/YanxingLiu/dify-mcp-server" dify_mcp_server
```
### 3. 자주 발생하는 문제
| 문제 | 원인 | 해결책 |
|------|------|--------|
| MCP 서버 연결 실패 | 서버가 on-demand로 실행됨 | 정상 동작, 실제 사용 시 자동 시작 |
| API 키 오류 | 잘못된 키 또는 만료 | 새 API 키 생성 및 교체 |
| 앱 유형 불일치 | 잘못된 엔드포인트 사용 | 앱 유형에 맞는 API 사용 |
| 게시 안됨 | 앱이 초안 상태 | Dify에서 앱 게시 필요 |
## 💡 사용 팁
### 1. 효율적인 MCP 활용
- 챗봇: 대화형 AI 서비스, 고객 상담
- 워크플로우: 복잡한 데이터 처리, 자동화
- 텍스트 생성: 콘텐츠 생성, 번역
### 2. 성능 최적화
```json
{
"env": {
"DIFY_BASE_URL": "http://localhost/v1",
"DIFY_APP_SKS": "app-key1,app-key2",
"DIFY_TIMEOUT": "30",
"DIFY_MAX_RETRIES": "3"
}
}
```
### 3. 보안 고려사항
- API 키를 환경 변수로 관리
- 로컬 네트워크에서만 사용 권장
- 정기적인 API 키 로테이션
## 📚 참고 자료
- [Dify 공식 문서](https://docs.dify.ai/)
- [MCP 프로토콜 규격](https://modelcontextprotocol.io/)
- [Dify MCP 서버 GitHub](https://github.com/YanxingLiu/dify-mcp-server)
- [Claude Code 문서](https://docs.anthropic.com/en/docs/claude-code)
---
**작성일**: 2025-09-10
**버전**: 1.0
**테스트 환경**: Dify 1.8.1, Claude Code latest