시간 추적기 애플리케이션의 대화형 전환
기존의 Slack 알림 기반 시간 추적기를 “오늘 Test 프로젝트에 8시간 기록해줘”와 같은 자연어 명령으로 제어할 수 있는 대화형 인터페이스로 발전시키고자 했습니다. 이는 사용자 경험을 혁신할 잠재력을 가집니다.
fast-mcp
를 활용한 Rails 통합
Ruby용 MCP 구현체인 fast-mcp
젬을 사용하여 Rails 애플리케이션에 MCP 서버를 구축하는 과정은 다음과 같이 간단합니다.
* Gemfile에 fast-mcp
를 추가하고 bundle install
을 실행합니다.
* rails generate fast_mcp:install
명령을 통해 서버 설정 파일, 샘플 리소스 및 도구를 생성합니다.
* 생성된 MCP 서버는 Rails 앱 시작 시 함께 실행되며, MCP 클라이언트(AI 모델)는 해당 서버에 연결하여 리소스와 도구를 활용할 수 있습니다. npx @modelcontextprotocol/inspector
를 통해 서버를 테스트하고 디버깅할 수 있습니다.
리소스 정의
MCP 리소스는 AI 모델에 구조화된 정보를 제공합니다. 예를 들어, 시간 추적기 MCP 서버는 timetracker://projects
라는 리소스를 정의하여 활성 프로젝트 목록을 반환합니다.
ruby
class ProjectsResource < ApplicationResource
uri "timetracker://projects"
resource_name "Projects"
description "Active projects"
mime_type "application/json"
def content
JSON.generate(Project.active.as_json)
end
end
이 리소스는 시간 기록 항목을 생성하기 전에 필요한 프로젝트 정보를 AI가 얻을 수 있도록 합니다.
인증 구현
MCP 서버의 보안을 위해 토큰 기반 인증이 필수적입니다.
* fast-mcp
는 베어러 토큰(bearer token)을 통한 서버 연결 인증을 지원합니다.
* 사용자 식별을 위해 User
모델에 mcp_token
필드를 추가하고, ApplicationTool
내 current_user
메서드에서 X-MCP-Token
헤더를 사용하여 사용자를 인증합니다.
ruby
class ApplicationTool < ActionTool::Base
private
def current_user
user = User.active.find_by mcp_token: headers["x-mcp-token"]
raise "MCP Token is invalid" unless user.present?
user
end
end
이를 통해 도구 호출 시 항상 인증된 사용자 컨텍스트를 확보할 수 있습니다.
도구 정의
도구는 AI 모델이 실제 작업을 수행하도록 하는 서버 측 함수입니다. CreateEntryTool
은 시간 기록을 생성하는 예시 도구입니다.
ruby
class CreateEntryTool < ApplicationTool
description "Create an entry"
arguments do
required(:project_id).filled(:integer).description("ID of the project, use the projects resource if it's unknown")
optional(:date).maybe(:date).description("Date of the entry")
required(:duration).filled(:string).description("Duration of the entry, always a float (eg. 2.0)")
optional(:comments).maybe(:string).description("Comments, leave empty if it hasn't been provided")
end
def call(project_id:, duration:, comments: nil, date: Date.current)
Entry.create(date: date, duration: duration.to_f, project_id: project_id, user: current_user, comments: comments)
"Entry was successfully created."
end
end
* arguments
블록은 dry-schema
를 사용하여 도구의 입력 인자를 정의하며, 각 인자의 description
은 LLM이 도구를 호출하는 방식을 결정하는 데 매우 중요합니다.
* call
메서드는 LLM이 전송한 인자를 받아 실제 로직(시간 기록 생성)을 수행하고, 결과를 문자열로 반환합니다.
LLM과의 상호작용
“어제 Test 프로젝트에 4시간 기록해줘”와 같은 사용자 프롬프트에 대해 AI 에이전트는 다음과 같이 반응합니다.
1. 프롬프트에서 duration
과 date
를 추출합니다.
2. project_id
가 명시되지 않았으므로, timetracker://projects
리소스를 호출하여 “Test” 프로젝트의 ID를 찾습니다.
3. 찾아낸 정보(project_id
, duration
, date
)를 바탕으로 CreateEntryTool
을 호출하여 시간 기록을 생성합니다.
이 과정은 AI 모델이 사용자의 의도를 이해하고 필요한 도구와 리소스를 자율적으로 활용하여 작업을 완료하는 능력을 보여줍니다.