Skip to main content

Overview

Arlo Health uses OAuth 2.1 with PKCE (Proof Key for Code Exchange). The MCP server at https://mcp.arlohealth.ai is its own authorization server: your client discovers the endpoints from its metadata, the user signs in to Arlo with a phone code and approves a consent screen in their browser, and your client exchanges the authorization code for tokens. Your agent never handles user credentials.
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. Everything below is for agent runtimes that manage their own OAuth (Claude Code, OpenClaw, Poke, custom agents).

Discovery endpoints

OAuth authorization server metadata

The OAuth flow

Checklist for a self-hosted MCP client

  1. Read the metadata first. Use the authorization_endpoint and token_endpoint it returns. Don’t hardcode paths. (As a fallback for SDKs that skip discovery, /authorize and /token at the root behave identically to /oauth/authorize and /oauth/token.)
  2. Dynamic client registration is supported at /register (RFC 7591). No pre-registration is needed. PKCE with S256 is required, and the client is public (token_endpoint_auth_method: none).
  3. Your redirect_uri must be an endpoint your client is listening on when the user’s browser is redirected back. This is the most common self-hosted failure:
    • Cloud or remote agents: use a publicly reachable HTTPS callback. Never localhost. A localhost callback points at the user’s device, where your agent isn’t running, so the sign-in result can never reach you.
    • Local clients (CLI agents, MCP Inspector): a loopback http://localhost:<port>/... callback is fine, but the listener must be running for the whole flow.
    • Malformed or insecure values are rejected at /oauth/authorize with a 400 JSON error (error, error_description, hint). Unreachable loopback callbacks show the user a guided error page instead of failing silently.
  4. The flow needs a browser. Authorization is interactive. A headless client must open the authorization URL in a real browser rather than expecting a device-code flow.
  5. After connecting, reload the tool list. Some clients cache the tool list from before auth completed.

Session-based signup (init_signup)

Bots that manage their own sessions rather than a full OAuth client (WhatsApp bots, OpenClaw-style runtimes) use the init_signup tool instead:
1

Call init_signup

Optionally with webhookUrl, webhookToken, deliveryContext, and conversationSessionKey to register notifications at the same time
2

Hand the user the authUrl

The link is single-use and expires after 15 minutes. The user signs in and approves access in their browser.
3

Poll check_account_status

If the user doesn’t complete authentication within 15 minutes, call init_signup again for a fresh link.

Scopes

Tokens

  • Send the access token as Authorization: Bearer <token> on every MCP and REST request. MCP clients manage this for you.
  • Access tokens are long-lived for connector hosts, so a connector stays connected without refreshing. Refresh when you receive a 401.
  • Refresh tokens rotate. Every refresh returns a new refresh token; store it and discard the old one. Parallel refreshes of the same token are served the same new pair, so a race does not log the user out.
  • A 503 temporarily_unavailable with a Retry-After header from the token endpoint, or from the MCP transport, means the auth backend is briefly unreachable. It is not an authentication failure: keep your tokens and retry after the delay. Only a 401 or an invalid_grant means the user must sign in again.

Webhook registration

Agent runtimes that receive HTTP callbacks should register a webhook right after connecting, with register_webhook (any authenticated session) or during init_signup:
Calling init_signup without webhook parameters preserves the existing webhook configuration. register_webhook uses PATCH semantics for everything except the secret: omitting webhookToken clears the stored one, so pass it every time you want Arlo to send an Authorization header. See Webhooks.

Session management

  • Sessions are tied to the user’s Arlo account and persist until revoked.
  • Webhook registrations persist per session.
  • If a session expires or the user revokes access: run the OAuth flow again (or init_signup), then re-register the webhook if needed.
  • check_account_status without a sessionId reports the current session and all webhook configurations:

Security best practices

Webhook token security

  • Use cryptographically random tokens
  • Store tokens securely (environment variables, a secrets manager)
  • Rotate tokens periodically, by calling register_webhook with the new one
  • Always validate tokens on incoming webhooks

PKCE requirements

  • Always use the S256 code challenge method
  • Generate cryptographically random code verifiers
  • Never reuse code verifiers

Errors