Connect with OAuth
OAuth lets an app work with Maison on your behalf without an API key. You sign in to Maison, see what the app is asking for, choose which hotels it may reach, and approve. You can disconnect it at any time. This is how Claude, ChatGPT and other MCP clients connect to Maison, and how a hotel's own integrations sign their users in.
https://maison-labs.com/api/v1, MCP https://maison-labs.com/mcp and A2A https://maison-labs.com/a2a — never the admin console.Pick your path:
- Connect Claude, ChatGPT or another MCP client as yourself
- Register an app for your hotel (Developer apps)
- For admins: approving and revoking
Reference for app builders:
Connect Claude, ChatGPT or another MCP client as yourself
You need a Maison account and an MCP client that supports OAuth sign-in. You do not need an API key, and you do not register anything first: the client introduces itself to Maison when you connect.
1. Copy the Maison MCP server URL
https://maison-labs.com/mcp2. Add it to your client
- Claude (web or desktop): open the connector settings, add a custom connector, paste the URL and leave any API key or header fields empty.
- ChatGPT: add a custom connector (MCP server) in the connector settings, paste the URL and choose OAuth as the authentication.
- Claude Code: add the server, then run
/mcpin a session and choose to authenticate. - Any other MCP client: add an HTTP (Streamable HTTP) server with the URL and no headers. A client that follows the MCP authorization spec finds Maison's sign-in by itself.
claude mcp add --transport http maison https://maison-labs.com/mcpMenu names differ between products and plans; look for “connectors” or “MCP servers”.
3. Sign in with Maison
Your client opens a Maison sign-in page in the browser. Sign in with your Maison email and password. If you are already signed in, you go straight to the consent screen.
4. Review what you are approving
The consent screen shows:
- The app — its name and logo, with a badge: Verified app when Maison has confirmed who it is (Claude and ChatGPT are recognised automatically when they introduce themselves with their published identity), or Unverified app with a warning to connect only if you trust the developer.
- Running locally on your machine — shown whenever the app receives the sign-in on
localhost, for example a command-line tool. Continue only if you started it yourself. - Where you will be sent back — the web address the app receives your approval on.
- What the app is requesting — permissions grouped by area (see Scopes). A permission you do not hold yourself is greyed out with “You do not have this permission” and is not given to the app.
- Which hotels it may access — tick the hotels, or choose All hotels I can access, including future ones. If you can reach only one hotel, it is chosen for you.
Choose Allow to connect or Deny to cancel. You are sent back to your client and the Maison tools appear.
What the app can do once connected
- Call Maison tools through MCP (or REST and A2A), and only the tools covered by the permissions you approved. The tool list it sees is already filtered to those.
- Act on the hotels you chose. A tool aimed at another hotel is refused. Tools that work across your whole account, such as listing hotels, see every hotel you can reach.
- Never exceed your own access: if an admin removes a permission or a hotel from you, the app loses it too, within about 30 seconds.
Staying connected
The app holds an access token that lasts 15 minutes and renews it with a refresh token, so you normally sign in once. If the client asks you to sign in again, the consent screen is skipped when nothing new is being requested.
Disconnect
Open your profile in the admin console, find the app under Connected apps and choose Revoke. The panel lists each app, what it can access, which hotels, when you connected and when it was last used. Revoking takes effect within 30 seconds and the app has to ask you again to reconnect. Removing the connector inside Claude or ChatGPT only removes it from that client; revoke in Maison to cut its access.
Register an app for your hotel (Developer apps)
A Developer app is an OAuth app that your hotel registers with Maison: an integration you build or buy that lets your team sign in with Maison and work with your hotel's data. Registering it gives you a client id (and, for a server-side app, a client secret). It does not grant access to anything by itself: each person who uses the app signs in and approves it, and the app then acts as that person.
1. Get Developer apps switched on
Developer apps is a plan feature that is off by default. A Maison admin switches it on for your hotel (Account › Features › Plan features › Developer apps); ask your Maison contact. The section then appears under Connect › Developer apps for people whose role includes a policy granting Developer apps (oauth-apps) with write access. Your hotel admin adds that policy under Access › Policies.
2. Register the app
In your hotel's workspace, open Connect › Developer apps and choose Register app.
| Field | What to enter |
|---|---|
| App name | Up to 80 characters. People see it on the consent screen. |
| Redirect URIs | One per line, up to 10. Each must be https://, or http://localhost / http://127.0.0.1 for a local tool. The URI your app sends must match one exactly. |
| Scopes | The permissions your app needs (see Scopes). Request only what it uses: people approve each one. |
| Client type | Public (no secret) for browser, mobile and desktop apps, which cannot keep a secret. Confidential (client secret) for an app with a server. You cannot change the type later. |
| Logo URL, website | Optional, https:// only. Shown to people who connect. |
3. Store the client id and secret
The App registered dialog shows the client id and, for a confidential app, the client secret, each with a copy button. The secret is shown only once and cannot be recovered; keep it in your server's secret store, never in a browser or mobile app or in source control. If you lose it, delete the app and register it again (people will need to reconnect).
4. Sign people in
Use the authorization code flow with PKCE (S256, required for every app). Send resource to name the API the token is for — https://maison-labs.com/api/v1, https://maison-labs.com/mcp or https://maison-labs.com/a2a; a token only works on the resource it was issued for. Without resource the token is for https://maison-labs.com/api/v1.
https://maison-labs.com/as/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.example.com/callback
&scope=openid clients:read knowledge:read
&resource=https://maison-labs.com/api/v1
&state=RANDOM_STATE
&code_challenge=BASE64URL_SHA256_OF_VERIFIER
&code_challenge_method=S256Exchange the code at /as/token. A confidential app sends its secret in the form body (client_secret_post); a public app sends only its client id and the verifier.
curl -X POST https://maison-labs.com/as/token \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "code=CODE_FROM_CALLBACK" \
--data-urlencode "redirect_uri=https://yourapp.example.com/callback" \
--data-urlencode "code_verifier=YOUR_VERIFIER" \
--data-urlencode "client_id=YOUR_CLIENT_ID" \
--data-urlencode "client_secret=YOUR_CLIENT_SECRET" # confidential apps onlyThe response carries an access_token (15 minutes) and a refresh_token (7 days; always keep the newest one, see Reading the token). Call the API with Authorization: Bearer ACCESS_TOKEN:
curl https://maison-labs.com/api/v1/tools -H "Authorization: Bearer ACCESS_TOKEN"
# Renew before or after expiry
curl -X POST https://maison-labs.com/as/token \
--data-urlencode "grant_type=refresh_token" \
--data-urlencode "refresh_token=REFRESH_TOKEN" \
--data-urlencode "client_id=YOUR_CLIENT_ID" \
--data-urlencode "client_secret=YOUR_CLIENT_SECRET" # confidential apps onlyTo sign people in with Maison and read their name and email (id_token, /as/userinfo, sign-out, the Continue with Maison button), follow Login with Maison. Server metadata is published at https://maison-labs.com/.well-known/oauth-authorization-server.
Verified badge, edits and deletion
- New apps are unverified: people see an Unverified app warning, but the flow works. A Maison admin can mark the app verified.
- Edit changes the name, redirect URIs, scopes, logo and website. Adding a scope does not reach existing connections by itself: see Getting more access.
- Delete removes the app and revokes every connection people made to it. It cannot be undone.
For admins: approving and revoking
There is no approval queue. Each person approves an app for themselves on the consent screen, and the app gets at most that person's own access, only on the hotels they chose. Admins decide who may register apps, and can verify, suspend or delete apps and revoke connections afterwards.
| What | Who | Where |
|---|---|---|
| Approve an app as yourself | Anyone with a Maison account | The consent screen, when connecting |
| See and revoke your own connections | Everyone, no permission needed | Profile › Connected apps |
| Switch Developer apps on for a hotel | Maison admins | The hotel's Account › Features › Plan features |
| Register, edit and delete a hotel's apps | People with Developer apps (oauth-apps) write access on that hotel, once the hotel has the feature | The hotel's Connect › Developer apps |
| See and revoke another person's connections | Maison staff with user management access | Users › the person › Connected apps |
| Verify, suspend or delete any app | Maison admins | The admin console's OAuth apps page |
What an approval grants
One connection: this app, acting as this person, with the permissions they approved, on the hotels they chose (or every hotel they can reach, including future ones). It lasts until it is revoked. Every call is checked again against the person's current permissions and the hotel's plan, so taking a permission away from the person takes it away from the app too.
Revoking access
| Action | Effect |
|---|---|
| Revoke a connection (Connected apps) | That person's connection ends; the app's tokens stop working within 30 seconds. |
| Delete the app (Developer apps or OAuth apps) | Every connection to the app ends; the app can no longer sign anyone in. |
| Suspend the app (Maison admins) | No new sign-ins or token renewals. Tokens already issued stop working when they expire, within 15 minutes. Unsuspending restores existing connections. |
| Remove a person's permission or hotel | Their connections lose it within about 30 seconds. |
Scopes reference
A scope is a permission an app asks for. It never adds to what the person can do: a scope only lets the app use, on that person's behalf, permissions the person already holds. :write does not include :read; request both when the app reads and changes the same thing.
| Scope | What it grants | Who can get it | Tools that accept it |
|---|---|---|---|
| openid | Issues an ID token that says who signed in. | Any app. Request it in scope=; it is not on the Developer apps form. | None |
| profile | The person's name (full, given and family) in the ID token. | Any app. Request it in scope=; it is not on the Developer apps form. | None |
| The person's email address, and whether it is verified, in the ID token. | Any app. Request it in scope=; it is not on the Developer apps form. | None | |
| offline_access | Accepted for OpenID Connect compatibility: apps allowed refresh tokens (every Developer app) get one without it. | Any app. Request it in scope=; it is not on the Developer apps form. | None |
| clients:read | See the hotel's configuration, channels, integrations, branding, activity and emails. | Choose it on the Developer apps form. | 50 tools
|
| clients:write | Change the hotel's configuration, channels, integrations, branding and policies. | Choose it on the Developer apps form. | 68 tools
|
| clients:execute | Deploy the hotel's demo site, start property discovery, look for knowledge gaps and send integration connect links. | Choose it on the Developer apps form. | 4 tools
|
| knowledge:read | See the hotel's document sources, questions and answers, tone and translations. | Choose it on the Developer apps form. | 11 tools
|
| knowledge:write | Add and change the hotel's document sources, questions and answers, tone and translations. | Choose it on the Developer apps form. | 23 tools
|
| knowledge:execute | Sync and scrape the hotel's sources and rediscover its booking links. | Choose it on the Developer apps form. | 4 tools
|
| conversations:read | Read the hotel's guest conversations. | Choose it on the Developer apps form. | 13 tools
|
| conversations:write | Take over and hand back the hotel's guest conversations, stop a reply and mark them read. | Choose it on the Developer apps form. | 3 tools
|
| conversations:execute | Send replies to the hotel's guests and whisper to the agent. | Choose it on the Developer apps form. | 2 tools
|
| guest-identity:read | See who a guest is: their verified identity and contact details, their name on conversation lists, and their other conversations. | Choose it on the Developer apps form. | 2 tools
|
| analytics:read | See conversation analytics and AI visibility analytics. | Choose it on the Developer apps form. | 7 tools
|
| analytics:write | Change the settings behind conversation and AI visibility analytics. | Choose it on the Developer apps form. | None |
| analytics:execute | Run analytics reports. | Choose it on the Developer apps form. | 4 tools
|
| agents:read | See the hotel's agents and their ledger. | Choose it on the Developer apps form. | 8 tools
|
| agents:write | Create and change the hotel's agents. | Choose it on the Developer apps form. | 6 tools
|
| agents:execute | Test the hotel's agents against a conversation. | Choose it on the Developer apps form. | 1 tool
|
| quality:read | See conversation feedback scores and test session results. | Choose it on the Developer apps form. | 7 tools
|
| quality:execute | Run feedback scoring, consistency checks, duplicate clean-up and test sessions. | Choose it on the Developer apps form. | 8 tools
|
| users:read | See people's accounts, the roles they hold and their access. | Choose it on the Developer apps form. | 10 tools
|
| users:write | Invite people, change their access and remove them. | Choose it on the Developer apps form. | 17 tools
|
| users:execute | Resend invitations. | Choose it on the Developer apps form. | 2 tools
|
| groups:read | See groups and who belongs to them. | Choose it on the Developer apps form. | 4 tools
|
| groups:write | Create, change and delete groups, and add or remove their members and roles. | Choose it on the Developer apps form. | 11 tools
|
| roles:read | See roles and what each one allows. | Choose it on the Developer apps form. | 7 tools
|
| roles:write | Create, change and delete roles, and give them to people and groups. | Choose it on the Developer apps form. | 19 tools
|
| policies:read | See policies and the rules in them. | Choose it on the Developer apps form. | 5 tools
|
| policies:write | Create, change and delete policies and their rules. | Choose it on the Developer apps form. | 14 tools
|
| apps:read | See the hotel's developer apps, their usage, request log and audit trail. | Choose it on the Developer apps form. | 5 tools
|
| apps:write | Register, change, revoke and reinstate the hotel's developer apps. | Choose it on the Developer apps form. | 11 tools
|
| usage:read | See AI usage and cost summaries. | Choose it on the Developer apps form. | 2 tools
|
| hubspot:read | See HubSpot company and deal data. | On the Developer apps form, but it works only for Maison staff who hold the matching permission. | 2 tools
|
| hubspot:write | Change HubSpot company and deal data. | On the Developer apps form, but it works only for Maison staff who hold the matching permission. | 2 tools
|
| hubspot:execute | Push conversation volume to HubSpot. | On the Developer apps form, but it works only for Maison staff who hold the matching permission. | 1 tool
|
| features:read | See which features each hotel has, and the plan templates. | On the Developer apps form, but it works only for Maison staff who hold the matching permission. | 8 tools
|
| features:write | Turn features on and off for hotels, and create and change plan templates. | On the Developer apps form, but it works only for Maison staff who hold the matching permission. | 12 tools
|
| jobs:execute | See and stop a hotel's running background jobs, such as a website scrape. | On the Developer apps form, but it works only for Maison staff who hold the matching permission. | 2 tools
|
| schedules:write | Change how often a hotel's website sources sync on their own. | On the Developer apps form, but it works only for Maison staff who hold the matching permission. | 1 tool
|
| admin | Run the whole platform (roles, policies, users, developer apps, features, clients, jobs and schedules) from Maison's own apps only. | Maison's own apps only. Never grantable to a Developer app or an MCP client. | 170 tools
|
The tool lists come from the API's tool registry. A tool marked checks more than one permission declares several grants, and the token needs a scope covering each of them. The security entry of each operation in the API reference is authoritative.
These tools need no scope and work with any connection: chat_site_diagnostic, check_website, disable_my_api_key, get_documentation, get_platform_status, get_site_diagnostic, list_my_api_keys, list_my_connected_apps, revoke_my_connected_app, start_site_diagnostic, whoami.
Where scopes are used
A scope is checked at every step from sign-in to each call. What the app can finally do is the overlap of four things: the scopes on its token, the person's own permissions, the hotels the person chose, and each hotel's plan.
| Step | What happens |
|---|---|
| Authorize request | The app lists the scopes in scope=, separated by spaces. A Developer app gets only the scopes registered on it; any other API scope it asks for is dropped. admin is refused with invalid_scope. The identity scopes (openid, profile, email) and offline_access work for any app. |
| Consent screen | The person sees the scopes grouped by area. A scope they do not hold themselves is greyed out and not given. Consent is skipped when an existing connection already covers every scope requested. |
| The token | The access token's scope claim lists the API scopes granted for the one API the token is for. Identity scopes are not in it; they shape the id_token. |
| Tool lists | GET https://maison-labs.com/api/v1/tools and the MCP tool list show only the tools the token's scopes cover and the person may use. |
| Every call | On https://maison-labs.com/api/v1, https://maison-labs.com/mcp and https://maison-labs.com/a2a the scope check runs first, then the chosen hotels, the person's permission and the hotel's plan. |
When a scope is missing
The call fails with 403 and code insufficient_scope. details.scopes lists the scopes that would cover what the token is missing.
{
"error": "Token scopes insufficient for this operation",
"code": "insufficient_scope",
"details": { "scopes": ["clients:read", "admin"] }
}- REST (
https://maison-labs.com/api/v1): the body above with status 403. - MCP: a tool result with
isError: true, the same body instructuredContent, and aWWW-Authenticatechallenge naming the scopes in_meta["mcp/www_authenticate"]. - A2A: a JSON-RPC error whose
datacarries the sameerror,codeanddetails, plusstatus: 403.
A 403 with code forbidden is different: the token has the scope, but the person lacks the permission or did not choose that hotel. A new scope does not fix it.
Reading the token
What the token response holds
| Field | What it is |
|---|---|
| access_token | A signed JWT (RS256) for one API, valid for 15 minutes. Send it as Authorization: Bearer. |
| token_type | Bearer |
| expires_in | Seconds until the access token expires. |
| scope | The API scopes granted on this token. |
| refresh_token | Gets a new access token for up to 7 days. Every Developer app receives one, with or without offline_access. |
| id_token | Only when you asked for openid: who signed in, as a signed JWT for your client id. |
Claims in the access token
| Claim | Meaning |
|---|---|
| iss | The issuer, https://maison-labs.com. |
| sub | The person's Maison user id. Stable: use it as your user key, together with iss. |
| aud | The API the token is for: https://maison-labs.com/api/v1, https://maison-labs.com/mcp or https://maison-labs.com/a2a. |
| scope | The API scopes granted, separated by spaces. |
| client_id | Your app's client id. |
| gid | The id of this connection (the person's approval of your app). |
| iat, exp, jti | Issued at, expiry and the token's own id. |
Verify the signature against https://maison-labs.com/as/jwks before you trust any claim. The token does not carry the hotels the person chose or the person's own permissions: Maison checks both on every call. Maison does not offer a token introspection endpoint.
import * as jose from "jose";
const JWKS = jose.createRemoteJWKSet(new URL("https://maison-labs.com/as/jwks"));
const { payload } = await jose.jwtVerify(accessToken, JWKS, {
issuer: "https://maison-labs.com",
audience: "https://maison-labs.com/api/v1", // the resource you asked for
});
const scopes = String(payload.scope ?? "").split(" ").filter(Boolean);
const canReadHotels = scopes.includes("clients:read");Learn what the token can do
Ask the API. GET /tools lists every tool this token can call: its scopes and the person's permissions, both applied. GET /me (the whoami tool, no scope needed) returns the person's name, email, permissions and the hotel ids they can act on; it describes the person, not the hotels they chose for your app.
curl https://maison-labs.com/api/v1/tools -H "Authorization: Bearer ACCESS_TOKEN"
curl https://maison-labs.com/api/v1/me -H "Authorization: Bearer ACCESS_TOKEN"Who signed in
Read identity from the id_token. Ask for openid to get one; add profile for name, given_name, family_name and updated_at, and email for email and email_verified. Because every Maison access token is issued for one of the three APIs, the id_token carries the claims of every identity scope you were granted, and /as/userinfo does not accept these access tokens. Verification steps: Login with Maison.
Refreshing
Exchange the refresh token at /as/token before or after the access token expires (curl in step 4 of Register an app). A public app receives a new refresh token on every refresh; a confidential app receives one once 70% of the current token's 7 days have passed. Always store the refresh token from the latest response. A refresh can narrow the scopes (send a smaller scope=) but never add one.
Getting more access
A Developer app keeps its client id, secret and connections when you change its scopes. Adding a scope takes three steps; every person who uses the app approves it again.
1. Add the scope to the app
In the hotel's workspace, open Connect › Developer apps, choose Edit on the app and tick the scope. Only people with Developer apps (oauth-apps) write access on that hotel can do this; Maison admins cannot change a hotel app's scopes from the OAuth apps page.
2. Ask for it in the authorize request
Add the scope to scope=. Registering it on the app is not enough: a token only carries what the app asked for and the person approved.
https://maison-labs.com/as/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.example.com/callback
&scope=openid clients:read knowledge:read knowledge:write
&resource=https://maison-labs.com/api/v1
&state=RANDOM_STATE
&code_challenge=BASE64URL_SHA256_OF_VERIFIER
&code_challenge_method=S2563. Send each person through sign-in again
The existing connection does not cover the new scope, so Maison shows the consent screen once more. After Allow, the new tokens carry the scope. Until then the app's current tokens and refresh token keep the old scopes, and a call that needs the new one fails with insufficient_scope: a good moment to start the sign-in. The person must hold the permission themselves, or the scope stays greyed out.
Removing a scope
Untick it in Edit. Tokens already issued keep it until they expire (15 minutes at most); the next refreshed token no longer has it, and a connection that held it shows the consent screen at the next sign-in.
Edit the app or register a new one?
- Edit when it is the same product asking for more or less: new scopes, another redirect URI, a new name or logo.
- Register a new app when you need the other client type (public and confidential cannot be switched), when the secret is lost, or for a separate product people should approve and revoke on its own. Each app has its own consent and its own line in Connected apps.
What you cannot get
adminbelongs to Maison's own apps. It is not on the Developer apps form, and any other app that asks for it is refused.- Staff-only scopes (
hubspot:read,hubspot:write,hubspot:execute,features:read,features:write,jobs:execute,schedules:write) can be registered, but only Maison staff hold the permissions behind them, so for anyone else the consent screen greys them out. - A scope never exceeds the person: to reach more, an admin gives the person the permission first (Access › Policies).
MCP clients such as Claude and ChatGPT are not registered in Developer apps. To change what one may do, disconnect it and connect again; the consent screen shows what it asks for. To have Developer apps switched on for a hotel, or for anything the form does not offer, ask your Maison contact.
Common mistakes
- Write without Read.
knowledge:writedoes not let the app read knowledge. Tick and request both when the app reads what it changes. - Commas between scopes. Separate scopes with spaces (
%20or+once URL-encoded).clients:read,knowledge:readis one unknown scope, so the app gets neither. - Asking for a scope the app is not registered for. It is dropped without an error, and the token arrives without it. Add it in Edit first.
- Requesting
offline_accessto get a refresh token. Every Developer app already receives one. Leave it out unless you need it. - Expecting a refresh to add a scope. Refreshing never adds scopes; send the person through sign-in again.
- A token for the wrong API. A token for
https://maison-labs.com/api/v1gets401onhttps://maison-labs.com/mcp. Send the matchingresource=. - Calling
/as/userinfowith the access token. Read the person's identity from theid_token. - Reusing an old refresh token. Store the newest one from every refresh response.
Endpoints
| URL | Purpose |
|---|---|
| https://maison-labs.com/.well-known/oauth-authorization-server | Authorization server metadata |
| https://maison-labs.com/.well-known/openid-configuration | The same, OpenID Connect name |
| https://maison-labs.com/.well-known/oauth-protected-resource/mcp | Where MCP clients discover Maison's sign-in (also /a2a, and the bare path for the REST API) |
| https://maison-labs.com/as/authorize | Start sign-in (PKCE S256 required) |
| https://maison-labs.com/as/token | Exchange a code or refresh token |
| https://maison-labs.com/as/revoke | Revoke a refresh token (ends that connection) |
| https://maison-labs.com/as/register | Dynamic client registration for MCP clients (public apps only) |
| https://maison-labs.com/as/jwks | Public signing keys (RS256) |
| https://maison-labs.com/as/userinfo | OpenID Connect userinfo. It does not accept Maison's access tokens, which are always issued for an API; read the id_token instead |
Errors
| Error | What it means | What to do |
|---|---|---|
| access_denied | The person chose Deny on the consent screen. | Show a message and offer to try again. |
| invalid_client | Unknown or deleted app, a suspended app, or a wrong client secret. Developer apps send the secret in the form body (client_secret_post), not HTTP Basic. | Check the client id and secret; ask your Maison contact if the app was suspended. |
| invalid_redirect_uri | The redirect URI is not registered exactly. | Register the exact URI in Developer apps. |
| invalid_request | A missing or malformed parameter, often PKCE (S256 is required). | Send code_challenge with code_challenge_method=S256. |
| invalid_target | The resource parameter is not one of Maison's three resources. | Use https://maison-labs.com/mcp, https://maison-labs.com/a2a or https://maison-labs.com/api/v1. |
| invalid_grant | The code expired (10 minutes) or was used twice, the verifier is wrong, or the refresh token expired or was revoked. | Start the sign-in again. |
| 429 too_many_requests | More than 60 token requests a minute for one app, or too many registrations from one address. | Wait for the Retry-After seconds, then retry. |
| 401 Unauthorized | The access token expired, was minted for a different resource, or the connection was revoked. | Refresh the token or reconnect. MCP clients do this for you. |
| 403 insufficient_scope | The connection is missing a permission this tool needs; details.scopes lists the ones that would work. | Request the scope and have the person sign in again; see Getting more access. |
| 403 forbidden | You lack the permission on that hotel, or the hotel was not chosen when you connected (details.missing is empty). | Ask an admin for the permission, or reconnect and choose the hotel. |
| 403 not_entitled | The hotel's plan does not include the feature. On Developer apps: the feature is off or you lack the permission. | Ask your Maison contact. |
Related
- Authentication — API keys and Login with Maison
- MCP Integration — the MCP server, sessions and the tool catalogue
- A2A Protocol — agent-to-agent calls