---
name: "maison-configuration"
description: "Configure how a hotel's concierge behaves and looks: the hotel configuration document (set/unset fields), the chatbot tone, the chat widget's runtime switches and full style map, guest-facing translations with machine translation, theme colour and visuals, media assets, the sales agent configuration and lead recipients, internal client notes, the email log, settings catalogues (regions, departments, tags) and report subscribers. Use for any 'change what the concierge says/looks like' request or to read a hotel's current setup. Tools: add_client_note, add_client_setting, add_report_subscribers, create_media_upload, create_theme_visual_upload, delete_client_note, generate_theme_icon, get_chat_runtime, get_chat_styles, get_chatbot_tone, get_client_email, get_client_email_attachment, get_hotel_config, get_staff_notification_emails, get_theme, get_theme_visual, get_translations, list_client_emails, list_client_notes, list_client_settings, list_media_assets, list_note_versions, list_report_subscribers,…"
license: "Proprietary. Use with a Maison API key under the Maison terms of service."
metadata:
  author: "maison-labs"
  version: "1.0.0"
  category: "configuration"
  api-base: "https://maison-labs.com"
  openapi: "https://maison-labs.com/api/v1/openapi.json"
  docs: "https://docs.maison-labs.com/skills/maison-configuration/"
---

# Maison — Hotel configuration, branding and content

Configure how a hotel's concierge behaves and looks: the hotel configuration document (set/unset fields), the chatbot tone, the chat widget's runtime switches and full style map, guest-facing translations with machine translation, theme colour and visuals, media assets, the sales agent configuration and lead recipients, internal client notes, the email log, settings catalogues (regions, departments, tags) and report subscribers. Use for any 'change what the concierge says/looks like' request or to read a hotel's current setup.

Part of the Maison public API. Read the `maison-public-api` skill first for authentication, discovery and transport details (`https://docs.maison-labs.com/skills/maison-public-api/SKILL.md`).

## When to use

- Update address, hours, policies or any hotel fact the concierge should know — `update_hotel_config`.
- Change the agent's voice — `set_chatbot_tone`; `get_chatbot_tone` returns `defaultTone` and `set_chatbot_tone` with `reset: true` restores it.
- Localise — `get_translations`, `translate_text`, `update_translations`.
- Brand the widget — `set_theme_color`, `upload_theme_visual`; the full style map with `get_chat_styles` / `set_chat_styles`.
- To make a chat icon in the brand colour call `generate_theme_icon`; it replaces the current icon.
- Switch the custom theme or document answers on or off — `get_chat_runtime` / `update_chat_runtime` (`branding`, `documents`).

## Before you start

1. Send `x-api-key: <key>` on every call; the key only reaches `/api/v1`.
2. `GET /api/v1/tools` (or MCP `tools/list`) returns the tools THIS key may run — if a tool below is missing there, you lack a grant; do not retry it.
3. Client-scoped tools take `clientId` (a hotel id). `whoami` lists the ids you can act on.

## Tools

| Tool | What it does | REST | Needs |
| --- | --- | --- | --- |
| `add_client_note` | Create a new operator note on the client. | `POST /api/v1/client/{clientId}/note` | update-client WRITE (client); plan: `client-notes` |
| `add_client_setting` | Create a new region, department, or tag for the hotel. | `POST /api/v1/client/{clientId}/setting/{kind}` | clients WRITE (client) |
| `add_report_subscribers` | Add one or more email addresses as report subscribers for the hotel. | `POST /api/v1/client/{clientId}/subscribers` | update-client WRITE (client); plan: `update-client` |
| `create_media_upload` | Start a media-library upload larger than 64 KiB (up to 5 MB): returns `{ uploadId, uploadUrl, method, headers, expiresAt }`. | `POST /api/v1/client/{clientId}/mediaasset/upload` | update-client WRITE (client); plan: `update-client` |
| `create_theme_visual_upload` | Start a theme visual upload larger than 64 KiB (up to 5 MB): returns `{ uploadId, uploadUrl, method, headers, expiresAt }`. | `POST /api/v1/client/{clientId}/theme/visual/upload` | branding WRITE (client); plan: `branding` |
| `delete_client_note` | Soft-delete a note from the client. | `DELETE /api/v1/client/{clientId}/note/{noteId}` | update-client WRITE (client); plan: `client-notes`; destructive |
| `generate_theme_icon` | Generate the chat widget's launcher icon in the hotel's theme colour and store it as the `icon` visual: it replaces the current chat icon. | `POST /api/v1/client/{clientId}/theme/icon` | branding WRITE (client); plan: `branding` |
| `get_chat_runtime` | Read the chat widget's runtime switches: `branding.enabled` (the hotel's custom theme is applied) and `documents.enabled` (the agent may answer from uploaded documents). | `GET /api/v1/client/{clientId}/config/runtime` | hotel-config READ (client); read-only |
| `get_chat_styles` | Read the chat widget's full style map (`chatStyles`: the seed colour `cuiSeedColor` and every other widget style token the console's theme editor writes). | `GET /api/v1/client/{clientId}/theme/chatstyles` | branding READ (client); plan: `branding`; read-only |
| `get_chatbot_tone` | Fetch the chatbot tone instructions for the hotel. | `GET /api/v1/client/{clientId}/config/tone` | chatbot-tone READ (client); read-only |
| `get_client_email` | Fetch the full detail of a single logged email, including the HTML/text body and event timeline. | `GET /api/v1/client/{clientId}/email/{emailId}` | client-emails READ (client); plan: `client-emails`; read-only |
| `get_client_email_attachment` | Generate a pre-signed download URL for an attachment at the given zero-based index on a logged email. | `GET /api/v1/client/{clientId}/email/{emailId}/attachment/{index}` | client-emails READ (client); plan: `client-emails`; read-only |
| `get_hotel_config` | Fetch the hotel configuration document (property fields such as name, address, phone, hours, policies). | `GET /api/v1/client/{clientId}/config` | hotel-config READ (client); read-only |
| `get_staff_notification_emails` | Returns the list of staff email addresses that receive upsell and payment-notice notifications for a hotel. | `GET /api/v1/client/{clientId}/notifications` | hotel-config READ (client); plan: `hotel-config`; read-only |
| `get_theme` | Fetch the hotel's chat-widget theme: seed colour and visual asset URLs (icon, hero, herodark). | `GET /api/v1/client/{clientId}/theme` | branding READ (client); plan: `branding`; read-only |
| `get_theme_visual` | Read the raw SVG text for one of the hotel's chat-widget visual assets (icon, hero, or herodark). | `GET /api/v1/client/{clientId}/theme/visual/{kind}` | branding READ (client); plan: `branding`; read-only |
| `get_translations` | Fetch the full chat-widget translation map for the hotel. | `GET /api/v1/client/{clientId}/translations` | translations READ (client); plan: `translations`; read-only |
| `list_client_emails` | Paginated list of email messages logged for the hotel. | `GET /api/v1/client/{clientId}/emails` | client-emails READ (client); plan: `client-emails`; read-only |
| `list_client_notes` | Page through operator notes on a client, pinned notes first. | `GET /api/v1/client/{clientId}/notes` | update-client READ (client); plan: `client-notes`; read-only |
| `list_client_settings` | Page through the hotel's regions, departments and tags. | `GET /api/v1/client/{clientId}/settings` | clients READ (client); read-only |
| `list_media_assets` | List all media assets in the hotel's library (images used in knowledge articles, widget customisations, etc.). | `GET /api/v1/client/{clientId}/mediaassets` | update-client READ (client); plan: `update-client`; read-only |
| `list_note_versions` | Page through the version history of a note, newest first. | `GET /api/v1/client/{clientId}/note/{noteId}/versions` | update-client READ (client); plan: `client-notes`; read-only |
| `list_report_subscribers` | List all active report email subscribers for the hotel, including linked user details where available. | `GET /api/v1/client/{clientId}/subscribers` | clients READ (client); read-only |
| `remove_client_setting` | Disable (soft-delete) a region or department, or permanently delete a tag. | `DELETE /api/v1/client/{clientId}/setting/{kind}/{settingId}` | clients WRITE (client); destructive |
| `remove_media_asset` | Delete a media asset from S3 and the hotel's media library. | `DELETE /api/v1/client/{clientId}/mediaasset/{assetId}` | update-client WRITE (client); plan: `update-client`; destructive |
| `remove_report_subscribers` | Soft-delete report subscribers by their subscriber row ids. | `DELETE /api/v1/client/{clientId}/subscribers` | update-client WRITE (client); plan: `update-client`; destructive |
| `remove_theme_visual` | Delete a chat-widget visual asset (icon, hero, or herodark) from S3 and the client config. | `DELETE /api/v1/client/{clientId}/theme/visual/{kind}` | branding WRITE (client); plan: `branding`; destructive |
| `set_chat_styles` | Replace the chat widget's full style map (`chatStyles`) — send every token you want kept (read it first with `get_chat_styles`); the widget's cached styles are refreshed. | `PUT /api/v1/client/{clientId}/theme/chatstyles` | branding WRITE (client); plan: `branding` |
| `set_chatbot_tone` | Replace the chatbot tone instructions for the hotel (a free-text prompt that shapes the agent's voice and personality), or send `reset: true` to restore the platform default (`defaultTone` from `get_chatbot_tone`). | `PUT /api/v1/client/{clientId}/config/tone` | chatbot-tone WRITE (client) |
| `set_staff_notification_emails` | Replaces the list of staff email addresses that receive upsell and payment-notice notifications for a hotel (trimmed, lower-cased, de-duplicated). | `PUT /api/v1/client/{clientId}/notifications` | hotel-config WRITE (client); plan: `hotel-config` |
| `set_theme_color` | Update the chat-widget seed colour (CUI seed color string). | `PUT /api/v1/client/{clientId}/theme` | branding WRITE (client); plan: `branding` |
| `translate_text` | Machine-translate up to 10 short strings to a target locale using AWS Translate. | `POST /api/v1/translate` | clients READ (any) |
| `update_chat_runtime` | Switch the chat widget's custom theme (`branding`) and/or document answers (`documents`) on or off. | `PUT /api/v1/client/{clientId}/config/runtime` | hotel-config WRITE (client) |
| `update_client_note` | Edit the body or pinned state of an existing note. | `PATCH /api/v1/client/{clientId}/note/{noteId}` | update-client WRITE (client); plan: `client-notes` |
| `update_client_setting` | Update the name or description of an existing region, department, or tag. | `PUT /api/v1/client/{clientId}/setting/{kind}/{settingId}` | clients WRITE (client) |
| `update_hotel_config` | Merge new fields into the hotel config (`set`), remove keys (`unset`), or declare value types (`types`). | `PUT /api/v1/client/{clientId}/config` | hotel-config WRITE (client) |
| `update_media_asset` | Update the description or published state of an existing media asset. | `PATCH /api/v1/client/{clientId}/mediaasset/{assetId}` | update-client WRITE (client); plan: `update-client` |
| `update_translations` | Replace the entire chat-widget translation map: `{ defaultLocale, languages }` where each language code (e.g. | `PUT /api/v1/client/{clientId}/translations` | translations WRITE (client); plan: `translations` |
| `upload_media_asset` | Add an image (PNG, JPEG, GIF, WebP or SVG) to the hotel's media library. | `POST /api/v1/client/{clientId}/mediaasset` | update-client WRITE (client); plan: `update-client` |
| `upload_theme_visual` | Upload or replace a chat-widget visual asset (icon, hero, or herodark): PNG, JPEG, GIF, WebP or SVG (SVG is sanitised). | `PUT /api/v1/client/{clientId}/theme/visual/{kind}` | branding WRITE (client); plan: `branding` |

Full input fields for every tool: [references/tools.md](references/tools.md).

## Recommended workflows

### Change a hotel fact safely

1. `get_hotel_config` to read the current document and exact field names.
2. `update_hotel_config` with `set: { field: value }` (and `unset: [field]` to remove); only the fields sent change.
3. Confirm with `send_message` (conversations skill) in a new session.

### Add a language

1. `get_translations` for the current map and keys.
2. `translate_text` in batches to draft the new locale, review, then `update_translations` with the merged map.

## Tips

- Notes support optimistic concurrency: send the `updatedDate` you read, and retry on 409.
- Theme visuals and media images up to 64 KiB go inline as `bytesBase64`; larger ones (≤ 5 MB): `create_theme_visual_upload` / `create_media_upload`, PUT the file to `uploadUrl` with exactly `headers`, then `upload_theme_visual` / `upload_media_asset` with the `uploadId`. `get_theme` returns visual URLs.

## Pitfalls

- `update_translations` replaces the whole map — always merge into the result of `get_translations`. It is validated exactly like the console (≤ 60 languages, identifier phrase keys, the default must be active).
- `set_chat_styles` replaces the whole style map — send every token you want kept (read it with `get_chat_styles` first).
- Agents tools require the hotel's plan to include `agents`, for Maison staff too; without it they answer 403 `not_entitled`.

## Calling conventions

Same tool, three transports — pick whichever your runtime already speaks. Always send `x-api-key`.

```bash
# REST
curl -X POST "https://maison-labs.com/api/v1/client/<clientId>/note" -H "x-api-key: $MAISON_API_KEY" -H "content-type: application/json" -d '{ "bodyMarkdown": … }'
```

```json
// MCP (https://maison-labs.com/mcp, Streamable HTTP): tools/call
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "add_client_note", "arguments": { "bodyMarkdown": … } } }
```

```json
// A2A (https://maison-labs.com/a2a): tasks/send with a data part
{ "jsonrpc": "2.0", "id": 1, "method": "tasks/send", "params": { "message": { "role": "user", "parts": [{ "type": "data", "data": { "tool": "add_client_note", "input": { "bodyMarkdown": … } } }] } } }
```

Errors are the same everywhere: `401` no/invalid key; `403 forbidden` with `details.missing` (the grants you lack — fall back to the composite's parts or stop); `403 not_entitled` (the hotel's plan lacks the feature); `404`, `409`, `413 too_large`, `503`. Inputs that fail validation return `400 invalid_input` with the Zod issues — fix and retry once.
