Skip to content

For PMS partners

Connect your PMS to HotelOne

Expose your PMS as an MCP server and every hotel that uses it can run HotelOne’s agents on top of it — no screen-scraping, no migration.

Running a hotel? Connect your system when you set up

What you get

  • Your PMS becomes agent-native

    Staff ask HotelOne’s console agent “who’s arriving?” or “check in Moreno into 14” and it reads and acts in your system through your MCP server.

  • Voice and phone, too

    The same tools power HotelOne’s voice front desk and the hotel’s phone line, so answers come from your live data.

  • People stay in charge

    Look-ups use your read-only tools. Every change is shown to hotel staff as a plan and only runs after they confirm it.

How it works

  1. Run a remote MCP server

    Streamable HTTP (MCP 2025-06-18; 2025-03-26 also works), authenticated with a per-hotel token — a bearer token or a header such as X-API-Key.

  2. The hotel connects it

    In HotelOne → Your PMS, the owner pastes your MCP URL and their token. We call initialize and tools/list before saving anything.

  3. We discover your tools

    Each tool is cached as a reusable skill and matched to the contract below. Names don’t have to be exact: common aliases and parameter names are recognised.

  4. Staff just ask

    Recognised operations run directly; anything else is planned by our AI with only the tools the task allows, at most 8 calls per task.

The recommended tool contract

Expose these tools and HotelOne works with your PMS the moment a hotel connects. Mark read tools with annotations.readOnlyHint: true, return JSON in structuredContent (or as JSON text), and report failures with isError: true and a message a front-desk clerk can read. Version 2026-10-18. ? = optional.

  • list_arrivalsread

    (date?)

    Reservations arriving on a date (default today), including whether each is checked in and its room.

    Also recognised: arrivals, get_arrivals, arrivals_list, list_arrival

  • list_departuresread

    (date?)

    Reservations departing on a date (default today), with balance due and room.

    Also recognised: departures, get_departures, departures_list, list_departure

  • list_in_houseread

    (—)

    Guests currently checked in, with room numbers and departure dates.

    Also recognised: in_house, get_in_house, list_inhouse, inhouse

  • get_reservationread

    (confirmation_code?, guest_name?, reservation_id?)

    Find reservations by confirmation code or guest name (partial names allowed). Returns every match.

    Also recognised: find_reservation, search_reservations, search_reservation, reservations_list

  • check_inwrite

    (reservation_id, room_number?)

    Check a reservation in, optionally into a specific room.

    Also recognised: checkin, check_in_guest, checkin_guest, check_in_reservation

  • check_outwrite

    (reservation_id)

    Check a reservation out (the PMS decides how balances are handled).

    Also recognised: checkout, check_out_guest, checkout_guest, check_out_reservation

  • assign_roomwrite

    (reservation_id, room_number)

    Assign (or move) a reservation to a room.

    Also recognised: assign_room_to_reservation, set_room, room_assign, assign_reservation_room

  • add_reservation_notewrite

    (reservation_id, note)

    Add a note or comment to a reservation, visible to the front desk.

    Also recognised: add_note, create_note, reservation_add_note, add_reservation_comment

  • get_availabilityread

    (check_in, check_out, room_type?)

    Rooms or room types available for a stay, with prices if the PMS has them.

    Also recognised: availability, check_availability, search_availability, list_availability

  • update_rateswrite

    (room_type, start_date?, end_date?, dates?, amount?, percent?)

    Change the nightly rate of a room type for a date range or a list of dates — to an amount, or by a percentage.

    Also recognised: set_rates, update_rate, set_rate, change_rates

  • set_room_statuswrite

    (room_number, status, reason?)

    Set a room’s housekeeping status: clean, dirty, inspected, out_of_order or out_of_service.

    Also recognised: update_room_status, room_status, set_housekeeping_status, update_housekeeping_status

Lists return reservations as { reservation_id, confirmation_code, guest_name, arrival, departure, room_number?, room_type?, status }. Write tools run only after staff confirm, so make them do exactly one thing. Your other tools still work through our planner — but we never call tools that delete, refund, export data or manage users.

Example tool definition
{
  "name": "list_arrivals",
  "title": "List arrivals",
  "description": "Reservations arriving on a date (default today), including whether each is checked in and its room.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "date": {
        "type": "string",
        "format": "date",
        "description": "Calendar day, YYYY-MM-DD (hotel’s local date)."
      }
    },
    "additionalProperties": false
  },
  "annotations": {
    "readOnlyHint": true
  }
}

Events webhook

Tell HotelOne when something changes and it shows up in the hotel’s activity log, where staff and the agent see it (“PMS: reservation created — Ana Moreno, 20–22 Oct”). The hotel’s owner copies the URL and secret from HotelOne → Your PMS.

Endpoint
POST https://hotelone.site/api/pms/events/<connectionId>
Body (JSON, up to 64 KB)
{ "id"?: "evt_…", "type": "reservation.created", "occurred_at": "ISO 8601", "data": { … } }
Types
reservation.created · reservation.updated · reservation.cancelled · reservation.checked_in · reservation.checked_out · room.status_changed · rates.updated · availability.changed · ping
Signature
X-HotelOne-Timestamp: <unix seconds>
X-HotelOne-Signature: sha256=<hex HMAC-SHA256(secret, timestamp + "." + raw body)>
Deliveries more than 5 minutes off our clock are rejected; an id seen in the last 24 hours is accepted once.
curl
SECRET='pmsevt_…'   # HotelOne → Your PMS → Events
URL='https://hotelone.site/api/pms/events/<connectionId>'
BODY='{"id":"evt_1001","type":"reservation.created","occurred_at":"2026-10-18T14:03:00Z","data":{"reservation_id":"R-1001","confirmation_code":"ABC123","guest_name":"Ana Moreno","arrival":"2026-10-20","departure":"2026-10-22","room_type":"Deluxe King"}}'
TS=$(date +%s)
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //')

curl -X POST "$URL" \
  -H 'Content-Type: application/json' \
  -H "X-HotelOne-Timestamp: $TS" \
  -H "X-HotelOne-Signature: sha256=$SIG" \
  --data "$BODY"
JavaScript (Node 18+)
import { createHmac } from 'node:crypto';

export async function sendHotelOneEvent(url, secret, event) {
  const body = JSON.stringify(event); // sign exactly the bytes you send
  const timestamp = Math.floor(Date.now() / 1000).toString();
  const signature = 'sha256=' + createHmac('sha256', secret).update(`${timestamp}.${body}`).digest('hex');
  const res = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'X-HotelOne-Timestamp': timestamp, 'X-HotelOne-Signature': signature },
    body,
  });
  if (!res.ok) throw new Error(`HotelOne answered ${res.status}`);
}

await sendHotelOneEvent(url, secret, {
  id: 'evt_1002',
  type: 'room.status_changed',
  occurred_at: new Date().toISOString(),
  data: { room_number: '14', status: 'clean', previous_status: 'dirty' },
});

Security

  • Tokens are sealed with AES-256-GCM on our server. They are never shown again, never logged and never sent to an AI model.
  • Look-ups may only call read-only tools. Write tools run only after a hotel staff member confirms the plan, and every change is written to the hotel’s activity log.
  • At most 8 tool calls and 60 seconds per task, with per-hotel hourly limits. Tools that delete, refund, export data or manage users are never called, and hotels can switch off any of your tools.
  • Your server must be public HTTPS; we don’t follow redirects and never connect to private network addresses.
  • Events are signed per connection, time-limited and rate-limited.

Build it