Local, read-only dashboard for Grok Build sessions under ~/.grok and Grok Bot agents.
Ruby 4.x · Sinatra
Privacy: Session data can include prompts and code. Binds to
127.0.0.1by default and never writes to~/.grok. See SECURITY.md.
- Projects by working directory — path, short description, model mix, tokens
- Sessions — live / stale / idle / needs input, models, turns, billed or recorded or est. tokens, context window, cost
- Codex / Cursor — optional session sources on Home (chips only if discovered); Cursor resume via
cursor-agent --resume - Grok Bot — separate agent roster (
/bot): section, working/idle, groups, unread, pins. Hidden unless agents are discovered - Mobirok inbox (
/inbox) — Mac relay attach + pending permission whensessions.jsonis present - Worktrees / memory —
/worktreesand/memory(hidden when empty) - Running tasks — in-flight bg shells / tools / live subagents (with process/port liveness checks)
- Nested subagents —
+N sub · K live - Search — FTS over Grok’s
session_search.sqlite - MCP server —
bin/grok-lens-mcp(stdio): search, list/get sessions, path → last agent, Bot roster, glossary. Read-only.resume-hereprints a complete resume command for the last session that touched a directory. - Compare — side-by-side metrics for two sessions
- Copy session id,
grok --cwd … --resume <id>,codex resume <id>,cursor-agent --resume <id>, andgrok usage <id> - Light / dark / system theme (single cycle control)
- Live polling re-renders Active + Sessions (any sort/filter) without a full page reload
- MCP tab — servers that sessions used, with active / idle / suspended / failed status
- Glossary of slash commands · plugins & skills inventory (hooks, personas, project/Cursor skills)
- Sort / filter sessions (last active, running tasks, tokens, title; Running only = live process or in-flight tasks)
| Label | Meaning |
|---|---|
| live | A Grok process for this session is running (registry and/or grok --resume …) |
| working | Grok Bot agent whose local replica is still streaming (app must be open) |
| stale | Listed open but pid is dead |
| idle | No live process |
| needs input | Unmatched Grok permission_requested (waiting on the user) |
| N running | Live in-flight work units (bg shell, tool, subagent) after liveness checks |
Token lifetime figures prefer Grok Build 1.0.14+ usage.json (the same ledger as grok usage <session-id>): billed input/output/cache/reasoning tokens and USD. Completeness is checked against session turn count — a partial ledger (old session that started recording mid-conversation) stays labeled est. and the recorded slice is shown separately. Sessions without usage.json keep the hybrid estimate (signals.json + on-disk sizes). Context still comes from signals.json. Optional napkin cost (GROK_LENS_USD_PER_M_TOKENS) is only for sessions without billed totals.
- macOS or Linux — Windows is not supported yet (live/stale uses
ps/lsof) - Ruby >= 4.0
- Bundler
ruby -v # must report 4.xgit clone https://github.com/monomyth/grok-lens.git
cd grok-lens
bundle install
bundle exec rackup -o 127.0.0.1 -p 9292
# or
bin/grok-lens| Variable | Default | Meaning |
|---|---|---|
GROK_HOME |
~/.grok |
Root of Grok Build data |
HOST |
127.0.0.1 |
Bind address |
PORT |
9292 |
HTTP port |
GROK_LENS_POLL_SECONDS |
300 |
Default auto-refresh (UI can override; 0 = off) |
GROK_LENS_USD_PER_M_TOKENS |
unset | Optional USD per 1M tokens for est. cost on sessions without usage.json. Billed cost from the ledger is always shown when present. |
GROK_LENS_CONFIG |
~/.grok-lens.yml |
Optional YAML (usd_per_m_tokens) — see config.example.yml |
GROK_LENS_GROK_BOT |
on | Set 0 to hide Grok Bot agents |
GROK_LENS_GROK_BOT_APP |
~/Library/Application Support/Grok Bot |
Desktop persistence root |
GROK_LENS_CODEX |
on | Set 0 to hide Codex |
GROK_LENS_CODEX_HOME |
~/.codex |
Codex data root |
GROK_LENS_CURSOR |
on | Set 0 to hide Cursor |
GROK_LENS_CURSOR_HOME |
~/.cursor |
Cursor data root |
GROK_LENS_MOBIROK |
on | Set 0 to hide the Mobirok inbox |
GROK_LENS_MOBIROK_HOME |
MobirokMac / Mobirok / ~/.mobirok |
Relay sessions.json root |
GROK_HOME=/path/to/.grok PORT=9292 bin/grok-lensRead-only stdio server. Does not require rackup. Gives the model session titles, paths, FTS snippets, and Grok Bot last-entry text — same sensitivity as the dashboard.
From a clone:
[mcp_servers.grok-lens]
command = "/opt/homebrew/bin/ruby"
args = ["/absolute/path/to/grok-lens/bin/grok-lens-mcp"]
enabled = true
[mcp_servers.grok-lens.env]
BUNDLE_GEMFILE = "/absolute/path/to/grok-lens/Gemfile"Same GROK_HOME / GROK_LENS_* env as the dashboard.
| Tool | What it does |
|---|---|
search_sessions |
Grok FTS plus Codex/Cursor title and cwd. Not Bot. |
list_sessions / get_session |
Primary sessions; no full transcript |
resume_command |
grok / codex / cursor-agent resume; null for Bot |
session_usage |
Billed usage.json or {billed: false} (no invented counts) |
compare_sessions |
Two ids, metrics only |
list_projects |
Working directories |
list_mcp_servers |
Grok MCP roster Lens already inferred |
sessions_for_path |
Which session last touched a directory or file, from which agent (Grok/Codex/Cursor). Bot has no cwd. |
list_bot_agents / get_bot_agent |
Grok Bot roster |
search_glossary / list_skills / list_plugins |
Local catalog |
Grok Bot is not a session source for path lookup. Codex/Cursor have no billed usage.json.
After a new grok session (or /mcps then r), you can ask:
- Which session last touched this directory? →
sessions_for_path(Grok / Codex / Cursor, resume command included) - Search my sessions for rate limiting. →
search_sessions(Grok FTS; Codex/Cursor by title and cwd) - What’s live or stale on this machine? →
list_sessions - What did session
<id>cost? →session_usage(billed Grok ledger only) - Are any Grok Bot agents working? →
list_bot_agents
Stdout is one line: the grok / codex / cursor-agent command to reopen the last matching session. Safe to eval. Hints (source, title, id) go to stderr.
# from a project directory — print
/absolute/path/to/grok-lens/bin/grok-lens-mcp resume-here
# run it
eval "$(/absolute/path/to/grok-lens/bin/grok-lens-mcp resume-here)"
# Grok or Codex only
bin/grok-lens-mcp resume-here --source grok
bin/grok-lens-mcp resume-here --source codexSame subcommand: bin/grok-lens resume-here.
You can ask headless Grok or Codex to look it up, but the model may add extra text, so that output is not safe to eval:
grok -p "Use grok-lens sessions_for_path on $(pwd). Reply with only the last resume_command."Grok-only, no Lens: grok --continue resumes the most recent Grok session in the current directory.
Dual-home dashboard (synthetic demo data — not real session history):
The layout is inspired by Edward Tufte’s data visualization: dense tables, sparklines, high data-ink, little chrome.
| Path | Use |
|---|---|
sessions/<cwd>/<id>/summary.json |
Titles, models, counts, times |
config.toml [mcp_servers] + plugin .mcp.json |
MCP roster (no env/headers) |
events.jsonl mcp_* |
MCP connect / fail / tool-call status |
usage.json |
Billed tokens + cost (grok usage); per-turn table on session detail |
signals.json |
Context tokens / window, turns, tools (when present) |
events.jsonl |
Models, tools, activity sparkline |
updates.jsonl |
In-flight / background tool status |
chat_history.jsonl |
Opening message (wrappers stripped); size for est. |
active_sessions.json + process table |
Live / stale sessions |
sessions/session_search.sqlite |
FTS search |
Project README.md |
Optional project description |
~/Library/Application Support/Grok Bot/sand-client-persistence |
Grok Bot roster + transcript replicas |
…/sand-session-marker.json |
Grok Bot app liveness |
~/.codex/session_index.jsonl + state_5.sqlite + rollout prefix/tail |
Codex threads (no full rollout parse) |
~/.codex/process_manager/chat_processes.json |
Codex live background commands |
~/.cursor/projects/*/agent-transcripts |
Cursor agent transcripts |
~/.cursor/chats/*/…/meta.json |
Cursor workspace cwd (never store.db on scan) |
~/.grok/worktrees (+ Cursor worktrees) |
Worktrees page |
~/.grok/memory/**/MEMORY.md |
Memory skim |
Mobirok sessions.json + remote/state.json |
Inbox attach / pending permission |
bundle install
bundle exec rake test
bundle exec rackup -o 127.0.0.1 -p 9292See CONTRIBUTING.md.
grok-lens/
bin/grok-lens
bin/grok-lens-mcp
config.ru
config.example.yml
lib/grok_lens/ # store, estimate, search, catalog, app
views/
public/
test/
docs/
MIT · Copyright (c) 2026 Eugene Ray
Grok Lens is an independent community tool. It is not affiliated with or endorsed by SpaceXAI. “Grok,” SpaceXAI, and related marks belong to their respective owners.
