Skip to main content
Glama

bookings-mcp: an AI booking agent that can't break the rules

An MCP server that lets an AI receptionist book, move and cancel appointments for a salon, clinic or studio, safely. The business rules live in code, not in the prompt, so a confused or manipulated model still can't double-book, ignore opening hours, cancel someone else's appointment or quietly rewrite history.

Works with Claude Desktop, Claude Code or any MCP-capable agent, and behind a WhatsApp or website chat.

▶ Live demo: https://enxo7899.github.io/bookings-mcp/ (replays agent conversations against the real booking rules in your browser)

Agent tool calls, calendar and audit log

Guardrails

Risk

What stops it

Booking without the customer agreeing

create_booking first returns a preview; nothing is written until it's called again with customer_confirmed: true

Double booking

Overlap check per staff member on every create and move; find_slots never offers a taken time

Impossible times

Opening hours per weekday, closed days, 15-minute grid, service length must fit before closing

Last-minute and far-future bookings

Minimum 2 hours' notice, maximum 60 days ahead

One customer blocking the diary

At most 2 bookings per customer per day

Seeing or changing other people's bookings

No "list all" tool exists; find, move and cancel require the phone number the booking was made with, and "wrong phone" looks the same as "no such booking"

Late changes

Within 24 hours, a move or cancellation becomes a request for staff; the agent has no tool to approve it

Approving a slot that filled up meanwhile

Staff approval re-runs every check

Covering tracks

Every call, including refusals, goes into a SHA-256 hash-chained audit log with phone numbers masked; admin verify detects any edit

Bad input

Zod schemas at the MCP layer, then validation in the core with a reason the agent can pass on

Prompt injection gets nowhere

Late cancellation waits for staff

Editing the log is detected

Related MCP server: booking-mcp

Tools exposed to the agent

Tool

Annotations

Purpose

list_services

read-only

Services, prices, staff, hours and rules

find_slots

read-only

Free start times for a service and date

create_booking

write

Preview, then book after the customer confirms

find_bookings

read-only

Upcoming bookings for one phone number

reschedule_booking

destructive

Move a booking (or request it, inside 24h)

cancel_booking

destructive

Cancel a booking (or request it, inside 24h)

Staff actions (approve, reject, list everything, verify the log) are in scripts/admin.js and are never exposed over MCP.

Run it

npm install
npm test                      # 16 tests: rules, privacy, approvals, audit chain, and a real MCP client round-trip
TZ=Europe/Tirane npm start    # MCP server on stdio, data in data/state.json
npm run admin -- pending      # staff: see requests waiting for approval
npm run admin -- approve RQ-001
npm run admin -- verify       # check the audit log hasn't been edited

Use it from Claude Desktop or Claude Code

{
  "mcpServers": {
    "bookings": {
      "command": "node",
      "args": ["/path/to/bookings-mcp/src/server.js"],
      "env": { "BOOKINGS_DATA": "/path/to/bookings.json", "TZ": "Europe/Tirane" }
    }
  }
}

Then just ask: "Book me a haircut on Wednesday morning, I'm Ana, +355 69 234 5678."

Adapt it

Services, staff, opening hours and rules are one config object (DEFAULT_CONFIG in src/core.js). Storage is a JSON file written atomically; swapping in Postgres, Supabase or Google Calendar means replacing loadState / saveState. The core has no dependencies and also runs in the browser (that's what the demo uses).

Path

What it is

src/core.js

Booking rules, privacy checks, approvals, audit log

src/server.js

MCP server (stdio) with Zod schemas and tool annotations

src/sha256.js

Dependency-free SHA-256 for the audit chain

scripts/admin.js

Staff command line

tests/

Rule tests and an end-to-end MCP client test

index.html

Interactive demo


Built by EmSoft: AI agents with safety guardrails, MCP servers and booking assistants. Get in touch through my Fiverr or Upwork profile.

Available Tools

6 tools
cancel_bookingCancel bookingA
Destructive

Cancels a booking. The phone must match the booking. Within 24 hours of the appointment this creates a request for staff instead.

Inputs: booking_id (required), customer_phone (required), reason.

create_bookingCreate bookingA

Books an appointment. First call WITHOUT customer_confirmed to get a summary, read it to the customer, and only call again with customer_confirmed: true after they say yes.

Inputs: date (required), time (required), service (required), customer_name (required), +3 more.

find_bookingsFind a customer's bookingsA
Read-only

Upcoming bookings for one phone number. There is no way to list other customers' bookings.

Inputs: customer_phone (required).

find_slotsFind free slotsA
Read-only

Free start times for a service on a date. Always check before offering a time.

Inputs: date (required), service (required), staff.

list_servicesList servicesA
Read-only

Services, prices, staff, opening hours and booking rules. Call this first.

Inputs: no named parameters.

reschedule_bookingReschedule bookingA
Destructive

Moves a booking. The phone must match the booking. Within 24 hours of the appointment this creates a request for staff instead.

Inputs: new_date (required), new_time (required), booking_id (required), customer_phone (required).

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 6 tools

    Disambiguation5/5

    Each tool maps to a distinct step of the booking workflow: catalog (list_services), availability (find_slots), booking creation, and per-phone booking lookup/modification. The descriptions explicitly disambiguate the closest pair (find_slots = free times vs find_bookings = existing bookings) and enforce call ordering, leaving no realistic misselection.

    Naming Consistency4/5

    All names are snake_case verb_noun and read predictably. The only minor deviation is mixing 'list_' and 'find_' for read operations (list_services vs find_slots/find_bookings), which is slightly inconsistent but still clear.

    Tool Count5/5

    Six tools is well-scoped for a customer-facing appointment booking server, and each one earns its place in the flow. Nothing feels redundant or missing at the tool-count level.

    Completeness4/5

    The full customer lifecycle is covered: browse services, check availability, book, look up, reschedule, and cancel, including the 24-hour escalation rule. Minor gaps remain — no retrieval of a single booking's details or booking identifier, and find_bookings only returns upcoming appointments, so past or specific-booking lookups are dead ends.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Scheduling and booking engine for AI agents. Check availability, hold slots, and confirm appointments with two-phase booking and conflict-free resource management.
      2
      Apache 2.0
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI assistants to safely manage appointment bookings for appointment-based businesses over MCP, including searching availability, holding, confirming, rescheduling, and canceling bookings, and reading business policies.
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI assistants to discover availability, place expiring holds, and confirm or cancel appointments for connected booking businesses, with idempotent retries and explicit user consent.
      1
      Apache 2.0
    • A
      license
      A
      quality
      C
      maintenance
      Enables AI agents to browse customers, bookings, and availability while any booking creation or cancellation stays gated behind a human-approved, single-use token cryptographically bound to the exact arguments. Runs over stdio or Streamable HTTP and enforces the read/write separation in host code with a full audit trail.
      7
      MIT