Skip to content

Repository files navigation

Grok Lens

CI License: MIT Ruby

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.1 by default and never writes to ~/.grok. See SECURITY.md.

Features

  • Projects by working directory — path, short description, model mix, tokens
  • Sessionslive / 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 when sessions.json is present
  • Worktrees / memory/worktrees and /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 serverbin/grok-lens-mcp (stdio): search, list/get sessions, path → last agent, Bot roster, glossary. Read-only. resume-here prints 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>, and grok 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)

Status meanings

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.

Requirements

  • macOS or Linux — Windows is not supported yet (live/stale uses ps / lsof)
  • Ruby >= 4.0
  • Bundler
ruby -v   # must report 4.x

Install & run

git 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

Open http://127.0.0.1:9292

Options

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-lens

MCP (Grok Build)

Read-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

Resume command for this directory

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 codex

Same 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.

Screenshots

Dual-home dashboard (synthetic demo data — not real session history):

Grok Lens home dashboard

The layout is inspired by Edward Tufte’s data visualization: dense tables, sparklines, high data-ink, little chrome.

Data sources (read-only)

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

Development

bundle install
bundle exec rake test
bundle exec rackup -o 127.0.0.1 -p 9292

See CONTRIBUTING.md.

Project layout

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/

License

MIT · Copyright (c) 2026 Eugene Ray

Disclaimer

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.

About

Local read-only dashboard for Grok Build sessions

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages