> For the complete documentation index, see [llms.txt](https://docs.kula.digital/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kula.digital/for-developers/oauth.md).

# OAuth

Kula Intelligence ships a standards-based **OAuth 2.1** authorization server so MCP clients can sign a user in and receive an access token, with no token-pasting. It implements the discovery and security RFCs the MCP ecosystem relies on.

For end users, the flow is invisible — they click "connect" and sign in. This page is the detail for client developers.

> **Not every client does OAuth.** Clients without a custom-connector flow (ChatGPT, Cursor, Lovable, the Claude API, custom agents) connect with a **role-scoped access token** minted in app.kula.digital instead — the same minted MCP credential, presented as a bearer header against `https://mcp.kula.digital/mcp`. See [Connect](/for-developers/connect.md). This page covers the OAuth path used by Claude's custom connector.

## The two hosts

| Role                                 | Host               | Serves                                                                             |
| ------------------------------------ | ------------------ | ---------------------------------------------------------------------------------- |
| **Resource server** (the MCP server) | `mcp.kula.digital` | the per-connector resource `/connect/{…}/mcp`, and its protected-resource metadata |
| **Authorization server**             | `app.kula.digital` | discovery, registration, authorize, token; connectors are created here             |

Clients are pointed at a **role-scoped connect link** (`https://mcp.kula.digital/connect/{…}/mcp`) created in app.kula.digital — there is no open `/mcp` endpoint to connect to. The resource advertises the authorization server, so a compliant client only needs the connect link to discover everything else. For a connect link, the protected-resource metadata is path-scoped: `/.well-known/oauth-protected-resource/connect/{…}/mcp`.

## Discovery

1. **Protected-resource metadata** (RFC 9728):

   ```
   GET https://mcp.kula.digital/.well-known/oauth-protected-resource
   ```

   Returns the canonical resource URL and the `authorization_servers` list (pointing at `app.kula.digital`).
2. **Authorization-server metadata** (RFC 8414):

   ```
   GET https://app.kula.digital/.well-known/oauth-authorization-server
   ```

   Returns the `authorization_endpoint`, `token_endpoint`, `registration_endpoint`, `code_challenge_methods_supported` (`["S256"]`), `grant_types_supported` (`authorization_code`, `refresh_token`), and `scopes_supported`.

## Dynamic client registration (RFC 7591)

Clients may self-register:

```
POST https://app.kula.digital/oauth/register
{ "redirect_uris": ["https://your-app.example/callback"], "client_name": "…" }
```

Returns a `client_id` (and a secret only for confidential clients; public clients use `token_endpoint_auth_method: "none"` with PKCE).

For Claude's hosted clients, register the callback `https://claude.ai/api/mcp/auth_callback`. For Claude Code, **loopback redirects** on `http://localhost:<port>` are accepted with port-agnostic matching.

## Authorization + token

* **Authorize** (`GET /oauth/authorize`) requires `response_type=code`, `code_challenge`, and `code_challenge_method=S256` (**PKCE is mandatory**). The user is signed in (delegated to our identity provider), consents, and is redirected back with a `code`.
* **Token** (`POST /oauth/token`) accepts `application/x-www-form-urlencoded` for the `authorization_code` grant (with `code_verifier`) and the `refresh_token` grant. Refresh tokens are **rotated** on use. Responses carry `Cache-Control: no-store`.

The access token is the same minted MCP token the runtime verifies — OAuth adds consent and discovery without introducing a new token type.

## Scopes

The OAuth `scope` maps to Kula's [permission levels](/connect-claude-and-access/scopes.md):

| Scope            | Means                                                        |
| ---------------- | ------------------------------------------------------------ |
| `analytics`      | Aggregates only; no personal data                            |
| `operations`     | Member/staff names visible; contact + payment details hidden |
| `admin`          | Emails/phones visible; payment details hidden                |
| `full`           | Everything; every call recorded                              |
| `offline_access` | Issue a refresh token                                        |

Request the **lowest** scope the integration needs.

## Audience binding

Tokens are bound to the canonical MCP resource URL (RFC 8707 resource indicator). The runtime verifies the token's audience, so a token minted for Kula can't be replayed against a different server.

## Revocation

Connectors are revocable from app.kula.digital and stop working within about a minute. Clients should handle a `401` by re-running the OAuth flow; if the connect link itself has been revoked or used up, the user creates a fresh connector.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kula.digital/for-developers/oauth.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
