ccrecall
v0.0.15
Published
Sync Claude Code transcripts to SQLite and recall context from past sessions
Downloads
228
Maintainers
Readme
ccrecall
Sync Claude Code transcripts to SQLite for analytics. Query your session history, token usage, tool calls, and team/swarm data.
Quick Start
Use ccrecall inline in Claude Code sessions. Tell Claude:
"run npx ccrecall sync then show me my top 5 projects by token usage"
"use npx ccrecall search to find sessions where we discussed database migrations"
"run npx ccrecall stats and tell me how many tokens I've used this week"Claude runs the command, gets structured output, and can answer follow-up questions about your session history.
How It Works
Claude Code stores transcripts as JSONL files in
~/.claude/projects/. ccrecall parses these into a SQLite database so
you can query across all sessions.
Step 1. Tell Claude to sync your transcripts:
npx ccrecall syncStep 2. ccrecall incrementally imports new content and reports what it found:
Synced 42 sessions, 1,847 messages, 923 tool callsStep 3. Claude can now query the database using any ccrecall command or raw SQL:
npx ccrecall stats
npx ccrecall search "database migration"
npx ccrecall query "SELECT project_path, SUM(input_tokens) FROM sessions s JOIN messages m ON m.session_id = s.id GROUP BY project_path ORDER BY 2 DESC LIMIT 5"Important: Claude doesn't know about ccrecall unless you mention it. Just mention
{npx,pnpx,bunx} ccrecalland Claude will discover subcommands and flags from the CLI output.
Commands
npx ccrecall sync # Import transcripts (incremental)
npx ccrecall stats # Session/message/token counts
npx ccrecall sessions # List recent sessions
npx ccrecall search <term> # Full-text search across messages
npx ccrecall tools # Most-used tools
npx ccrecall query "<sql>" # Raw SQL against the database
npx ccrecall schema # Show database table structureAll commands support -v, --verbose for detailed output and
-d, --db <path> to use a custom database path (default:
~/.claude/ccrecall.db).
Database Schema
erDiagram
sessions ||--o{ messages : contains
sessions ||--o{ tool_calls : contains
sessions ||--o{ tool_results : contains
sessions ||--o| teams : "lead session"
messages ||--o{ tool_calls : has
messages ||--o{ tool_results : has
tool_calls ||--o{ tool_results : produces
teams ||--o{ team_members : has
teams ||--o{ team_tasks : has
sessions {
text id PK
text project_path
text git_branch
text cwd
int first_timestamp
int last_timestamp
text summary
}
messages {
text uuid PK
text session_id FK
text parent_uuid
text type
text model
text content_text
text content_json
text thinking
int timestamp
int input_tokens
int output_tokens
int cache_read_tokens
int cache_creation_tokens
}
tool_calls {
text id PK
text message_uuid FK
text session_id FK
text tool_name
text tool_input
int timestamp
}
tool_results {
int id PK
text tool_call_id FK
text message_uuid FK
text session_id FK
text content
int is_error
int timestamp
}
teams {
text id PK
text name
text description
text lead_session_id FK
int created_at
}
team_members {
text id PK
text team_id FK
text name
text agent_type
text model
text prompt
text color
text cwd
int joined_at
}
team_tasks {
text id PK
text team_id FK
text owner_name
text subject
text description
text status
int created_at
int completed_at
}
sync_state {
text file_path PK
int last_modified
int last_byte_offset
}Team/Swarm Support
Syncs team data from ~/.claude/teams/ when Claude Code's swarm mode
is enabled.
Why track teams?
- Debug runaway agents: compare
prompt(original instructions) vs actual behavior - Link swarm runs to sessions and PRs
- Track task assignments and completion
Example Queries
-- Token usage by project
SELECT project_path, SUM(input_tokens + output_tokens) as tokens
FROM sessions s
JOIN messages m ON m.session_id = s.id
GROUP BY project_path
ORDER BY tokens DESC;
-- Daily message count
SELECT DATE(timestamp/1000, 'unixepoch') as day, COUNT(*) as messages
FROM messages
GROUP BY day
ORDER BY day DESC;
-- Most used models
SELECT model, COUNT(*) as count
FROM messages
WHERE model IS NOT NULL
GROUP BY model
ORDER BY count DESC;
-- Tool usage breakdown
SELECT tool_name, COUNT(*) as count
FROM tool_calls
GROUP BY tool_name
ORDER BY count DESC;
-- Files read in a session
SELECT tc.tool_name, json_extract(tc.tool_input, '$.file_path') as file
FROM tool_calls tc
WHERE tc.tool_name = 'Read' AND tc.session_id = 'your-session-id';
-- Code changes (edits) with before/after
SELECT
json_extract(tc.tool_input, '$.file_path') as file,
json_extract(tc.tool_input, '$.old_string') as old,
json_extract(tc.tool_input, '$.new_string') as new
FROM tool_calls tc
WHERE tc.tool_name = 'Edit';
-- Session cost estimate (Opus 4.5)
SELECT
s.project_path,
SUM(m.input_tokens) / 1000000.0 * 15 +
SUM(m.output_tokens) / 1000000.0 * 75 +
SUM(m.cache_read_tokens) / 1000000.0 * 1.5 +
SUM(m.cache_creation_tokens) / 1000000.0 * 18.75 as cost_usd
FROM sessions s
JOIN messages m ON m.session_id = s.id
WHERE m.model LIKE '%opus%'
GROUP BY s.id
ORDER BY cost_usd DESC;
-- Teams with member count
SELECT t.name, t.description, COUNT(tm.id) as members
FROM teams t
LEFT JOIN team_members tm ON tm.team_id = t.id
GROUP BY t.id;
-- Agent prompts for debugging (what were they told to do?)
SELECT name, prompt FROM team_members WHERE team_id = 'your-team-id';
-- Task status by team
SELECT team_id, status, COUNT(*) as count
FROM team_tasks
GROUP BY team_id, status;
-- Link Teammate tool calls to team configs
SELECT tc.timestamp, t.name, t.description
FROM tool_calls tc
JOIN teams t ON json_extract(tc.tool_input, '$.team_name') = t.name
WHERE tc.tool_name = 'Teammate';Requirements
- Node.js 22+
License
MIT
