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 서버를 기반으로 지능형 일정 계획 시스템을 구현했다. 시스템은 다음과 같은 단계로 작동한다:

  1. AI(Claude, Cursor)가 순차적 사고법(Sequential Thinking)을 통해 검색 전략을 수립한다.
  2. 네이버 로컬서치와 블로그 API, 그리고 Tmap을 통해 주변 식당과 카페 정보를 수집한다.
  3. 수집된 정보를 바탕으로 사용자에게 적합한 후보 일정들을 생성한다.
  4. 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 서버 구축 경험이라는 중요한 성과를 이루었다. 이러한 기술적 발전은 더 스마트한 이동 및 일정 계획 솔루션의 기반이 될 것이다.

향후에는 자동화해서 일정 생성에 대한 고도화 툴을 만들어보고자 한다.

 

+ Recent posts