MCP Server

Reservly includes a Model Context Protocol (MCP) server that lets AI assistants like Claude, ChatGPT, and others interact with your booking system through natural language. Customers can check availability, browse services, and book appointments through AI conversations.

Available Tools

The MCP server exposes seven tools. Each maps directly to a public REST API endpoint, so the data returned is identical.

ToolDescriptionREST Equivalent
get_business_infoGet business profile, hours, contact, and social linksGET /info
search_servicesList available services with prices and durationsGET /services
list_staffGet staff members, optionally filtered by serviceGET /staff
check_availabilityFind available time slots for a date and serviceGET /slots
list_eventsBrowse upcoming events with dates and capacityGET /events
list_rentalsBrowse rental items with pricesGET /rentals
book_appointmentCreate a new booking with customer detailsPOST /book

Claude Desktop Setup

To connect your Reservly business to Claude Desktop, add the following to your claude_desktop_config.json file. Replace YOUR-BUSINESS-SLUG with your actual business slug (found in Settings on your dashboard).

claude_desktop_config.json
{
  "mcpServers": {
    "reservly": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://reservly.io/api/mcp/YOUR-BUSINESS-SLUG"
      ]
    }
  }
}
json

On macOS, the config file is located at ~/Library/Application Support/Claude/claude_desktop_config.json. On Windows, it is at %APPDATA%\Claude\claude_desktop_config.json.

That configuration is enough to browse — services, events, rentals, staff and availability all answer without a credential. To let the assistant actually book, it must also present an API key; see Authentication below.

Claude Code Setup

Claude Code speaks the HTTP transport directly, so no bridge is needed. Add the server once, with your key on the header if the assistant should be able to book:

Terminal
claude mcp add --transport http reservly \
  https://reservly.io/api/mcp/YOUR-BUSINESS-SLUG \
  --header "Authorization: Bearer YOUR-API-KEY"
bash

Run claude mcp list to check it shows as connected. Leave out the --header line for a browse-only connection.

n8n Setup

Use n8n's MCP Client node. Set the transport to HTTP Streamable, the endpoint to your MCP server URL, and authentication to Bearer Auth with a credential holding your API key. Pick the tool by name and pass its arguments as JSON. A refused call (wrong scope, revoked key) does not fail the node: its output carries the refusal text, so branch on it with an IF node.

HTTP Transport

The MCP server is available over HTTP at a single endpoint — note that there is no /sse path:

https://reservly.io/api/mcp/{slug}
text

The protocol is JSON-RPC 2.0 over POST requests to that URL. Supported methods are initialize, tools/list, tools/call, and ping. The transport is Streamable HTTP in stateless mode — each request is independent, so no session tracking is required and the server scales horizontally.

There is no Server-Sent Events endpoint. The server never opens a long-lived stream, so a client that can only speak the older SSE transport cannot connect to it directly. Use mcp-remote (as in the Claude Desktop config above) to bridge such a client to this endpoint, or send plain JSON-RPC HTTP requests.

A raw tools/list call
curl -X POST https://reservly.io/api/mcp/YOUR-BUSINESS-SLUG \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
bash

Authentication

Browsing is open; booking is not. The six read-only tools work with no credential at all, which is what lets an assistant answer questions about your business straight away. book_appointment writes a real reservation, so it always requires a key that your business issued.

RequestResult
A read tool, no credentialWorks. Not attributed to any key, so it is not logged.
A read tool, with a valid read or all keyWorks, and is recorded in your MCP activity log.
A read tool, with a write keyRefused — a write key is write-only and can call book_appointment alone. The tool result reads This API key is not permitted to call search_services. (naming the tool), and the activity log records it as a scope refusal.
Any tool, with an invalid or revoked keyRefused. A credential that was presented and failed is never treated as anonymous — revoking a leaked key stops its reads immediately.
book_appointment, no credentialRefused.

Keys are created in Settings → Integrations on your dashboard, and are presented on the standard header:

Authorization: Bearer YOUR-API-KEY
text

A key can call book_appointment only when all three hold:

  • It is enabled for AI assistants. Tick Enable for AI assistants on the key. This is off by default, and it is a separate switch from the key's scope — a key you created for the REST API stays inert over MCP until you turn it on deliberately.
  • It carries the write scope (or all). A read key can call the six read tools and nothing else; a write key can call book_appointment and nothing else — it is refused on every read tool. Use all for an assistant that both looks up and books.
  • It has not been revoked or expired. Revocation takes effect on the next request.

Every authenticated call is written to the activity log on the same Integrations page, with the tool name, the key it used and the outcome — so you can see what an assistant did on your behalf, and cut it off if you do not like the answer.

A refusal is an ordinary JSON-RPC result, not an HTTP error: the response is 200, the result carries isError: true, and its text says why (for example This API key is not permitted to call book_appointment. or This API key has been revoked.).

Rate Limits

  • 60 requests per minute from one IP address. Every JSON-RPC request counts, including each element of a batch (at most 20 per batch). Over the limit the server answers HTTP 429 with Retry-After: 60 and a JSON-RPC error (code -32000, “Rate limit exceeded”).
  • 100 requests per minute per API key. A key over its limit gets a refusal result (isError: true, “Rate limit exceeded for this API key”) rather than an HTTP error. From a single IP address the per-IP limit is reached first.

Tool Parameters

Your business slug is injected automatically by the MCP endpoint, so most tools need no arguments. search_services, list_events, list_rentals and list_staff take an optional locale for translated names, and list_staff an optional service_id. The two tools with required parameters are:

check_availability

ParameterTypeRequiredDescription
datestringYesDate to check (YYYY-MM-DD)
service_idstringYesComma-separated service UUIDs
staff_idstringNoFilter slots by a specific staff member

book_appointment

ParameterTypeRequiredDescription
service_idsstring[]YesArray of service UUIDs to book
datestringYesBooking date (YYYY-MM-DD)
timestringYesBooking time (HH:MM, 24-hour)
customer_namestringYesCustomer full name
customer_emailstringYesCustomer email address
staff_idstringNoThe staff member to book (a staffId from check_availability). Leave it out and, for a service a staff member performs, Reservly assigns the first staff member free at that time in the business's Auto-Assign order — the same choice its booking page makes when the customer does not pick. If nobody is free at that time the call is refused (409) and nothing is booked.
customer_phonestringNoCustomer phone number
party_sizenumberNoParty size for group bookings (default 1)
promo_codestringNoPromo or session-package redemption code. A package code is reserved for one customer — it only applies when customer_email matches the buyer.
class_schedule_idstringNoClass session UUID. For a class-based service the server resolves the session from date + time, claims the seat, and rejects a time with no session — so you normally omit this. Send it only to disambiguate a date and time where two sessions of the same class start together.
payment_choicestringNo"online" or "at_door". Read only when the business lets the customer choose how to pay; omitted, the booking is paid at the door.

A successful call returns the booking with its status: confirmed, or pending when the business uses owner approval or customer confirmation (Settings → Booking Defaults → Booking Confirmation).

Example Conversation

Here is how a typical AI-assisted booking conversation works. The AI assistant handles tool calls behind the scenes while the customer interacts in natural language.

Customer

What services does Luxe Salon offer?

AI calls search_services

AI Assistant

Luxe Salon offers Haircut ($45, 60 min), Blowout ($35, 45 min), Color Treatment ($120, 120 min), and several other services. Would you like to book one?

Customer

Book me a haircut for tomorrow at 2pm.

AI calls check_availability → confirms 2:00 PM is open
AI calls book_appointment → booking confirmed

AI Assistant

Done! Your haircut at Luxe Salon is booked for tomorrow at 2:00 PM. A confirmation has been sent to your email.