> ## Documentation Index
> Fetch the complete documentation index at: https://grow-hub.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> OAuth 2.1 sign-in, discovery endpoints, and how a token maps to a studio.

Studio has no API keys. Every MCP client authenticates with **OAuth 2.1** against
Studio's own authorization server (better-auth), which also owns the Google
sign-in the web app uses. Tokens belong to a user, so a tool call can never do
more than that user could do in the UI.

## The flow

<Steps>
  <Step title="Unauthenticated request">
    `POST /mcp` without a bearer token returns `401` with:

    ```http theme={null}
    WWW-Authenticate: Bearer resource_metadata="https://studio-api.growhub.ai/.well-known/oauth-protected-resource"
    ```
  </Step>

  <Step title="Discovery">
    The client fetches that resource metadata, then
    `/.well-known/oauth-authorization-server` to find the authorize, token, and
    registration endpoints.
  </Step>

  <Step title="Client registration">
    Clients that have no pre-registered id use dynamic client registration
    ([RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591)) at
    `/api/auth/mcp/register`. This is what makes one-click connect work.
  </Step>

  <Step title="Authorize">
    The browser opens `/api/auth/oauth2/authorize`. With no active session,
    Studio redirects to `https://studio.growhub.ai/login` for Google sign-in,
    then back into the authorize step.
  </Step>

  <Step title="Consent and token">
    You approve the client, and Studio issues an access token (PKCE-protected
    authorization code exchange).
  </Step>

  <Step title="Authenticated calls">
    The client sends `Authorization: Bearer <token>` on every `POST /mcp`
    request. Studio resolves the token to a user, then to a studio.
  </Step>
</Steps>

## Endpoints

| Endpoint                                  | Purpose                                    |
| ----------------------------------------- | ------------------------------------------ |
| `POST /mcp`                               | The MCP endpoint itself (streamable HTTP)  |
| `/.well-known/oauth-protected-resource`   | Points clients at the authorization server |
| `/.well-known/oauth-authorization-server` | OAuth 2.1 metadata document                |
| `/api/auth/mcp/register`                  | Dynamic client registration                |
| `/api/auth/oauth2/authorize`              | Authorization endpoint                     |
| `https://studio.growhub.ai/login`         | Google sign-in page                        |

Swap the host for `http://localhost:8787` in local development.

## Which studio do tools act on?

A user can belong to several studios. The MCP session resolves to **one**:

1. The session's active studio, if the token's user is a member of it.
2. Otherwise, the user's first studio membership.

<Warning>
  MCP has no studio switcher yet. If you belong to more than one studio and the
  tools are writing to the wrong one, switch the active studio in the web app —
  then reconnect the client so the new session picks it up. Explicit per-tool
  studio selection is planned.
</Warning>

If the user has no membership at all, `/mcp` returns `403 No studio membership`.

## Roles

Studio roles come from the workspace (`owner`, `admin`, `member`). Most tools are
open to any member. Two are restricted:

| Tool                  | Required role      |
| --------------------- | ------------------ |
| `connect_platform`    | `owner` or `admin` |
| `disconnect_platform` | `owner` or `admin` |

A member without the role gets a `forbidden` tool error.

## Token lifetime and revocation

Access tokens are issued and stored by your MCP client; Studio keeps the
authorization records in its own database. Signing out of the web app does not
revoke a client's token — remove the server from the client to cut its access.
