Tool usage
Query the tool-monitor database to look up and analyze Claude tool usage. Use when asked about tool usage statistics, which tools have been used most, recent tool activity, bash commands run, files read or edited, grep patterns searched, session analysis, or any question about how Claude has been using its tools.From its SKILL.md
npx -y skills add richardkmichael/claude-rodin --skill tool-usageAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 17 days oldThe repository was created 17 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
5.7 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
Tool Usage
The tool-monitor database records every Claude Code tool invocation.
Database: ~/.claude/tool-monitor.sqlite
tool_events table
| Column | Type | Notes |
|---|---|---|
id | INTEGER | Primary key |
session_id | TEXT | Groups events by conversation session |
hook_event_name | TEXT | PreToolUse, PostToolUse, PostToolUseFailure, or PermissionRequest |
tool_name | TEXT | e.g. Bash, Read, Grep, Edit, Write, Glob, Task |
cwd | TEXT | Working directory at time of invocation |
transcript_path | TEXT | Path to the session transcript file |
created_at | DATETIME | Timestamp |
payload | TEXT | Full JSON payload (all fields above, plus tool_input and more) |
Tool-specific input fields live inside payload and are accessed with json_extract:
json_extract(payload, '$.tool_input.command') -- Bash: the shell command
json_extract(payload, '$.tool_input.file_path') -- Read/Write: file path
json_extract(payload, '$.tool_input.pattern') -- Grep: search pattern
json_extract(payload, '$.tool_input.old_string') -- Edit: text being replaced
Discovering fields for any tool
To see what tool_input fields are available for a specific tool, query tool_schemas:
SELECT json_extract(schema_json, '$.properties.tool_input.properties')
FROM tool_schemas
WHERE tool_name = 'Bash' AND hook_event = 'PreToolUse';
To list all tracked tools and their categories:
SELECT DISTINCT tool_name, category FROM tool_schemas WHERE hook_event = 'PreToolUse' ORDER BY tool_name;
FTS5 wildcard and substring search
For substring and wildcard searches, FTS5 virtual tables are far faster than
LIKE '%term%' on large databases (typically 100-700x).
The database is self-describing: query tool_schemas.indexed_fields to discover
which tools have FTS coverage and which tables and columns to use:
SELECT tool_name,
indexed_fields
FROM tool_schemas
WHERE hook_event = 'PreToolUse'
AND indexed_fields != '[]'
ORDER BY tool_name;
Each indexed_fields value is a JSON array of {"path", "fts_table", "fts_column"} objects.
Use fts_table and fts_column from those results to build the JOIN:
SELECT e.created_at, json_extract(e.payload, '$.tool_input.command')
FROM tool_events e
JOIN fts_bash_command f ON f.event_id = e.id
WHERE f.command MATCH '"git commit"'
ORDER BY e.created_at DESC;
Special characters (., -, /) require phrase quoting: MATCH '"CLAUDE.md"' not MATCH 'CLAUDE.md'
Use json_extract with = for exact equality (hits expression indexes). Use FTS5 MATCH
for substring or wildcard search.
Running queries
Before querying, verify the database exists:
test -f ~/.claude/tool-monitor.sqlite || echo "Database not found — is tool-monitor installed and running?"
sqlite3 ~/.claude/tool-monitor.sqlite "<SQL>"
Use .mode column and .headers on for readable tabular output:
sqlite3 -column -header ~/.claude/tool-monitor.sqlite "<SQL>"
Two-step workflow for tool-specific queries
When the user asks about a specific tool's inputs (e.g. "which files have I read?", "what bash commands containing git?"), first look up the field names, then query:
- Look up fields:
SELECT json_extract(schema_json, '$.properties.tool_input.properties') FROM tool_schemas WHERE tool_name = 'Read' AND hook_event = 'PreToolUse'; - Query events:
SELECT json_extract(payload, '$.tool_input.file_path'), created_at FROM tool_events WHERE tool_name = 'Read' ORDER BY created_at DESC LIMIT 20;
Common patterns
Filter by text pattern:
WHERE json_extract(payload, '$.tool_input.command') LIKE '%git%'
Scope to a directory:
WHERE cwd LIKE '/path/to/my-project%'
Scope to current session:
WHERE session_id = (SELECT session_id FROM tool_events ORDER BY created_at DESC LIMIT 1)
Activity today:
WHERE date(created_at) = date('now')
Tool frequency summary:
SELECT tool_name, COUNT(*) AS uses
FROM tool_events
WHERE hook_event_name = 'PreToolUse'
GROUP BY tool_name
ORDER BY uses DESC;
Cross-referencing session transcripts
Session JSONL hook_progress entries log a compound hookName field in the
format {hookEvent}:{tool_name} (e.g. PreToolUse:ExitPlanMode). The
tool-monitor database stores these as separate columns, so to find the
corresponding entry, query by hook_event_name and tool_name independently:
SELECT id, hook_event_name, tool_name, created_at
FROM tool_events
WHERE hook_event_name = 'PreToolUse'
AND tool_name = 'ExitPlanMode'
AND session_id = '32dff3bf-c7e7-4ef8-a9a3-53f7c7b65917';
Note: the matcher regex from hook configuration (e.g. "*", "Bash") does
not appear in the database. The tool_name column always holds the actual
tool that triggered the hook, regardless of which matcher matched it.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.