Python으로 MCP 서버 구축하고 Stable Diffusion 연동하기

Melon Coder·2026년 4월 4일

Python

목록 보기
6/7
post-thumbnail

개요

저번 포스팅에서 HuggingFace로 Stable Diffusion 이미지 생성을 해봤는데,
이번엔 한 단계 더 나아가서 MCP 서버를 구축하고 이미지 생성 기능을 연동해봤다.

MCP(Model Context Protocol)는 AI가 외부 기능을 표준화된 방식으로 호출할 수 있게 해주는 프로토콜이다. 쉽
게 말하면 AI가 쓸 수 있는 기능들을 서버로 만들어 제공하는 것이다.


MCP

MCP 없을 때 (저번 포스팅)

test.py → 직접 Stable Diffusion 실행 → 결과

MCP 있을 때

클라이언트 → MCP 프로토콜 → MCP 서버 → Stable Diffusion → 결과

클라이언트와 서버가 분리되어, 어떤 AI든 MCP 서버에 연결만 하면 이미지 생성 기능을 쓸 수 있다.


환경 세팅

저번 포스팅에서 세팅한 환경에 mcp 라이브러리만 추가 설치했다.

pip install mcp

MCP 서버 구축

mcp_server.py

from mcp.server.fastmcp import FastMCP
from diffusers import StableDiffusionPipeline
import torch
import base64
from io import BytesIO

# 모델 로드
print("모델 로딩 중...")
pipe = StableDiffusionPipeline.from_pretrained(
    "prompthero/openjourney",
    torch_dtype=torch.float32,
    safety_checker=None,
    requires_safety_checker=False
).to("cuda")
pipe.safety_checker = None
print("모델 로딩 완료!")

mcp = FastMCP("iann-image-server")

@mcp.tool()
def generate_image(prompt: str) -> str:
    """텍스트 프롬프트로 이미지를 생성합니다"""
    print(f"이미지 생성 중: {prompt}")

    pipe.safety_checker = None
    image = pipe(prompt).images[0]

    # 파일 저장
    image.save("output.png")

    # base64 변환
    buffer = BytesIO()
    image.save(buffer, format="PNG")
    img_base64 = base64.b64encode(buffer.getvalue()).decode()

    return f"data:image/png;base64,{img_base64}"

if __name__ == "__main__":
    mcp.run(transport="sse")

핵심은 @mcp.tool() 데코레이터

@mcp.tool()
def generate_image(prompt: str) -> str:

이 함수를 MCP 툴로 등록한다는 의미이고, 등록하면 어떤 MCP 클라이언트든 이 툴을 발견하
고 호출할 수 있다.

서버 실행

python mcp_server.py
모델 로딩 완료!
INFO: Started server process
INFO: Uvicorn running on http://127.0.0.1:8000

MCP 클라이언트 구현

test_mcp.py

import asyncio
from mcp.client.sse import sse_client
from mcp import ClientSession

async def main():
    async with sse_client("http://localhost:8000/sse") as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # 툴 목록 확인
            tools = await session.list_tools()
            print("사용 가능한 툴:", [t.name for t in tools.tools])

            # 이미지 생성 요청
            result = await session.call_tool(
                "generate_image",
                {"prompt": "a beautiful mountain landscape at sunset, digital art"}
            )

            # base64 → 이미지 저장
            import base64
            from PIL import Image
            from io import BytesIO

            img_data = result.content[0].text
            img_data = img_data.replace("data:image/png;base64,", "")
            img_bytes = base64.b64decode(img_data)
            img = Image.open(BytesIO(img_bytes))
            img.save("mcp_output.png")
            print("mcp_output.png 저장 완료!")

asyncio.run(main())

실행 결과

사용 가능한 툴: ['generate_image']
mcp_output.png 저장 완료!


트러블슈팅

1. 검은 이미지 생성

원인: torch_dtype=torch.float16 사용 시 일부 환경에서 검은 이미지 출력

해결: float32 로 변경

# 기존
torch_dtype=torch.float16

# 교체
torch_dtype=torch.float32

2. NSFW 필터로 인한 검은 이미지

원인: 모델 내장 safety_checker 작동

해결: 모델 로드 시 + 실행 전 강제 제거

pipe = StableDiffusionPipeline.from_pretrained(
    "prompthero/openjourney",
    safety_checker=None,
    requires_safety_checker=False
)
pipe.safety_checker = None

3. ValueError: a coroutine was expected

원인: mcp 1.27.0에서 API 변경

해결: FastMCP 방식으로 교체

# 기존 (구버전)
from mcp.server import Server

# 교체 (신버전)
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("server-name")

전체 흐름 정리

test_mcp.py (클라이언트)
      ↓ MCP 프로토콜 (SSE)
mcp_server.py (서버 - localhost:8000)
      ↓
Stable Diffusion (openjourney 모델)
      ↓
이미지 생성 → base64 반환
      ↓
test_mcp.py에서 디코딩 → mcp_output.png 저장

정리

MCP 서버를 직접 구축해보니 구조가 명확하게 이해됐다.
핵심은 @mcp.tool() 데코레이터로 함수를 등록하면 어떤 클라이언트든 호출할 수 있다는 점이다.


참고

profile
About me: https://resume-seven-beige.vercel.app/

0개의 댓글