複数の宿泊施設の料金と在庫をMCPツールで確認し、必要な施設の管理画面だけを開く構成のイメージ
숙박업소나 호텔을 두세 개 운영하는 회사는 매일 아침 '각 시설의 Jalannet 가격과 재고가 이상하지 않은지' 누군가가 확인하고 있습니다. 연휴 전에 재고가 0으로 방치되었거나, 요금 변경이 한 시설에만 반영되지 않는 등의 사고는 인지하는 것이 하루 늦어질 경우 매출에 영향을 미칩니다.
이러한 확인 작업을 AI 에이전트에게 도움받게 하고 싶다는 상담은 자주 있습니다. 하지만 여기서 가장 먼저 결정해야 할 것은 '에이전트에게 어떤 툴을 제공할 것인가'입니다. 툴 설계가 잘못되면, 에이전트는 규정에 위반하는 방식으로 데이터를 수집하거나, 확인만 하려다가 요금을 수정해 버릴 수도 있습니다.
여기서는 복수 시설의 가격과 재고를 에이전트로 확인하기 위한 MCP(Multi-Capability Platform) 툴을 설계 개념부터 구현까지 순서대로 만들어 보겠습니다. 관리 화면에 접속할 때는 BitBrowser의 MCP 서버를 사용하고, 시설별 로그인 정보를 저장한 브라우저 프로필을 확인이 필요한 시설만큼 열어둡니다.
가장 먼저 결정해야 할 것: 데이터를 어디서 가져올 것인가
에이전트에게 가격과 재고를 확인시키려고 할 때, 가장 먼저 떠오르는 방법은 'Jalannet 페이지를 읽게 하는' 것입니다. 하지만 이것은 선택하지 않습니다.
Jalannet 숙박 시설 등 예약 서비스 이용 약관에는 Jalannet을 이용하여 얻은 정보를 운영 회사와 게재 시설의 사전 승낙 없이 사적 이용 목적 외로 복제하거나 전송할 수 없으며, 제3자의 이용에 제공해서는 안 된다고 명시되어 있습니다. 자사 시설 정보라 할지라도 공개 페이지를 기계적으로 계속 읽어 나가는 구조는 약관의 취지상으로도, 사이트에 부하가 걸리는 측면에서도 피해야 합니다. 관리 화면을 자동 조작하는 것도 같은 이유로 삼가야 합니다. 관리 화면은 사람이 사용하는 것을 전제로 만들어졌으며, Jalannet 참여 안내에서도 숙박 시설용 관리 화면을 약 20년에 걸쳐 다듬어 왔다고 소개하고 있습니다.
그렇다면 데이터는 어디에 있을까요? 여러 OTA(Online Travel Agency)에 노출하는 시설의 대부분은 사이트 컨트롤러(Site Controller, 수고로움 제로, 네っぱん!사이트 컨트롤러++, TL-링컨 등)를 통해 가격과 재고를 일원 관리하고 있습니다. 사이트 컨트롤러는 Rakuten Travel이나 Jalannet, Booking.com 등에 노출하는 객실 재고와 가격을 하나의 화면에서 처리하기 위한 시스템입니다. 시설 측에게 '정답'은 여기에 존재합니다.
따라서 이번에는 다음과 같이 역할을 분담합니다.
- 확인에 사용되는 데이터는 사이트 컨트롤러나 PMS(Property Management System)로부터 시설 스스로 출력한 파일
- 에이전트는 이 파일을 읽고, 사전에 결정된 가격표와 대조하여 차이를 발견한다
- 수정 작업은 사람이 Jalannet 관리 화면이나 사이트 컨트롤러에서 진행한다
- 에이전트는 수정이 필요한 시설의 관리 화면을 열 준비만 한다
툴 설계 원칙
구현에 들어가기 전에, MCP 툴 설계를 통해 지켜야 할 규칙들을 정합니다.
첫째, 읽기 전용(Read-only)으로 하는 것입니다. 이번 툴은 파일만 읽을 뿐, 어디에도 쓰지 않습니다. 에이전트가 어떤 지시를 받더라도, 툴 쪽에서 할 수 없는 일은 일어나지 않게 합니다.
둘째, 출력을 작고 구조화하는 것입니다. 가격표 전체를 반환하면, 에이전트의 컨텍스트(Context)가 채워져 판단이 흐릿해집니다. 툴이 '문제가 있는 날짜와 객실 타입'만 반환하도록 하면, 에이전트는 결과를 정렬하여 사람에게 전달하는 데 집중할 수 있습니다.
셋째, 데이터의 신선도(Freshness)를 반드시 반환하는 것입니다. 출력 파일이 언제 생성되었는지 알 수 없다면, 어제 데이터를 가지고 '문제 없음'이라고 보고해 버릴 수 있습니다. 툴의 리턴 값에 파일 업데이트 시각을 포함시킵니다.
넷째, 시설을 이름이 아닌 키(Key)로 다루는 것입니다. '〇〇 온천 본관'과 '〇〇 온천 본관'처럼 별개의 것으로 취급될 수 있는 모호함을 키와 설정 파일로 제거합니다.
다섯째, 로그인 정보를 툴에 전달하지 않는 것입니다. 관리 화면의 로그인은 브라우저 프로필 측에 저장하고, 툴의 인자(Argument)나 반환 값에 비밀번호가 나타나지 않도록 합니다.
데이터 형태 통일하기
사이트 컨트롤러마다 출력 파일의 형태는 다릅니다. 따라서 툴이 읽을 형식을 하나로 정하고, 시설별 출력을 그 형태로 변환하는 작은 스크립트를 별도로 준비합니다. 이번 공통 형식은 다음과 같습니다.
date,room_type,plan_code,rate,remaining,stop_sell
2026-11-20,일본식 10평,STD,18000,3,0
2026-11-21,일본식 10평,STD,22000,0,0
...
remaining은 잔여 객실 수이며, stop_sell은 판매 중지 플래그입니다. 가격표(시설이 의도하는 가격) 역시 같은 방식으로 별도의 파일로 준비합니다.
date,room_type,plan_code,rate
2026-11-20,와시츠 10畳,STD,18000
2026-11-21,와시츠 10畳,STD,24000
...
시설 목록은 설정 파일에서 관리합니다. BitBrowser의 프로필 이름도 여기에 작성해 두겠습니다.
{
"honkan": { "label": "본관", "snapshot": "snapshots/honkan.csv", "plan": "plans/honkan.csv", "profile": "JLN-本館" },
"bekkan": { "label": "별관", "snapshot": "snapshots/bekkan.csv", "plan": "plans/bekkan.csv", "profile": "JLN-別館" }
...
}
변환 스크립트는 시설별로 분리한다
공통 형식으로의 변환은 사이트 컨트롤러(site controller)별, 경우에 따라서는 시설별로 작성합니다. 열 이름이나 날짜 표기 방식, 판매 중단 표시 방법 등이 출력 원본마다 다르기 때문입니다. 변환 스크립트를 툴 본체에 혼합하지 않는 이유는, 출력 원본의 사양이 변경되었을 때 수정할 위치를 한 곳으로 제한하기 위함입니다. 툴 본체는 공통 형식만 알면 충분하며, 변환상의 오류는 스크립트 측에서 완결됩니다.
변환 마무리 단계에 행 수와 날짜 범위를 표준 출력(standard output)에 표시해 두면, 아침 작업 시 '어제보다 행 수가 극단적으로 적다'와 같은 이상 징후를 사람이 감지할 수 있습니다.
MCP 서버 구현
Python의 MCP SDK (mcp 패키지의 FastMCP)로 작성합니다. 툴은 세 가지입니다.
import csv
import json
import os
...
find_issues가 반환하는 것은 문제 발생 날짜와 객실 유형, 그리고 문제 종류만입니다. 종류는 stop_sell (판매 중단), sold_out (재고 없음), rate_mismatch (요금표 불일치) 세 가지로 고정합니다. 종류를 고정해 두면 에이전트가 결과를 사람에게 전달할 때의 표현 방식이 흔들리지 않습니다.
재고 없음(sold_out)은 반드시 문제가 아닐 수 있습니다. 만실이라서 판매가 끝난 것일 수도 있기 때문입니다. 툴은 사실만을 반환하며, '판매 종료인지, 설정 오류인지'에 대한 판단은 사람에게 맡깁니다. 예약 현황을 알고 있는 담당자라면 한눈에 구분할 수 있을 것입니다. 이 경계 설정을 하는 것도 툴의 책임 범위를 작게 유지하기 위한 고안입니다.
툴 설명문을 정성껏 작성한다
MCP의 툴은 함수의 docstring이 그대로 에이전트에게 전달되는 설명서가 됩니다. 이곳을 짧게 작성하면, 에이전트는 툴 사용법을 추측으로 보완하기 시작합니다. 이번 툴에서는 날짜 형식(YYYY-MM-DD), 읽기 전용(read-only)이라는 점, 요금이나 재고를 변경하지 않는다는 점을 docstring에 명확히 기재했습니다.
반환 값의 항목명 역시 설명의 일부입니다. snapshot_updated나 issue_count처럼 이름만으로 내용이 파악되도록 해두면, 에이전트가 결과를 표로 정리할 때 혼동이 생길 가능성이 줄어듭니다. 반대로, data나 result와 같은 모호한 이름은 피해야 합니다.
BitBrowser에서 시설별 프로필을 만든다
확인 결과 수정이 필요한 시설이 발견되면, 사람이 해당 시설의 관리 화면에서 작업을 진행합니다. 시설마다 로그인(login)이 분리되어 있으면, 탭을 오가다가 다른 시설의 화면에서 요금을 변경하는 사고가 발생할 수 있습니다.
BitBrowser에서는 프로필별로 쿠키(Cookie), 로그인 상태, 열람 기록이 분리됩니다. 시설마다 프로필을 만들고, 그 프로필 안에서 자란net 시설용 관리 화면과 사이트 컨트롤러에 로그인해 둡니다. 프로필 이름은 properties.json의 profile과 일치시킵니다 (예: JLN-本館). 메모란에는 시설명, 관리 화면 로그인에 사용하는 계정, 담당자를 작성해 둡니다.
직원에게 작업을 맡길 때는 BitBrowser의 직원 관리(employee management)에서 담당 시설의 프로필만 사용 권한으로 할당합니다. 다른 시설의 프로필은 보이지 않기 때문에, 착오가 생길 여지가 애초에 없어집니다.
네트워크는 평소 작업하는 회선 그대로 사용해도 무방합니다. 자체 시설 관리 화면을 열기만 하는 것이므로 연결 출처를 바꿀 이유가 없습니다. BitBrowser의 'IP 국가가 바뀌면 프로필을 열지 않음' 설정을 켜두면, 출장지 회선에서 예상치 못한 연결이 발생하는 것을 막을 수 있습니다.
施設ごとのBitBrowserプロフィールと、出力ファイルを読むMCPツールの関係を示すイメージ
툴은 파일을 읽어 불일치를 발견하고, BitBrowser는 수정이 필요한 시설의 프로필만 열게 합니다
BitBrowser와 MCP 연동하기
BitBrowser는 클라이언트 7.1.5부터 MCP 서버를 내장하고 있습니다. 이 툴에는 프로필, 그룹, 태그, 프록시, 창(Window), 클라우드 스마트폰을 다루는 기능들이 포함되어 있습니다.
- BitBrowser 설정에서 '브라우저 설정'을 열고 '로컬 API'로 이동합니다.
- 인증을 활성화하고 API 토큰을 기록해 둡니다. 클라이언트는 이를
x-api-key 헤더로 전송합니다. - BitBrowser가 표시하는 MCP 설정을 사용 중인 클라이언트에 추가해야 합니다. 연결 주소는 보통 http://127.0.0.1:54345/mcp입니다.
자체 제작한 property-inventory는 로컬에서 실행되는 stdio 서버로 등록합니다.
{
"mcpServers": {
"property-inventory": {
...
아침 점검 절차
매일 아침, 사이트 컨트롤러(Site Controller)에서 각 시설의 파일을 출력하고 공통 형식으로 변환한 후, 에이전트에게 다음 지시를 내립니다.
1. property-inventory의 list_properties로 시설 목록을 가져옵니다.
2. 각 시설에 대해 snapshot_age를 호출하여 오늘 6시보다 오래된 파일이 있다면, 해당 시설명을 제시하고 중지합니다.
...
두 번째 절차가 바로 '신선도 원칙'을 실제로 적용하는 부분입니다. 출력 시간을 정해 두면 에이전트가 판단에 사용하는 데이터의 날짜가 통일되어, 시설별로 오래된 것과 새로운 것이 섞이는 일이 없습니다. 오래된 파일 그대로 '문제 없음'으로 보고되는 것이 가장 위험하므로, 여기서 중지합니다. 5초를 기다리는 것은 BitBrowser 로컬 API 사용 시 주의사항인 '프로필을 닫은 후에는 브라우저 프로세스가 끝날 때까지 기다린다'는 내용에 맞춘 것입니다.
AIエージェントが施設ごとの問題件数をまとめ、料金のずれがある施設のプロフィールから順に開く様子
요금 불일치나 판매 중단이 있는 시설만, 건수가 많은 순서대로 하나씩 열어봅니다
스마트폰 화면 확인 방법
요금 확인과는 별도로, 시설 페이지가 스마트폰에서 어떻게 보이는지 확인하고 싶은 경우도 있습니다. Jalannet으로 예약하는 사람들은 대부분 스마트폰을 사용하기 때문입니다. 손에 든 단말기에서는 하나의 환경만 볼 수 있으므로, BitCloudPhone의 클라우드 안드로이드 단말기를 사용하는 방법이 있습니다. PC에서 조작할 수 있으며 앱이나 파일을 단말기별로 분리하여 보관할 수 있습니다. iPhone에서의 표시는 BitCloudPhone-iOS로 확인할 수 있습니다. 이는 iPhone SE 실물 기기에서 구동되는 iOS이며, 앱은 미리 준비된 앱 마켓으로부터 설치하는 방식입니다. 화면 확인은 사람이 직접 눈으로 하고, 에이전트에게는 단말기의 시작과 중지 역할만 맡깁니다.
자주 묻는 질문
Jalannet 화면에서 데이터를 직접 가져오는 것이 빠르지 않나요?
이용 약관에서는 Jalannet에서 얻은 정보를 승낙 없이 사적 이용 목적 외의 용도로 복제하거나 전송하는 것을 금하고 있습니다. 시설 측의 정확한 데이터는 사이트 컨트롤러나 PMS에 있으므로, 거기서 출력한 파일을 사용하는 것이 더 확실하며 약관 걱정도 없습니다.
에이전트가 요금을 수정하게 할 수 있나요?
이 설계에서는 의도적으로 그렇게 하지 않았습니다. 요금과 재고는 판매와 직결되기 때문에 사람이 화면에서 확인하고 수정합니다.
시설이 늘어나면 무엇을 변경해야 하나요?
properties.json에 한 줄 추가하고, 출력 파일 변환 스크립트와 같은 이름의 BitBrowser 프로필만 준비하면 됩니다. 툴 코드는 바뀌지 않습니다.
사이트 컨트롤러를 사용하지 않는 시설은요?
Jalannet 관리 화면에서 사람이 확인한 내용을 동일한 공통 형식으로 기록하는 방법이 있습니다. 수작업은 남아있지만, 에이전트가 불일치를 발견하는 부분은 똑같이 사용할 수 있습니다.
다음 단계
우선 두 시설, 그리고 앞으로 14일치 데이터만 가지고 find_issues를 실행해 보세요. 공통 형식으로의 변환과 요금표 정비가 완료되면, 시설을 늘려도 아침 점검에 걸리는 시간은 거의 달라지지 않습니다. 툴은 읽기만 하고, 수정은 사람이 하며, 에이전트는 그 사이의 준비 역할을 합니다. 이 분담 구조를 무너뜨리지 않는 것이 판매와 관련된 데이터를 에이전트에게 처리하게 할 때 가장 안전한 방법입니다.
Discussion