# Tamloot Auth for Agents

> How AI agents and developers authenticate to Tamloot's MCP server and public REST API.

Tamloot has two separate agent-facing surfaces with two different auth models. Pick the one that matches what you're building.

## Pick a method

| Surface | Use when | Credential |
| --- | --- | --- |
| MCP server — `https://mcp.tamloot.cc/mcp` | You're an MCP client (Claude, ChatGPT, Cursor) acting on behalf of a signed-in Tamloot user | OAuth 2.1 access token, self-service |
| Public REST API — `https://api.tamloot.cc/v1` | You're calling the read-only REST API directly (scripts, background agents, custom integrations) | Long-lived bearer API key, human-issued |

Both surfaces are **read-only**. Neither can create, edit, or delete anything in a Tamloot account.

---

## MCP server: OAuth 2.1

### Discover

A request without a token gets a 401 carrying a spec-shaped hint:

```
WWW-Authenticate: Bearer error="invalid_token", error_description="No authorization provided", resource_metadata="https://mcp.tamloot.cc/.well-known/oauth-protected-resource"
```

Follow `resource_metadata` to the RFC 9728 Protected Resource Metadata document, which names the Authorization Server:

- Protected resource metadata: [/.well-known/oauth-protected-resource](https://mcp.tamloot.cc/.well-known/oauth-protected-resource)
- Authorization server metadata (RFC 8414, mirrored on this origin too): [/.well-known/oauth-authorization-server](https://mcp.tamloot.cc/.well-known/oauth-authorization-server)
- Issuer: `https://umnrjoocxsxjwclpbncv.supabase.co/auth/v1` (Supabase Auth is the Authorization Server; Tamloot is only the Resource Server)

### Register

The Authorization Server supports **Dynamic Client Registration** — there is no manual app-registration step. A compliant MCP client registers itself the first time it connects to `https://mcp.tamloot.cc/mcp`.

```json
{
  "mcpServers": {
    "tamloot": {
      "type": "http",
      "url": "https://mcp.tamloot.cc/mcp"
    }
  }
}
```

### Claim

The client runs a standard OAuth 2.1 authorization-code flow with PKCE (S256 supported). A human opens the Authorization Server's login screen, signs in with their Tamloot account, and consents — this is an **identity_assertion** flow tied to that person's own Supabase session, not an anonymous or service credential. There is no client-credentials / machine-only grant: a human has to be present for the first login.

### Use the credential

Send the resulting access token as a bearer token on every MCP request:

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

The token is a normal Supabase user token (role `authenticated`), scoped to that user's own rows by Postgres row-level security — not by audience binding (no RFC 8707 resource indicator is enforced). Read-only is enforced at the database layer: `RESTRICTIVE` RLS policies reject writes whenever the token carries the `client_id` claim that OAuth-issued tokens carry, so a connected client cannot escalate to writes even by bypassing the MCP tool layer.

### Errors

A 401 always carries the `WWW-Authenticate` header shown above. An expired or revoked token also returns 401 with `error="invalid_token"` — refresh or re-run the authorization flow.

### Revocation

Rotate or revoke a Tamloot session the same way you would any other connected app tied to your Tamloot account — signing out invalidates the underlying Supabase session. There is currently no self-serve "connected apps" list scoped specifically to MCP clients; treat a leaked MCP access token like a leaked session token and sign out / rotate your account credentials.

---

## Public REST API: bearer API key

### Discover

- Base URL: `https://api.tamloot.cc/v1`
- OpenAPI description: [/openapi.json](https://tamloot.cc/openapi.json)
- API catalog (RFC 9727): [/.well-known/api-catalog](https://tamloot.cc/.well-known/api-catalog)
- Health check (no credential required): `GET /v1/health`

### Register / Claim

There is **no anonymous or fully automated self-serve path** today. Minting a key requires:

1. A Tamloot account.
2. Manual beta enrollment (the public API is currently a gated rollout).
3. A signed-in dashboard session — a human opens **Settings → API** in the Tamloot dashboard and creates the key. `POST /v1/api-key` is authenticated by that dashboard session, not by an API key, so an agent cannot mint its own first key without a human present.

An agent that already has a key can use it indefinitely — it just can't provision its own first key. If you're building an integration, have the human owner generate the key once in **Settings → API** and hand it to the agent as a stored secret.

### Use the credential

Send it as a bearer token on every data request:

```bash
curl "https://api.tamloot.cc/v1/contacts?query=maya" \
  -H "Authorization: Bearer tml_live_your_key"
```

`/v1/health` is the only endpoint that doesn't require a credential.

### Errors

Every error is a JSON object, never an HTML page:

```json
{ "error": { "code": "404", "message": "Contact not found" } }
```

- `401` — missing or invalid API key.
- `404` — resource not found, or not visible to this account (row-level security hides other accounts' data as a 404, not a 403).
- `503` — the public API is temporarily disabled.

### Revocation

In **Settings → API**:

- `POST /v1/api-key/rotate` issues a new key and immediately invalidates the old one.
- `DELETE /v1/api-key` revokes the key with no replacement.

Both require the same dashboard session used to create the key — not the API key itself.

---

## Rate limits

The public REST API declares its throttling policy on every response, so an agent can pace itself without probing for the ceiling:

- `RateLimit-Limit` — requests allowed per one-second window
- `RateLimit-Policy` — the policy, as `<limit>;w=<window seconds>`
- `Retry-After` — seconds to wait, sent on a `429`

There is no `RateLimit-Remaining`: the throttle is enforced at the edge, so no single server can see a caller's running total. The MCP server does not publish rate-limit fields at all; pace MCP tool calls conservatively.

---

## Links

- [Developer resources](https://tamloot.cc/en/developers)
- [MCP setup guide](https://tamloot.cc/en/docs/mcp-server)
- [Public API docs](https://tamloot.cc/en/docs/api)
- [OpenAPI spec](https://tamloot.cc/openapi.json)
- [llms.txt](https://tamloot.cc/llms.txt)
