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

# Authentication

> Connect an MCP client in platform mode, provisioned business mode, or Layer-token passthrough.

Layer's MCP server supports three Streamable HTTP URLs. The JWT proves who the caller is. **Which URL you hit** selects platform vs business mode and which capability groups are registered by default.

Hosts:

| Environment | MCP host                          | Layer API scope                       |
| ----------- | --------------------------------- | ------------------------------------- |
| Sandbox     | `https://mcp-sandbox.layerfi.com` | `https://sandbox.layerfi.com/sandbox` |
| Production  | `https://mcp.layerfi.com`         | `https://api.layerfi.com/production`  |

The environment is inferred from the token's `scope` claim, so the token and the MCP host must be from the same environment. Layer remains the authorization boundary.

## Platform: `/mcp`

```
POST   https://mcp.layerfi.com/mcp
GET    https://mcp.layerfi.com/mcp
DELETE https://mcp.layerfi.com/mcp
Authorization: Bearer <mcp-client-jwt>
```

Platform mode is for operators who move between businesses. The agent must call `set_active_business` with a Layer business UUID before business-scoped tools. Default groups are `core` and `reporting`. Extra groups can be set on the provisioned client (`capabilityGroups`) or with `LAYER_MCP_GROUPS`.

Platform mode does not register accounting mutations. See [Platform session](/insights/mcp-server/platform-session).

## Provisioned business: `/mcp/:businessToken`

```
POST   https://mcp.layerfi.com/mcp/{businessToken}
GET    https://mcp.layerfi.com/mcp/{businessToken}
DELETE https://mcp.layerfi.com/mcp/{businessToken}
Authorization: Bearer <mcp-client-jwt>
```

The business is fixed at provisioning (`layerBusinessId` on the MCP server client entry). There is no `set_active_business` tool. Default groups are `core`, `reporting`, and `accounting`. Additional groups (`banking_imports`, `ar_imports`, `ap_imports`, `loans_assets`, `qbo`) are opt-in via `capabilityGroups` or `LAYER_MCP_GROUPS`.

Use this when Layer (or the platform) has already issued a per-business MCP URL token for an interactive client.

## Passthrough business: `/mcp/b/{businessId}`

Point an MCP client at a single Layer business using a [Layer API access token](/api-details/authentication). The MCP server validates that token the same way the Layer API does and forwards it verbatim to Layer.

```
POST   https://mcp.layerfi.com/mcp/b/{businessId}
GET    https://mcp.layerfi.com/mcp/b/{businessId}
DELETE https://mcp.layerfi.com/mcp/b/{businessId}
Authorization: Bearer <layer-api-access-token>
```

`{businessId}` is the Layer business UUID. It must be a business owned by the token's client.

Passthrough registers **all** business capability groups (`core`, `reporting`, `accounting`, `banking_imports`, `ar_imports`, `ap_imports`, `loans_assets`, `qbo`) unless `LAYER_MCP_GROUPS` is set on the MCP server.

This is the right fit when platform engineers already mint Layer API tokens and want to expose Layer MCP tools inside their own agents.

### Authenticate for a given business (passthrough)

<Steps>
  <Step title="Mint a Layer API token">
    This is the same client credentials flow used for the Layer REST API. See [Authentication](/api-details/authentication) for full details.

    ```bash theme={null}
    curl -X POST https://auth.layerfi.com/oauth2/token \
      -u "$LAYER_CLIENT_ID:$LAYER_CLIENT_SECRET" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=client_credentials&client_id=$LAYER_CLIENT_ID&scope=https://sandbox.layerfi.com/sandbox"
    ```

    The authorization server responds with a short-lived access token:

    ```json theme={null}
    {
      "access_token": "...",
      "expires_in": 3600
    }
    ```
  </Step>

  <Step title="Point the MCP client at the business">
    Use `…/mcp/b/<businessId>` as the server URL and send the token as `Authorization: Bearer <access_token>`.
  </Step>

  <Step title="Configure Claude Desktop for testing (optional)">
    Claude Desktop runs OAuth discovery on remote servers, so pass the static bearer through the `mcp-remote` proxy in `~/Library/Application Support/Claude/claude_desktop_config.json`:

    ```json theme={null}
    {
      "mcpServers": {
        "layer-sandbox": {
          "command": "npx",
          "args": [
            "-y", "mcp-remote",
            "https://mcp-sandbox.layerfi.com/mcp/b/<businessId>",
            "--header", "Authorization:${AUTH_HEADER}"
          ],
          "env": { "AUTH_HEADER": "Bearer <access_token>" }
        }
      }
    }
    ```

    After making this change, restart Claude Desktop.

    <Note>
      The `${AUTH_HEADER}` env indirection avoids a Claude Desktop bug that splits `--header "Authorization: Bearer ..."` on the space.
    </Note>
  </Step>
</Steps>

## Errors

| Status                   | Meaning                                                                                                     |
| ------------------------ | ----------------------------------------------------------------------------------------------------------- |
| `401`                    | Missing or malformed bearer, or JWT invalid/expired/wrong issuer                                            |
| `403 insufficient_scope` | Token's scope is not a recognized Layer environment scope (passthrough) or required MCP scope (provisioned) |
| `404`                    | Provisioned business token not found, or (from Layer) business not found / not owned by the token's client  |

## Token lifetime

Platform customers building an MCP integration typically wrap passthrough in a refresher that re-mints via `client_credentials`, or run a local MCP process that manages token refresh.

For a human's Claude Desktop config, a pasted token stops working at expiry and must be re-pasted.

## When to use which URL

| Need                                               | URL                   |
| -------------------------------------------------- | --------------------- |
| One agent across many businesses                   | `/mcp` (platform)     |
| Interactive client, business fixed at provisioning | `/mcp/:businessToken` |
| Existing Layer API token, one business in the path | `/mcp/b/{businessId}` |
