# Integrations (PMS, payments, events) — tool reference

Generated from the OpenAPI document (`https://maison-labs.com/api/v1/openapi.json`). Field types are JSON Schema types; GET/DELETE inputs travel as path or query, other methods as a JSON body.

## `add_integration` — Connect or update an integration

Create or update a hotel's integration: creates a new integration row for the provider, or replaces an existing one's credentials, config, and tool audiences. Validates the provider against the registry, required config fields against the manifest, and toolAudiences keys. For `stripe` with a `secretKey`, also creates (or rotates) the hotel's Stripe webhook endpoint and stores its signing secret — 422 `stripe_key_invalid` / `stripe_webhook_failed` when Stripe refuses, with nothing saved. Re-run to update credentials or config. Returns the masked integration row after upsert.

- REST: `PUT https://maison-labs.com/api/v1/client/{clientId}/integration/{provider}`
- MCP tool / A2A skill: `add_integration`
- Needs: update-client WRITE (client); client plan must include `update-client`

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |
| `provider` | path | string | yes | Provider slug, e.g. rezstream, mews, stscloud (from list_integration_catalog) |
| `credentials` | body | object \| null | no | Provider credential key-value pairs (encrypted at rest) |
| `config` | body | object \| null | no | Provider config values (e.g. propertyId, rfpFormId) |
| `enabledToolIds` | body | array of string \| null | no | Tool ids to enable; null = use manifest defaults |
| `toolAudiences` | body | object \| null | no | Per-tool audience map: deny \| client \| guest \| all. Null clears the map. |

## `check_integration_config` — Check an integration config value

Validates one operator-entered config value against the provider before it can silently break a guest conversation. Returns the resolved object name, id and any required fields the operator still needs to supply. 404 when the value does not exist at the vendor. 409 when the integration is not saved or not yet connected.

- REST: `GET https://maison-labs.com/api/v1/client/{clientId}/integration/{provider}/configcheck`
- MCP tool / A2A skill: `check_integration_config`
- Needs: update-client READ (client); client plan must include `update-client`
- Read-only.

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |
| `provider` | path | string | yes | Provider slug, e.g. stscloud |
| `field` | query | string | yes | Config field key to check, e.g. rfpFormId |
| `value` | query | string | yes | The field value to validate against the provider |

## `disable_integration` — Disable an integration

Pauses an integration — config and credentials are preserved but the integration is excluded from tool delivery at once, until re-enabled. Idempotent: already-disabled is a no-op. 404 when no active integration exists.

- REST: `POST https://maison-labs.com/api/v1/client/{clientId}/integration/{provider}/disable`
- MCP tool / A2A skill: `disable_integration`
- Needs: update-client WRITE (client); client plan must include `update-client`
- Destructive — confirm with the user first.

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |
| `provider` | path | string | yes | Provider slug |

## `enable_integration` — Enable an integration

Re-enables a previously disabled integration — credentials and config are restored exactly as they were and its tools are served again at once. Idempotent: already-enabled is a no-op. 404 when no active integration exists.

- REST: `POST https://maison-labs.com/api/v1/client/{clientId}/integration/{provider}/enable`
- MCP tool / A2A skill: `enable_integration`
- Needs: update-client WRITE (client); client plan must include `update-client`

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |
| `provider` | path | string | yes | Provider slug |

## `list_client_integrations` — List client integrations

Returns all active integrations for a hotel with credentials MASKED (last 4 characters only — never decrypted). Optionally includes soft-deleted history rows via `includeRemoved`. Use `list_integration_catalog` to map provider slugs to human names.

- REST: `GET https://maison-labs.com/api/v1/client/{clientId}/integrations`
- MCP tool / A2A skill: `list_client_integrations`
- Needs: update-client READ (client); client plan must include `update-client`
- Read-only.

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |
| `includeRemoved` | query | boolean | no | When true, the response also includes a `removed` array of historical rows; default false |

## `list_integration_catalog` — Integration catalog

Returns the full integration provider catalog grouped by type (pms, bookingengine, payments, …), including credential/config fields and available tools for each provider, plus announced coming-soon placeholders. Use before `add_integration` to discover provider slugs and required fields.

- REST: `GET https://maison-labs.com/api/v1/integrations/catalog`
- MCP tool / A2A skill: `list_integration_catalog`
- Needs: clients READ (any)
- Read-only.

Inputs:

_No inputs._

## `list_integration_properties` — List integration properties

Returns the properties (rezStream), bookable services (Mews) or businesses (ResNexus) of the connected account, as `properties: [{ id, name, timezone, currency, address, bookablePeriod? }]` — the choices for the integration's property field (`propertyId`, `serviceId`, `businessId`; set it with `add_integration`). Also refreshes the stored name and metadata of the currently selected item and clears an Error status the list proves stale. Mews: `refresh: true` also re-syncs the booking-engine configuration bypassing its cache. 409 when the integration is not saved or not yet connected; 502 when the vendor call fails.

- REST: `GET https://maison-labs.com/api/v1/client/{clientId}/integration/{provider}/properties`
- MCP tool / A2A skill: `list_integration_properties`
- Needs: update-client READ (client); client plan must include `update-client`
- Read-only.

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |
| `provider` | path | enum: rezstream \| mews \| resnexus | yes | Provider: rezstream \| mews \| resnexus |
| `refresh` | query | boolean | no | Mews: re-sync the booking-engine configuration, bypassing its cache; default false |

## `list_pms_rate_plans` — List PMS rate plans

Returns the rate plans of the hotel's connected PMS (the provider's own response shape), e.g. to choose the rate a booking link or offer should use. Filters are passed to the PMS as given; Mews takes `serviceIds`. `rates` (default true), `rateGroups` and `availabilityBlockAssignments` (default false) select what Mews includes. 404 when the hotel has no active PMS.

- REST: `GET https://maison-labs.com/api/v1/client/{clientId}/pms/rateplans`
- MCP tool / A2A skill: `list_pms_rate_plans`
- Needs: hotel-config READ (client); client plan must include `hotel-config`
- Read-only.

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |
| `serviceIds` | query | string | no | Comma-separated PMS service ids (Mews) |
| `rateId` | query | string | no | One rate plan id |
| `roomTypeId` | query | string | no | Room type id |
| `hotelId` | query | string | no | PMS hotel/property id |
| `checkIn` | query | string | no | Check-in date (YYYY-MM-DD) |
| `checkOut` | query | string | no | Check-out date (YYYY-MM-DD) |
| `adults` | query | integer | no |  |
| `children` | query | integer | no |  |
| `rateCategories` | query | string | no | Rate categories filter |
| `limit` | query | integer | no |  |
| `offset` | query | integer | no |  |
| `count` | query | integer | no |  |
| `rates` | query | boolean | no | default true |
| `rateGroups` | query | boolean | no | default false |
| `availabilityBlockAssignments` | query | boolean | no | default false |

## `remove_integration` — Disconnect an integration

Soft-deletes the active integration row and wipes all stored credentials and tokens; for `stripe` it also deletes the hotel's Stripe webhook endpoint (best-effort). The integration can be reconnected with `add_integration`. 404 when no active integration exists for the provider.

- REST: `DELETE https://maison-labs.com/api/v1/client/{clientId}/integration/{provider}`
- MCP tool / A2A skill: `remove_integration`
- Needs: update-client WRITE (client); client plan must include `update-client`
- Destructive — confirm with the user first.

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |
| `provider` | path | string | yes | Provider slug to disconnect |

## `send_integration_connect_link` — Email an integration connect invitation

Emails the hotel's own account holder a one-time link to grant Maison access to their rezStream or STS Cloud account — the only way these integrations connect, because consent must come from the hotel. The recipient is the `emailId` saved on the integration (never a request value); STS Cloud also needs its OAuth Client Secret saved first. Returns `{ message, sentTo }`. 404 when the integration is not saved; 409 when the saved email (or STS secret) is missing; 503 when the connect flow is not configured in this environment; 502 when the email could not be sent. Each call issues a new link.

- REST: `POST https://maison-labs.com/api/v1/client/{clientId}/integration/{provider}/connectlink`
- MCP tool / A2A skill: `send_integration_connect_link`
- Needs: update-client EXECUTE (client); client plan must include `update-client`

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |
| `provider` | path | enum: rezstream \| stscloud | yes | Provider: rezstream \| stscloud |
