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 20 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 chatlab 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
chatlab sessions list # List imported sessions
chatlab sessions show # Session details
chatlab members list # Session members
chatlab members history # Member name history
chatlab messages list # List messages in a time window
chatlab messages search <keywords...> # Keyword search (multi-word, context, paging)
chatlab messages context --id <id> # Messages around a specific id
chatlab messages between # Conversation between two members
chatlab stats overview # Session overview
chatlab stats activity # Member activity ranking
chatlab stats time --by day # Time distribution (hour/weekday/day/month)
chatlab stats keywords # High-frequency words (privacy-filtered)
chatlab stats response # Reply speed ranking
chatlab topics list # AI segment summaries
chatlab topics show --id <id> # Original messages of one segment
chatlab sql "<SELECT ...>" # Read-only SQL fallback (strings desensitized)
chatlab schema # Database schema
chatlab 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 runchatlab config set cli.allow_raw trueor setCHATLAB_CLI_ALLOW_RAW=1.- If you don't need the SQL fallback, disable it with
chatlab config set cli.allow_sql false.
Query example
A typical recipe — "who mentioned this first? inspect the surrounding context":
chatlab 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:
chatlab messages context --id 1021 --window 10 --format agent