# OwAI auth.md

Authentication instructions for AI agents and MCP client developers connecting
to an owner's Organize with AI photo and video library.

OwAI supports OAuth dynamic client registration followed by user sign-in and
consent using Authorization Code with PKCE (S256). Client registration is not
account signup and does not grant access to any library. The owner needs an
OwAI account with permanent Cloud Access. Hosted inference uses separate
prepaid credits; registration does not purchase Cloud Access or credits.

This document describes existing OAuth only. OwAI does not implement the
separate Auth.md agent-registration protocol: no ID-JAG, verified_email identity
assertions, anonymous agent provisioning, claim ceremony, or agent_auth block.
Do not send those requests to /agent/auth or invent a claim endpoint.

## 1. Discover the resource and authorization server

- MCP resource: https://index.organizewith.ai/mcp
- Protected Resource Metadata: https://index.organizewith.ai/.well-known/oauth-protected-resource/mcp
- Root metadata alias: https://index.organizewith.ai/.well-known/oauth-protected-resource
- Authorization server issuer: https://index.organizewith.ai
- Authorization Server Metadata: https://index.organizewith.ai/.well-known/oauth-authorization-server

The website at https://organizewith.ai hosts this guide; the protected MCP
resource and OAuth bridge are at https://index.organizewith.ai. An unauthenticated MCP request
returns HTTP 401 with a WWW-Authenticate Bearer resource_metadata URL.
Fetch that document, then the advertised authorization server metadata.
Check that its issuer exactly matches the advertised authorization server.
Use the published resource, scopes_supported, bearer_methods_supported and
endpoint URLs as authoritative. Discovery is public and needs no credentials.
The website's separate account and inference APIs have their own metadata at
https://organizewith.ai/.well-known/oauth-protected-resource (see Website APIs
below). For MCP, keep using the index-origin metadata and resource identifier;
do not substitute the website resource or its direct Clerk issuer.

## 2. Choose the existing OAuth method and minimum scopes

If your assistant already handles OAuth, add the MCP resource URL in its
connector settings and let the client perform registration and user consent.
Reuse an existing client registration; do not register a new client on every call.
For your own MCP client, use the procedure below.

| Scope | Permission |
| --- | --- |
| media:search | Search indexed media. |
| media:read | Read media and locate assets. |
| library:read | Inspect library organization and duplicate candidates. |
| library:write | Make supported library edits. |
| library:delete | Perform supported, explicitly confirmed destructive operations. |
| ACCESS_VIEW_MANAGE_MCP_CONTENT | Gemini compatibility alias granting the five media/library permissions above, not device sync. |
| SHARE_THROUGH_MCP_CONVERSATION_INFO | Gemini conversation-context consent; not library access by itself. |

Start with media:search media:read library:read for read-only assistance.
Request write/delete scopes only when the owner wants those operations.
The Gemini aliases are for compatible Gemini clients, not recommended defaults
for other agents. Do not request desktop sync or standalone inference scopes
through this MCP setup. Granting a tool permission inside an assistant does not
expand its OAuth token's scopes.

## 3. Register an OAuth client if needed

Registration endpoint: https://index.organizewith.ai/oauth/register

Only POST when actually setting up a user-requested connection. Registration
creates a client record; passive health checks and scanners must use GET/HEAD
discovery only. This is OAuth Dynamic Client Registration, not an agent identity
assertion endpoint. For a public PKCE client, the request shape is:

```http
POST /oauth/register HTTP/1.1
Host: index.organizewith.ai
Content-Type: application/json

{
  "client_name": "My OwAI MCP client",
  "redirect_uris": ["https://agent.example.com/oauth/callback"],
  "token_endpoint_auth_method": "none",
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "scope": "media:search media:read library:read"
}
```

Replace the example callback with a real callback controlled by your client.
Store the returned client_id and registration configuration securely. If your
registered client uses confidential-client authentication, follow its returned
token_endpoint_auth_method; never embed a client secret in browser or mobile code.
OwAI's OAuth bridge delegates registration and consent to Clerk.

## 4. Obtain the owner's approval with PKCE

Authorization endpoint: https://index.organizewith.ai/oauth/authorize

Generate a fresh cryptographically random state and PKCE code_verifier. Derive
code_challenge = BASE64URL(SHA256(code_verifier)) without padding. Open the
authorization endpoint in the owner's browser with these URL-encoded parameters:

```text
response_type=code
client_id=<registered client_id>
redirect_uri=<exact registered callback>
scope=media:search media:read library:read
state=<fresh random state>
code_challenge=<S256 challenge>
code_challenge_method=S256
resource=https://index.organizewith.ai/mcp
```

The user signs in and reviews permissions. Do not collect the user's password,
automate approval, or treat client registration as user authorization. Validate
the callback state before accepting its code. If consent is denied, stop.
Do not reuse a code or PKCE verifier from another authorization attempt.

Token endpoint: https://index.organizewith.ai/oauth/token

Exchange the code with a form-encoded POST. This example is for a registered
public client; confidential clients must also use their registered client auth:

```text
grant_type=authorization_code
client_id=<registered client_id>
code=<authorization code>
redirect_uri=<same exact callback>
code_verifier=<original verifier>
resource=https://index.organizewith.ai/mcp
```

Read access_token, token_type, expires_in, granted scope and any refresh_token
from the token response. Do not assume that requested scopes were granted or
that a refresh token is always issued. OwAI does not support client_credentials
for accessing a user's library.

## 5. Use the credential with MCP

Send the access token in the HTTP header, never in the URL:

```http
Authorization: Bearer <access_token>
```

Connect using an MCP SDK to https://index.organizewith.ai/mcp; initialize the connection and
discover the actual schemas through tools/list. The HTTP transport is described
at https://organizewith.ai/openapi.json. Tool names and schemas are authoritative;
do not invent REST endpoints for library actions. Start with a bounded read-only
request. Mutations still require their normal scopes and user confirmation.

Authentication selects the owner's account, not a copy of their local catalog.
Local-folder and Apple Photos metadata must have synced before remote search can
find it. OneDrive uses its shared cloud catalog. Source availability rules still
apply when reading originals or executing device-owned changes.

## 6. Refresh, disconnect and handle errors

If a refresh_token was issued, send a form-encoded POST to the token endpoint
with grant_type=refresh_token, refresh_token and client_id, plus the registered
client authentication when required. Store any replacement refresh token
securely. Do not widen the original grant during refresh. If none was issued,
or refresh returns invalid_grant, request a new user-approved authorization.

Revocation endpoint: https://index.organizewith.ai/oauth/token/revoke

On disconnect, POST the token to revoke as a form field named token, with an
appropriate token_type_hint (access_token or refresh_token) and registered
client authentication as required. Revoke the refresh token too when one was
issued, then remove locally stored credentials. Do not assume revoking only
an access token also revokes its refresh grant. Never log tokens, authorization
codes, client secrets, or complete authorization callback URLs.

| Error | Next action |
| --- | --- |
| invalid_scope | Compare the request with live metadata and the client's allowed scopes; do not keep retrying the same request. |
| invalid_client | Check the registered client ID and authentication method. |
| invalid_grant | Discard the unusable code or refresh grant and restart user authorization. |
| HTTP 401 / invalid_token | Refresh if appropriate; otherwise reconnect with the owner's approval. |
| HTTP 403 / insufficient_scope | Inspect the error and required scopes. Obtain additional user consent only if needed; a missing Cloud Access entitlement is not fixed by adding scopes. |
| HTTP 429 | Respect Retry-After where provided and back off. |

Do not interpret a token's existence as proof of entitlement or permission.
Legacy developer-key provisioning is a manual account-settings workflow, not a
public agent registration API; prefer OAuth for agents. Public discovery does
not expose private library data or grant anonymous access.

## Website APIs

OwAI's existing account and hosted-inference APIs under https://organizewith.ai/api
are a separate protected resource from the MCP endpoint:

- Resource: https://organizewith.ai
- Protected Resource Metadata: https://organizewith.ai/.well-known/oauth-protected-resource
- Authorization server issuer: https://clerk.organizewith.ai
- Authorization Server Metadata: https://clerk.organizewith.ai/.well-known/oauth-authorization-server

These APIs already validate Clerk OAuth access tokens and Cloud Access through
the website's remote authentication layer. Send tokens in the Authorization:
Bearer header. Their HTTP 401/403 challenges point to the website metadata.
Use the issuer's published endpoints and the permissions allowed for your
registered client. The metadata does not create accounts, change token audiences
or grant permissions. Scope requirements are endpoint-specific; this document
does not advertise the MCP scope set as a website-wide permission set.

Use the supported MCP tools for agent library management, not internal website
routes. The MCP resource still uses its existing index-origin OAuth bridge and
metadata above. No connector recreation or authentication-provider change is needed.

## More documentation

- Setup guide: https://organizewith.ai/en/guides/connect-ai-assistants
- Agent library workflows: https://organizewith.ai/en/guides/manage-media-with-ai
- API catalog: https://organizewith.ai/.well-known/api-catalog
- Account and Cloud Access: https://organizewith.ai/en/account
- Support: mailto:support@organizewith.ai
