Analyze with an external AI agent
ChatLab lets AI agents such as Codex, Claude Code, and HermesAgent query and analyze chat records locally. Queries are read-only, apply desensitization and blacklist filtering by default, and do not require the ChatLab desktop or web interface to be open.
Get started
Node.js 22.19 or newer is required, and chat records must already be imported into ChatLab. Install ChatLab CLI and the English Skill:
npm install -g chatlab-cli
npx skills add ChatLab/ChatLab --skill chatlab-analyze -gAfter installation, ask Codex, Claude Code, Cursor, or another external agent:
chatlab-analyze help me analyze my chat history with AliceThe skill tells the agent to run clb manifest first, then query chat records safely with explicit --format agent/json commands.
chatlab-analyze always remains read-only. To let an agent import a new chat export, use the separate chatlab-import skill; it previews the import, then automatically creates or incrementally updates a session. See the Import Chat Records Guide.
Command overview
clb sessions list # List imported sessions
clb sessions show # Session details
clb members list # Session members
clb members history # Member name history
clb messages list # List messages in a time window
clb messages search <keywords...> # Keyword search (multi-word, context, paging)
clb messages context --id <id> # Messages around a specific id
clb messages between # Conversation between two members
clb stats overview # Session overview
clb stats activity # Member activity ranking
clb stats time --by day # Time distribution (hour/weekday/day/month)
clb stats keywords # High-frequency words (privacy-filtered)
clb stats response # Reply speed ranking
clb topics list # AI segment summaries
clb topics show --id <id> # Original messages of one segment
clb sql "<SELECT ...>" # Read-only SQL fallback (strings desensitized)
clb schema # Database schema
clb manifest # Machine-readable command manifest for agentsWith a single session --session can be omitted; with multiple sessions, commands return candidates for disambiguation.
Output formats
Pass --format explicitly:
agent: recommended for AI agents. A JSON envelope whose body is compact text produced by the full preprocessing pipeline (cleaning, blacklist, denoising, merging consecutive messages, desensitization, token-aware truncation). Single-message markers[#id]/[#id*]can be used withmessages context --id; merged ranges such as[#a-b]are display-only.json: for programmatic parsing. Structured message items with privacy steps applied (cleaning, blacklist, desensitization) but no merging or denoising. The right choice for structural scouting with--no-content/--fields.text: human-readable output (TTY default).
In agent/json mode stdout contains exactly one JSON envelope; logs go to stderr:
{
"ok": true,
"command": "messages.search",
"data": { "text": "returned: 2\n\n--- 2026/6/1 ---\n[#1*] 09:00 Wang: how about a trip on May Day..." },
"meta": { "totalHits": 2, "returnedHits": 2, "hasMore": false, "preprocess": { "desensitized": true }, "apiVersion": 1 }
}Failures return { "ok": false, "error": { "code", "message", "hint", "candidates" } } with semantic exit codes: 0 success, 2 invalid argument or disabled capability, 3 not found, 4 ambiguous (with candidates), 5 SQL error.
Common query parameters
- Time:
--since/--untilaccept2026-06-01,"2026-06-01 08:30", ISO 8601,today,yesterday;--last 30dsupports h/d/w. Date-only--untilincludes the whole day; resolved bounds are echoed inmeta.timeRange. - Members:
--memberaccepts a member id, exact name, orme(the data owner); ambiguous names return candidate ids. - Paging: when
meta.hasMoreis true, pass--cursor <meta.nextCursor>; cursors are bound to the exact query conditions. - Token budget:
--limit(primary objects),--max-messages(context expansion cap),--max-tokens(agent text budget, default 4000),--max-chars(per-message truncation).
Privacy boundaries
- All query commands apply your ChatLab desensitize rules and blacklist by default — including the
stats keywordsvocabulary,topics listsummaries, and string cells insqlresults; reading the messagecontentcolumn withsqlrequires explicit--raw. --raw(bypassing preprocessing) is disabled by default; it only works after you explicitly runclb config set cli.allow_raw trueor setCHATLAB_CLI_ALLOW_RAW=1.- If you don't need the SQL fallback, disable it with
clb config set cli.allow_sql false.
Query example
A typical recipe — "who mentioned this first? inspect the surrounding context":
clb messages search "server migration" --sort asc --limit 5 --context 3 --format agent
# Take the message id from a single-message [#1021*] marker in the returned text, then dig in:
clb messages context --id 1021 --window 10 --format agent