> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chatsailer.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> OAuth for a person, a workspace token for a script. One server per grant.

Every MCP request carries a bearer credential. There is no workspace header —
the credential *is* the workspace.

Two kinds. Pick the one that matches who is calling.

|                  | OAuth                                   | Workspace token                           |
| ---------------- | --------------------------------------- | ----------------------------------------- |
| Who it's for     | A person in Claude, ChatGPT, or Cursor  | A script, CI job, or Cloud Agent          |
| How you get it   | Sign in when the client opens a browser | An admin mints `sk_live_…` in Sailer      |
| Who is behind it | The person who approved                 | Nobody                                    |
| CRM visibility   | That person's ACL                       | The whole workspace                       |
| Bound to         | One MCP server                          | Both servers, if the token's scopes allow |

`whoami` reports `credential: oauth` or `credential: api_token`, and
`reads_company_wide: true` when there is no user to filter on. Ask it when you
are not sure which kind of connection you are looking at.

## OAuth

This is what the [client tutorials](/mcp/connect) walk you through. The client
discovers Sailer's authorization server, you sign in with your Sailer email, you
pick a workspace if you belong to more than one, you Approve.

Three screens, in this order:

1. **Auth0 sign-in** — the email that is a member of a Sailer workspace. Already
   signed in? This step is skipped.
2. **Consent** — which workspace, and which permissions. One workspace per
   connection, for the life of the grant. Nothing in a URL or a tool argument
   can change it.
3. **Done** — close the tab. The client now has tokens.

Leave Client ID and Client Secret blank. Sailer registers the client itself.
Pasting credentials you invented, or ones from some other OAuth app, is how
this fails.

### First connection is reads only

The first consent asks for identity (`openid`, `profile`, `offline_access`) plus
every `*:read` scope your role can actually grant. No writes. Nobody should
approve "update my contacts" before they have read a single one.

If you ask the model to create or update something, the tool will say the
connection is missing a scope and that **retrying will not help**. Disconnect,
reconnect, and approve the write when consent asks.

### Scopes are an intersection

Consent shows what *your role in that workspace* can grant. Struck-through
permissions are not a bug — your role cannot give them away. Ask an admin to
widen the role if you need them.

A scope is `<resource>:<access>`. Tools you cannot call do not appear in
`tools/list`. A read-only connection should not see `create_record` at all.

### One server per grant

An OAuth token is minted for exactly one resource: `/mcp/crm` or `/mcp/studio`.
Using a CRM token on Studio is **401**, not 403. Audience mismatch is not a
missing scope. Reconnect to the other server; do not retry.

## Workspace tokens

A static `sk_live_…` / `sk_test_…` token is the machine path. Same format as
the [REST API](/guides/authentication). Send it as
`Authorization: Bearer sk_live_…`.

It has no user, so the CRM visibility ACL does not apply: the token reads every
record in the workspace that its scopes allow. Treat it as workspace-wide
access. One token per integration, never in source control.

## Switching workspace

A connection is bound to one workspace for its lifetime. To use a different
one, remove the connector and add it again, then pick the other workspace at
consent. The same reconnection is how you grant writes.

You cannot point one URL at two workspaces at once.
