안녕하세요. 지난 8월 공개된 gpt-oss 모델을 기반으로 vLLM과 MCP를 활용하여 ‘나만의 AI Chat’ 환경을 구성해 본 내용을 공유해 드리려고 합니다. 단순히 모델을 띄우고 채팅 환경을 구성하는 것을 넘어, 실제로 LLM이 외부 도구(Kubernetes 등)와 상호작용할 수 있도록 구성해 보았는데요. 어떤 기술들을 사용했는지 처음 접하시는 분들께 도움이 되었으면 좋겠습니다.
활용된 오픈소스들
-
gpt-oss: 프라이빗 환경에서 운영가능한 오픈소스 ChatGPT 모델
-
vLLM: LLM의 속도와 처리량을 최적화하는 서빙 엔진
-
MCP: MCP는 LLM이 외부 도구와 상호 작용할 수 있도록 정의한 프로토콜
-
MCPO: MCP 서버의 기능을 OpenAPI로 노출시켜 주는 인터페이스
-
Open-WebUI: LLM 모델과 채팅으로 상호작용할 수 있는 웹 기반 사용자 인터페이스
서빙 환경 구성 및 아키텍처
LLM 서빙 환경
- 내부 GPU 서버에 프라이빗 ChatGPT인 gpt-oss 모델 배포
- 모델 서빙 엔진으로 vLLM 으로 구성(Ollama 처럼 초기 구동시간 없이 빠르게 응답)
UI 및 AI, MCP 연동
- 사용자 인터페이스로 Open-WebUI 구성
- vLLM 연결 및 외부 도구(MCP)연결
Kubernetes 클러스터 연동
- 클러스터 자연어 조작을 위한 MCP 구성
- MCP의 Open-WebUI 연결을 위한 MCPO 구성
MCP Process
1)User
|
v
2)Open-WebUI
|
v Tool: https://some-mcp-servers.domain.com/kubernetes
3)mcp-proxy
|
v all requests forwarded
4)mcpo
|
v config.json based routing
+------------------+-----------+-----------+
v v v v
5)mcp-kubernetes mcp-a mcp-b mcp-c ...
(port 8083) (8085) (8086) (8087)
|
v
7)Kubernetes Cluster
FastMCP
직접 MCP 서버를 만들고 싶다면, FastMCP도 많은 도움이 될 것 같습니다. 참고로, 프라이빗 모델에 "현재 시간은?"이라고 물으면 마지막으로 학습된 시간을 대답합니다. 아래와 같은 MCP 서버를 FastMCP 프레임워크로 쉽게 만들 수 있습니다.
"""
Time-related tools for MCP Playground
이 모듈은 시간 관련 도구들을 제공합니다.
- 특정 timezone의 현재 시간 조회
- 여러 timezone의 시간 정보 동시 조회
"""
from fastmcp import FastMCP
from datetime import datetime
import pytz
def register_time_tools(mcp: FastMCP):
"""
시간 관련 도구들을 MCP 서버에 등록합니다.
Args:
mcp: FastMCP 인스턴스
"""
@mcp.tool() #<-- 이렇게 기존 코드에 FastMCP 를 활용 할 수 있도록 추가
def get_current_time(timezone: str = "Asia/Seoul") -> str:
"""
Get the current time in the specified timezone with UTC reference.
Args:
timezone: Timezone name (e.g., 'Asia/Seoul', 'America/New_York', 'Europe/London')
Default is 'Asia/Seoul'
Returns:
Current time string with local time first and UTC as reference
"""
try:
# 지정된 timezone의 현재 시간 가져오기
# pytz.timezone()으로 timezone 객체 생성
local_tz = pytz.timezone(timezone)
local_now = datetime.now(local_tz)
# 로컬 시간을 "YYYY-MM-DD HH:MM:SS" 형식으로 포맷
local_time_str = local_now.strftime("%Y-%m-%d %H:%M:%S")
# UTC 시간도 함께 가져오기 (참고용)
utc_now = datetime.now(pytz.UTC)
utc_time_str = utc_now.strftime("%Y-%m-%d %H:%M:%S")
# 로컬 시간을 먼저 표시하고, UTC는 괄호 안에 참고로 표시
# 예: "2025-11-03 13:14:00 (UTC: 2025-11-03 04:14:00)"
return f"{local_time_str} (UTC: {utc_time_str})"
except pytz.exceptions.UnknownTimeZoneError:
# 잘못된 timezone 이름이 입력된 경우 에러 메시지 반환
return f"Unknown timezone: {timezone}. Please use a valid timezone name."
@mcp.tool()
def get_current_time_info() -> dict:
"""
Get detailed current time information including multiple timezones.
Returns:
Dictionary with current time in UTC, Korea, and other common timezones
"""
# 자주 사용되는 timezone들을 미리 정의
# 각 지역별로 timezone 객체를 생성
timezones = {
"UTC": pytz.UTC, # 협정 세계시
"Korea": pytz.timezone("Asia/Seoul"), # 한국 표준시 (KST)
"Japan": pytz.timezone("Asia/Tokyo"), # 일본 표준시 (JST)
"US Eastern": pytz.timezone("America/New_York"), # 미국 동부 표준시 (EST/EDT)
"US Pacific": pytz.timezone("America/Los_Angeles"), # 미국 서부 표준시 (PST/PDT)
}
# 각 timezone별로 현재 시간을 조회하여 딕셔너리로 반환
result = {}
for name, tz in timezones.items():
now = datetime.now(tz)
# "%Z"는 timezone 약어 (KST, JST 등)를 포함
result[name] = now.strftime("%Y-%m-%d %H:%M:%S %Z")
return result
마치며
물론 프라이빗 모델은 여러 가지 부족한 면이 있습니다. 다만 vLLM의 빠름과 MCP의 확장성을 결합하여 나만의 대화형 운영 환경을 구성해 보는 일이 크게 어렵지는 않았던 것 같습니다. 글 읽어 주셔서 고맙습니다. ![]()

