Skip to main content

Agent Access relay

Agent Access is not the Evolu CRDT sync path. It is a separate /api/context relay path that must prove its own privacy boundary. The safe contract is:
The user-facing setup path is generated by settings-agent-access-panel.js. It builds a private one-paste command:
Supported <client> values are hermes, openclaw, claude-code, claude-desktop, cursor, cline, and codex. The gbsetup_v1_... payload is base64url JSON containing the Agent Access token, Agent Context key, gateway URL, selected client, version, and creation timestamp. Installers and logs must redact the setup payload; never print the blob after --setup.

Capabilities

Browser write shape

The context gateway keeps the legacy top-level context string field for compatibility. The string must contain encrypted-envelope JSON, not plaintext context.
The write signature is:
The relay rejects unsigned writes, stale timestamps, token-owner mismatches, profile-limit excess, token-limit excess, and owner quota excess.

Context assembly contract

The browser renders Agent Access text through buildLabContext({ skipGroupFilter: true, ignoreContextToggles: true, ... }). It is the same serializer used by in-app AI, but Agent Access intentionally bypasses in-app Data sources because Settings → Agent Access is the separate external-sharing permission. Do not maintain a second context-card formatter for the relay. Stored values that mean “answered negatively” must survive just like positive answers: Diet & Digestion serializes values such as none and normal, and Light & Circadian serializes skinType. Tests should decrypt the outgoing envelope and assert those fields in the plaintext, not merely assert that a POST occurred.

Envelope shape

Version 2 envelopes use a random raw 256-bit Agent Context key. There is no v2 salt because no token/password KDF is involved.
AES-GCM additional authenticated data is:

MCP read/decrypt behavior

getbased-mcp fetches the relay with:
Then it parses data.context, detects encryptedContext.version === 2, and decrypts locally with GETBASED_AGENT_CONTEXT_KEY. Wrong or missing keys must fail closed. The MCP may retain legacy plaintext/v1 decrypt compatibility only for rollout, not as the expected path.

Wearable daily-series section

Agent Access always receives the compact wearable summary when wearable context is enabled. The Settings → Agent Access panel can also sync a daily-series window: off, 7 days, 30 days, or 90 days. That preference is stored with the profile as agentAccessWearableSeriesDays and travels through encrypted Sync. When enabled, the browser pushes a separate machine-readable section for MCP clients, shaped as wearables-series-{N}d: one metric per line, daily values oldest → newest, for missing days, and source labels in parentheses. The hosted relay still stores only the encrypted context envelope; the MCP decrypts and exposes the section locally.

Clean-slate deployment note

If an old context gateway ever stored plaintext summaries, do not migrate those files into the owner-bound layout. Delete the legacy context store and require fresh browser pushes from updated clients. The fixed relay is intentionally fail-closed for old clients that do not send owner proof.

Verification gates

Before marking Agent Access ready:
  1. Run relay unit tests for signature validation, stale timestamp rejection, owner quota, profile limits, and token limits.
  2. Run browser/app tests proving the POST body contains context: JSON.stringify({ encryptedContext }), not plaintext.
  3. Decrypt a captured browser envelope and prove redesigned context-card fields—including explicit negative/normal digestive answers and skin type—match in-app buildLabContext() output.
  4. Run MCP tests proving v2 decrypt works with GETBASED_AGENT_CONTEXT_KEY and wrong-key/token-alone decrypt fails.
  5. Run a live relay E2E against the deployed gateway:
    • insert or create a disposable owner;
    • POST an encrypted sentinel;
    • fetch the relay payload directly;
    • prove the sentinel is absent from the serialized relay response;
    • prove the envelope has version: 2, keyDerivation: raw-256-bit-key, iv, ciphertext, keyId, and no salt;
    • prove getbased-mcp decrypts locally with the right key;
    • prove wrong key fails closed;
    • delete/revoke the test token mapping.
Good production E2E summary shape: