Terms and an explicit setup action
GET /v1/onboarding/terms is public. It returns version, sha256, url,
privacy_url, and notice. The terms URL identifies an immutable document.
POST /v1/users/me/onboarding requires a verified Firebase bearer token and
{ "terms_version": "<displayed version>", "terms_sha256": "<displayed digest>" }.
Only call it from an explicit continue/copy action after displaying the notice
and links. It records account, version, digest and server timestamp, then
returns HTTP 201 with attempt_id, connect_code, and expires_at.
Passive session restoration must not call it.
The connect code is a bearer secret, valid for 15 minutes, and exchanged
once. Keep it out of URLs, logs, analytics and persistent browser storage.
The server stores only its hash. These endpoints return Cache-Control: no-store.
Connect and verify
POST /v1/onboarding/exchange accepts { "connect_code": "<copied code>" }.
It atomically consumes the code and creates an ordinary, revocable account API
token. The response contains attempt_id, token, token_id, and the token’s
expires_at. mireye-mcp connect stores the token and its ID in the local credential file;
agent configuration contains the credential file path, never the token itself.
The ID lets mireye-mcp logout --revoke revoke this credential through
DELETE /v1/users/me/tokens/{token_id}, authenticated with that same API token.
An API token can revoke itself but cannot revoke other tokens on the account.
If the exchange response is lost, copy a new prompt. Replaying a consumed code
cannot reveal its token.
POST /v1/onboarding/{attempt_id}/progress requires that attempt’s API token.
The body contains stage (installed or verified), clients (client names),
and skill_installed (boolean). Repeated reports are idempotent. Installation
reports describe the local machine; they cannot assert first-call success.
Browser progress and first-call proof
GET /v1/users/me/onboarding/{attempt_id} requires the owning Firebase identity.
Persist only the attempt ID under that user’s identity to resume after refresh.
The response includes status (waiting, connected, or complete),
installed_at, verified_at, first_call_at, clients, skill_installed,
first_call, and expires_at. No credential or setup code is returned.
The configured local adapter attaches X-Mireye-Onboarding-Attempt to its
authenticated POST /v1/fetch. The API matches the attempt’s token and records
proof only when at least one returned field has status: "ok" and a meaningful
value. Zero and false are valid values. Failed, absent and null fields, catalog
reads, and token checks do not complete setup. first_call includes the field
names and source URLs, without copying the customer’s field values.
complete additionally requires installed clients, an installed skill, and the
verified stage. A tracking outage cannot turn a successful data call into an
error. See setup troubleshooting for retrying doctor.
Storage and deployment
Firestore stores attempts, hashed codes and per-version acceptance separately; token records use the existing account token collection. Local tests use the in-memory store and Firebase Auth emulator. Configure Firestore TTL for theexpires_at field in agent_onboarding_codes to remove expired codes; expiry
is enforced by the application regardless of cleanup timing. Keep acceptance
records according to the account’s retention policy.
The Firestore TTL policy is a deployment step; it is not created by the API.
Cleanup is asynchronous. Deleting a code document does not delete the separate
attempt, acceptance, or API token. A cleaned-up code returns not-found instead
of the expired/used response. Attempts and legal acceptance records have no
automatic TTL in this implementation; retain them under the account retention
policy, independently of the short-lived exchange credential.
Before releasing a terms change, update the immutable website artifact and
manifest, then update TERMS_VERSION and TERMS_SHA256 together in
api/agent_onboarding.py. The API does not fetch the website at runtime. Release
validation should set MIREYE_WEB_REPO to the website checkout and run
pytest tests/test_agent_onboarding.py -k terms_manifest; this checks the
approved manifest entry and the artifact’s actual bytes. Without that variable,
the test checks a sibling mireye-web checkout when present and skips when it
is absent.
Deploy the API, publish mireye-mcp==0.7.0, verify that version can be installed,
then deploy the website that generates its command. The new command is not
available from older cached adapters. The public MCP repository remains a
release mirror of mcp_server/.