--- name: guestavo description: Run a hospitality venue on Guestavo through its MCP server — bookings, menus, events, the rota, guests and reports. Use when the user asks about their venue's diary, menu, staffing or guests, or wants to set a venue up. Covers connecting a client, what an API key opens, the order things must be built in, and how to undo a mistake. 72 tools. --- # Guestavo for agents Guestavo is the system a hospitality venue runs on: its diary, its menus, its events, its rota, its guest book and its reports. This document is how you talk to one. Everything below is generated from the tool registry the server itself reads, so it cannot describe a tool that does not exist. **This copy is generic.** It is served to anybody who asks, so it lists every tool the product has rather than the ones your key can call. The set you are actually offered is decided at connection time from your key's scopes, its per-venue narrowing and the modules the venue has switched on — ask your client for its tool list once you are connected, and trust that over this document. Where the two disagree, this one is wider. Guest-facing text — menu descriptions, booking notes, anything a person at the venue will read — should be written in German unless the user asks for another language. That is this venue's own language, and it is not necessarily yours. Tools listed here: 72. Endpoint: `https://mcp.guestavo.com/mcp`. ## Connecting The server is hosted and speaks streamable HTTP, so there is nothing to install and nothing to keep running. It authenticates with one header: `Authorization: Bearer gvsk_…`. Swap the placeholder below for the key the venue owner minted — see the next section for where that comes from. ### Claude Code ```bash claude mcp add --transport http guestavo https://mcp.guestavo.com/mcp \ --header "Authorization: Bearer gvsk_your_key_here" ``` ### Claude Desktop — `claude_desktop_config.json` ```json { "mcpServers": { "guestavo": { "type": "http", "url": "https://mcp.guestavo.com/mcp", "headers": { "Authorization": "Bearer gvsk_your_key_here" } } } } ``` ### Cursor — `.cursor/mcp.json` ```json { "mcpServers": { "guestavo": { "type": "http", "url": "https://mcp.guestavo.com/mcp", "headers": { "Authorization": "Bearer gvsk_your_key_here" } } } } ``` ### Anything else, over plain HTTP ```bash curl -X POST https://mcp.guestavo.com/mcp \ -H "Authorization: Bearer gvsk_your_key_here" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' ``` If the connection is refused before any tool runs, the key is the problem rather than the request: an expired key, a revoked key, or a key pasted with the `Bearer ` prefix doubled up. ## The key, and what its ticks mean A key belongs to a venue's owner, not to you. They mint it in Guestavo: Settings, then Organizations, then the company, then its API keys tab. It is shown once, at creation, and never again — if it is lost, a new one is minted and the old one revoked. You cannot mint one, widen one, or ask for a scope to be added; all three are decisions for a person. A key is pinned to one company at mint time and can be narrowed further, per venue and per action. Enforcement is AND: the scope opens a module, the narrowing picks actions inside it, and the venue must have the module switched on. Ticking an action can never open something the scopes left shut. - `agent:read` — **Agent Trail Read.** View this key’s own record of what it has changed, and read what undoing one would do - `agent:write` — **Agent Trail Undo.** Undo this key’s own recent changes — its own only, one at a time, and only for a short while - `analytics:read` — **Analytics Read.** View revenue, margin, covers, no-show rate and labour cost reports - `booking:read` — **Booking Read.** View bookings, availability, resources and service types — not revenue or margin - `booking:write` — **Booking Write.** Create, confirm, reschedule and cancel bookings - `contact:read` — **Contact Read.** View guest contacts and groups - `contact:write` — **Contact Write.** Create and update guest contacts and their group membership - `event:read` — **Event Read.** View events and their registrations - `event:write` — **Event Write.** Create, update and publish events - `loyalty:read` — **Loyalty Read.** View visits, points and rewards - `menu:read` — **Menu Read.** View menus, sections, items and specials - `menu:write` — **Menu Write.** Create and update menus and items, and publish them - `org:read` — **Organization Read.** View organization data - `org:write` — **Organization Write.** Manage organization settings and members - `staff:read` — **Staff Read.** View staff members, the rota and coverage — not pay or labour cost - `staff:write` — **Staff Write.** Create and update shifts and staff assignments Two of those are worth calling out. `analytics:read` is implied by nothing on purpose — a key that can read the diary is not thereby allowed to read the venue's money — so reporting has to be ticked deliberately. And `agent:write` is the one that lets you undo yourself; without it you can read your own trail and not take anything back. ## Standing a venue up, in order This order is not a style preference. Each step depends on the one above it, and getting it wrong fails quietly rather than loudly — the write succeeds and the venue is left unbookable. 1. `get_organization` — Read the company first. It tells you which modules are switched on, and a module that is off is a wall no amount of retrying gets through. 2. `list_properties`, `get_property` — Find out whether the venue already exists. Most "set up my restaurant" requests are about a venue that is already there and half-configured. 3. `create_property` — Only if it genuinely does not exist. A venue is the thing everything else hangs off, and a duplicate is expensive to unpick — ask the person before you create one. 4. `update_property_profile`, `set_property_operating_hours` — Profile and opening hours, before anything that depends on when the venue is open. Availability is computed against these, so a diary configured over empty hours returns nothing and looks like a bug. 5. `create_booking_service_type`, `update_booking_service_type` — What the venue sells: a dinner sitting, a treatment, a tasting. These come before the things that host them. 6. `create_booking_resource`, `update_booking_resource` — What it sells them on: tables, rooms, chairs, a member of staff. A resource references its service types by id, so it cannot be created before them. 7. `create_staff_shift`, `update_staff_shift` — The rota, if the venue gates availability on staff coverage. Until somebody is rostered, a coverage-gated diary is empty for the honest reason that nobody is there. 8. `create_booking_blocked_time`, `update_booking_blocked_time` — Closures and holidays. Cheaper to block a week now than to cancel the bookings taken over it later. 9. `set_property_booking_settings` — The switch that makes the venue bookable, and the one that publishes it. Do this last and confirm it with the person first: it is the step that puts the venue in front of the public. 10. `create_menu`, `create_menu_category`, `create_menu_item`, `publish_menu` — The menu is a separate build and can happen at any point after the venue exists. Sections and dishes first, placement second, publish last — an unpublished menu is invisible, which is the right state while you are still assembling it. Confirm with the person before each step that changes what the public sees. Everything you do is written down and most of it can be put back, but a menu published to a live venue was still published. ## The tools Grouped the way the venue owner sees them when deciding what to grant. A tool marked **writes** changes venue data; everything else only reads. ### See which modules are switched on - `get_organization` — Read the organization: its name, locale and which product modules (menu, booking, events, outreach, loyalty, staff) are switched on. Call it when an action is refused because a module is off — only an owner can switch one on. ### Find our venues - `list_properties` — List the venues (properties) in an organization. Start here to get the propertyId that menu, booking, event and staff tools ask for. - `get_property` — Read one venue in full: address, timezone, opening hours and booking configuration. Use it to find out whether a venue is bookable at all before asking why get_booking_availability returns nothing. ### Open a venue and set it up - `create_property` **writes** — Create a venue: name, URL slug, type, address and timezone. Set its opening hours and booking settings afterwards with the set_property_ tools. A key narrowed to particular venues cannot call this — the new venue is not one of them. - `update_property_profile` **writes** — Change a venue’s name, description, address, city, country or timezone. Only the fields sent are written. The URL slug is not changeable here, because a printed QR code resolves through it. - `set_property_operating_hours` **writes** — Set a venue’s opening hours. Only the days you name change; the rest of the week is left alone, and exceptions merge by date, so adding one holiday cannot drop the others. removeExceptionDates takes one back off. - `set_property_booking_settings` **writes** — Configure how a venue takes bookings: interval, lead time, buffer, auto-confirm. enabled must be true or no slot is ever offered. publicBookingEnabled publishes the venue and requireStaffShiftCoverage can close its diary — confirm both. ### Read the menu - `list_menus` — List an organization's menus with their status (draft, published, archived). Supports a search term. - `get_menu` — Read one menu in full: its categories, the items filed under each, prices, allergens and dietary tags. - `list_menu_items` — Search the dish catalogue by name across the whole organization. Items live independently of the menus they appear on, so use this to find a dish when the menu is unknown. - `list_menu_categories` — List the organization's dish sections (starters, mains, wine) as catalogue records. A section is filed here once and placed on any number of menus, so use this to find the categoryId add_category_to_menu needs. - `list_menu_specials` — List a menu's daily specials with the dates each one runs. ### Build and edit the menu - `create_menu` **writes** — Create a menu for a venue: an empty shell with a name and a URL slug. Fill it with add_category_to_menu and add_item_to_menu_category, then publish_menu. Nobody sees it until it is published. - `update_menu` **writes** — Rename a menu or change its slug, description, language, currency or display options. This edits the menu itself and not what is on it; a dish is edited with update_menu_item. - `create_menu_category` **writes** — Create a dish section in the catalogue — starters, mains, desserts. It is on no menu until add_category_to_menu places it, and one section can be placed on several menus. - `update_menu_category` **writes** — Rename a catalogue dish section or change its description or image. The change lands on every menu that section appears on. - `create_menu_item` **writes** — Create a dish in the catalogue with its price, allergens and dietary tags. It is on no menu until add_item_to_menu_category files it under a section of one. - `update_menu_item` **writes** — Edit a catalogue dish: name, description, base price, allergens, dietary tags. It changes on every menu it appears on — to change one menu only, use set_menu_item_availability on that placement. - `add_category_to_menu` **writes** — Put an existing catalogue section on a menu at a given position. Returns the assignmentId that add_item_to_menu_category needs — that id, not the categoryId, is what dishes are filed under. - `add_item_to_menu_category` **writes** — Put a catalogue dish on one menu under one section, optionally with a price override for that menu alone. Takes the assignmentId add_category_to_menu returned, not a categoryId. ### Publish the menu and change what is on today - `create_menu_special` **writes** — Add a daily special to a menu for a given date or date range. - `set_menu_item_availability` **writes** — Change the availability note or price override of one item as it appears on one menu. This is how a dish comes off tonight, or goes lunch-only, without being deleted. - `publish_menu` **writes** — Publish a menu so the venue's public page and QR code serve it. Draft edits are invisible to guests until this runs. - `archive_menu` **writes** — Take a menu out of service: it stops being served publicly and is filed as archived rather than deleted. publish_menu brings it back. There is no way to delete a menu here, by design. ### Read the diary - `get_booking_availability` — Free booking slots at a venue on one date, optionally narrowed by party size, service type or resource. Call before create_booking. Name the venue by propertyId or by propertySlug. - `list_booking_resources` — List the bookable resources at a venue — tables, rooms, chairs, courts — with their capacities. - `list_booking_service_types` — List the service types a venue takes bookings for (dinner service, treatment, rental) with their durations. - `list_booking_blocked_times` — List a venue’s closures — holidays, maintenance windows, a table out of service — over an optional date range. This is why a date with opening hours can still offer no slots. - `list_bookings` — List bookings for an organization, filterable by venue, date range, status and guest name. This answers "who is coming in tonight". - `get_booking` — Read one booking: guest, party size, time, assigned resources, status and notes. ### Set the diary up: services, tables, closures - `create_booking_service_type` **writes** — Define something a venue takes bookings for — dinner service, a treatment, a court hire — with its duration and optional price. Create these before resources, which reference them by id. - `update_booking_service_type` **writes** — Rename a service type or change its duration, price or order. Send isActive false to retire one: it stops being offered and the bookings already taken against it keep saying what was booked. There is no delete, by design. - `create_booking_resource` **writes** — Add something a booking can be assigned to — a table, a room, a chair, a court — with its capacity and largest party. serviceTypeIds narrows it to particular services, so create those first. - `update_booking_resource` **writes** — Change a bookable resource: name, capacity, largest party, which services it takes, its own weekly availability. Send isActive false to take it out of service without destroying which parties sat at it. - `create_booking_blocked_time` **writes** — Close a venue, or one resource, for a period: a holiday, a private hire, maintenance. Times are the venue’s own wall clock, not UTC. recurrenceRule takes FREQ=DAILY or FREQ=WEEKLY, optionally with ;UNTIL=YYYY-MM-DD. - `update_booking_blocked_time` **writes** — Move or shorten a closure, change its reason, or scope it to one resource. Shortening it to a past window is how a closure is lifted — there is no delete here, and the original times are what an undo restores. ### Take and change bookings - `create_booking` **writes** — Take a booking for a guest at a venue on a date and time. Check get_booking_availability first; an identical repeat is answered from the first call, not booked twice. No confirmation is sent, but the venue may still send its own reminder. - `confirm_booking` **writes** — Confirm a pending booking. This call emails nobody, but a confirmed booking becomes eligible for the venue's automatic reminder, which may reach the guest. Do not tell the caller the guest has been notified. - `reschedule_booking` **writes** — Move an existing booking to a different date or time, keeping the guest and party size. The guest is not emailed about the change; the venue tells them. - `cancel_booking` **writes** — Cancel a booking, with an optional reason recorded against it. The reason does not reach the guest and no cancellation email is sent; the venue tells them. ### Read events - `list_events` — List events, filterable by venue, status, category, search term, or upcoming-only. - `get_event` — Read one event: schedule, venue, capacity, ticketing and whether it is published. - `list_event_registrations` — List who has registered for an event, with party sizes and check-in state. This answers "how many are coming to the quiz". ### Create, edit and publish events - `create_event` **writes** — Create an event at a venue. It starts as a draft and is not public until publish_event runs. - `update_event` **writes** — Change an event: title, description, dates, capacity, venue details, category or ticket links. Only the fields sent are written. Changes to a published event are live on the public page immediately. - `publish_event` **writes** — Publish a draft event so it appears on the venue's public page and starts taking registrations. - `create_event_category` **writes** — Create a category for the programme — live music, quiz, private hire — with a URL slug. It is on no event until create_event or update_event names its id. Slugs are unique within the organization. - `update_event_category` **writes** — Rename a programme category or change its slug, description, colour, image or order. The change lands on every event filed under it, and a new slug changes the category’s public address. ### Read the guest book - `list_contacts` — Search guests by name, email or phone, optionally within one contact group. Use it to resolve a name to a contactId. - `get_contact` — Read one guest: contact details, consent state, and the email and phone endpoints they can be reached on. - `list_contact_groups` — List contact groups (segments), static and rule-based, with member counts. Use it to find the groupId for add_contact_to_group. ### Add, correct and file guests - `create_contact` **writes** — Add a guest to the contact book. Creating a contact is not a marketing opt-in — consent is recorded separately. - `update_contact` **writes** — Correct a guest’s details: name, email, phone, tags or custom fields. Only the fields sent are written, and at least one of email, phone or an external id must remain. This cannot change their marketing consent. - `add_contact_to_group` **writes** — Put a guest into a contact group. Groups are how this product tags people — there is no separate tag. Adding somebody who is already in it changes nothing. ### Create and retire guest groups - `create_contact_group` **writes** — Create a contact group (a segment) to file guests into. Names are unique within the organization. Leave definition out for a hand-picked list; a definition makes it a rule-based group the platform recomputes. - `update_contact_group` **writes** — Rename a contact group or change its description, colour or matching rules. Changing the rules of a rule-based group changes who a campaign addressed to it will reach. - `archive_contact_group` **writes** — Take a contact group out of use: it stops appearing in the ordinary listing and is filed as archived rather than deleted, keeping every membership. unarchive_contact_group brings it back. There is no delete, by design. - `unarchive_contact_group` **writes** — Put an archived contact group back into use. Refused if it is not archived, so this cannot be used to check whether one is. ### Read visits and loyalty - `list_visits` — Visit history: recorded guest check-ins, filterable by guest, venue, status and date range. This answers "when was she last in". ### Read the rota - `list_staff_members` — List the people on a venue's team, with their roles and employment state. - `list_staff_shifts` — The rota over a date range: who is on, when, in what role, and which shifts are still open. Requires from and to dates. - `get_staff_coverage_day` — Coverage for one venue on one date: rostered hours against expected demand, hour by hour, so a gap is visible. This answers "are we short on Saturday". - `get_staff_publish_impact` — What publishing the rota for a venue over a date range would take off sale: with requireStaffShiftCoverage on, an unpublished shift leaves a resource bookable and a published one constrains it. Read this before publishing. ### Fill and publish the rota - `create_staff_shift` **writes** — File a shift on the rota at a venue: date, start and end in the venue’s own wall clock, optional role and break. Leave staffMemberId out for an open shift nobody is assigned to. It is a draft until published. - `update_staff_shift` **writes** — Move a shift, reassign it, edit its role or break, or send status published to put it on the rota and draft to take it off. Where the venue requires shift cover, publishing changes what guests can book — read get_staff_publish_impact first. ### Read the reports, including money - `get_booking_analytics` — Booking trend, capacity use, no-show rate, revenue and margin over a date range. The general "how did we do" number. - `get_covers_report` — Booked covers by day and service type over a date range. - `get_labour_cost_report` — Rostered labour cost against booked covers for one venue over a date range, including cost per cover. ### See what this key itself has done - `list_agent_actions` — List what THIS key has already done — its own changes and reads, newest first, with the id of each one and whether it can still be undone. Call it to check whether a write landed after a timeout, or before reporting back what you changed. - `get_agent_action_revert_plan` — Ask what undoing one of your own actions would do, and what it would refuse, without undoing anything. Call it before revert_agent_action when the change is not one you made seconds ago. ### Let it take back its own recent changes - `revert_agent_action` **writes** — Undo one change YOU made, named by its id from list_agent_actions. Refused if it was not yours, was already undone, is older than an hour, or the record has changed since — the refusal says which. - `revert_last_agent_action` **writes** — Undo the last change you made — this conversation only, when your client sends a session id. Pass expectedTool to be refused rather than undo the wrong thing if the ledger disagrees with what you think you did last. ## When you are refused Every refusal on this surface names its own reason, and the reasons are not interchangeable. Read the code before you retry — most of them mean retrying is pointless. - `api_key_tool_not_granted` — the key holds the scope and its owner deliberately left this action out. **A broader scope will not help.** Stop, and say which action you were refused so a person can widen the key if they meant to. - `api_key_property_not_granted` — the key works at this company and not at this venue. Re-read the venue list: for a narrowed key it returns only the venues you may reach, so the right venue is probably in it. - `api_key_property_unresolved` — the call could not be attributed to one venue. Usually your fault and usually fixable: name the venue. If the record genuinely has no venue, or the tool has no venue dimension at all, only widening the key fixes it. - `api_key_organization_mismatch` — this key is for a different company. No permission fixes that; a different credential does. - `api_key_ambiguous_request_value` — the request named one id two ways, or named it twice. Your request is malformed; the key is fine. - **A module refusal** (403 naming a module) — the venue does not have that part of the product switched on. No agent can switch a module on: the module comes with the venue’s plan, so switching it on may mean changing plan. Say which module you needed and stop. - `api_key_idempotency_key_required` — only ever seen by a hand-rolled HTTP client. The four tools that must not be able to happen twice require an `Idempotency-Key` header. Send one; do not retry without it. A refusal is information, not an obstacle. Report it in the words above rather than trying a second route to the same data — every alternative route is gated by the same key. ## The rules that keep the venue safe - **Nothing here deletes.** There is no delete tool in the registry and there never will be; a menu, a group or a booking is archived, and an archived thing can be brought back. If the user asks you to delete something, archive it and say that is what you did. - **Every write is written down.** All 42 of the writing tools record what they did, to what, and what the record looked like beforehand, before the change lands. If that record cannot be written, the change is refused. This is what makes an undo possible at all. - **Confirm before you change anything.** Reads are free and writes are not. Say what you are about to do, in the venue’s own words — "book table 4 for six at 19:30 on Saturday" — and wait. - **Creating a venue is a company-level act.** A key narrowed to particular venues is refused for it, and for the other company-level tools, because a credential handed out to work at one restaurant must not be able to open a second one. - **No tool here messages a guest.** Booking tools that would normally email a confirmation or a cancellation run with that suppressed when the caller is a key. Do not tell the user the guest has been told. The one exception is the venue’s own reminder sweep, which is a scheduled job rather than something you triggered — a booking you confirm will still be reminded about, and both tools say so. - **A contact is not a marketing opt-in.** Creating a guest record does not consent them to anything. ## Undoing your own mistake You can take back your own recent changes: `list_agent_actions`, `get_agent_action_revert_plan`, `revert_agent_action`, `revert_last_agent_action`. Only your own, only one at a time, and only within the last hour. An undo cannot itself be undone — putting the change back means making it again with the ordinary tool, which is a new action. Work in this order, and do not skip the middle step: read your trail, ask for the plan, then revert. The plan says what undoing would actually do and what it would refuse, without doing it. "Revertible" in a listing only means the cheap checks passed. The refusals mean different things and only one of them is worth trying again: - `record_changed` — a person has edited that record since. Undoing would overwrite their work. Stop and tell them. - `dependents_exist` — something newer hangs off it. A person has to decide. - `already_reverted` — nothing to do. Say so rather than looking for another route. - `too_old` — past the window. Only a person can undo it now. - `not_found` — that action is not yours. Do not go looking for it another way. And an undo restores DATA. It does not un-send what went out, un-see what was public, or free what somebody else has since taken. The plan lists those; repeat them verbatim rather than reporting a clean success over them. ## How fast you may go One key is allowed 120 requests a minute, and the limit fails closed: over it, every call is refused until the minute rolls. There are wider ceilings above it, per person and per company, so several agents running at once share less headroom than the per-key number suggests. In practice that is the difference between a menu that builds and one that half-builds. A sixty-dish menu is roughly a hundred and thirty calls — a create per dish, a placement per dish, plus the sections — so it does not fit in one minute. Work in batches, pause between them, and re-read what you have written rather than assuming a call that timed out did not land. ## The shortcuts The server ships ready-made workflows as MCP prompts. They are the shortest path through everything above — each one is the ordered tool sequence for a job the venue does over and over, written by the people who wrote the tools. Reach for one before improvising a plan of your own. - `service-brief` — **Service brief.** Brief the team on one service: who is booked in, what is on, who is working, and where the pressure lands. - `staffing-gap-check` — **Staffing gap check.** Answer "are we short on Saturday": rostered cover against booked demand for a date or a range, hour by hour. - `plan-weekly-specials` — **Plan the weekly specials.** Draft the daily specials for a coming week from the current menu, what is already scheduled, and the demand the week is carrying. - `guest-brief` — **Guest brief.** Everything the venue knows about one guest before they walk in: who they are, when they last came, and what they book. - `allergen-check` — **Allergen and diet check.** Work out what a guest with an allergy or a dietary requirement can eat from a menu, using the allergen tags recorded on the menu. - `stand-up-venue` — **Stand up a venue.** Open a new venue and take it from nothing to bookable: profile, opening hours, what it sells, what it sells it on, and the switch that turns the diary on. - `build-menu` — **Build a menu.** Create a menu from a list of dishes and put it together section by section, reusing the catalogue the venue already has. - `take-booking` — **Take a booking.** Take a booking end to end: find a slot, match the guest to the contact book, book it, confirm it. - `undo-a-mistake` — **Undo something you just did.** Take back a change you made by mistake — find it in your own trail, check what undoing it would do, then undo it.