CClawMetryDocs

Get started

How it works#

Three processes, one database, three ways data gets in. Understanding this layout explains most of the behaviour you will encounter, including why reading a raw log file inside a request handler works on your laptop and returns nothing in the cloud.

The processes#

The sync daemon (clawmetry sync, or python -m clawmetry.sync) is where the work happens. It polls every runtime it can find, reads what is new, normalises it, and writes it into the local store. It owns the DuckDB writer lock — exclusively. It also runs the detectors, evaluates Guard policies, and, when cloud sync is on, encrypts and pushes a snapshot.

The dashboard (clawmetry) is a Flask app serving the UI on port 8900. It holds no writer lock and, in normal operation, does not open DuckDB at all: the process marks itself CLAWMETRY_ROLE=dashboard precisely so the store layer refuses to hand it a writer.

The enforcement proxy (clawmetry proxy start) is optional. It sits in front of model calls on port 4100 and applies budget limits, loop detection and model routing. Nothing else depends on it — except OpenClaw's advisory pause, which is only enforced when the proxy is running.

Getting data in#

Everything lands in the same store, through three paths.

1. The filesystem#

Most runtimes write transcripts to disk. The daemon reads them where they are, read-only, and never modifies an agent's directory. Each runtime has its own format — JSONL, SQLite, a directory of JSON files, a Markdown transcript, a Postgres database, even an undocumented protobuf blob — and its own adapter. See How detection works and the per-runtime reference pages.

2. The gateway WebSocket#

OpenClaw and NemoClaw expose a JSON-RPC gateway on port 18789. Subscribing to it gives sub-second liveness that filesystem polling cannot: you see a tool call while it is running, not after the transcript is flushed.

3. OpenTelemetry#

The dashboard exposes OTLP receivers at /v1/metrics, /v1/traces and /v1/logs. Anything that speaks OTLP can push into ClawMetry, which is the supported path for runtimes with no local store — n8n on Postgres, a hosted CI agent, your own service. See OpenTelemetry ingest.

There is also a fourth, explicitly opt-in path for code you control: the HTTP ingest API and the interceptor.

The store#

One DuckDB file, on your machine, holding events, sessions, spans, rollups and Guard state. It is the single data layer every feature reads and writes; there is no second source of truth.

Because the daemon holds the writer lock, the dashboard cannot simply open the file. Instead the daemon runs a localhost query server and advertises it in a discovery file:

~/.clawmetry/local_query.json
{"port": 51843, "token": "…", "pid": 4711}

Anything that needs to read — the dashboard, the MCP server, the cloud relay — reads the discovery file, checks the pid is alive, and posts a query to http://127.0.0.1:<port>/api/local/query with the bearer token. One writer, many readers, no lock contention.

The rule this implies

A request handler must read from the store, not from raw files. Opening ~/.openclaw/**.jsonl inside a handler works on a laptop and returns empty in the cloud, where the container has no agent directories at all. Everything goes through the query API.

The query contract#

The read surface is a declared contract, q/1, with a fixed set of shapes (sessions, events, transcript, aggregates, spans, traces, models, runtimes, search, health, and more). Inside q/1, evolution is additive only: new shapes and new optional arguments may appear, but renaming or removing one requires a new contract version. The same shapes back the HTTP API, the MCP server and the cloud relay, so all three agree by construction.

Full list and argument reference: Query API.

Cloud, when you turn it on#

The daemon builds a snapshot, encrypts the content-bearing parts with AES-256-GCM using a key that never leaves your machine, and pushes it to the ingest endpoint. The server stores ciphertext; your browser decrypts it locally when you open the cloud dashboard. Aggregate counters — cost totals, session counts, health status — travel in plaintext so the cloud can render a summary and a device display without holding your key.

Which fields are which is documented in End-to-end encryption.

Where intervention fits#

Nothing in the ingest path can touch an agent. There are exactly four surfaces that can, and adding a fifth means adding it to that list with locks of the same strength:

  1. Manual control — you press Pause, Stop or Kill in the Guard tab.
  2. Autonomous policy — a Guard policy fires, which requires all three locks

open: the policy's action must not be monitor, CLAWMETRY_POLICY_ENFORCE=1 must be set on the node, and an entitlement check that fails closed must pass.

  1. Pre-tool gates — where a runtime exposes a hook, ClawMetry can hold an

action before the tool runs.

  1. Cron management via gateway RPC.

Both control paths end in the same actuator, so an automatic pause and a hand-pressed pause are identical to the agent process. See Pause, stop, kill.

The frontend#

The dashboard UI is served from static files and templates — no npm, no bundler, no build step. That is a deliberate constraint: a dashboard you can pip install and run on a Raspberry Pi should not need a JavaScript toolchain.

Cookie preferences