Rails 애플리케이션에 MCP 서버를 추가하기 위해 fast-mcp
젬을 설치하고 초기 설정을 진행했습니다. 이 과정에서 ApplicationResource
클래스 이름 충돌이 발생하여, 모든 MCP 관련 파일을 app/mcp
디렉토리 아래로 옮기고 Zeitwerk 설정을 재구성하여 MCP
네임스페이스 아래에서 로드되도록 처리했습니다.
Zeitwerk 및 도구 로딩 문제 해결
MCP::ApplicationTool.descendants
를 통한 도구 등록 방식은 개발 환경에서 Rails의 eager loading 비활성화로 인해 초기화 시점에 도구 클래스가 로드되지 않는 문제를 야기했습니다. 이를 해결하기 위해 EAGER_LOAD
환경 변수를 통해 개발 환경에서도 필요시 eager loading이 활성화되도록 config/environment/development.rb
를 수정하고 서버를 재시작했습니다.
클라이언트 연결 및 도구 개발
서버 실행 후 curl
을 통해 SSE 연결을 확인했으며, Zed 텍스트 편집기에 내장된 MCP 클라이언트와 mcp-remote
를 활용하여 LLM과 연동했습니다. SearchBuildingsTool
과 SearchAccessLogsTool
과 같은 도구를 개발하며 LLM이 여러 도구를 조합하여 복잡한 요청을 처리할 수 있는지 시험했습니다. 초기에는 도구 설명이 불충분하여 LLM이 예상과 다른 쿼리를 생성하는 문제가 발생했습니다.
상세한 도구 설명의 중요성
MCP 프로토콜은 도구의 입력 형식 지정에 한계가 있어 LLM의 오용 가능성이 높았습니다. 이를 극복하기 위해 도구의 description
필드에 입출력 형식, 오류 상태, 가능한 열거형 값, 예상되는 날짜/시간 형식, 허용되지 않는 값 등을 매우 구체적으로 기술하는 것이 필수적임을 깨달았습니다. 예를 들어, SearchAccessLogsTool
의 설명은 건물 ID, 쿼리, 로그 시간 범위, 상태 목록 등을 명확히 정의하도록 개선되었습니다. 또한, Llama 3 7b와 같은 소규모 LLM의 입력 값 정규화를 위해 value.presence&.to_s&.strip&.singularize&.underscore
와 같은 처리가 유용하다는 점도 확인했습니다.