Caura / docs
Interviewer

Setup

Enable the Interviewer on a tenant, then wire each harness — the OpenClaw plugin, or the caura-interviewer CLI for Claude Code and Cursor workstations.

Turning the Interviewer on takes two switches: enable the tenant (server-side), then turn on a capture source (per harness). Neither half does anything alone.

1. Enable the tenant

The Interviewer reads no trail and writes no memory until the tenant opts in. Set it in the tenant's org settings:

{ "interviewer": { "enabled": true } }

Optional tuning under the same key (defaults shown):

KeyDefaultMeaning
enabledfalseMaster switch for the tenant.
period_hours12How often a node is due for an interview.
template_id"default-v1"Which report template the synthesis prompt uses.

On a multi-worker deployment the setting is cached per worker (short TTL), so a freshly-flipped flag is honored within a few minutes rather than instantly.

2a. OpenClaw — plugin-buffer

If you already run the OpenClaw plugin, the Interviewer rides it. The plugin keeps a durable, node-local event buffer and submits windows when the server tells it a node is due. Turn it on by adding one variable to the plugin's environment and restarting the gateway:

# in ~/.openclaw/plugins/memclaw/.env
CAURA_INTERVIEWER=true
openclaw gateway restart

Requires the Caura plugin 2.15.1 or newer. Earlier builds abort the interview submit before the server finishes synthesizing a window, so the command never completes and no memories are written. A fresh install from the server always satisfies this — only a pinned or long-unupgraded gateway needs attention.

With the tenant enabled and CAURA_INTERVIEWER=true, the server's schedule drives capture — no cron, no CLI. Nothing is buffered or submitted while either switch is off.

2b. Claude Code & Cursor — disk-parser CLI

Claude Code and Cursor have no gateway, but each keeps a durable transcript on disk. The caura-interviewer CLI reads it read-only and submits windows. It ships inside the Python client:

pip install caura-client

Point it at your deployment and pick the harness:

export CAURA_API_KEY=mc_xxx
export CAURA_TENANT_ID=my-team
export CAURA_BASE_URL=https://caura.ai          # or your self-hosted URL
export CAURA_INTERVIEWER_PROJECTS="my-app,acme-*"  # allowlist (see Privacy)

caura-interviewer status                 # cursors vs. local transcript lines
caura-interviewer run --dry-run -v       # parse + window, submit nothing
caura-interviewer run                     # submit due windows (Claude Code)
caura-interviewer run --harness cursor    # harvest Cursor instead

The harness selects both the transcript root and the parser dialect:

--harnessReadsEnv alternative
claude-code (default)~/.claude/projects/<slug>/*.jsonlCAURA_INTERVIEWER_HARNESS=claude-code
cursor~/.cursor/projects/<slug>/agent-transcripts/<id>/*.jsonlCAURA_INTERVIEWER_HARNESS=cursor

Environment variables

VariableRequiredPurpose
CAURA_API_KEYTenant- or agent-scoped credential.
CAURA_TENANT_IDTenant to write into.
CAURA_BASE_URLDeployment URL (default https://caura.ai).
CAURA_AGENT_IDAgent identity for the written memories (default user@host).
CAURA_FLEET_IDFleet to attribute writes to.
CAURA_INTERVIEWER_PROJECTSComma-separated project-dir globs to allow.
CAURA_INTERVIEWER_HARNESSclaude-code (default) or cursor.

Triggers

Run the CLI on whatever cadence you like — both triggers are safe to combine because duplicate submissions dedup server-side:

  • Cron — a periodic caura-interviewer run is the floor; it catches every session, including ones that crashed.

  • Session-end hook — interview a session the moment it ends. The same hook command serves both harnesses; each sends transcript_path on stdin and the harness is inferred from the path.

    Claude Code (~/.claude/settings.json):

    { "hooks": { "SessionEnd": [ { "hooks": [
      { "type": "command", "command": "caura-interviewer hook", "timeout": 300 }
    ] } ] } }

    Cursor (~/.cursor/hooks.json):

    { "version": 1, "hooks": {
      "sessionEnd": [ { "command": "caura-interviewer hook" } ]
    } }

The hook always exits 0 — a memory-harvest failure never fails your agent session. If it can't act (project not allowlisted, missing credentials) it prints a one-line reason to stderr and exits cleanly.

Privacy: default-deny allowlist

A workstation's transcripts span every project on the machine — including NDA and client work, and whatever secrets got pasted into a prompt. So the CLI harvests nothing until you name projects. With no allowlist it lists the discovered project directories and exits with guidance. Opt in with CAURA_INTERVIEWER_PROJECTS, --projects <glob…>, or the explicit --all-projects. Independently, credential-shaped strings are scrubbed locally before anything leaves the machine, and the server masks again on receipt.

2c. Hermes — disk-parser (planned)

TBD. A Hermes adapter is planned: it will read Hermes's state.db conversation store and reuse the same windowing, watermark, and submit protocol as the Claude Code and Cursor adapters. Not yet shipped — this section will document --harness hermes when it lands.

Verify

After a real (non-dry) run, confirm the cursor advanced and a memory landed:

  • caura-interviewer status shows pending=0 once a file is fully drained.
  • The written memories appear in recall / the dashboard, typed as episode, decision, outcome, task, fact, or preference.
  • Re-running submits nothing new — the watermark and server-side dedup make repeat runs idempotent.