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

# Authentication

> OAuth 2.1 with PKCE for Arlo Health

## Overview

Arlo Health uses OAuth 2.1 with PKCE (Proof Key for Code Exchange) for authentication. This provides secure authentication without requiring the agent to handle user credentials.

<Note>
  **On connector hosts (Claude.ai, ChatGPT)** the platform's connector UI runs this whole flow for you — `init_signup` and `check_account_status` are not advertised there and must not be called. The flow below is for agent runtimes that manage their own OAuth (Claude Code, OpenClaw, custom agents).
</Note>

## OAuth 2.1 Flow

```mermaid theme={null}
sequenceDiagram
    participant Agent
    participant Arlo
    participant Auth0
    participant User

    Agent->>Arlo: init_signup(baseUrl, webhookUrl)
    Arlo-->>Agent: authUrl, sessionId

    Agent->>User: "Click to sign up"
    User->>Auth0: Opens authUrl
    User->>Auth0: Completes signup/login
    Auth0->>Arlo: Authorization callback

    Agent->>Arlo: check_account_status(sessionId)
    Arlo-->>Agent: authenticated: true
```

## Discovery Endpoints

Arlo exposes standard OAuth 2.1 discovery endpoints:

| Endpoint                                  | Purpose                                         |
| ----------------------------------------- | ----------------------------------------------- |
| `/.well-known/mcp.json`                   | MCP Server Card with capabilities and auth info |
| `/.well-known/oauth-protected-resource`   | RFC 9728 protected resource metadata            |
| `/.well-known/oauth-authorization-server` | OAuth authorization server metadata             |

### MCP Server Card

```json theme={null}
{
  "name": "arlo-health",
  "version": "1.0.0",
  "description": "Healthcare infrastructure for AI agents",
  "publisher": {
    "name": "Arlo Health",
    "url": "https://www.arlohealth.ai"
  },
  "transport": {
    "type": "streamable-http",
    "url": "https://mcp.arlohealth.ai/mcp"
  },
  "authentication": {
    "type": "oauth2",
    "metadata_url": "https://mcp.arlohealth.ai/.well-known/oauth-authorization-server"
  }
}
```

### OAuth Authorization Server Metadata

```json theme={null}
{
  "issuer": "https://mcp.arlohealth.ai",
  "authorization_endpoint": "https://auth.arlohealth.ai/authorize",
  "token_endpoint": "https://mcp.arlohealth.ai/oauth/token",
  "registration_endpoint": "https://mcp.arlohealth.ai/oauth/register",
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["none"],
  "scopes_supported": ["openid", "profile", "email", "offline_access"]
}
```

## Authentication Flow

### Step 1: Initialize Signup

Call `init_signup` to begin the OAuth flow:

```json theme={null}
{
  "baseUrl": "https://mcp.arlohealth.ai",
  "webhookUrl": "https://your-agent/hooks/arlo",
  "webhookToken": "secret-token"
}
```

Response:

```json theme={null}
{
  "authUrl": "https://auth.arlohealth.ai/authorize?...",
  "sessionId": "sess_abc123",
  "expiresIn": 900
}
```

### Step 2: User Completes Auth

Direct the user to open `authUrl` in their browser. They will:

1. Create an account or sign in
2. Grant permissions to your agent
3. Be redirected back to Arlo

### Step 3: Poll for Completion

Poll `check_account_status` until authentication completes:

```javascript theme={null}
async function waitForAuth(sessionId) {
  const maxAttempts = 90; // 15 minutes at 10s intervals

  for (let i = 0; i < maxAttempts; i++) {
    const status = await checkAccountStatus({ sessionId });

    if (status.authenticated) {
      return status;
    }

    await sleep(10000); // 10 seconds
  }

  throw new Error("Authentication timed out");
}
```

<Note>
  The auth link expires after 15 minutes. If the user doesn't complete authentication, you'll need to call `init_signup` again.
</Note>

## Scopes

| Scope            | Description                            | Required    |
| ---------------- | -------------------------------------- | ----------- |
| `openid`         | OpenID Connect identifier              | Yes         |
| `profile`        | User profile information               | Yes         |
| `email`          | User email address                     | Yes         |
| `offline_access` | Refresh tokens for long-lived sessions | Recommended |

## Token Management

### Access Tokens

* Short-lived (typically 1 hour)
* Include in requests as `Authorization: Bearer <token>`
* Automatically managed by MCP clients

### Refresh Tokens

* Long-lived (days/weeks)
* Use to obtain new access tokens
* Requires `offline_access` scope

### Token Refresh Flow

```mermaid theme={null}
sequenceDiagram
    participant Agent
    participant Arlo

    Agent->>Arlo: API request with expired token
    Arlo-->>Agent: 401 Unauthorized

    Agent->>Arlo: Token refresh request
    Arlo-->>Agent: New access token

    Agent->>Arlo: Retry API request
    Arlo-->>Agent: Success
```

## Webhook Registration

The best time to register webhooks is during `init_signup`:

```json theme={null}
{
  "baseUrl": "https://mcp.arlohealth.ai",
  "webhookUrl": "https://your-agent/hooks/arlo",
  "webhookToken": "your-secret-token",
  "deliveryContext": {
    "to": "+15551234567",
    "channel": "whatsapp",
    "deliver": true
  },
  "conversationSessionKey": "your-session-key"
}
```

<Tip>
  You can also register or update webhooks after authentication using `register_webhook`. If you call `init_signup` without webhook parameters, existing webhook config is preserved.
</Tip>

## Session Management

### Session Persistence

* Sessions are tied to the user's Arlo account
* Sessions persist until explicitly revoked
* Webhook registrations are permanent per session

### Re-authentication

If a session expires:

1. Call `init_signup` again
2. User completes OAuth flow
3. New session is created
4. Re-register webhooks if needed

### Checking Session Status

Use `check_account_status` without a `sessionId` to check the current session:

```json theme={null}
{
  "authenticated": true,
  "webhookConfigured": true,
  "sessions": [
    {
      "sessionId": "sess_abc123",
      "linkedAt": "2024-01-15T10:30:00Z",
      "webhookUrl": "https://your-agent/hooks/arlo"
    }
  ]
}
```

## Security Best Practices

### Webhook Token Security

* Use cryptographically random tokens
* Store tokens securely (environment variables, secrets manager)
* Rotate tokens periodically
* Always validate tokens on incoming webhooks

### PKCE Requirements

* Always use `S256` code challenge method
* Generate cryptographically random code verifiers
* Never reuse code verifiers

## Error Handling

### Common Authentication Errors

| Error               | Cause                 | Resolution         |
| ------------------- | --------------------- | ------------------ |
| `not_authenticated` | No valid session      | Call `init_signup` |
| `token_expired`     | Access token expired  | Refresh token      |
| `invalid_grant`     | Refresh token invalid | Re-authenticate    |
| `session_revoked`   | User revoked access   | Re-authenticate    |
