booking-gap MCP Server
Measures the shape of idle time in a booking calendar. Separates gaps that can actually be sold from structurally unsellable dead time, accounting for turnover time and the booking start grid. Fully offline, no API key required.
README
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 unsellable
The 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.
Tools
| Tool | What it answers |
|---|---|
booking_gap_analyze |
How much of my idle time is actually sellable? |
booking_gap_profile |
Which weekdays and hours is the dead time concentrated in? |
booking_gap_simulate |
If I allowed 30-minute bookings, how many hours would become sellable? |
booking_gap_list_dead |
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 unsellable
scenario 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 build
Add 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,confirmed
Recognised 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 |
|---|---|---|
minBookingMinutes |
Shortest booking a customer may make | 60 |
slotGranularityMinutes |
Allowed start times, measured from midnight | 30 |
turnoverMinutes |
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%が死んでいます。
ツール
| ツール | 答える問い |
|---|---|
booking_gap_analyze |
空き時間のうち、実際に売れるのはどれだけか |
booking_gap_profile |
デッドタイムはどの曜日・時間帯に集中しているか |
booking_gap_simulate |
最小予約単位を30分にしたら、何時間が売れるようになるか |
booking_gap_list_dead |
どの日・どの部屋で発生しているか |
やらないこと
測るだけで、推奨はしません。 「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 protocol
Background
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
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。