A Next.js-based barbershop management and booking system with Stripe payment integration
This is a Next.js/Prisma barbershop booking system exposing 4 server actions as tools. Tool definitions are present with names, descriptions, and input schemas, but quality is uneven. Naming follows verb_noun convention (cancelBooking, createBooking, etc.) which is good. Descriptions are present but generic, they state what the tool does but lack context on when to use it vs similar tools, prerequisites, or recovery guidance. Input schemas exist and include type information (UUID, date), but parameters lack descriptions in their schema definitions. Output schemas are not documented anywhere, critical for agents to know what they're receiving. Error handling exists in code but is not reflected in tool definitions (no error classification, no recovery guidance in schema). No pagination documented for potential list results. Date handling uses JavaScript Date objects which may cause serialization issues in MCP contexts.
Cancel a booking by marking it as cancelled. Processes a Stripe refund if a charge ID exists. Only the booking owner can cancel future bookings.
Create a new barbershop with name, address, description, phone number, and style. Assigns a random image based on the selected style.
Create a new barbershop service with name, description, image URL, and price. Price is converted to cents.
Create a booking for a barbershop service on a specific date. Checks for existing bookings at the same time slot.
Create a Stripe checkout session for booking payment. Returns a Stripe checkout session with metadata and line items.
Soft delete a barbershop by setting its deletedAt timestamp. Only the barbershop owner can deactivate.
Deactivate a barbershop service by setting isActive to false. Only the barbershop owner can deactivate.
Input parameter descriptions missing from schema definitions. The Zod schemas define types (z.uuid(), z.date()) but do not include descriptions for individual parameters. LLMs cannot infer parameter meaning from type alone, a 'date' parameter could mean booking date, availability check date, or filter date. This violates pattern:tool-description which requires every parameter to have context.
Output/return schemas are not documented. None of the 4 tools document what fields/structure they return. For example, createBooking likely returns a Booking object, does it include id, status, userId, stripeChargeId? Without output schema documentation, agents cannot plan downstream tool calls or extract the right data for follow-up actions.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 0 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 28 | - | v1 |
Update an existing barbershop with new name, address, description, and/or phone numbers.
Update an existing barbershop service with new name, description, price, and/or image URL.
Get available time slots for a barbershop on a specific date. Returns list of unoccupied 30-minute slots from 09:00 to 18:00.
Tool descriptions lack 'when to use' context and prerequisites. The descriptions state WHAT the tool does (e.g., 'Create a booking for a barbershop service') but not WHEN the LLM should call it, what preconditions are needed (e.g., 'User must be authenticated'), or what to do if it fails. This makes it harder for LLMs to reason about tool selection among similar tools.
createBooking and createBookingCheckoutSession both create bookings but have different workflows (one for checkout, one direct). The distinction is not clear from names alone. An LLM might call the wrong one. Names should disambiguate: consider createBookingWithCheckout vs createDirectBooking.
Error handling not reflected in tool definitions. The code validates authentication, booking existence, ownership, cancellation status, and past dates, but these checks are not declared in the tool schema. An LLM calling cancelBooking with an invalid bookingId gets a cryptic error; the schema should document which errors are possible and what to do (e.g., 'If booking not found, try fetching available bookings first').
Date parameters use JavaScript Date type. This may cause serialization issues in MCP JSON RPC contexts. Dates should be ISO 8601 strings (YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ) for clarity and to prevent timezone/format confusion. Current Zod schema uses z.date() which may not round-trip cleanly through JSON.
getDateAvailableTimeSlots returns time slots but schema does not specify structure. Does it return an array of { time, available } objects? An array of strings? Without documented output schema, agents cannot extract or reason about the data.
cancelBooking requires bookingId but does not document that the user must own the booking. The authorization check ('booking.userId !== session.user.id') is in code but not in the tool description. An agent might assume any authenticated user can cancel any booking.
No pagination/limit documented for getDateAvailableTimeSlots. If a barbershop has 100+ available slots, does the tool return all or a subset? Does it support cursor-based or offset pagination? Without documented limits, agents may receive unexpectedly large responses.