token prefix and only an OAuth token uses Bearer. Over MCP, always use Bearer — the server inspects the credential and routes it to the verification path that recognizes it.
API key
For headless and CI use, or clients that cannot run a browser flow. An API key from Settings → Integrations → API is user-scoped, carries theTHIRD_PARTY_OPERATION scope, and is the same credential the Lofty CLI reads from LOFTY_CUSTOMER_KEY. Send it as Authorization: Bearer <key> using any of the client configurations.
OAuth 2.0 authorization code + PKCE
The recommended path. A client discovers the flow on its own: an unauthenticated call returns401 with a WWW-Authenticate header naming the resource metadata, and the client follows that to the authorization server. Nothing is configured by hand.
S256 is mandatory and enforced at both ends. Public clients authenticate at the token endpoint with method none — no client secret. Code exchange returns an access token and a rotating refresh token.
Standards
Scopes
The authorization server issues a single scope:openApi, which grants access to the Open API surface and therefore to every MCP tool.
There’s no read/write split. openApi is a single grant covering the whole surface, so a connection that can read can also write — see the one invariant for what the tool boundary does and doesn’t enforce.
What a scope never does is widen what a person can do. Authorization runs unchanged underneath every call: a token cannot touch a record its user could not touch in the CRM itself, and the denial surfaces as the same 403 a direct REST request would return.
Registering a client
Applications are registered by hand in the Lofty vendor portal, which issues aclientId. Public clients get no secret — PKCE replaces the client secret, but not the client id, which is still required on every authorize request.
Permissions and rate limits
A tool call is authenticated and authorized exactly like a direct call to the endpoint it resolves to:- It runs as the caller identified by the token, with that caller’s existing permissions. An operation the caller couldn’t perform through the CRM directly (or through the REST API) is refused here too, with the same error.
- It’s subject to the same rate limits as a direct REST call to that endpoint — using MCP doesn’t grant a separate quota.