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
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.
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.
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.
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.
{
"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; anidseen in the last 24 hours is accepted once.
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"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
- contract.json — the contract with full JSON Schemas
- Model Context Protocol specification — transports, tools and annotations
- Contact us — or write to hello@hotelone.site for a test hotel