Build your own client with the Gondola MCP

Last updated June 20, 2026

This guide is for developers building their own MCP client or integration on top of the Gondola MCP server, for example embedding Gondola hotel, flight, and rental car search and booking into your own assistant. If you just want to use Gondola from Claude Code, Claude Desktop, ChatGPT, or Cursor, those clients handle all of this for you, so you do not need this page.

The Gondola MCP server is a standard OAuth 2.1 protected resource. If your client implements standard MCP discovery and the authorization-code flow with PKCE, it works out of the box. You should never hand-build or hard-code tokens.

Endpoints

PurposeURL
MCP endpoint (the resource)https://mcp.gondola.ai/mcp
Protected-resource metadata (RFC 9728)https://mcp.gondola.ai/.well-known/oauth-protected-resource
Authorization serverhttps://www.gondola.ai
Authorization-server metadata (RFC 8414)https://www.gondola.ai/.well-known/oauth-authorization-server

Discover everything from the metadata documents rather than hard-coding paths. The authorization-server metadata advertises the authorization, token, registration, and revocation endpoints.

How discovery works

Your client does not configure tools manually. It connects to the MCP endpoint and calls the standard tools/list method, and the server returns every tool with its name, description, and input schema. All tools are always listed. Sign-in is enforced only when a tool that needs it is actually called, so search works with no account.

Authorization flow

  1. Call a tool that needs sign-in (or call with no or expired credentials). The server responds 401 with a WWW-Authenticate: Bearer ... resource_metadata="https://mcp.gondola.ai/.well-known/oauth-protected-resource" header.
  2. Fetch the protected-resource metadata. It returns the authorization_servers list pointing at https://www.gondola.ai.
  3. Fetch the authorization-server metadata to learn the authorization, token, registration, and revocation endpoints.
  4. Register your client with Dynamic Client Registration (RFC 7591) if you do not already have a client_id. See below.
  5. Run the authorization-code flow with PKCE (S256 is required). The user signs in to Gondola in a browser and approves the requested scopes.
  6. Exchange the code at the token endpoint for an access token, plus a refresh token if you registered for it.
  7. Send the access token as Authorization: Bearer <token> on MCP requests.

Dynamic client registration

POST https://www.gondola.ai/api/oauth/register (open registration, no auth required). Example body:

{
  "client_name": "Your App",
  "client_uri": "https://your-app.example.com",
  "redirect_uris": ["https://your-app.example.com/oauth/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none"
}

A few rules:

  • redirect_uris must be https (or http://localhost for local development), exact-match at authorize time, with no fragments, up to 10 entries.
  • Include refresh_token in grant_types to receive refresh tokens.
  • For token_endpoint_auth_method, use none for a public client (PKCE protects the exchange) or client_secret_post to receive a client_secret. The secret is shown only once at registration and stored as a hash, so capture it then.
  • The response also returns a registration_access_token. Keep it for future client management.

Scopes

ScopeGrants
mcp:readSearch, plus reading the member's own trips, loyalty accounts, payment methods, and saved searches. Granted by default when scope is omitted.
mcp:bookBook hotels and rental cars and manage price alerts. Must be requested and approved explicitly.

Request mcp:read mcp:book if your integration books. A read-only token that calls a booking tool gets a clear error telling the user to reconnect and approve the booking permission.

Token lifetimes and rotation

  • Access token: a signed JWT sent as a bearer token. Revocation is enforced on every request independent of the token's own expiry, so a Disconnect by the user or a re-consent takes effect within about 30 seconds regardless.
  • Refresh token: opaque, stored hashed, and rotated on every use. Each refresh returns a new refresh token and invalidates the one you presented. Always persist the newest refresh token you receive and discard the old one.
  • Authorization code: single-use, 5-minute lifetime, PKCE-bound.

Refresh-token reuse detection

Gondola rotates refresh tokens and detects reuse (RFC 6819 section 5.2.2.3). If a refresh token that has already been rotated is presented again, the server treats it as a theft signal and revokes the entire token family for that user and client. The user then has to sign in again.

What this means for you:

  • Never present a refresh token more than once. After a successful refresh, use only the new one.
  • Never replay an old refresh token to "test" it. By design that is indistinguishable from an attacker replaying a stolen token, and it will revoke the live session too.
  • If two parts of your app might refresh at the same time, serialize refreshes so you never present the same token twice.

Re-authentication

When a refresh fails because the family was revoked (the user disconnected, reuse was detected, or a re-consent happened), there is no silent recovery. Start a fresh authorization-code flow and have the user sign in again. Surface a clear "reconnect" action rather than failing silently.

Security do's and don'ts

  • Do store tokens in OS-level secure storage (Keychain, Credential Manager, and the like), never in logs or chat transcripts.
  • Do persist and rotate to the newest refresh token on every refresh.
  • Do handle 401 with WWW-Authenticate by driving the standard flow, not by asking the user to paste a token.
  • Don't print access or refresh tokens into any model context or chat. If a token is ever exposed, the user can revoke it instantly at Connected Agents.
  • Don't replay or reuse a rotated refresh token.

Questions

Reach out to the Gondola team. We are happy to help partners land a clean integration before they rely on it in production.