Tool reference
96 tools across 22 namespaces. Each tool requires a specific OAuth scope and a plan module — the consent screen lets hosts opt in per-permission.
Auto-generated
This page is a snapshot. The authoritative tool list comes from the live registry on the dashboard; if you're building a custom client, the tools/list JSON-RPC method returns the same data with full input-schema details.
How tools are gated
For every tools/call, the server checks four things in order:
- OAuth scope — the token must include the tool's declared scope (granted by the host during consent).
- Plan module — the host's active membership plan must include the tool's
requiredModule(ormcp_accessfor always-on tools). - Input validation — arguments are validated against a Zod schema; invalid input returns a structured
invalid_inputerror. - Cross-tenant scoping — every handler scopes its DB queries to the host's account.
accounts.*
| Tool | Scope | Module | Type |
|---|---|---|---|
accounts.list | mcp_access | mcp_access | READ |
accounts.switch | mcp_access | mcp_access | WRITE (session state) |
accounts.list returns every workspace this user can drive via MCP — their own account plus any account where they're an accepted cohost. accounts.switch changes which workspace the rest of the session operates on (it affects every subsequent tool call until you switch again). Switching the MCP session does not change the host's dashboard session.
help.*
| Tool | Scope | Module | Type |
|---|---|---|---|
help.search | help:read | mcp_access | READ |
help.get | help:read | mcp_access | READ |
Searches articles on this Help Center via the hints.json index.
bookings.*
| Tool | Scope | Module | Type |
|---|---|---|---|
bookings.search | bookings:read | bookings | READ |
bookings.get | bookings:read | bookings | READ (+ PII opt-in) |
bookings.get_upcoming | bookings:read | bookings | READ |
bookings.get_today_checkins | bookings:read | bookings | READ |
bookings.get_today_checkouts | bookings:read | bookings | READ |
bookings.import | bookings:write_import | bookings | WRITE |
bookings.import lands past or manually-tracked bookings into hejGuide (e.g. for historical revenue/occupancy). It's the only booking write on the MCP surface; live OTA bookings still flow in via Channex, not this tool.
bookings.get supports include_pii=true with a reason enum to unmask the guest's email + phone + city. Requires the guests:read_pii scope in addition to bookings:read, and consumes from the daily 50-unmask budget. Sync-audited.
calendar.*
| Tool | Scope | Module | Type |
|---|---|---|---|
calendar.get_availability_window | bookings:read | bookings | READ |
calendar.list_blocks | bookings:read | bookings | READ |
get_availability_window returns per-day occupancy, blocks, and stop-sell flags for 1–90 days. list_blocks returns the host-set blocks (maintenance, owner stay, etc.) so the AI can explain why a particular date is unavailable.
pricing.*
| Tool | Scope | Module | Type |
|---|---|---|---|
pricing.get_current_rates | rates:read | rates | READ |
Read-only daily rates + min-stay + stop-sell + per-day is_gap flag (set on days where PriceLabs didn't deliver a price and we fell back to the rate plan / nightly rate). No push to Channex via MCP in this phase.
payments.*
| Tool | Scope | Module | Type |
|---|---|---|---|
payments.get_booking_detail | bookings:read | bookings | READ |
payments.list_overdue | bookings:read | bookings | READ |
get_booking_detail returns the full payment picture for one booking — charge breakdown, payment schedule and what's been paid. list_overdue returns direct bookings whose payment deadline has passed without (full) payment. Both are read-only and respect the listing's own currency (currency field per row); they never record a payment or message the guest.
products.*
| Tool | Scope | Module | Type |
|---|---|---|---|
products.list | products:read | products | READ |
products.get | products:read | products | READ |
products.add_to_booking | products:write | products | WRITE |
list / get read the host's product & extras catalogue (cleaning fees, linen, breakfast, …) with prices and per-OTA channel routing. add_to_booking is the only write — it puts catalogue products on a booking's bill. It does not record a payment and sends nothing to the guest; the host settles the charge in the dashboard.
listings.*
| Tool | Scope | Module | Type |
|---|---|---|---|
listings.list | listings:read | mcp_access | READ |
listings.get | listings:read | mcp_access | READ |
listings.get_amenities | listings:read | mcp_access | READ |
listings.get_photos | listings:read | mcp_access | READ |
listings.get_ai_context | listings:read | mcp_access | READ |
get_ai_context returns the host-curated "About this property (for AI)" free-text background (≤2000 chars, never shown to guests). Designed to be fetched before drafting anything property-specific. Includes updated_at for cache-invalidation across an LLM session.
host.*
| Tool | Scope | Module | Type |
|---|---|---|---|
host.get_voice_profile | messages:read | mcp_access | READ |
Returns the host's tone-of-voice profile — summary (a 1-paragraph distillation that drafting tools use), plus tone, pronoun, length_pref, languages, audience, bio, summary_locked and updated_at. Soft-fails to configured:false when the host hasn't filled in /account-settings?tab=ai yet, in which case the client should default to a warm, friendly tone in the guest's language.
reports.*
| Tool | Scope | Module | Type |
|---|---|---|---|
reports.get_revenue_summary | reports:read | bookings | READ |
reports.get_occupancy | reports:read | bookings | READ |
reports.get_top_listings | reports:read | bookings | READ |
reports.get_channel_performance | reports:read | bookings | READ |
reports.compare_periods | reports:read | bookings | READ |
reports.get_payment_status | reports:read | bookings | READ |
reports.get_review_stats | reports:read | channels | READ |
reports.get_operations_stats | reports:read | bookings | READ |
reports.get_smart_insights | reports:read | mcp_access | READ |
All aggregates; no row-level PII.
messages.*
| Tool | Scope | Module | Type |
|---|---|---|---|
messages.list_threads | messages:read | messages | READ |
messages.get_thread | messages:read | messages | READ |
messages.search | messages:read | messages | READ |
messages.create_draft | messages:write_draft | messages | WRITE |
messages.mark_no_reply_needed | messages:write_draft | messages | WRITE |
messages.suggest_reply | messages:write_draft | messages | WRITE |
create_draft writes a draft into the host's inbox — never sends to the guest. mark_no_reply_needed clears the needs-reply flag when a thread was handled outside the inbox (idempotent). suggest_reply calls the AI reply-draft pipeline (3-layer feature gate) and returns a draft body without saving; the response auto-injects a host_context block (voice profile + per-listing AI background) so the client can refine the draft without a second roundtrip.
All three messages.* read tools filter out team-chat conversations (isNull(teamConversationId)) so internal threads never leak into the guest-messaging surface.
reviews.*
| Tool | Scope | Module | Type |
|---|---|---|---|
reviews.list | reviews:read | channels | READ |
reviews.get | reviews:read | channels | READ |
reviews.get_pending_replies | reviews:read | channels | READ |
reviews.get_sentiment_summary | reviews:read | channels | READ |
reviews.create_draft_reply | reviews:write_draft | channels | WRITE |
create_draft_reply saves a draft in a dedicated mcp_review_drafts table — never publishes to the OTA. The host clicks Send in the dashboard to publish via Channex.
tasks.*
| Tool | Scope | Module | Type |
|---|---|---|---|
tasks.list | tasks:read | tasks | READ |
tasks.get | tasks:read | tasks | READ |
tasks.list_housekeeping | tasks:read | tasks | READ |
tasks.add_note | tasks:write | tasks | WRITE |
tasks.update_status | tasks:write | tasks | WRITE |
tasks.report_issue | tasks:write | tasks | WRITE |
Write-tools block housekeeping transitions (those must complete via the cleaner UI), enforce booking ↔ listing consistency, and reject status=scheduled (automation-only) and any move out of dismissed (terminal).
housekeeping.*
| Tool | Scope | Module | Type |
|---|---|---|---|
housekeeping.list_checklists | housekeeping:read | tasks | READ |
housekeeping.create_checklist | housekeeping:write | tasks | WRITE |
housekeeping.delete_checklist | housekeeping:write | tasks | WRITE |
These manage cleaning checklist templates (a named list of sections, each with tick-off items) — not the per-clean task state, which stays in tasks.*. create_checklist builds a template from sections + items; delete_checklist removes a template and its sections/items.
locks.*
| Tool | Scope | Module | Type |
|---|---|---|---|
locks.list_devices | locks:read | smart_locks | READ |
locks.list_codes | locks:read | smart_locks | READ |
locks.get_booking_code | locks:read | smart_locks | READ (code masked) |
locks.get_audit_log | locks:read | smart_locks | READ |
list_devices returns connected smart locks with battery/online health; list_codes lists access codes (guest/cleaner/team) with their status but never the PIN itself. get_booking_code returns one booking's door-code status with the PIN masked by default — passing include_code: true reveals the actual code, which requires the separate locks:read_codes scope and is sync-audited to the lock audit log (the PIN is stored only as a SHA-256 hash). get_audit_log returns recent lock events (code creations, revokes, accesses).
guests.*
| Tool | Scope | Module | Type |
|---|---|---|---|
guests.search | bookings:read | bookings | READ |
guests.get_history | bookings:read | bookings | READ |
guests.get_analytics | bookings:read | bookings | READ |
guests.unmask | guests:read_pii | bookings | PII (sync-audited) |
guests.unmask is the only tool that reveals raw email/phone/full name. Gated by the guests:read_pii scope, consumes from the daily 50-unmask budget, requires a reason enum + reason_detail ≥10 chars when reason='other'. Every call is sync-written to mcp_audit_log. get_analytics returns an aggregate view (repeat-guest rate, top nationalities, channel mix, average length-of-stay) without surfacing individual guests.
guidebook.*
| Tool | Scope | Module | Type |
|---|---|---|---|
guidebook.list | guidebook:read | guidebooks | READ |
guidebook.list_pages | guidebook:read | guidebooks | READ |
guidebook.get_page | guidebook:read | guidebooks | READ |
guidebook.search_pages | guidebook:read | guidebooks | READ |
guidebook.create_page | guidebook:write | guidebooks | WRITE (publishes to guests) |
guidebook.update_page | guidebook:write | guidebooks | WRITE (publishes to guests) |
The write tools change content that guests see immediately if is_published=true (the default for new pages). The AI can also flip is_published=false to hide a page without deleting it. Slugs are auto-generated from the title and collision-suffixed within the same guidebook. AI-created pages get a wand-icon "AI draft" badge in the dashboard until the host publishes them; once published, the badge clears.
places.*
| Tool | Scope | Module | Type |
|---|---|---|---|
places.list_categories | places:read | guidebooks | READ |
places.list | places:read | guidebooks | READ |
places.get | places:read | guidebooks | READ |
places.create | places:write | guidebooks | WRITE (publishes to guests) |
places.update | places:write | guidebooks | WRITE (publishes to guests) |
places.create_category | places:write | guidebooks | WRITE (host-only) |
Same publish-to-guests semantics as the guidebook writes for create / update. create_category is host-only (categories live in the dashboard's organization, not on the guest portal) and writes directly without an accept-step. Both surfaces share the guidebooks plan module (and consent UI bundles them under "Guidebook" + "Local guide") because hosts always edit them together.
translations.*
| Tool | Scope | Module | Type |
|---|---|---|---|
translations.list_available_languages | guidebook:read | guidebooks | READ |
translations.list_keyfields | guidebook:read | guidebooks | READ |
translations.set_page_translation | guidebook:write | guidebooks | WRITE (pending review) |
translations.set_place_translation | places:write | guidebooks | WRITE (pending review) |
translations.set_category_translation | places:write | guidebooks | WRITE (host-only, direct) |
translations.set_guidebook_settings_translation | guidebook:write | guidebooks | WRITE (pending review) |
translations.set_checkin_confirmation_translation | guidebook:write | checkin | WRITE (pending review) |
The AI client produces the translated text itself — hejGuide doesn't run server-side machine translation on the MCP path. list_available_languages returns the languages configured for the guest portal, and list_keyfields returns the placeholder tokens ({guest_first_name}, {checkin_link}, etc.) that survive translation, so the client writes them as literal tokens instead of free text. Four of the five write-tools land as pending updates that the host accepts or rejects from a banner in the dashboard. The accept-handler uses jsonb_set per-locale so writing one language never wipes the others. set_category_translation writes directly because category labels live only in the dashboard organization layer (no guest-visible surface).
team.*
| Tool | Scope | Module | Type |
|---|---|---|---|
team.list_conversations | team:read | messages | READ |
team.list_messages | team:read | messages | READ |
team.list_participants | team:read | messages | READ |
team.find_or_create_dm | team:write_message | messages | WRITE (creates conversation) |
team.send_message | team:write_message | messages | WRITE (instant send) |
Team-chat is the internal messaging surface between the host and their cohosts — separate from guest threads. Unlike messages.create_draft, team.send_message delivers instantly (no draft step), mirroring the dashboard team-chat panel. Other participants see the message immediately on refresh.
Every team tool verifies that the calling user is a participant of the target conversation before reading or writing. team.find_or_create_dm is idempotent — it returns the existing 1-on-1 if one already exists between you and the target user on the active account, otherwise it creates a new one (under an advisory lock to prevent races).
automations.*
| Tool | Scope | Module | Type |
|---|---|---|---|
automations.list_journey | automations:read | emails | READ |
automations.get_journey_template | automations:read | emails | READ |
automations.list_custom | automations:read | emails | READ |
automations.get_upcoming | automations:read | emails | READ |
automations.get_skip_reasons | automations:read | emails | READ |
Read-only access to the journey-automation surface. No writes — toggling automations on/off, editing the body, cancelling a scheduled message or sending one immediately all stay in the dashboard (/emails). The host owns those flows.
list_journey has two modes: pass listing_id for the effective config of one property (resolves per-listing override → shared default → catalog default), or omit it for the account-wide shared defaults plus a summary of which listings have per-key overrides. Template bodies come back with un-substituted variable tokens ({guest_first_name}, {checkin_link}, etc.) — there's no per-booking rendering on this surface, so no guest PII leaks via the catalog.
get_upcoming shows the scheduled outbox: pending automation messages that haven't been sent yet. Filterable by booking (internal id or public_id), listing, and a 1–30 day window. Guest names are masked; when no guest name is on file (early Channex bookings), the response falls back to Guest (PUBLIC-ID).
get_skip_reasons is the diagnostic tool — pass a booking_id and you get the most recent journey_reconciled audit event for that booking, decoded into reason codes (ota_skip, no_guest_email, missing_vars:X, past_or_in_buffer, update_skipped_in_buffer, cancel_skipped_in_buffer, preserve_future_pending, listing_scope_excluded). Useful for explaining "why didn't this guest get a check-in invite?".
website.*
| Tool | Scope | Module | Type |
|---|---|---|---|
website.list_sites | website:read | direct_booking | READ |
website.get_site | website:read | direct_booking | READ |
website.get_collection | website:read | direct_booking | READ |
website.update_copy | website:write | direct_booking | WRITE (host reviews) |
website.update_collection_copy | website:write | direct_booking | WRITE (host reviews) |
website.check_domain_dns | website:read | direct_booking | READ |
The read tools return the host's direct-booking web presence — per-listing booking sites and collection sites (/c/...), their section toggles, brand and copy. check_domain_dns is a read-only diagnostic for a site's custom domain. The two write tools propose new copy for a booking site or collection; the proposal isn't live until the host reviews and approves it in the dashboard editor.