2025-08-26 02:35:44 +09:00
|
|
|
# FLUX.1 Kontext MCP Server 개발 가이드
|
|
|
|
|
|
|
|
|
|
## 프로젝트 개요
|
|
|
|
|
|
|
|
|
|
**프로젝트명**: flux1-edit
|
|
|
|
|
**목적**: FLUX.1 Kontext 모델 API를 이용한 MCP server 및 connector 구현
|
|
|
|
|
**특화 기능**: 이미지 생성이 아닌 편집(editing)에 특화된 MCP 도구 제공
|
|
|
|
|
|
|
|
|
|
## ⚠️ 소스 코드 작성 규칙 (중요!)
|
|
|
|
|
|
|
|
|
|
### MCP 서버 호환성을 위한 필수 규칙
|
|
|
|
|
|
|
|
|
|
#### 1. Unicode 문자 사용 금지
|
|
|
|
|
```python
|
|
|
|
|
# 금지: ✅❌🎲📁📐💾 등 모든 이모지/특수문자
|
|
|
|
|
# 권장: [SUCCESS] [ERROR] [INFO] [OK] [FAILED]
|
|
|
|
|
|
|
|
|
|
print("[SUCCESS] 작업 완료") # ✅
|
|
|
|
|
print("✅ 작업 완료") # ❌
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 2. 콘솔 출력 금지 (stdout 사용 안함)
|
|
|
|
|
```python
|
|
|
|
|
# 금지: print() - JSON 파싱 오류 유발
|
|
|
|
|
# 권장: logger 사용
|
|
|
|
|
|
|
|
|
|
logger.info("서버 시작") # ✅
|
|
|
|
|
print("서버 시작") # ❌
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 3. 배치 파일에 UTF-8 설정 필수
|
|
|
|
|
```batch
|
|
|
|
|
chcp 65001 >nul 2>&1
|
|
|
|
|
set PYTHONIOENCODING=utf-8
|
|
|
|
|
set PYTHONUTF8=1
|
|
|
|
|
python main.py
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 4. 로깅 설정
|
|
|
|
|
```python
|
|
|
|
|
logging.basicConfig(
|
|
|
|
|
handlers=[
|
|
|
|
|
logging.FileHandler('app.log', encoding='utf-8') # 파일만
|
|
|
|
|
# logging.StreamHandler(sys.stdout) # 금지!
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 수정 후 검증
|
|
|
|
|
```bash
|
|
|
|
|
python test_fixes.py # 반드시 실행하여 확인
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## API 스펙 분석 (FLUX.1 Kontext)
|
|
|
|
|
|
|
|
|
|
### 1. 엔드포인트
|
|
|
|
|
- **생성 요청**: `POST /flux-kontext-pro`
|
|
|
|
|
- **결과 조회**: `GET /v1/get_result?id={request_id}`
|
|
|
|
|
|
|
|
|
|
### 2. 주요 파라미터 설정
|
|
|
|
|
|
|
|
|
|
#### 2.1 입력 파라미터
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"prompt": "편집 설명 (텍스트)",
|
|
|
|
|
"input_image": "base64 인코딩된 이미지 (20MB 제한)",
|
|
|
|
|
"seed": "필수 입력 (일관된 편집 결과를 위해)",
|
|
|
|
|
"safety_tolerance": 2,
|
|
|
|
|
"output_format": "png",
|
2025-08-26 04:10:31 +09:00
|
|
|
"prompt_upsampling": false
|
2025-08-26 02:35:44 +09:00
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 2.2 설정 방향
|
|
|
|
|
- **prompt**: 토큰 크기 제한이 명시되지 않음 - 제한없이 처리
|
|
|
|
|
- **input_image**: 20MB 크기 제한 반영
|
2025-08-26 04:10:31 +09:00
|
|
|
- **aspect_ratio**: 편집 작업에서는 사용하지 않음 (입력 이미지의 원본 비율 유지)
|
2025-08-26 02:35:44 +09:00
|
|
|
- **seed**: 반드시 입력받아서 일관된 스타일 유지 및 재현성 보장
|
|
|
|
|
- **prompt_upsampling**: false (기본)
|
|
|
|
|
- **safety_tolerance**: 2 (기본값)
|
|
|
|
|
- **output_format**: png 고정
|
|
|
|
|
- **webhook_url, webhook_secret**: 사용 안 함
|
|
|
|
|
|
|
|
|
|
### 3. 워크플로우
|
|
|
|
|
1. 요청 생성 → `request_id` 반환
|
|
|
|
|
2. `request_id`로 결과 폴링
|
|
|
|
|
3. `result['sample']`에서 서명된 URL 획득
|
|
|
|
|
4. URL은 10분간 유효 (즉시 다운로드 필요)
|
|
|
|
|
|
|
|
|
|
## 개발 구조
|
|
|
|
|
|
|
|
|
|
### 1. 디렉터리 구조
|
|
|
|
|
```
|
|
|
|
|
D:\Project\little-fairy\flux1-edit\
|
|
|
|
|
├── CLAUDE.md # 이 가이드 문서
|
|
|
|
|
├── README.md # 프로젝트 설명서
|
|
|
|
|
├── requirements.txt # Python 의존성
|
|
|
|
|
├── main.py # 메인 서버 실행 파일
|
|
|
|
|
├── .env # 환경변수 (FLUX API 키)
|
|
|
|
|
├── .env.example # 환경변수 예시
|
|
|
|
|
├── input_images/ # 입력 이미지 디렉터리
|
|
|
|
|
├── generated_images/ # 출력 이미지 디렉터리
|
|
|
|
|
├── src/
|
|
|
|
|
│ ├── __init__.py
|
|
|
|
|
│ ├── server/
|
|
|
|
|
│ │ ├── __init__.py
|
|
|
|
|
│ │ ├── mcp_server.py # MCP 서버 메인
|
|
|
|
|
│ │ ├── handlers.py # 도구 핸들러들
|
|
|
|
|
│ │ └── models.py # 데이터 모델들
|
|
|
|
|
│ ├── connector/
|
|
|
|
|
│ │ ├── __init__.py
|
|
|
|
|
│ │ ├── config.py # 설정 관리
|
|
|
|
|
│ │ └── flux_client.py # FLUX API 클라이언트
|
|
|
|
|
│ └── utils/
|
|
|
|
|
│ ├── __init__.py
|
|
|
|
|
│ ├── image_utils.py # 이미지 처리 유틸
|
|
|
|
|
│ └── validation.py # 입력 검증
|
|
|
|
|
└── tests/ # 단위 테스트
|
|
|
|
|
├── __init__.py
|
|
|
|
|
├── test_config.py
|
|
|
|
|
├── test_flux_client.py
|
|
|
|
|
└── test_handlers.py
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 2. MCP 도구 정의
|
|
|
|
|
|
|
|
|
|
#### 2.1 flux_edit_image (메인 도구)
|
|
|
|
|
- **설명**: FLUX.1 Kontext로 이미지 편집
|
|
|
|
|
- **입력**:
|
|
|
|
|
```python
|
|
|
|
|
{
|
|
|
|
|
"input_image_b64": str, # Base64 인코딩된 입력 이미지
|
|
|
|
|
"prompt": str, # 편집 설명
|
|
|
|
|
"seed": int, # 재현성을 위한 시드값
|
|
|
|
|
"save_to_file": bool # 파일 저장 여부 (기본: True)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
- **출력**: 편집된 이미지 + 메타데이터
|
|
|
|
|
|
|
|
|
|
#### 2.2 지원 도구들 (gpt-edit 참고)
|
|
|
|
|
- `validate_image`: 이미지 검증
|
|
|
|
|
- `flux_edit_image_from_file`: 파일에서 읽어서 편집
|
|
|
|
|
- `move_temp_to_output`: 임시 파일을 출력 디렉터리로 이동
|
|
|
|
|
|
|
|
|
|
### 3. 주요 구현 포인트
|
|
|
|
|
|
|
|
|
|
#### 3.1 Config 클래스 (src/connector/config.py)
|
|
|
|
|
```python
|
|
|
|
|
class Config:
|
|
|
|
|
# FLUX.1 Kontext 전용 설정
|
|
|
|
|
API_BASE_URL = "https://api.bfl.ai"
|
|
|
|
|
MODEL_NAME = "flux-kontext-pro"
|
|
|
|
|
MAX_IMAGE_SIZE_MB = 20 # FLUX 제한에 맞춤
|
|
|
|
|
DEFAULT_ASPECT_RATIO = "1:1"
|
|
|
|
|
DEFAULT_SAFETY_TOLERANCE = 2
|
|
|
|
|
OUTPUT_FORMAT = "png"
|
|
|
|
|
PROMPT_UPSAMPLING = False
|
|
|
|
|
|
|
|
|
|
# 환경변수
|
|
|
|
|
FLUX_API_KEY = os.getenv('FLUX_API_KEY')
|
|
|
|
|
|
|
|
|
|
# 파일 경로
|
|
|
|
|
input_path: Path
|
|
|
|
|
generated_images_path: Path
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 3.2 FLUX Client (src/connector/flux_client.py)
|
|
|
|
|
```python
|
|
|
|
|
class FluxEditClient:
|
|
|
|
|
async def edit_image(self, request: FluxEditRequest) -> FluxEditResponse:
|
|
|
|
|
# 1. 편집 요청 생성
|
|
|
|
|
# 2. 결과 폴링
|
|
|
|
|
# 3. 이미지 다운로드
|
|
|
|
|
# 4. 응답 생성
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
class FluxEditRequest:
|
|
|
|
|
input_image_b64: str
|
|
|
|
|
prompt: str
|
|
|
|
|
seed: int
|
|
|
|
|
aspect_ratio: str = "1:1"
|
|
|
|
|
|
|
|
|
|
class FluxEditResponse:
|
|
|
|
|
success: bool
|
|
|
|
|
edited_image_data: bytes
|
|
|
|
|
image_size: Tuple[int, int]
|
|
|
|
|
execution_time: float
|
|
|
|
|
error_message: Optional[str]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 3.3 핸들러 구현 (src/server/handlers.py)
|
|
|
|
|
- gpt-edit의 `handle_edit_image_from_file` 구조 참고
|
|
|
|
|
- FLUX API 특성에 맞게 수정:
|
|
|
|
|
- 마스크 기능 없음 (FLUX.1 Kontext는 프롬프트만으로 편집)
|
|
|
|
|
- 폴링 방식의 비동기 처리
|
|
|
|
|
- 20MB 이미지 크기 제한
|
|
|
|
|
|
|
|
|
|
## 개발 우선순위
|
|
|
|
|
|
|
|
|
|
### Phase 1: 핵심 기능 구현
|
|
|
|
|
1. ✅ 프로젝트 구조 생성
|
|
|
|
|
2. ⏳ Config 및 환경설정
|
|
|
|
|
3. ⏳ FLUX API 클라이언트 구현
|
|
|
|
|
4. ⏳ 기본 MCP 서버 구현
|
|
|
|
|
5. ⏳ `flux_edit_image` 도구 구현
|
|
|
|
|
|
|
|
|
|
### Phase 2: 편의 기능 추가
|
|
|
|
|
1. 파일 기반 편집 (`flux_edit_image_from_file`)
|
|
|
|
|
2. 이미지 검증 도구
|
|
|
|
|
3. 결과 파일 관리 도구
|
|
|
|
|
|
|
|
|
|
### Phase 3: 테스트 및 최적화
|
|
|
|
|
1. 단위 테스트 작성
|
|
|
|
|
2. 에러 핸들링 강화
|
|
|
|
|
3. 성능 최적화
|
|
|
|
|
|
|
|
|
|
## 참고사항
|
|
|
|
|
|
|
|
|
|
### 1. gpt-edit와의 차이점
|
|
|
|
|
- **API 구조**: OpenAI는 동기식, FLUX는 비동기식 (폴링)
|
|
|
|
|
- **마스크 기능**: OpenAI는 마스크 지원, FLUX는 프롬프트만
|
|
|
|
|
- **이미지 크기**: OpenAI 4MB → FLUX 20MB
|
|
|
|
|
- **출력 형식**: 다양한 형식 → PNG 고정
|
|
|
|
|
|
|
|
|
|
### 2. 보안 고려사항
|
|
|
|
|
- FLUX API 키 환경변수 관리
|
|
|
|
|
- 임시 파일 자동 정리
|
|
|
|
|
- 이미지 데이터 메모리 관리
|
|
|
|
|
|
|
|
|
|
### 3. 에러 핸들링
|
|
|
|
|
- 네트워크 타임아웃
|
|
|
|
|
- API 할당량 초과
|
|
|
|
|
- 이미지 형식/크기 오류
|
|
|
|
|
- 폴링 중 서버 오류
|
|
|
|
|
|
|
|
|
|
## 환경변수 설정
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# .env 파일 예시
|
|
|
|
|
FLUX_API_KEY=your_flux_api_key_here
|
|
|
|
|
LOG_LEVEL=INFO
|
|
|
|
|
MAX_IMAGE_SIZE_MB=20
|
|
|
|
|
DEFAULT_TIMEOUT=300
|
|
|
|
|
INPUT_PATH=./input_images
|
|
|
|
|
GENERATED_IMAGES_PATH=./generated_images
|
|
|
|
|
SAVE_PARAMETERS=true
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 다음 단계
|
|
|
|
|
|
|
|
|
|
1. **환경 설정 파일 생성** (.env, requirements.txt)
|
|
|
|
|
2. **기본 구조 코드 작성** (config.py, flux_client.py)
|
|
|
|
|
3. **MCP 서버 메인 로직** (mcp_server.py, handlers.py)
|
|
|
|
|
4. **단위 테스트 작성 및 실행**
|
|
|
|
|
5. **Claude에서 실제 테스트**
|
|
|
|
|
|
|
|
|
|
이 가이드를 바탕으로 step-by-step으로 구현을 진행하면 됩니다.
|