Skip to main content
Glama

stay-search MCP

Airbnb(한국)와 야놀자 NOL의 숙소 검색 결과를 수집해 가격·시장 데이터를 분석하는 MCP 서버. Claude가 직접 호출할 수 있는 툴 4개를 제공하고, 수집한 결과를 SQLite에 스냅샷으로 쌓아 추이를 본다.

사용

Claude Code / Desktop에 등록한 뒤 자연어로 물으면 된다.

9월 10~12일 서울 2인, Airbnb랑 야놀자 가격대 비교해줘

역할

search_stays

지역·날짜·인원으로 숙소 목록 수집 (+ 자동 스냅샷 저장)

compare_prices

소스별 1박 가격 분포(중앙값·사분위·유형별) 비교

price_history

저장된 스냅샷에서 일자별 가격 중앙값 추이 조회

list_snapshots

어떤 지역·기간이 수집돼 있는지 목록

지역 지정

region서울·제주·강릉 같은 한글 지명을 그대로 넣으면 된다 — 주요 국내 지역은 Airbnb용 영문 슬러그로 자동 변환된다 (src/sources/airbnb.tsKOREAN_SLUGS).

변환 목록에 없는 지역은 airbnbRegion에 슬러그를 직접 지정한다:

airbnbRegion: "Sokcho--South-Korea"

왜 필요한가: Airbnb는 URL 경로의 지역을 City--Country 슬러그로만 해석한다. 한글이나 자유 텍스트를 넘기면 오류 없이 전 세계 숙소를 섞어서 반환한다. 이걸 그대로 통계에 넣으면 조용히 틀린 시세가 나오므로, 결과 좌표가 5도 이상 흩어지면 에러를 던진다.

Related MCP server: korea-realestate-mcp

개발

npm install
npm run build

# 소스 어댑터만 단독 검증 (파서가 깨졌는지 가르는 첫 도구)
npx tsx scripts/probe-airbnb.ts "Seoul--South-Korea" 2026-09-10 2026-09-12 2
SOURCE=yanolja npx tsx scripts/probe-airbnb.ts 서울 2026-09-10 2026-09-12 2

# MCP 툴 수동 호출
npm run inspect

scripts/probe-yanolja.tsprobe-yanolja-api.ts는 야놀자의 내부 검색 엔드포인트를 찾아낼 때 쓴 Playwright 진단 스크립트다. 야놀자가 API를 바꾸면 다시 돌려서 새 형태를 확인한다. 평상시 수집에는 브라우저가 필요 없다.

구조

src/index.ts          MCP 서버 · 툴 4개 등록
src/types.ts          두 소스를 맞춘 정규화 Listing 타입
src/sources/airbnb.ts 검색 페이지 HTML의 내장 JSON 파싱
src/sources/yanolja.ts universal-search API POST
src/store.ts          node:sqlite 스냅샷 저장/조회
src/stats.ts          1박 기준 가격 분포 집계
src/throttle.ts       호스트별 직렬 요청 + 최소 간격 + TTL 캐시

데이터 해석 시 주의

  • 가격 기준: Airbnb는 총액, 야놀자는 1박가로 표시된다. 모든 통계는 1박 기준으로 정규화한 값.

  • 야놀자 광고 표기: 검색 결과가 사실상 전량 광고로 표시된다. 제외하면 표본이 거의 남지 않으므로 기본 포함이고, 필요하면 excludeAds: true로 걷어낸다.

  • Airbnb 가격 누락: 일부 숙소는 가격이 비어 온다(해당 날짜 예약 불가 등). 통계에서 제외되며 건수를 경고로 알린다.

  • 야놀자 좌표 없음: 검색 응답에 위경도가 없어 lat/lng는 null이다.

수집 정책

두 사이트 모두 이용약관상 자동 수집을 허용하지 않으며, 야놀자는 robots.txt로 /discovery/ 경로를 차단하고 있다. 개인 분석 범위를 넘지 않도록 코드 레벨에서 강제한다:

  • 호스트당 직렬 요청 + 최소 간격 (Airbnb 1.5초, 야놀자 3초)

  • 같은 조건 재조회는 6시간 캐시로 받아 중복 요청을 내지 않음

  • 안티봇 우회 로직 없음 — 차단되면 그대로 에러를 올린다

상업적 재배포로 용도가 확장되면 야놀자는 제휴 문의, Airbnb는 파트너 API 경로를 별도로 검토해야 한다.

Available Tools

4 tools
compare_prices가격 분포 비교A

같은 조건에서 Airbnb와 야놀자의 1박 가격 분포(중앙값·사분위·유형별)를 비교합니다. 개별 숙소가 아니라 "어느 플랫폼이 싼가", "이 지역 시세가 얼마인가"를 물을 때 호출하세요. 두 사이트의 표시 기준(총액 vs 1박)을 1박으로 정규화해 비교합니다.

ParametersJSON Schema
NameRequiredDescriptionDefault
adultsNo성인 인원 수
regionYes검색할 지역. "서울"·"제주"·"강릉" 같은 한글 지명을 그대로 넣으면 됩니다 (주요 국내 지역은 Airbnb용 영문 슬러그로 자동 변환). 변환 목록에 없는 지역은 airbnbRegion에 슬러그를 직접 지정하세요.
checkinYes체크인 날짜 YYYY-MM-DD
checkoutYes체크아웃 날짜 YYYY-MM-DD
maxPagesNo
excludeAdsNo광고 표기 숙소 제외 여부. 야놀자는 검색 결과 대부분이 광고로 표시되므로 기본은 포함입니다.
airbnbRegionNoAirbnb에만 쓸 지역 슬러그 오버라이드. 형식은 "Seoul--South-Korea"처럼 City--Country. region이 자동 변환되지 않는 지역일 때 사용하세요.
yanoljaRegionNo야놀자에만 쓸 검색 키워드 오버라이드 (한글).

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It does disclose a key behavioral trait: normalizing both sites' display standards (total vs per-night) to per-night prices. However, it does not mention whether this is a read-only operation, any rate limits, or output format, which are important for an unannotated tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, front-loaded with purpose, then usage, then normalization detail. Every sentence contributes meaningful information with no fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 8 parameters, 3 required, and no output schema. The description covers purpose, usage, and normalization, and even hints at output content (median, quartiles, by type). However, it lacks an explicit description of the return format or possible errors, which would be more critical given the absence of an output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 88%, so most parameters are already documented in the schema. The description does not add significant param-specific semantics; it only implies 'same conditions' anchoring to region, checkin, and checkout. The undocumented maxPages parameter is not compensated by the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool compares one-night price distributions (median, quartiles, by type) between Airbnb and Yanolja under the same conditions. It explicitly distinguishes itself from individual listing searches with '개별 숙소가 아니라', which differentiates it from sibling tool search_stays.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use the tool: when asking 'which platform is cheaper' or 'what is the market rate in this area'. It also gives a clear exclusion by noting it is not for individual listings, which helps avoid misuse. However, it does not name specific sibling tools as alternatives, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_snapshots수집 이력 목록A

어떤 지역·기간·소스의 데이터가 DB에 쌓여 있는지 보여줍니다. price_history를 부르기 전에 무엇이 조회 가능한지 확인할 때, 또는 사용자가 "뭘 모아뒀지"라고 물을 때 호출하세요.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It implies a read-only operation ('shows') but does not explicitly state that it has no side effects, nor does it disclose return format or limitations. Purpose is clear, but behavioral details are minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core function and followed by usage guidance. Every word earns its place, with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters and no output schema, the description adequately explains what the tool does and when to use it. It implies the return structure (region, period, source dimensions) but does not explicitly outline it, which would be helpful for an agent. Still, it is sufficiently complete for a simple listing tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and schema description coverage is 100% (vacuously). The baseline for 0 params is 4, and while the description adds no parameter-specific semantics, none are needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool shows which region, period, and source data is accumulated in the DB. It explicitly distinguishes itself from the sibling tool price_history by positioning itself as a pre-check before calling that tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance: call it before price_history to verify queryability, or when the user asks what data has been collected. This is a clear, actionable directive that also names an alternative tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

price_history가격 추이 조회A

이전에 수집해 둔 스냅샷에서 일자별 1박 가격 중앙값 추이를 읽습니다. "지난주보다 올랐나", "가격이 어떻게 변했나"처럼 시간에 따른 변화를 물을 때 호출하세요. 새로 수집하지 않고 DB만 읽으므로 빠릅니다. 데이터가 없으면 먼저 search_stays를 여러 날에 걸쳐 실행해야 합니다.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNo종료일 YYYY-MM-DD
fromNo시작일 YYYY-MM-DD
regionYessearch_stays에 사용했던 것과 동일한 지역 문자열
sourceNo
excludeAdsNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses that the tool reads from the DB only, is fast, and requires prior snapshot collection. It also warns that without data, search_stays must be run first. However, it does not specify what happens if no data exists, leaving a minor transparency gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core function, then examples, then speed and prerequisite. Each sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 5 parameters and no output schema, the description covers the essential context: purpose, when to use, and prerequisite. However, it does not describe the exact return shape or behavior when no data exists, so it's slightly incomplete for a no-output-schema tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 60%, and the description adds some context (snapshot-based, region must match search_stays) but does not meaningfully explain the from/to, source, or excludeAds parameters beyond what the schema provides. The description reinforces that region must align with prior searches but adds no new parameter-level detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reads daily median price trends from previously collected snapshots, using a specific verb and resource. It distinguishes from siblings by emphasizing it uses pre-collected data and is a read-only DB operation, and it provides example queries that clarify its function.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to call this tool: when users ask about price changes over time. It also gives a clear prerequisite: if no data exists, run search_stays first over multiple days. This provides both positive and negative usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_stays숙소 검색A

특정 지역·날짜·인원의 숙소 목록을 Airbnb와 야놀자에서 가져옵니다. 사용자가 여행 날짜와 지역을 말하며 "숙소 찾아줘", "어디가 싼지 알려줘"라고 할 때 호출하세요. 결과는 자동으로 DB에 스냅샷 저장되어 나중에 price_history로 추이를 볼 수 있습니다.

ParametersJSON Schema
NameRequiredDescriptionDefault
adultsNo성인 인원 수
regionYes검색할 지역. "서울"·"제주"·"강릉" 같은 한글 지명을 그대로 넣으면 됩니다 (주요 국내 지역은 Airbnb용 영문 슬러그로 자동 변환). 변환 목록에 없는 지역은 airbnbRegion에 슬러그를 직접 지정하세요.
sourceNo수집할 사이트. 한쪽만 필요하면 지정하세요.both
checkinYes체크인 날짜 YYYY-MM-DD
checkoutYes체크아웃 날짜 YYYY-MM-DD
maxPagesNo소스별 최대 페이지 수. Airbnb는 18건/페이지, 야놀자는 20건/페이지입니다.
airbnbRegionNoAirbnb에만 쓸 지역 슬러그 오버라이드. 형식은 "Seoul--South-Korea"처럼 City--Country. region이 자동 변환되지 않는 지역일 때 사용하세요.
yanoljaRegionNo야놀자에만 쓸 검색 키워드 오버라이드 (한글).

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It discloses a key side effect: results are automatically saved as DB snapshots for later price_history. However, it omits other behavioral details such as rate limits, pagination behavior, or return format, which are important for a web-scraping tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core action and resource. The second sentence provides usage trigger and side effect. No redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description must explain return values. It only says '숙소 목록' (accommodation list) without specifying fields like price, rating, or URL. Given the tool's complexity and lack of output schema, this is a significant gap for an agent to correctly present or process results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The description adds no param information beyond the schema, which already richly documents region conversion, overrides, and per-site fields. The description's mention of '지역·날짜·인원' only paraphrases existing schema content.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool fetches accommodation lists for a specific region/date/person count from Airbnb and Yanolja. It includes a specific verb '가져옵니다' (fetches) and a clear resource. It also distinguishes from siblings by mentioning the snapshot saving that feeds into price_history.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to call: when the user mentions travel dates and region and says '숙소 찾아줘' or '어디가 싼지 알려줘'. Provides context but does not explicitly exclude alternatives like compare_prices, though sibling names imply their roles.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedcompare_prices
    • First observedlist_snapshots
    • First observedprice_history
    • First observedsearch_stays

TDQS

A4.1/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clear, distinct purpose: search_stays fetches current listings, compare_prices compares price distributions between platforms, price_history reads historical trends, and list_snapshots shows available data. There is no overlap or ambiguity between them.

Naming Consistency4/5

Three tools follow the verb_noun pattern (search_stays, compare_prices, list_snapshots), but price_history is a noun phrase and breaks the pattern. While the names are still readable and clear, the inconsistency prevents a perfect score.

Tool Count5/5

With only 4 tools, the server is well-scoped for its purpose of stay search, price comparison, and historical trend analysis. Each tool earns its place and there is no bloat or redundancy.

Completeness4/5

The server covers the core workflow of searching, comparing, and tracking price history, with list_snapshots providing metadata. However, there is no way to retrieve the raw saved snapshot listings themselves, only the price history medians, which is a minor gap for users who want to inspect past search results in detail.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables automated collection of apartment listing data from Naver Real Estate using Playwright browser automation with passive network response capture. Provides MCP tools to search complexes, resolve property identifiers, and extract normalized listing information including duplicate properties.
    -
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI agents to query and analyze Korean apartment real estate transaction prices (sales and rentals) using natural language, providing tools for price trends, regional comparisons, and rent ratios.
    7
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables scraping LLM inference pricing from websites like Cloudrift, DeepInfra, Fireworks, and Groq, storing results in SQLite for cost comparison.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables querying Korean apartment sales and rental transaction data from the public data portal through natural language, with tools for searching transactions and computing price statistics.
    51
    MIT