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).
Explore
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.



