Privacy

Agent Relay is local-first. Every byte written by the always-on layer lands in ~/.relay/ on your machine. Nothing uploaded unless you explicitly opt into the proxy mode or telemetry — and even then, the defaults stay conservative.

What gets captured

AdapterCaptures
Claude Code hookTool name on each invocation, stop reasons, notification text.
PTY wrapperProcess lifecycle + line-level rate-limit detection from stdout. The agent's full stdout is mirrored to your terminal, not copied to disk.
Codex Stop hookLast assistant message, error/output fields, and transcript tail only when needed to detect a rate limit.
Gemini Notification hookNotification payload fields used only to detect Google quota/rate-limit signals.
OpenCode pluginSelected session.error, message.updated, and session.status event payload fields used only to detect quota/rate-limit signals.
OpenCode exportOptional sanitized opencode export output for Relay-managed OpenCode sessions when Relay can determine the native OpenCode session id. Export failure is non-fatal.
Warp MCPWhatever an MCP-aware client sends to relay mcp serve; relay install --warp only writes a snippet and paste instructions.
Proxy mode (opt-in)LLM API response headers (rate-limit counters, retry-after). Request/response bodies are seen in flight but never written to disk.

What gets redacted

By default (privacy.redact_secrets = true), every adapter applies the same redaction rules before writing:

  • Object keys matching (secret|key|token|password|credential|bearer|api[_-]?key) → value replaced with [redacted].
  • Inline values matching well-known token formats → replaced inline:
    • sk-… (Anthropic / OpenAI)
    • ghp_… (GitHub personal access tokens)
    • xox[abp]-… (Slack)
  • Tool argument values are not captured by default (privacy.capture_tool_args = false) — we keep the structure ("agent called Edit with these arg names") but drop the values. Flip the flag if you want lossless capture and trust your redaction rules.

Same rules apply across the Python daemon and MCP server. Source: src/agent_relay/daemon/redact.py.

Where it lives on disk

~/.relay/
├── VERSION                       # layout version
├── config.toml                   # your settings
├── sessions/                     # per-session manifests
├── events/<session>.jsonl        # append-only event log
├── snapshots/<id>.md             # handoff primers
├── logs/daemon.log               # daemon stdout/stderr
├── relay.sock                    # unix socket (POSIX)
└── telemetry-id                  # random UUID, only present if you opt in

To inspect everything captured for a session:

terminal
cat ~/.relay/events/<session>.jsonl       # raw events
relay snapshots                            # the resulting primers
relay daemon status                        # in-memory view

To wipe everything captured:

terminal
relay uninstall                            # remove adapters + launch agent
rm -rf ~/.relay                            # delete the data

Telemetry

Off by default. Toggle on in ~/.relay/config.toml:

toml
[telemetry]
enabled = true
endpoint = "https://telemetry.agent-relay.dev/v1/ingest"

When enabled we send aggregate-only counters: which adapters are in use, handoff success rate, the daemon version. No event content, no file paths, no environment variables, no per-session anything. The install id is a random UUID stored at ~/.relay/telemetry-id; deleting it rotates the id.

What gets sent (full schema):

json
{
  "schema": "agent-relay.telemetry/v1",
  "event": "handoff.fired",
  "install_id": "01HRZ…",
  "sdk_version": "0.1.0",
  "properties": {  aggregate counters }
}

The full source is at src/agent_relay/daemon/telemetry.py. Sends are background-threaded with a 3-second timeout and silently dropped on failure — telemetry can never block the daemon.

What we never store

  • Your source code.
  • LLM prompts or responses.
  • Hidden OpenCode state that is not exposed by opencode export.
  • Environment variables.
  • .env file contents.
  • Tool argument values (with the default config).
  • Anything resembling an API key — even when the proxy is on.

Reporting concerns

If you find a redaction miss or a place where data leaves the machine unexpectedly, please open an issue at github.com/bethvourc/agent--relay. This is the area we treat as a hair-trigger bug class.