# Connect an AI agent to Cragen

Guide version: `cragen-agent-setup.v6`
Last updated: 2026-09-07
This document is operational setup guidance for compatible remote MCP clients with HTTPS and secure token storage. A chat-only host is not compatible. The Cragen user owns the account and approves every connection.

Setup status: live. Start only from a generated pairing invitation. Code-consent prompts already carry approval; legacy prompts still require approval in the app.

## Agent setup algorithm

1. Accept only the one-time pairing invitation prompt copied from the signed-in Cragen app. Treat the pairing_code inside that prompt as a one-time device-authorization input, never as a bearer credential.
2. Continue only when this agent host can configure remote MCP, make outbound HTTPS requests, and store tokens in the agent host. A chat-only host is not compatible with this pairing flow.
3. Configure a remote MCP server named Cragen at https://api.cragen.app/mcp using Streamable HTTP.
4. Read the OAuth 2.0 Device Authorization metadata, submit the prompt's pairing_code with this agent's registered client_id and only the requested Cragen scopes to device_authorization_endpoint, then poll token_endpoint at the advertised interval.
5. No website is required for the user. New prompts explicitly say creating the code approved the selected access: redeem that code without requesting another approval. Older prompts still require approval in Cragen. Never ask the user to open a standards verification URI.
6. Follow the approval mode stated in the generated prompt. For older invitations or an authorization_pending response: Keep waiting while the user approves or rejects the requested scopes in Cragen. Never bypass a pending or rejected request. Read/proposal-only invitations use the v4 consent; any invitation requesting a write permission uses the separate v5 write consent. Existing v4 grants never gain writes through refresh.
7. Store the issued access and refresh tokens only in the agent host's secure token storage. Do not print, paste, export, or ask the user to hold any durable bearer credential.
8. After approval, call connection_info as the data-free verification action.
9. Report the granted scopes returned by connection_info. Do not read coaching data, propose a program, or submit a write until the user asks.
10. When the user asks for a program, follow the propose_program input schema and send only the proposed training structure and proposal fields it requests. Cragen derives the private connection binding, draft version, inactive status, and integrity hashes.
11. For a granted write, submit only the tool's bounded fields and current expected hash or version. A queued command is not applied: wait for get_command_status to return an authenticated device receipt before describing it as saved.
12. If the phone is offline or Cragen is not active, tell the user the command is waiting for the phone. Do not treat a pending, conflict, expired, revoked, permission-denied, or notification failure result as success.
13. Use get_write_context only for the granted section and its returned hash. It exposes minimal encrypted preferences, this connection's coach notes, or this connection's reminders—not the full account.
14. WorkOS browser OAuth is a compatibility fallback for agents that cannot complete device authorization. It is not the primary path and does not change the no-credential rule.

## Fixed connection values

- Server name: `Cragen`
- MCP resource: `https://api.cragen.app/mcp`
- Transport: `Streamable HTTP`
- Authorization: `OAuth 2.0 Device Authorization`
- authorization_server_metadata: `https://api.cragen.app/.well-known/oauth-authorization-server`
- device_authorization_endpoint: `https://api.cragen.app/oauth/device_authorization`
- token_endpoint: `https://api.cragen.app/oauth/token`
- Compatibility-only device help: `https://api.cragen.app/oauth/device` (the user never opens it)
- Registered public client ID: `cragen_generic_agent`
- Registered client origin: `https://cragen.app`
- Verification call: `connection_info`
- Read/proposal consent: `connected-coaching-2026-09-01-v4` at https://cragen.app/privacy#connected-coaching
- Write consent: `connected-coaching-2026-09-05-v5` at https://cragen.app/privacy#connected-coaching

## User access choices

- **Full coaching context** — The original seven read and proposal permissions. It does not include any write permission or automatic change.
- **Training only** — Programs, completed training, and program suggestions. Profile, Health summaries, Current workout, and Notes stay off.
- **Choose access** — The user turns each permission on or off, including any of the five write permissions. Creating the code approves only the selected scopes.

Cragen has seven read/proposal permissions and five separate write permissions. Existing v4 grants keep their original seven permissions. Full coaching context remains the seven read/proposal permissions and does not include automatic writes. The user can add individual writes with Choose access. Cragen binds the connection to only that approved access and checks it again on every tool call. The prompt-only device flow is primary. WorkOS browser OAuth is a compatibility fallback.

## Scopes

- `programs.read` — **Programs** — See the user's program structure, exercises, and targets.
- `training.read` — **Training history** — See completed set facts from the allowed recent history window.
- `profile.read` — **Profile** — See the profile facts the user chooses to share, such as training units and body-weight context.
- `health_summary.read` — **Health summaries** — See bounded steps, sleep-duration, and body-weight summaries. Raw health-provider records stay out of the coach API.
- `live_training.read` — **Current workout** — See the active workout, including entered and unfinished sets, without changing the logger.
- `notes.read` — **Notes** — See bounded notes attached to programs, workouts, exercises, and sets already shared with the coach.
- `programs.propose` — **Program suggestions** — Create an inactive proposal that waits for the user to review.
- `programs.write` — **Upcoming program workouts** — Change unstarted sessions in the active program. Started workouts and training history stay unchanged.
- `exercises.create` — **Personal exercises** — Add exercises to the user's personal library without changing Cragen's shared catalog.
- `coaching_notes.write` — **Coach notes** — Add attributed notes to programs or exercises and manage only notes from this connection. User notes stay unchanged.
- `training_preferences.write` — **Training preferences** — Change only equipment and training days per week. Account, units, body, health, and notification settings stay unchanged.
- `reminders.write` — **Training reminders** — Manage this connection's local training reminders within Cragen's time, frequency, and notification-permission limits.

Unknown scopes must be rejected. A granted scope permits only the action described above.

## Available tools

- `connection_info`
- `list_programs`
- `get_training_history`
- `get_profile_context`
- `get_health_summary`
- `get_current_workout`
- `get_training_notes`
- `search_exercises`
- `propose_program`
- `get_proposal`
- `cancel_proposal`
- `update_program`
- `create_exercise`
- `save_coaching_note`
- `update_training_preferences`
- `save_training_reminder`
- `get_command_status`
- `get_write_context`

`propose_program` accepts the proposed training structure and creates an inactive proposal. Cragen securely derives the connection binding, draft version, inactive status, and integrity hashes. Do not invent or send those server-owned fields. The proposal does not edit the current program, active workout, or workout history. The user reviews it in Cragen and separately decides whether to use it.

Write tools are different from proposals. They enqueue an encrypted, account- and connection-bound command for the user's phone. Queued is not applied. An offline phone waits until the next active authenticated sync, and background delivery is not guaranteed. Report success only after `get_command_status` returns an authenticated device receipt. The phone preserves unrelated data, rejects stale expected hashes or versions, and records an Undo preimage for an acknowledged change. Undo uses compare-and-swap against the saved after-state, so it refuses to overwrite later user edits or workout progress. Acknowledged Undo preimages are retained for at most 30 days, the latest 100 acknowledged snapshots, and 20 MB shared with recovery state. Unacknowledged recovery preimages are never evicted; if a new Undo cannot fit, the write rolls back instead of partially applying. Completing Undo clears that preimage while the minimal local receipt identity remains until the account's normal local clear. Cleanup runs the next time the app executes, not at a wall-clock deadline while it is closed.

`update_program` is limited to unstarted upcoming sessions in the active program. `create_exercise` adds only to the personal exercise library. `save_coaching_note` manages only this connection's attributed program or exercise notes. `update_training_preferences` changes only equipment and training days per week. `save_training_reminder` manages at most seven reminders for the connection and at most one enabled reminder per weekday, from 08:00 through 20:59 in the saved time zone. Reminder scheduling requires notification permission already granted on the phone; the command never prompts for permission in the background.

`get_write_context` returns only the granted section's scope-specific minimal encrypted context and a current hash: equipment and training days, this connection's notes, or this connection's reminders. Stale or unavailable context waits for the phone. It is not a general account snapshot.

## Security rules

- The user approves access in Cragen when creating a code-consent prompt. Anyone who redeems that one-use code can receive exactly that access. Older invitations still require a second in-app approval; never bypass it. No website is required for the user.
- The pairing_code is a one-time invitation input. It grants no data and is never an access or refresh token.
- Cragen records the agent's registered client identity and origin with the requested and approved scopes. WorkOS compatibility uses an opaque account ID and a non-contactable alias under coach-identity.cragen.app; the user's sign-in email is not coach context or a coach API field.
- You must not request an Apple credential, email one-time code, Cragen session token, copied bearer token, API key, browser cookie, or any long-lived credential.
- You must never request the user's sign-in email as a workaround for authorization or missing access.
- You must not scrape Cragen, invent a non-OAuth setup path, or tell the user to use the compatibility-only verification URI.
- Keep RIR optional. Do not invent RIR values where the user did not record one.
- Make no training or program request until the user asks.
- A one-time invitation expires after 30 minutes. Access tokens last 10 minutes; rotating refresh tokens have a 30-day lifetime.
- Optional iOS account backup may include saved coach notes, training preferences, and reminder desired state. It does not include local command receipts or Undo preimages. Restoring a backup clears the ability to Undo pre-restore commands.
- Encrypted server command request and receipt content and encrypted write context are erased after 30 days. Minimal connection IDs, hashes, and status records may remain until account deletion.

## Failure behavior

If your client cannot configure remote Streamable HTTP, outbound HTTPS, and secure token storage, stop and tell the user that this chat-only or local-only host is not compatible yet. If device authorization, in-app approval, or verification fails, stop. Do not work around the failure with a browser, pasted secrets, or a durable bearer credential. WorkOS browser OAuth remains a compatibility fallback only when the agent explicitly supports it.

After a successful `connection_info` call, tell the user that Cragen is connected and list the exact granted scopes. Explain that proposals require review and that a write is saved only after its authenticated device receipt reports `applied`.
