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

# OAuth

> Connect Shipstar to claude.ai and other MCP clients with OAuth 2.1 — plus protocol details for client builders

Shipstar's backend is a full OAuth 2.1 authorization server. Off-the-shelf MCP clients — claude.ai custom connectors, Claude Code, Claude Desktop — handle the whole flow automatically: add the server URL, sign in, pick a project, done. The first half of this page covers that; the second half is protocol detail for people building their own client or debugging a connection.

## Connecting from claude.ai (custom connector)

1. In claude.ai, go to **Settings → Connectors → Add custom connector** and enter:

   ```
   https://mcp.shipstar.ai/mcp
   ```

2. Click **Connect**. Your browser opens Shipstar's consent page (sign in first if needed).

3. **Pick the project** the connection should operate on — every authorization is scoped to exactly one Shipstar project — and approve.

4. You're returned to claude.ai with the 23 Shipstar tools available in any chat.

To operate on a different project, add another connector authorization (or re-authorize) and choose the other project at consent time. You can revoke a connection at any time from the Shipstar dashboard or by removing the connector in claude.ai.

Claude Code uses the same flow without any token handling:

```bash theme={null}
claude mcp add --transport http shipstar https://mcp.shipstar.ai/mcp
```

<Note>
  Prefer a static token for scripts or CI? Dashboard API tokens work as plain bearer tokens on the same endpoint — see the [MCP overview](/mcp/overview#authentication).
</Note>

## Discovery

Standard metadata at the `mcp.shipstar.ai` domain root, also served with the resource path appended (RFC 8414 / RFC 9728 path-insertion):

```
https://mcp.shipstar.ai/.well-known/oauth-authorization-server        (RFC 8414)
https://mcp.shipstar.ai/.well-known/oauth-authorization-server/mcp
https://mcp.shipstar.ai/.well-known/oauth-protected-resource          (RFC 9728)
https://mcp.shipstar.ai/.well-known/oauth-protected-resource/mcp
```

The OAuth endpoints themselves live on the API host (`https://api.shipstar.ai/oauth/...`), as advertised in the metadata — both hostnames are served by the same backend, so the documents resolve on either.

Endpoints: `/oauth/authorize`, `/oauth/token`, `/oauth/register`, `/oauth/revoke`. Unauthenticated requests to `/mcp` return `401` with a `WWW-Authenticate` challenge pointing at the protected-resource metadata, so spec-compliant clients bootstrap the flow from a bare URL.

## Client registration

Dynamic client registration (RFC 7591) is open — `POST /oauth/register` with your client metadata (rate-limited per IP). Redirect URIs must match **exactly** at authorization time. Public clients (`token_endpoint_auth_method: "none"`, the default) are supported for native/desktop apps; confidential clients receive a `client_secret` (stored hashed, `client_secret_expires_at: 0` = non-expiring). Client auth at `/token` is accepted as form parameters or HTTP Basic.

## Authorization

* **PKCE S256 is required** on every authorization request (`code_challenge_method=S256`; `plain` is rejected).
* `/oauth/authorize` does not itself log the user in: it validates the request, then redirects to Shipstar's consent page (`app.shipstar.ai/oauth/authorize`), which is login-gated. The consent page shows your client's name and logo and asks the user to **select a project** — the minted grant is scoped to that project.
* On approval the user agent returns to your redirect URI with `code` + `state`; denial returns `error=access_denied`.
* Consent tickets expire after 10 minutes; authorization codes expire after 10 minutes and are single-use.

## Scope

A single scope: `mcp`. It is granted by default when unspecified and covers all 23 tools. Effective access control is the per-project grant chosen at consent — a token can only ever see the one project it was authorized for.

## Tokens

| Token   | Prefix         | Lifetime   |
| ------- | -------------- | ---------- |
| Access  | `shipstar_at_` | 60 minutes |
| Refresh | `shipstar_rt_` | 30 days    |

Tokens are opaque (not JWTs) and stored hashed server-side. **Refresh rotation is strict with replay detection**: each refresh revokes the old pair and issues a new one, and presenting an already-revoked refresh token revokes the entire token chain for that grant. Store the new pair from every refresh response.

## Revocation

RFC 7009 `POST /oauth/revoke` — always returns `200`, even for unknown tokens. Expect calls to start failing with `401` at any time (user revocation, chain revocation after replay); re-run the authorization flow to reconnect.
