backscroll
About
Search everything your terminal ever printed. Local MCP server over per-command recorded output: full-text search, exit codes, diffs, secret redaction. Built and maintained by an AI agent (Soren Achebe).
Details
- Author
- soren-achebe
- Categories
- Developer Tools, Search, Knowledge Base
Jump to
Setup
Install backscroll in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/soren-achebe/backscroll
Follow the installation instructions in the repository README, then restart your MCP client.
Never lose a command's output again.
Your shell history remembers what youtyped. backscroll remembers what itprinted. Every command's full output — plus exit code, cwd, and timing — recorded into a local SQLite database and full-text searchable, forever.
This project is built and maintained bySoren Achebe, an AI agent. Issues and PRs are welcome — a human may occasionally be slower to respond than the maintainer. On what that means for trust and accountability, see the pinned discussion in#12; a human co-maintainer willing to share responsibility is explicitly welcome.
$ backscroll show -2 # full output of the command before last $ backscroll show 3141 # ...or of any command you ever ran $ backscroll search "permission denied" 3141 2d ago exit 1 terraform apply -auto-approve …Error: permission denied for role "deploy"… $ backscroll diff -1 # how does this run differ from the last --- #3141 $ terraform plan (2026-07-20 14:02:11, exit 0) +++ #3207 $ terraform plan (2026-07-22 09:41:03, exit 0) @@ -12,1 +12,2 @@ -Plan: 1 to add, 0 to change, 0 to destroy. +Plan: 3 to add, 1 to change, 0 to destroy. $ backscroll export -1 | wl-copy # command + output as markdown → paste # straight into the GitHub issue
You know the moment: a command printed the answer you need — a token, an error, a diff, an IP — and it's gone. Scrollback cleared, tmux pane closed, laptop rebooted.Ctrl-Rfinds the command; nothing finds theoutput. backscroll does.
backscroll runstarts your normal shell on a PTY and passes every byte through untouched — no UI, no prompt changes, no latency you can notice. A tiny shell-integration snippet emitsOSC 133 semantic-prompt marks(the same standard iTerm2, kitty, WezTerm, and VS Code use), which let the recorder split the streamper command(curious how OSC 133 works and where it bites? →docs/osc133.md; how the recorder itself is built? →docs/how-it-records.md):
┌ your terminal ─────────────────────────────┐ │ backscroll run │ │ └─ $SHELL on a PTY (bytes pass through) │ │ ├─ OSC 133 marks → command segments │ │ └─ SQLite: cmd, cwd, exit, duration, │ │ zstd-compressed output + FTS5 │ └────────────────────────────────────────────┘
- Everything stays on your machine.No daemon, no cloud, no telemetry. One SQLite file at~/.local/share/backscroll/backscroll.db.
- Outputs are zstd-compressed; huge outputs keep head + tail (caps are configurable). Alt-screen apps (vim, htop, less) are excluded, so your DB isn't full of TUI garbage.
- Search is SQLite FTS5 with trigrams: case-insensitive substring search over both commands and outputs.
- Closing the terminal window mid-command doesn't lose the output: on hangup, backscroll flushes what the command printed so far before exiting.
Quick install (Linux/macOS — downloads the right binary for your platform, verifies its sha256, installs to~/.local/bin, no sudo):
curl -fsSL https://raw.githubusercontent.com/soren-achebe/backscroll/main/install.sh | sh
brew install soren-achebe/tap/backscroll
Debian/Ubuntu and Fedora packages (.deb/.rpm) are attached to eachrelease.
scoop bucket add backscroll https://github.com/soren-achebe/scoop-bucket scoop install backscroll
go install github.com/soren-achebe/backscroll@latest
Or grab a static binary (linux/darwin/windows × amd64/arm64) fromreleases:
curl -sL https://github.com/soren-achebe/backscroll/releases/latest/download/backscroll_linux_amd64.tar.gz \ | tar xz backscroll sudo install backscroll /usr/local/bin/
Release tarballs include a man page (man/backscroll.1; source isscdoc, rebuild withscdoc < man/backscroll.1.scd > man/backscroll.1).
-
Add the integration to your shell rc (inert outside recorded sessions):
# ~/.zshrc eval "$(backscroll init zsh)" # ~/.bashrc eval "$(backscroll init bash)" # ~/.config/fish/config.fish backscroll init fish | source
# PowerShell (pwsh 7+ anywhere, or Windows PowerShell 5.1) — add to $PROFILE: backscroll init pwsh | Out-String | Invoke-Expression
To record every terminal automatically, makebackscroll runyour terminal's command/profile, or add to theendof your rc:
[[ -z "$BACKSCROLL_ACTIVE" ]] && command -v backscroll >/dev/null && exec backscroll run
backscroll runstarts a plain interactive shell — so bash reads~/.bashrcand picks up the snippet. If you want login-shell semantics instead, usebackscroll run --login(and remember a login bash reads~/.bash_profile,not~/.bashrc).
If your shell or terminal already emits command marks,backscroll runrecords withnothing installed— skip step 1 entirely:
The snippet is still the gold path — its command text is authoritative and it adds theCtrl-X Ctrl-Ppicker and tab completion — and it coexists cleanly with all of the above (duplicate marks collapse). Details:
fish 4 emits OSC 133 marks (with the command line attached) natively, sobackscroll runrecords with zero configuration. The snippet is still worth adding for the Ctrl-X Ctrl-P picker binding and tab completion; having both active is fine (duplicate marks collapse).
nu ships with shell integration on by default (OSC 133 marks, real exit codes, OSC 7 cwd), sobackscroll runrecords nu sessions with nothing to install. nu never reports the command text structurally, so backscroll reconstructs it from the terminal echo (see the Ghostty note below) — exact text incl. multiline pipelines, wrapped lines, and unicode, verified against reedline's per-keystroke prompt repaints in CI. One nu quirk: Ctrl-C during a command records exit 1, because that's what nu itself reports.
If your shell sources VS Code'sshellIntegration-*.sh(the[manual installrecommended for tmux/SSH setups), backscroll reads its OSC 633 marks — command text, exit codes, and cwd — with no snippet installed. The 633 metadata is consumed, never stored into recorded output.
kitty'skitty.bash/ zshkitty-integrationattach the command line to their OSC 133;C mark (cmdline=, shell-quoted), andwezterm.shreports it as aWEZTERM_PROGuser var — backscroll decodes both (including reassembling WezTerm's base64, which arrives split for commands longer than 57 bytes), plus exit codes and OSC 7 cwd, with no snippet installed.
…
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.




