booking-gap MCP Server
This MCP server analyzes idle time in booking calendars for exclusive resources (e.g., rooms, studios), separating sellable gaps from structural dead time caused by booking rules.
booking_gap_analyze: Measures sellable vs. dead idle time; returns utilization, fragmentation rate, gap-length histogram, and per-resource breakdown.booking_gap_profile: Shows when dead time occurs by weekday and hour, with worst weekday–hour cells and a bar chart.booking_gap_simulate: Compares booking configurations (minimum booking length, start grid, turnover time) and shows recovered dead time vs. baseline.booking_gap_list_dead: Lists individual unsellable gaps, longest first, filterable by resource; supports JSON output.Input: Accepts bookings as structured objects or CSV/TSV with English/Japanese headers; configurable opening hours including exceptions and closed dates.
Settings: Minimum booking length, slot granularity, turnover time, and hourly rate for monetary valuation.
Privacy/operation: Uses only start/end time and resource label; offline, stateless, no personal data.
Scope: Exclusive resources only; reports recovered time as an upper bound without making configuration recommendations.
booking-gap-mcp-server
Utilization tells you how much idle time you have. It does not tell you what shape it is in.
Two venues can both sit at 33% utilization. One has its empty time in long, bookable blocks. The other has it scattered into slivers that no customer can ever book. The utilization number is identical. The businesses are not.
This MCP server measures the shape of idle time in a booking calendar, and separates it into two buckets:
Sellable gaps — long enough to book once turnover time and the start grid are accounted for
Structural dead time — cannot be sold under the current settings, no matter how good the marketing is
Marketing does not fix structural dead time. Only changing the booking rules does.
Fully offline. No API key. No external services. Zero runtime dependencies beyond the MCP SDK.
The problem it makes visible
An 80-minute gap sounds sellable. Often it is not:
Booking ends 12:00
Turnover (15 min) 12:00 - 12:15
Next start allowed at 12:30 <- the booking grid only permits :00 and :30
Latest possible end 13:05 <- 15 min turnover before the 13:20 booking
-----
Actually bookable 35 min with a 60-minute minimum, this is unsellableThe gap looks like 1h 20m on the calendar. 100% of it is dead.
Do that a few times a day across a few rooms and it compounds into hours per week that never appear as a problem anywhere — the calendar looks busy, the utilization looks normal, and the revenue quietly is not there.
Related MCP server: Floyd
Tools
Tool | What it answers |
| How much of my idle time is actually sellable? |
| Which weekdays and hours is the dead time concentrated in? |
| If I allowed 30-minute bookings, how many hours would become sellable? |
| Which specific dates and rooms produced it? |
Example output
## Shape of the idle time
Sellable gaps : 35 gaps / 197h -> 179.5h actually bookable
Structural dead : 90 gaps / 60.5h (¥121,000)
Overhead in gaps : 17.5h (turnover + start-grid alignment)
Fragmentation rate : 23.5% of idle time is unsellablescenario min grid turn dead delta frag
current (60/30/15) 60 30 15 60.5h baseline 23.5%
30-min minimum 30 30 15 37.2h -23.3h 14.4%
15-min start grid 60 15 15 60.5h ±0h 23.5%
30-min min + 15 grid 30 15 15 29.2h -31.3h 11.3%
faster turnover (5m) 60 30 5 60.5h ±0h 23.5%Note what that comparison reveals: shortening turnover alone changes nothing, because the coarse start grid is the real constraint. That is the kind of thing a single utilization percentage can never show you.
What it deliberately does not do
It measures. It does not recommend.
The tool will tell you that a 30-minute minimum would make 23 hours sellable. It will not tell you to switch to a 30-minute minimum. Shorter slots change your price positioning, your cleaning load, and your customer mix. Those trade-offs belong to the operator, not to a calculator.
Recovered minutes are also an upper bound. They show what becomes sellable, not what will sell.
Scope
Exclusive resources only — rooms, studios, meeting rooms, photo sets, treatment beds, courts. Anything where one booking occupies one unit for a stretch of time.
Pooled shared seating is not supported. Where any free seat can absorb a booking, the constraint is concurrent headcount against capacity, and the concept of a "gap" does not apply the same way. Running that model through this tool would produce plausible-looking but meaningless numbers, so it is out of scope rather than approximated.
Install
Requires Node.js 18 or later.
git clone https://github.com/h-kazuki-pixel/booking-gap-mcp-server.git
cd booking-gap-mcp-server
npm install
npm run buildAdd to your Claude Desktop config
(~/Library/Application Support/Claude/claude_desktop_config.json on macOS,
%APPDATA%\Claude\claude_desktop_config.json on Windows):
{
"mcpServers": {
"booking-gap": {
"command": "node",
"args": ["/absolute/path/to/booking-gap-mcp-server/dist/index.js"]
}
}
}Restart Claude Desktop.
Input
Paste a CSV export, or pass structured objects. Column names are matched in English and Japanese.
date,start,end,room,status
2026-08-03,09:00,10:30,Room A,confirmed
2026-08-03,11:00,12:00,Room A,confirmed
2026-08-03,13:20,16:00,Room A,confirmedRecognised column names include start / end / resource / date / status, and
開始時刻 / 終了時刻 / 部屋 / 日付 / ステータス, among others. Full datetimes
(2026-08-03 09:00, 2026-08-03T09:00:00+09:00) work with or without a separate date column.
Rows whose status contains a cancellation word are excluded automatically.
Opening hours:
{
"default": [["09:00", "22:00"]],
"sun": [["10:00", "18:00"]],
"closedDates": ["2026-08-11"],
"exceptions": { "2026-08-14": [["12:00", "20:00"]] }
}Split hours (a lunch break) are supported by listing more than one range. Use "24:00" to close at midnight.
Settings that decide sellability
Setting | Meaning | Default |
| Shortest booking a customer may make | 60 |
| Allowed start times, measured from midnight | 30 |
| Cleaning / changeover required between bookings | 0 |
hourlyRate is optional and has no default. Supply it only if you want dead time expressed as an amount.
Privacy
The server accepts start time, end time, and a resource label. That is all.
There is no field for a guest name, contact detail, or payment. Nothing is written to disk, and nothing leaves your machine — every calculation is local and stateless. You can hand it a calendar export without sanitising it first, because the columns it reads cannot carry personal data.
日本語
稼働率は「量」しか教えてくれません。「形」は教えてくれない。
稼働率30%が2つあっても、空きが「連続3時間×1回」なのか「20分×9回」なのかで、売れる見込みは全く違います。それでも数字上は同じ30%です。
このMCPサーバーは、予約カレンダーの空き時間を次の2つに分解します。
販売可能な空き — 転換時間と開始時刻の刻みを差し引いても、まだ最小予約単位以上ある空き
構造的デッドタイム — 現在の設定では、どれだけ集客しても絶対に売れない空き
集客では構造的デッドタイムは埋まりません。予約ルールの設計を変えるしかない。
見えていなかった問題
80分の空きは、一見売れそうに見えます。実際には売れないことがよくあります。
前の予約が終了 12:00
清掃・転換(15分) 12:00 - 12:15
開始できる最短時刻 12:30 ← 予約開始は :00 と :30 のみ
終了できる最遅時刻 13:05 ← 次の13:20の予約前に15分の転換が必要
-----
実際に売れる時間 35分 最小予約単位が60分なら、販売不能カレンダー上は「1時間20分の空き」。その100%が死んでいます。
ツール
ツール | 答える問い |
| 空き時間のうち、実際に売れるのはどれだけか |
| デッドタイムはどの曜日・時間帯に集中しているか |
| 最小予約単位を30分にしたら、何時間が売れるようになるか |
| どの日・どの部屋で発生しているか |
やらないこと
測るだけで、推奨はしません。 「30分刻みにすれば23時間が売れるようになる」とは出しますが、「30分刻みにすべき」とは言いません。単価設定・清掃負荷・客層への影響は運営者が判断すべきことです。
また、回収可能時間は上限値です。「売れるようになる時間」であって「売れる時間」ではありません。
対象範囲
排他型リソースのみ(会議室・スタジオ・撮影スペース・施術ベッド・コート等)。
プール型の共有座席は対象外です。 空いている席ならどれでも予約を受けられる形態では、制約は「同時利用数 対 定員」であり、「隙間」という概念が同じようには成立しません。無理に同じロジックを通すと、もっともらしいが意味のない数字が出ます。近似せず、対象外としています。
個人情報について
受け取るのは開始時刻・終了時刻・リソース名だけです。氏名・連絡先・金額の入力欄は存在しません。ディスクへの書き込みも外部送信もなく、すべてローカルで完結します。予約データを加工せずそのまま渡しても、個人情報が入る余地がありません。
Development
npm install
npm run build
npm test # 35 unit tests
node test/live-check.mjs # end-to-end check over the MCP protocolBackground
Built from experience running unstaffed, time-based spaces, where the gap between "the calendar looks busy" and "the revenue is there" turned out to be a measurable thing.
License
MIT
Available Tools
4 toolsbooking_gap_analyzeAnalyze booking gapsARead-onlyIdempotent
Measure the shape of idle time in a time-based booking calendar, not just the utilization rate.
Two venues can both sit at 33% utilization while one has its idle time in long sellable blocks and the other has it scattered into slivers that can never be sold. This tool separates the two.
It classifies every gap between bookings as either:
sellable: long enough to book after turnover time and start-grid alignment are subtracted
structural dead time: too short to ever be sold under the current settings
Args:
bookings or bookingsCsv (required, exactly one)
openingHours (required)
minBookingMinutes, slotGranularityMinutes, turnoverMinutes: the settings that decide sellability
periodStart / periodEnd: analysis window (defaults to the span of the data)
resources: include resources that had no bookings
hourlyRate / currency: optional, expresses dead time as an amount
Returns a text report with utilization, sellable vs dead breakdown, fragmentation rate, a gap-length histogram, and a per-resource table.
Scope: exclusive resources only (rooms, studios, meeting rooms, treatment beds). Pooled shared seating, where any free seat can absorb a booking, uses a different model and is not supported.
Use when: "why is my utilization stuck", "how much of my empty time is actually sellable", "is my calendar fragmented". Don't use when: you want a recommended configuration — use booking_gap_simulate to compare options and decide yourself.
| Name | Required | Description | Default |
|---|---|---|---|
| bookings | No | Bookings as structured objects. Provide either this or bookingsCsv. | |
| currency | No | Currency symbol prefix, e.g. "¥". | |
| periodEnd | No | Last date to analyse (YYYY-MM-DD). Defaults to the latest booking. | |
| resources | No | Resources to include even when they have no bookings in the period. | |
| hourlyRate | No | Optional hourly price, used to express dead time as an amount. No default. | |
| bookingsCsv | No | Bookings as pasted CSV or TSV with a header row. Column names are matched in English and Japanese (start/end/resource/date/status, 開始時刻/終了時刻/部屋/日付/ステータス). A separate date column plus HH:mm times is supported. | |
| periodStart | No | First date to analyse (YYYY-MM-DD). Defaults to the earliest booking. | |
| openingHours | Yes | Opening hours. Use "default" for the usual day and override individual weekdays as needed, e.g. {"default": [["09:00","22:00"]], "sun": [["10:00","18:00"]]}. Use "24:00" to close at midnight. | |
| timezoneOffset | No | Venue timezone offset, used only for inputs that carry an explicit offset or "Z". | +09:00 |
| turnoverMinutes | No | Cleaning or changeover time required between two bookings. | |
| minBookingMinutes | No | Shortest booking a customer is allowed to make. | |
| slotGranularityMinutes | No | Allowed booking start interval, measured from midnight (30 means :00 and :30). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds deep behavioral context beyond the readOnlyHint/idempotentHint annotations: it explains how gaps are classified into 'sellable' vs 'structural dead time', that it returns a text report with specific components, and that pooled shared seating is explicitly out of scope. It also clarifies the role of the settings (minBookingMinutes, slotGranularityMinutes, turnoverMinutes) in determining sellability, which is vital for the agent to understand the tool's decision logic.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every section earns its place: a motivating example, gap classification definitions, an Args list that maps to parameters, a Returns summary, and a Scope paragraph. It's well-structured with headers and bullet-like formatting, making it easy to scan while conveying all necessary information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 12 parameters, nested objects, and no output schema, this description is exceptionally complete. It covers the input formats (structured objects or CSV), the analysis window defaults, the meaning of the optional hourly rate, the scope limitations, and the exact contents of the returned report. Nothing essential is left unexplained, and the tool's complexity is matched by the description's detail.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. However, the description adds meaningful value by stating that bookings and bookingsCsv are required but exactly one must be provided, and by grouping minBookingMinutes/slotGranularityMinutes/turnoverMinutes as 'the settings that decide sellability'. This gives higher-level understanding beyond individual schema descriptions, though the schema already covers most details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: 'Measure the *shape* of idle time in a time-based booking calendar, not just the utilization rate.' It distinguishes itself from siblings by explicitly redirecting to booking_gap_simulate for configuration recommendations, and from booking_gap_profile and booking_gap_list_dead by focusing on the shape/classification of gaps rather than listing them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when' and 'Don't use when' sections are provided, with concrete example queries ('why is my utilization stuck', 'how much of my empty time is actually sellable') and a direct alternative (booking_gap_simulate) for when the user wants a recommendation. This is exactly the kind of when/when-not/alternatives guidance the dimension asks for.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
booking_gap_list_deadList individual dead gapsARead-onlyIdempotent
List the individual gaps that are structurally unsellable, longest first, so the underlying bookings can be inspected.
Use this after booking_gap_analyze when the aggregate number needs to be traced back to concrete dates and resources.
Args: same as booking_gap_analyze, plus
limit (number, default 30, max 500): how many gaps to list
resourceFilter (string, optional): only list gaps for this resource
outputJson (boolean, default false): return machine-readable JSON instead of a table
Returns a table of date, weekday, time window, length and resource.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many gaps to list. | |
| bookings | No | Bookings as structured objects. Provide either this or bookingsCsv. | |
| currency | No | Currency symbol prefix, e.g. "¥". | |
| periodEnd | No | Last date to analyse (YYYY-MM-DD). Defaults to the latest booking. | |
| resources | No | Resources to include even when they have no bookings in the period. | |
| hourlyRate | No | Optional hourly price, used to express dead time as an amount. No default. | |
| outputJson | No | Return JSON (gaps plus summary) instead of a formatted table. | |
| bookingsCsv | No | Bookings as pasted CSV or TSV with a header row. Column names are matched in English and Japanese (start/end/resource/date/status, 開始時刻/終了時刻/部屋/日付/ステータス). A separate date column plus HH:mm times is supported. | |
| periodStart | No | First date to analyse (YYYY-MM-DD). Defaults to the earliest booking. | |
| openingHours | Yes | Opening hours. Use "default" for the usual day and override individual weekdays as needed, e.g. {"default": [["09:00","22:00"]], "sun": [["10:00","18:00"]]}. Use "24:00" to close at midnight. | |
| resourceFilter | No | Only list gaps for this resource. | |
| timezoneOffset | No | Venue timezone offset, used only for inputs that carry an explicit offset or "Z". | +09:00 |
| turnoverMinutes | No | Cleaning or changeover time required between two bookings. | |
| minBookingMinutes | No | Shortest booking a customer is allowed to make. | |
| slotGranularityMinutes | No | Allowed booking start interval, measured from midnight (30 means :00 and :30). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint/destructiveHint, so the description only needs to add non-safety behavior. It adds sorting ('longest first'), output shape ('table of date, weekday, time window, length and resource'), and the machine-readable JSON option, going beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences plus a short bullet-style list, with the core action in the first sentence. Every sentence adds purpose, usage timing, or output details; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description adequately specifies the return table columns and default/option behavior. It also references booking_gap_analyze for inherited args, but lightly—an agent unfamiliar with that sibling might need more parameter context, though the schema fills the gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all 15 parameters already have descriptions. The description contributes the higher-level relationship 'same as booking_gap_analyze' and highlights the three tool-specific parameters, but adds little semantics beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+object ('List the individual gaps that are structurally unsellable') and immediately states ordering ('longest first'). It distinguishes itself from sibling tools by noting it traces aggregate numbers back to concrete dates/resources, complementing booking_gap_analyze.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states explicit usage context: 'Use this after booking_gap_analyze when the aggregate number needs to be traced back...' This clearly positions when to choose this tool over the analysis sibling and implies it is not for first-pass analysis.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
booking_gap_profileProfile where dead time occursARead-onlyIdempotent
Show when structural dead time occurs, broken down by weekday and by hour of day.
The total dead-time figure from booking_gap_analyze says how much is lost. This says where to look. Dead time concentrated in one weekday or one part of the day usually points at a specific booking pattern rather than a general problem.
Gaps are distributed proportionally across the hours they span, so a 40-minute gap running 13:50-14:30 is attributed to both hours.
Args: same as booking_gap_analyze, plus
topCells (number, default 8): how many worst weekday x hour cells to list
Returns a text report with a weekday table, an hour-of-day bar chart, and the worst weekday x hour cells.
Use when: "which days are worst", "when does the fragmentation happen".
| Name | Required | Description | Default |
|---|---|---|---|
| bookings | No | Bookings as structured objects. Provide either this or bookingsCsv. | |
| currency | No | Currency symbol prefix, e.g. "¥". | |
| topCells | No | How many worst weekday x hour cells to list. | |
| periodEnd | No | Last date to analyse (YYYY-MM-DD). Defaults to the latest booking. | |
| resources | No | Resources to include even when they have no bookings in the period. | |
| hourlyRate | No | Optional hourly price, used to express dead time as an amount. No default. | |
| bookingsCsv | No | Bookings as pasted CSV or TSV with a header row. Column names are matched in English and Japanese (start/end/resource/date/status, 開始時刻/終了時刻/部屋/日付/ステータス). A separate date column plus HH:mm times is supported. | |
| periodStart | No | First date to analyse (YYYY-MM-DD). Defaults to the earliest booking. | |
| openingHours | Yes | Opening hours. Use "default" for the usual day and override individual weekdays as needed, e.g. {"default": [["09:00","22:00"]], "sun": [["10:00","18:00"]]}. Use "24:00" to close at midnight. | |
| timezoneOffset | No | Venue timezone offset, used only for inputs that carry an explicit offset or "Z". | +09:00 |
| turnoverMinutes | No | Cleaning or changeover time required between two bookings. | |
| minBookingMinutes | No | Shortest booking a customer is allowed to make. | |
| slotGranularityMinutes | No | Allowed booking start interval, measured from midnight (30 means :00 and :30). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool read-only and non-destructive, and the description adds a non-obvious calculation rule: 'Gaps are distributed proportionally across the hours they span, so a 40-minute gap running 13:50-14:30 is attributed to both hours.' It also discloses the output structure, which is not present in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and each subsequent block earns its place: sibling comparison, interpretation guidance, calculation nuance, args note, return format, and use-when phrases. It is appropriately sized for a 13-parameter analytical tool with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description adequately explains the return value ('a text report with a weekday table, an hour-of-day bar chart, and the worst weekday x hour cells'). It also orients the agent among four sibling tools and covers the key behavioral nuance, making it complete enough for correct selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% parameter coverage, so the schema carries most of the burden. The description adds a useful cross-reference ('Args: same as booking_gap_analyze, plus topCells') and restates the topCells meaning, but this mostly duplicates the schema's existing description of topCells.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Show when structural dead time occurs, broken down by weekday and by hour of day.' It clearly distinguishes this tool from booking_gap_analyze, which reports the total dead-time figure, by presenting this as the 'where to look' breakdown.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly names the sibling tool for aggregate analysis and provides concrete use triggers: 'Use when: "which days are worst", "when does the fragmentation happen".' This gives the agent clear selection guidance among the sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
booking_gap_simulateCompare booking settingsARead-onlyIdempotent
Re-run the gap analysis under several booking configurations and compare how much structural dead time each one produces.
The first scenario is the baseline; every other scenario reports its delta against it. This answers questions like "if I allowed 30-minute bookings instead of 60, how many hours would stop being structurally unsellable".
Args:
the same booking data and openingHours as booking_gap_analyze
scenarios (required): array of { label, minBookingMinutes?, slotGranularityMinutes?, turnoverMinutes? }. Any omitted field falls back to the top-level setting, so scenarios can vary one dimension at a time.
Returns a comparison table of dead time, delta versus baseline, and fragmentation rate, optionally valued at hourlyRate.
Important: recovered minutes are an upper bound. They show what becomes sellable, not what will sell. This tool deliberately does not pick a winner — shorter slots also change price positioning and cleaning load, and those trade-offs belong to the operator.
| Name | Required | Description | Default |
|---|---|---|---|
| bookings | No | Bookings as structured objects. Provide either this or bookingsCsv. | |
| currency | No | Currency symbol prefix, e.g. "¥". | |
| periodEnd | No | Last date to analyse (YYYY-MM-DD). Defaults to the latest booking. | |
| resources | No | Resources to include even when they have no bookings in the period. | |
| scenarios | Yes | Configurations to compare. The first entry is treated as the baseline. | |
| hourlyRate | No | Optional hourly price, used to express dead time as an amount. No default. | |
| bookingsCsv | No | Bookings as pasted CSV or TSV with a header row. Column names are matched in English and Japanese (start/end/resource/date/status, 開始時刻/終了時刻/部屋/日付/ステータス). A separate date column plus HH:mm times is supported. | |
| periodStart | No | First date to analyse (YYYY-MM-DD). Defaults to the earliest booking. | |
| openingHours | Yes | Opening hours. Use "default" for the usual day and override individual weekdays as needed, e.g. {"default": [["09:00","22:00"]], "sun": [["10:00","18:00"]]}. Use "24:00" to close at midnight. | |
| timezoneOffset | No | Venue timezone offset, used only for inputs that carry an explicit offset or "Z". | +09:00 |
| turnoverMinutes | No | Cleaning or changeover time required between two bookings. | |
| minBookingMinutes | No | Shortest booking a customer is allowed to make. | |
| slotGranularityMinutes | No | Allowed booking start interval, measured from midnight (30 means :00 and :30). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, but the description adds substantial behavioral context: the first scenario serves as baseline with every other scenario reporting delta, and the 'Important' note explains that recovered minutes are an upper bound and the tool deliberately does not pick a winner. This goes well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections: a lead purpose sentence, an example question, an 'Args' block, and an 'Important' callout. Every sentence earns its place; no filler or redundancy. It's longer than a single line, but the length is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 13 parameters, nested objects, and no output schema, the description carries a heavy load. It covers the return format (comparison table with dead time, delta, fragmentation rate, optional hourlyRate valuation), the baseline behavior, and the upper-bound caveat. Combined with 100% schema coverage, this is complete for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds crucial semantics: the scenarios array structure with optional fields and fallback behavior ('Any omitted field falls back to the top-level setting'), and the baseline/delta interpretation. This is essential for correct invocation and interpretation beyond what the raw schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Re-run the gap analysis under several booking configurations and compare how much structural dead time each one produces.' This clearly distinguishes it from siblings like booking_gap_analyze (single analysis) and booking_gap_profile, and it includes a concrete example question ('if I allowed 30-minute bookings instead of 60...').
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description establishes clear context: it's for comparing configurations and answering 'what-if' questions. It references booking_gap_analyze for the input data, implying the single-analysis alternative. However, it does not explicitly state 'use this when you need to compare, use booking_gap_analyze when you need one configuration'—an explicit exclusion would earn a 5.
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. Dates show when Glama detected each change.
4 tool updates
v1.0.0- First observed
booking_gap_analyze - First observed
booking_gap_list_dead - First observed
booking_gap_profile - First observed
booking_gap_simulate
TDQS
Each tool has a clearly distinct role: analyze measures overall gap composition, profile shows temporal distribution, simulate compares configurations, and list_dead enumerates individual unsellable gaps. No two tools overlap in purpose.
All tools share the consistent 'booking_gap_' prefix followed by a distinct verb (analyze, profile, simulate, list_dead). The naming pattern is uniform and predictable.
Four tools are well-scoped for this narrow domain. Each tool adds a distinct capability without redundancy, and the count feels neither sparse nor bloated.
The set covers the full workflow: measure (analyze), locate (profile), explore options (simulate), and drill down (list_dead). The decision to deliberately not include a recommender tool is clearly communicated and filled by simulate.
Maintenance
Related MCP Connectors
Business-day, SLA, cron and recurrence calculations — offline, holiday-aware, no network.
Scheduling, availability, clients, billing and CRM for appointment-based services.
Airbnb & short-term rental market analytics: occupancy, ADR, RevPAR, revenue, comparables.
Business days, meeting overlap and recurrence expansion, deterministic. 3 of 5 tools free.
Related MCP Servers
- AlicenseAqualityCmaintenanceCalendar MCP server with atomic booking, conflict prevention, deterministic RRULE expansion, and TOON token compression for AI agents.1812MIT
- FlicenseNot gradedqualityDmaintenanceScheduling and booking engine for AI agents. Check availability, hold slots, and confirm appointments with two-phase booking and conflict-free resource management.2-
- AlicenseNot gradedqualityDmaintenanceAudit any Airbnb, VRBO, or STR listing URL for dollar-denominated revenue gaps. Free tier shows category grades and monthly losses. Pro tier unlocks ranked action plans.14MIT
- AlicenseNot gradedqualityAmaintenancewhen2meet-style scheduling polls — self-hostable, reverse-proxy-auth friendly, agent-first API (OpenAPI + llms.txt + MCP).MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/h-kazuki-pixel/booking-gap-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server