Version 1.2.1
June 17, 2026
Added
- MCP authorization settings (Settings → Security): Allow MCP write operations (
mcpWriteEnabled) and Allow MCP refunds (mcpAllowRefunds), both off by default. A migration adds the columns to existing installs.
Security
- MCP write tools are now default-deny: every create/update/cancel/delete/refund tool is gated behind
mcpWriteEnabled(and refunds additionally behindmcpAllowRefunds), rather than relying on the craft-mcp server config alone (this supersedes the 1.2.0 "authorization is delegated to the craft-mcp server" note). In a web context an authenticated user must also holdbooked-manageBookings. booked_refund_reservationis now idempotent — it nets out prior refunds and never refunds more than the outstanding (paid minus already-refunded) amount.- Customer PII (email/phone) is now redacted by default in all MCP responses — including create/update/booking responses, not just bulk lists — so a forgotten flag fails safe.
- MCP list tools clamp their page size to a hard ceiling (200) to prevent unbounded result sets (memory exhaustion / bulk data export).
Fixed
booked_delete_event_dateon an event that still has reservations now returns the actionable "retire it withenabled=falseinstead" message (via a typed exception) rather than a generic internal-error response.
Version 1.2.0
June 17, 2026
Added
- MCP integration: Booked now registers ~50 tools with the optional craft-mcp plugin, exposing near-complete headless admin to AI assistants — services, employees, locations, schedules, blackout dates, service extras, availability, reservations, event dates, waitlist and reporting. Covers reads, create/update (soft-disable via
enabledrather than hard delete), reschedule, quantity changes, refunds and analytics. The dependency is soft (class_exists-guarded) — Booked runs unchanged when craft-mcp is absent. See MCP.md. - MCP safety model: customer email/phone are redacted on every reservation/waitlist read (not just bulk lists); booking capability tokens and virtual-meeting URLs are never exposed; cancellations always run the refund/capacity-release flow (status cannot be force-set to
cancelledvia update); retired (disabled) services/events remain listable and re-enablable; inputs are validated (quantity ≥ 1, employeeserviceIdsmust exist); and notification/refund side effects are rate-limited with a fixed-window, mutex-guarded limiter (separate budgets, charged only on success) since Booked's IP-based limiter does not apply over MCP. Authorization is delegated to the craft-mcp server (IP allowlist / dangerous-tool gating). All 50 tools verified end-to-end against the live MCP server.
Version 1.1.1
April 15, 2026
Added
- New
slot/get-range-capacitycontroller action andBookedAvailability.getRangeCapacity()JS helper for querying the remaining capacity of a multi-day date range (tightest day wins). ScheduleResolverService::getCapacityForDay()resolves day-based capacity fromSchedule.workingHours[day].capacity, honoring service → employee → aggregated-employee precedence.- Day-service wizard step now shows a quantity picker (with +/− controls and live remaining-capacity hint) when a multi-day range has capacity greater than one.
- Inline booking error banner on the date/time step so backend error messages surface to the user instead of being swallowed.
Changed
- Multi-day availability now enforces capacity per day using the resolved schedule capacity instead of
Service.capacity, correctly accounting for overlapping reservations across each day of the range. SlotControllerrate limits raised to 120 req/min acrossget-slots,get-dates,get-valid-end-dates,get-event-dates, andget-availability-calendarto reduce false 429s for legitimate wizard traffic.BookedAvailability.getDates()andcreateBooking()now parse error response bodies so the wizard can display the server message and status code.- Wizard caches fetched available-date results per month/service/employee/location/quantity/extras key and de-dupes in-flight requests.
- Flexible-day price calculation guards against missing
selectedService.price.
Fixed
- GraphQL mutation registration for
QuantityMutations,ReservationMutations, andWaitlistMutations(minor correction). - Day-service “Next” button enable/disable logic now accounts for day-range capacity picker state.
Version 1.0.2
April 2, 2026
Fixed
- Bundled Alpine.js with the plugin so the built-in booking wizard works out of the box without requiring the site theme to include Alpine separately (#3)
- Alpine.js is loaded at
POS_ENDto ensure proper initialization order with wizard components - Added detection to skip loading Alpine.js if the site already includes it