What Input Tracking records
When enabled, time.md installs a local macOS event tap while the app is running. It batches allowed keyboard and cursor events into a separate SQLite database and builds aggregates for the Input screen.
Keystrokes
Configurable from no capture to timestamps, key codes, or actual characters.
Cursor
Configurable from no capture to movement heatmap, clicks, or a full move/drag/click/scroll trail.
Aggregates
Builds typed-word counts, key-frequency counts, typing intensity, and 32-pixel cursor heatmap bins.
Input data is stored separately from the main screen-time database at ~/Library/Application Support/time.md/input-tracking.db.
Enable and grant permissions
-
Turn on the master switch
Open Settings → Input Tracking and enable the feature. The app initializes safe default streams if both levels were off.
-
Grant Input Monitoring
macOS registers time.md in System Settings → Privacy & Security → Input Monitoring. Approve it, then restart the app if macOS asks.
-
Choose stream levels
Select the least detailed keystroke and cursor levels that power the views you need.
Some macOS flows may also request Accessibility permission for global observation. If events do not appear, re-check the privacy pane and relaunch time.md.
Tracking levels
Keystrokes
| Level | Stored | Powers | Privacy note |
|---|---|---|---|
| Off | No keystrokes. | Nothing keyboard-related. | Safest choice if you only want cursor data. |
| Activity only | Timestamps only; no key codes and no characters. | Typing intensity and per-app activity counts. | Does not store what key was pressed. |
| Per-key counts | Timestamps, virtual key codes, and modifier flags. | Intensity plus most-pressed keys. | No characters or message content are stored. |
| Full content | Timestamps, key codes, modifiers, and actual characters when available. | Top typed words, raw character queries, and all lower-level views. | High privacy cost. The app shows a destructive-style confirmation before enabling it. |
Cursor
| Level | Stored | Powers |
|---|---|---|
| Off | No cursor events. | No cursor views. |
| Heatmap only | Movement and drag positions, roughly 30 events per second while active. | Cursor Heatmap. |
| Heatmap + clicks | Movement, drags, and click locations. | Heatmap plus click overlays. |
| Full event trail | Move, drag, click, and scroll events. | Detailed raw cursor analysis and local queries. |
Privacy safeguards
- Secure Input: when macOS Secure Input is active, time.md drops typed characters and marks the row with
secure_input=1. - Excluded apps: default exclusions include 1Password, Bitwarden, Dashlane, LastPass, and Keychain Access. Events in excluded apps are dropped entirely.
- Pause hotkey: press Option-Command-P to pause all input capture for 30 minutes. Settings also offers Pause Now and Resume Now.
- Content gate: full content is a separate explicit level so timestamps or key-count analytics do not silently start storing characters.
- Word filtering: typed-word aggregation rejects long blobs, mixed digits/symbols, hex-like values, and high-entropy strings that look like tokens.
Input Tracking views
Cursor Heatmap
Shows 32-pixel movement-density bins per screen, with click locations when click capture is enabled.
Top Typed
Switch between Words and Keys. Words require Full content; keys require Per-key counts or higher.
Intensity
Shows typing counts over time. Day-scale ranges use minute granularity; wider ranges use hourly buckets.
Views respect the global date range and can filter by bundle/app where the underlying query supports it.
Retention
The pruner runs at app launch and every six hours. The default raw-event retention is 14 days for keystrokes. Raw mouse events use half that retention because they grow faster, so the default mouse retention is 7 days. The slider supports 1–30 days.
| Data | Default retention | Notes |
|---|---|---|
keystroke_events |
14 days | Controlled by the raw-event retention setting. |
mouse_events |
7 days | Uses half the configured retention window, minimum 1 day. |
typed_words |
Kept indefinitely | Aggregate counts power the Top Typed Words view. |
cursor_heatmap_bins |
Kept indefinitely | Aggregate bins power the Cursor Heatmap view. |
Retention pruning removes old raw events, then periodically vacuums the database. Aggregates remain until you use the destructive delete action.
Delete input data
Use Settings → Input Tracking → Delete all input data to remove every row from:
keystroke_events
mouse_events
typed_words
cursor_heatmap_bins
input_tracking_meta
The delete action runs a local SQLite transaction and then vacuums the database. It cannot be undone.
You can also quit time.md and remove the database files manually:
~/Library/Application Support/time.md/input-tracking.db
~/Library/Application Support/time.md/input-tracking.db-wal
~/Library/Application Support/time.md/input-tracking.db-shm
Exports, CLI, and MCP
Input Tracking data stays local, but you can expose it to local tools if you choose:
- Export sections can include top words, top keys, cursor heatmap bins, typing intensity, and capped raw keystroke or mouse rows.
- The formatted auto export excludes raw input sections as a safety guardrail.
- MCP and CLI database tools read local SQLite data. Agents connected through MCP can see whatever rows the selected tool returns.
- Share input exports only after reviewing them, especially if Full content was enabled.