2025년 4월 7일 - Tmap API를 활용한 MCP 서버 구축
오늘 Tmap REST API 기반의 MCP(Model Context Protocol) 서버 구축에 성공했다. 판다스스튜디오의 'pymcp' 패키지 덕분에 구현 과정은 순조롭게 진행되었다. 이 MCP 서버는 Cursor 편집기와 Tmap API 사이의 연결 고리 역할을 하며, AI 도구가 위치 정보와 교통 데이터에 직접 접근할 수 있게 해준다.
서버 구현의 핵심 코드
서버 구현은 mcp_server.py 파일을 중심으로 이루어졌다. 다음은 MCP 서버 초기화 및 Tmap API 연동 코드의 핵심 부분이다:
import os
from pymcp import PyMCP, mcpwrap
from tmap_api.tmap_api import TmapAPI
# Tmap API 클라이언트 초기화
TMAP_APP_KEY = os.environ.get("TMAP_APP_KEY")
if not TMAP_APP_KEY:
raise ValueError("TMAP_APP_KEY 환경 변수가 설정되지 않았습니다.")
tmap_client = TmapAPI(app_key=TMAP_APP_KEY)
# MCP 서버 생성
tmap_server = PyMCP(
name="Tmap API Server",
instructions="A server providing Tmap API functions for location search, geocoding, route planning, and more"
)
이 코드는 Tmap API 클라이언트를 초기화하고 MCP 서버를 생성한다. 환경 변수에서 API 키를 가져와 안전하게 관리하는 방식을 사용했다.
Tmap API 함수를 MCP 서버에 등록하는 방식은 다음과 같이 데코레이터 패턴을 활용했다:
@tmap_server.wrap_function(name="search_poi_keyword")
def search_poi_keyword(keyword: str, search_type: str = "all", count: int = 20):
"""
Search for Points of Interest (POI) using keywords
Args:
keyword: Search keyword
search_type: Search type (all, name, telno)
count: Maximum number of search results
Returns:
POI search result data
"""
return tmap_client.search_poi_keyword(keyword, search_type, count)
이러한 방식으로 모든 Tmap API 기능을 MCP 서버에 등록했다. pymcp 라이브러리의 데코레이터 패턴을 활용해 Python 함수를 MCP 프로토콜을 통해 호출 가능한 함수로 변환했다.
서버 실행을 위해 run_mcp_server.bat 파일을 만들어 환경 설정과 실행을 자동화했다:
@echo off
echo Starting Tmap MCP Server...
rem Set environment variables if not already set
if "%TMAP_APP_KEY%"=="" (
echo TMAP_APP_KEY environment variable is not set.
echo Please set your Tmap API key:
set /p TMAP_APP_KEY="Enter your Tmap API key: "
)
rem Add current directory to Python path
set PYTHONPATH=%PYTHONPATH%;%~dp0
rem Run the MCP server
python %~dp0\mcp_server.py
pause
또한 Cursor 편집기에 MCP 서버를 등록하기 위한 setup_cursor.py 스크립트도 개발했다:
def register_mcp_server():
"""pymcp 도구를 사용하여 Cursor 편집기에 MCP 서버를 등록합니다."""
print("Registering Tmap MCP server with Cursor editor...")
# 현재 스크립트 디렉토리
script_dir = get_script_path()
# mcp_server.py 파일의 절대 경로 구성
server_path = os.path.join(script_dir, "mcp_server.py")
server_path = os.path.normpath(server_path)
# Python 인터프리터 경로
python_path = get_python_path()
# pymcp 명령어 구성
cmd = [
python_path,
"-m",
"pymcp",
"cursor",
"add-server",
"tmap-api",
server_path,
"--python",
python_path
]
# 명령어 실행
try:
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print("Successfully registered Tmap MCP server with Cursor editor!")
print(result.stdout)
else:
print("Failed to register Tmap MCP server:")
print(result.stderr)
except Exception as e:
print(f"Error registering MCP server: {e}")
이렇게 개발한 MCP 서버를 기반으로 지능형 일정 계획 시스템을 구현했다. 시스템은 다음과 같은 단계로 작동한다:
- AI(Claude, Cursor)가 순차적 사고법(Sequential Thinking)을 통해 검색 전략을 수립한다.
- 네이버 로컬서치와 블로그 API, 그리고 Tmap을 통해 주변 식당과 카페 정보를 수집한다.
- 수집된 정보를 바탕으로 사용자에게 적합한 후보 일정들을 생성한다.
- Tmap 경로 API를 활용해 각 장소 간 이동 거리와 시간을 정확히 계산한다.
이러한 접근법은 사용자가 특정 지역을 방문할 때 시간과 이동 효율성을 극대화할 수 있는 맞춤형 일정을 제공한다. Tmap의 실시간 데이터를 활용함으로써 이전의 대략적인 소요시간 예측이 아닌 현실적이고 실용적인 일정 계획이 가능해졌다.
2025년 4월 9일 - Gemini API의 멀티모달 기능 활용 연구
Google Gemini API의 멀티모달 기능을 활용한 선제적 분류 시스템 개발에 착수했다. 특히 GPT-4 Vision과의 비교 테스트를 통해 흥미로운 점을 발견했다.
Gemini는 같은 멀티모달 작업에서 GPT-4에 비해 현저히 낮은 비용으로 이미지를 처리할 수 있었다. 이는 Gemini가 base64 인코딩된 이미지를 특별한 방식으로 처리하여 토큰 수를 크게 줄이기 때문인 것으로 보인다. 이러한 비용 효율성은 대규모 이미지 처리가 필요한 프로젝트에서 상당한 경제적 이점을 제공할 것이다.
이 기술은 제품 이미지 자동 분류, 의료 영상 사전 스크리닝, 부동산 사진 분석 등 다양한 분야에서 활용 가능성이 높다. 이번 연구를 통해 Gemini가 비용 효율적인 멀티모달 AI 솔루션으로서 높은 잠재력을 가지고 있음을 확인했다.
2025년 4월 10일 - Tmap API 확장 및 대중교통 기능 통합
Tmap API의 대중교통 관련 기능을 MCP 서버에 추가로 통합했다. 새롭게 추가된 기능은 다음과 같다.
지하철 혼잡도 정보 API 연동
@tmap_server.wrap_function(name="get_subway_congestion")
def get_subway_congestion(route_nm: str, station_nm: str, dow: str = None, hh: str = None):
"""
Get train congestion information for a subway station
Args:
route_nm: Subway line name (e.g., "Line 1")
station_nm: Station name (e.g., "Seoul Station")
dow: Day of week (MON, TUE, WED, THU, FRI, SAT, SUN)
Returns current day's data if not specified
hh: Hour (05~23)
Returns current hour's data if not specified
Returns:
Train congestion information at 10-minute intervals
"""
return tmap_client.get_subway_congestion(route_nm, station_nm, dow, hh)
이 함수는 특정 지하철 노선과 역에 대한 열차 혼잡도 정보를 제공한다. 사용자는 요일과 시간을 지정하여 해당 시점의 예상 혼잡도를 조회할 수 있다.
대중교통 경로 탐색 API 연동
@tmap_server.wrap_function(name="public_transit_route")
def public_transit_route(start_x: str, start_y: str, end_x: str, end_y: str,
lang: int = 0, format: str = "json", count: int = 10,
search_dttm: str = None):
"""
Search for public transit routes
Args:
start_x: Starting point X coordinate (longitude) - WGS84
start_y: Starting point Y coordinate (latitude) - WGS84
end_x: Destination X coordinate (longitude) - WGS84
end_y: Destination Y coordinate (latitude) - WGS84
lang: Language selection (0: Korean, 1: English)
format: Output format (json, xml)
count: Maximum number of results (1~10)
search_dttm: Time machine search date (yyyymmddhhmi)
Returns:
Public transit route information
"""
return tmap_client.public_transit_route(
start_x, start_y, end_x, end_y,
lang, format, count, search_dttm
)
이 함수는 출발지와 목적지 좌표를 기반으로 대중교통 경로를 탐색한다. 버스와 지하철을 포함한 복합 경로를 제공하며, 타임머신 기능을 통해 미래 시점의 경로도 조회할 수 있다.
지하철 칸별 혼잡도 및 하차 비율 조회
@tmap_server.wrap_function(name="get_subway_car_congestion")
def get_subway_car_congestion(route_nm: str, station_nm: str, dow: str = None, hh: str = None):
"""
Get car-specific congestion information for a subway station
Args:
route_nm: Subway line name (e.g., "Line 1")
station_nm: Station name (e.g., "Seoul Station")
dow: Day of week (MON, TUE, WED, THU, FRI, SAT, SUN)
Returns current day's data if not specified
hh: Hour (05~23)
Returns current hour's data if not specified
Returns:
Car-by-car congestion information at 10-minute intervals
"""
return tmap_client.get_subway_car_congestion(route_nm, station_nm, dow, hh)
이 기능은 지하철 열차의 각 칸별 혼잡도 정보를 제공한다. 이를 통해 사용자는 덜 혼잡한 칸을 선택하여 더 쾌적한 승차 경험을 할 수 있다.
@tmap_server.wrap_function(name="get_subway_car_getoff_rate")
def get_subway_car_getoff_rate(route_nm: str, station_nm: str, dow: str = None, hh: str = None):
"""
Get car-specific passenger exit rate information for a subway station
Args:
route_nm: Subway line name (e.g., "Line 1")
station_nm: Station name (e.g., "Seoul Station")
dow: Day of week (MON, TUE, WED, THU, FRI, SAT, SUN)
Returns current day's data if not specified
hh: Hour (05~23)
Returns current hour's data if not specified
Returns:
Car-by-car passenger exit rate information at 10-minute intervals
"""
return tmap_client.get_subway_car_getoff_rate(route_nm, station_nm, dow, hh)
이 함수는 지하철 열차의 각 칸별 하차 비율 정보를 제공한다. 이를 통해 특정 역에서 어느 칸에서 많은 승객이 하차하는지 파악할 수 있다.
대중교통 경로 요약 정보 API
@tmap_server.wrap_function(name="public_transit_route_summary")
def public_transit_route_summary(start_x: str, start_y: str, end_x: str, end_y: str,
format: str = "json", count: int = 10,
search_dttm: str = None):
"""
Get summary of public transit route information
Args:
start_x: Starting point X coordinate (longitude) - WGS84
start_y: Starting point Y coordinate (latitude) - WGS84
end_x: Destination X coordinate (longitude) - WGS84
end_y: Destination Y coordinate (latitude) - WGS84
format: Output format (json, xml)
count: Maximum number of results (1~10)
search_dttm: Time machine search date (yyyymmddhhmi)
Returns:
Summary of public transit route information including total time, distance, and transfers
"""
return tmap_client.public_transit_route_summary(
start_x, start_y, end_x, end_y,
format, count, search_dttm
)
이 함수는 대중교통 경로의 요약 정보를 제공한다. 총 소요 시간, 거리, 환승 횟수 등의 정보를 간략하게 조회할 수 있어 효율적인 경로 계획을 수립하는 데 도움이 된다.
이러한 기능 확장을 통해 MCP 서버는 이제 자동차 경로뿐만 아니라 대중교통을 활용한 이동 계획도 지원할 수 있게 되었다. 사용자는 자동차와 대중교통의 이동 시간과 비용을 비교하여 최적의 이동 수단을 선택할 수 있으며, 대중교통 이용 시에는 혼잡도 정보를 참고하여 더 쾌적한 이동 경험을 누릴 수 있다.
결론 및 향후 계획
최근 연구를 통해 Tmap API 기반 MCP 서버 구축 경험이라는 중요한 성과를 이루었다. 이러한 기술적 발전은 더 스마트한 이동 및 일정 계획 솔루션의 기반이 될 것이다.
향후에는 자동화해서 일정 생성에 대한 고도화 툴을 만들어보고자 한다.
'사이드 프로젝트 연구일지' 카테고리의 다른 글
| 사이드 프로젝트 연구 일지: LLM기반 업데이트 (0) | 2025.04.06 |
|---|---|
| 프롬프트 엔지니어링 / RAG 연구일지: MCP 탐색(feat. cursor, claude) (0) | 2025.03.31 |
| 프롬프트 엔지니어링 / RAG 연구일지 (0) | 2025.03.25 |