--- title: Claude Code description: How ClawMetry observes Claude Code — where its data lives, the environment variables that move it, what cost data is real, and the traps in its store. eyebrow: Runtime reference --- # Claude Code Claude Code writes a JSONL transcript per session under its projects tree. ClawMetry maps each turn to OpenTelemetry-shaped spans, so an assistant turn becomes an `llm.call` span, each tool use becomes a child span, and a `Task` becomes an `agent.spawn` — which is what makes the Agent Graph and the turn-anatomy views work. | | | |---|---| | **Runtime id** | `claude_code` | | **Category** | Terminal coding agent | | **Vendor** | Anthropic | | **Tier** | Paid tier (Starter and up) | | **Upstream** | [claude.com/claude-code](https://claude.com/claude-code) | ## Where the data comes from ClawMetry reads these locations, in order, and never writes to any of them. - `~/.claude/projects//.jsonl` — transcripts - `$CLAUDE_CONFIG_DIR` — when the CLI has been relocated - `~/Library/Application Support/Claude` — Claude Desktop sidecar records (macOS; %APPDATA%\Claude on Windows, $XDG_CONFIG_HOME/Claude on Linux) **Format.** One JSONL file per session; each line is a conversation turn with content blocks (text, thinking, tool_use, tool_result). ## Environment variables | Variable | Effect | |---|---| | `CLAUDE_CONFIG_DIR` | Claude Code's own config-dir override | | `CLAWMETRY_CLAUDE_DESKTOP_DIR` | Desktop state dir override | | `CLAWMETRY_FAMILY_SESSION_LIMIT` | how many recent sessions to ingest (default 50) | | `CLAWMETRY_DISABLE_CLAUDE_SESSION_INGEST` | turn the adapter off entirely | See [Environment variables](/docs/config/environment/) for the variables that apply to every runtime. ## Tokens and cost **Tokens.** Full split per turn, including cache reads and writes. **Cost.** Derived from the token split and model. Claude Code's native OpenTelemetry export also reports cost on both a log and a metric — ClawMetry counts it once. :::note Why this section exists Runtimes differ enormously in what they persist. Rather than showing a plausible number everywhere, ClawMetry reports what the store actually contains and marks the rest unknown. A cost of `$0.00` and a cost of *unknown* mean different things, and the dashboard keeps them different. ::: ## Sub-agents and delegation `tool_use` with name `Task` becomes an `agent.spawn` span and a child session, so sub-agent spend is attributed to the child rather than smeared across the parent. ## Things worth knowing - The CLI, the Desktop app and the VS Code extension all write into the same `~/.claude/projects` tree. ClawMetry labels the surface each session came from so a Desktop conversation is not reported as a terminal run. - Sessions that OpenClaw spawned are ingested under the OpenClaw session id and skipped here — otherwise the same work appears twice. ## Verify it is being read ```bash # Is this runtime detected, and would this install unlock it? clawmetry runtimes --json | jq '.runtimes[] | select(.id=="claude_code")' # Why is it locked, if it is? clawmetry runtimes --why claude_code # Any sessions ingested yet? curl -s 'http://localhost:8900/api/local/sessions?limit=5' \ | jq '.rows[] | {session_id, agent_id, events, cost_usd}' ``` If detection succeeds but no sessions appear, work through [Troubleshooting](/docs/ops/troubleshooting/) — the usual causes are a relocated data directory (set the override above), a session limit that is hiding older runs, or a runtime that simply has not written anything yet.