Skip to main content
Glama
roxabi-sense

roxabi-sense

Official
by Roxabi

roxabi-sense

Workstation attention journal — light sensors, local store, agent surfaces.

Status: phases 1–3 live (collectors + store + CLI + daemon + MCP stdio) · NATS still stub
Not screenpipe. Not a web SaaS. Not inside roxabi-factory.
Agent SSOT: AGENTS.md


Why

Screen capture + OCR is the wrong tool for “what was I doing?”.

You already have timestamped work in ~/.claude / ~/.grok, plus live Herdr/OMP panes (tmux still supported). Meetings live in Claap. What is missing is a cheap focus spine: which app/window was active, which agent sessions were open, whether Slack/Discord was running — without pixels, keyloggers, or a 174 MB trial for 40 seconds of frames.

roxabi-sense is that spine. It publishes facts, not policy.


Related MCP server: agent-prompt-capture

What it is / is not

Is

Is not

Local user-session daemon (systemd --user)

Factory hub module

CLI + optional MCP + optional NATS publisher

Screen OCR / continuous screenshots

Reads Claude/Grok files + live Herdr/OMP (tmux still ok)

Re-logs AI conversations

Focus / idle / process presence

Meeting recorder (→ Claap)

Edge sensor for Sentinelle later

Sentinelle decision brain (→ factory hub)


Architecture (target)

  collectors (facts only)
  ┌─────────────┐  ┌──────────────┐  ┌────────────────┐
  │ focus/idle  │  │ agent + mux  │  │ process presence│
  │ (Wayland /  │  │ ~/.claude    │  │ slack/discord  │
  │  AT-SPI)    │  │ ~/.grok      │  │ herdr/omp/tmux │
  │             │  │ herdr/OMP    │  │ (running?)     │
  │             │  │ tmux panes   │  │                │
  └──────┬──────┘  └──────┬───────┘  └───────┬────────┘
         │                │                   │
         └────────────────┼───────────────────┘
                          ▼
                 local store (SQLite)
                 ~/.local/share/roxabi-sense/
                          │
          ┌───────────────┼────────────────┐
          ▼               ▼                ▼
        CLI             MCP              NATS (opt-in)
     day-slice      agent query    factory.event.host.*
     status         what_was_i…    activity | stale only

Boundary (ADR-091-aligned): sensors publish facts; roxabi-factory Sentinelle (hub module, not shipped yet) may consume host events and decide. This repo never opens Discord, never dispatches jobs, never applies ops policy.

Surface

Granularity

Depends on factory?

Local store + CLI

Fine timeline

No

MCP (stdio)

Query on demand

No

NATS plane ①

Coarse heartbeats (activity / stale)

Yes (bus up)

Details: docs/ARCHITECTURE.md · purpose: docs/PURPOSE.md


Stack decision

Local daemon + CLI + MCP — not a Silex web boilerplate.

Candidate

Verdict

silex-boilerplate / Next / multi-page web app

No — that shape is for client demos & product UI, not a user-session sensor

Full stack inside roxabi-factory

No — factory owns Sentinelle consumer; capture stays on the workstation

Python 3.13 + uv + systemd --user

Yes — matches Roxabi satellites (voiceCLI, xcli, cortex packages)

SQLite under ~/.local/share/roxabi-sense/

Yes — single-machine, Syncthing-friendly if paused

MCP stdio

Yes — Claude / Grok / Hermes

NATS publisher (optional extra)

Yes later — facts only, feature-flagged

Tiny 127.0.0.1 status page

Optional V2 — human glance only, not the product surface

Install matrix

Layer

What it does

How

Data plane

Always-on collectors → SQLite

sense install-service + systemctl --user enable --now roxabi-sense.service

Query plane

Read API for humans/agents

CLI: sense status / recap · MCP: sense mcp (stdio)

Agent DX

Host wires MCP

Grok/Claude host snippets or thin plugin plugins/roxabi-sense/ (.mcp.json → PATH sense mcp)

Data plane and query plane are separate: MCP does not start collectors. Empty/offline tools ⇒ fix the daemon, not the agent config.

Setup (PATH-stable)

Prefer a stable sense on PATH so agent configs never hardcode a worktree path.

# 1. clone (or pull) + install CLI + MCP deps into uv tool env
git clone git@github.com:Roxabi/roxabi-sense.git
cd roxabi-sense
uv tool install -e '.[mcp]'
# re-run after pull when the package changes:
#   uv tool install -e '.[mcp]' --force
# After PyPI release: uv tool install 'roxabi-sense[mcp]'

# 2. data plane — user systemd unit (not the same process as MCP)
sense install-service
systemctl --user enable --now roxabi-sense.service

# 3. smoke / DoD
sense doctor                  # FAIL if offline / no DB / MCP missing
sense status                  # last_tick should refresh while daemon is up
sense recap                   # day summary; Meetings fidelity=full|active_only
which sense                   # typically ~/.local/bin/sense

# 5. optional NATS (when factory Sentinelle is ready)
#    sense config set nats.enabled true

MCP host registration (Grok + Claude)

Prereq: steps 1–3 above — which sense resolves, sense doctor is green (daemon + DB + MCP SDK). MCP does not start collectors; empty tools ⇒ fix data plane first.

Happy path: host spawns sense mcp from PATH — never a worktree absolute path.

Grok

User-global TOML (~/.grok/config.toml):

[mcp_servers.roxabi-sense]
command = "sense"
args = ["mcp"]
enabled = true

Or CLI (same result; user scope is default):

grok mcp add roxabi-sense -- sense mcp
grok mcp doctor roxabi-sense   # config + spawn smoke

Restart the Grok session (or open a new one) so the server is re-spawned.

Claude Code

CLI (preferred one-liner):

# workstation-wide (recommended for a host sensor)
claude mcp add -s user roxabi-sense -- sense mcp

# or project-local (writes/approves .mcp.json in the repo)
claude mcp add -s project roxabi-sense -- sense mcp

Project .mcp.json (equivalent shape):

{
  "mcpServers": {
    "roxabi-sense": {
      "command": "sense",
      "args": ["mcp"]
    }
  }
}

Project-scoped servers may show as pending approval until accepted in Claude. User scope avoids per-repo approval for a machine-local sensor.

Asymmetry (intentional): Grok stores servers in TOML (~/.grok/config.toml or project .grok/config.toml); Claude uses CLI scopes / .mcp.json JSON. Both spawn the same stdio command: sense + mcp.

After registration

sense doctor          # still green (host config is not a substitute for data plane)
sense status          # last_tick moving while daemon is up

Then ask the agent for tools. Heartbeat agents should call care_brief (not day_recap). If tools are missing: restart the host session; if tools return offline/empty: fix daemon/sense doctor, not MCP JSON.

Hardening (optional)

Pin absolute binary if PATH is unreliable in the agent environment:

# Grok example — replace with real path from `which sense`
[mcp_servers.roxabi-sense]
command = "/home/YOU/.local/bin/sense"
args = ["mcp"]
enabled = true

Dev-only fallback (not for agent configs)

# contributor smoke — do not paste worktree paths into host MCP configs
uv run --extra mcp --directory /path/to/durable/clone sense mcp

Editable uv tool install -e must point at a durable clone (e.g. ~/projects/roxabi-sense), not a feature worktree. If you delete that worktree, sense breaks with ModuleNotFoundError — reinstall:

cd ~/projects/roxabi-sense   # durable path
uv tool install -e '.[mcp]' --force
sense doctor

Privacy / trust

  • Default MCP redaction is coarse (no window titles / media tracks / full paths). Full detail only via operator config [mcp] detail = "full" — not tool-arg escalation (ADR-002). One bounded exception: care_brief carries agent session titles (e.g. OMP auto-titles) so the heartbeat can map agent work to priorities — never window titles (ADR-002 §6 amendment).

  • Agent spawn trusts the sense binary on PATH. Prefer operator-owned uv tool install over a world-writable clone.

  • Only wire agents you trust with activity metadata.

Thin agent plugin (optional)

Optional DX package under plugins/roxabi-sense/ — wiring only:

Ships

Does not ship

.mcp.json → command: sense, args: [mcp]

Python runtime, collectors, AT-SPI

Skill: when/how to use sense_* tools

Second query layer / private SQL

Plugin README + missing-PATH fallback

systemd unit / daemon start

# Same happy path as host snippets — plugin just packages it:
#   command = "sense"  args = ["mcp"]
# Manual still wins until marketplace publish:
grok mcp add roxabi-sense -- sense mcp
claude mcp add -s user roxabi-sense -- sense mcp

Requires roxabi-sense[mcp] on PATH (package ≥ 0.0.1 with MCP extra) and sense doctor green. Full plugin notes: plugins/roxabi-sense/README.md.

Contributor / in-tree workflow (not for host MCP config):

cd roxabi-sense && uv sync --extra mcp
uv run sense status

No Podman required on the laptop for V1. M₂ may use the same user unit. M₁ host-sensor path (services snapshot only) is a later collector, not a Quadlet of this whole app.


Roadmap (coarse)

Phase

Deliverable

State

0 — scaffold

Public repo, purpose, architecture

done

1 — local spine

Agent-session collector + store + CLI status / day / recap

done

2 — focus + idle

Multi-backend focus probes + idle chain + process/mpris/tmux

done (P0+P1)

3 — MCP

stdio tools over SenseQuery (active_now, timeline, sessions, …)

done

4 — NATS opt-in

factory.event.host.{machine}.activity|stale for Sentinelle

open

5 — optional

Filtered browser history, local status HTTP

open

Focus probes (multi-Linux)

Focus is one collector (kind=focus) with swappable FocusProbe backends. Fact field source is the backend id (atspi | x11 | wlr | kde | noop).

Session

Candidate order (first healthy wins)

Wayland GNOME / Cosmic / unknown

atspi → x11 → noop

Wayland wlroots (Hyprland / Sway)

wlr → atspi → x11 → noop

Wayland KDE

atspi → kde (stub) → x11 → noop

Pure X11

x11 → atspi → noop

  • AT-SPI — long-lived agent (system Python + gi); best on GNOME/Cosmic when a11y works.

  • X11 — xprop / active window (XWayland fallback). Package: x11-utils.

  • wlr — hyprctl activewindow -j or swaymsg -t get_tree when compositor env is set.

  • kde — stub for now (probe() false until KWin D-Bus path lands).

  • Runtime demote — if AT-SPI dies, daemon switches to next healthy probe without blocking other collectors.

  • Meta focus: focus_backend, focus_status, session_type, desktop_family, last_focus_path.

  • Meta idle: idle_backend, idle_status, idle_chain_reason (wayland → logind → noop).

Agent sessions (Grok / Claude / Herdr·OMP / optional Cursor)

Source

Default

Paths (read-only)

Grok

on (agent_sessions)

~/.grok/active_sessions.json

Claude

on (agent_sessions)

~/.claude/sessions/*.json

Herdr / OMP

on (herdr)

live herdr agent list + pane list (cwd, status, session_id, session title without spinner, focused pane; no raw terminal titles, no jsonl)

tmux

on (tmux)

tmux_snapshot panes (grok/claude/omp still match)

Cursor

off (cursor_sessions = true)

~/.config/Cursor/User/workspaceStorage/*/workspace.json

Cursor opt-in emits agent_sessions_snapshot with agent=cursor (workspace id + folder path + mtime only). Never opens chat DBs (state.vscdb), composer history, or rewrites agent dirs.

# ~/.config/roxabi-sense/config.toml
[collectors]
cursor_sessions = true
# cursor_root = "/home/you/.config/Cursor"   # optional override
# cursor_max_workspaces = 20
# cursor_max_age_days = 30

Agent status detail: AGENTS.md § Status.

Out of scope forever (for this repo): OCR, continuous screenshots, keylogging, clipboard dumps, scraping Slack/Discord desktop clients, meeting transcription, cloud upload of agent chat bodies.


Relation to the rest of Roxabi

Project

Relation

roxabi-factory

Future consumer (Sentinelle hub module). Not the home of collectors. ADR-091 factory-host-sensor role lives here as an edge process.

roxabi-cortex

Downstream memory/insight may ingest sense observations later. Sense stays capture + query, not the entity graph.

Claap

Meetings — do not duplicate

~/.claude / ~/.grok / ~/.omp

Read-only sources for agent presence (Herdr live list; never rewrite)


License

AGPL-3.0-or-later (same family as roxabi-cortex).


Status

Phases 1–3 live (collectors, store, CLI, daemon, MCP stdio). Host registration: README § MCP host registration. NATS still open.

Available Tools

5 tools
active_nowB

Current presence, latest focus app, open agent sessions.

Inputs: no named parameters. Returns: object

agent_sessionsC

Claude/Grok sessions seen during a local calendar day.

Inputs: day. Returns: object

day_recapC

Compiled day recap (apps, away, meetings, agents) as JSON.

Inputs: day. Returns: object

sense_statusC

Daemon health, presence, last collect meta.

Inputs: no named parameters. Returns: object

what_was_i_doingB

Timeline for a local calendar day (YYYY-MM-DD); default today.

Returns summarized events (coarse by default). limit caps event count.

Inputs: day, limit. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.2/5.0

    Scored across 5 tools

    Disambiguation4/5

    Most tools have distinct purposes: daemon health, current presence, daily timeline, agent sessions, and day recap. However, what_was_i_doing and day_recap both cover a day's activities, and agent_sessions is a subset of the timeline, creating minor overlap that descriptions help resolve.

    Naming Consistency3/5

    Names are readable and mostly snake_case, but patterns vary: sense_status and agent_sessions are noun_noun, active_now is adjective_noun, what_was_i_doing is a sentence fragment, and day_recap is noun_noun. No consistent verb_noun or clear pattern, though not chaotic.

    Tool Count5/5

    Five tools is well-scoped for a personal sense daemon covering health, presence, timeline, sessions, and recap. Each tool earns its place without redundancy or bloat.

    Completeness4/5

    The surface covers core lifecycle needs: status, current state, historical timeline, specific session data, and a compiled recap. Missing minor capabilities like searching or filtering events, but agents can work around these gaps for typical tasks.

    Maintenance

    ActivityActive
    ResponsivenessMixed handling

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      B
      maintenance
      Provides local-first durable memory and session continuity for AI coding agents over MCP, enabling context across restarts without cloud services or telemetry.
      1
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Provides a local MCP interface to query captured, PII-scrubbed prompt telemetry from coding agents and browser chats, enabling time summaries, prompt search, and activity analysis without data leaving the machine.
      9
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Provides a local AI assistant with tools to query your computer's episodic memory, such as where you were, what you were working on, activity summaries, and timeline details, all sourced from a privacy-filtered SQLite database.
      MIT