Let your AI agent read your terminal history¶
backscroll ships a built-in Model Context Protocol
server: backscroll mcp. It's a zero-dependency stdio server compiled into
the same binary you already installed — no npm, no Python, no sidecar.
Why you'd want this: coding agents constantly need to know what a command actually printed. Without it they guess, or worse, re-run things — and "just re-run it" is exactly wrong for the interesting cases: the flaky test, the 40-minute build, the migration you only get to run once, the deploy that failed last night. With backscroll recording your shells, the agent can query ground truth instead:
- "Why did the deploy fail last night?" →
search_output "deploy"with failures-only filter, then read the real error. - "Did the output of
make testchange since it last passed?" →diff_outputagainst the previous run of the same command. - "What warnings did that 40-minute build print?" →
get_outputon a command that finished hours ago, scrollback long gone.
The tools¶
| Tool | What it does |
|---|---|
search_output |
Full-text search over commands, outputs, and notes; grep -C-style context via context_lines |
list_commands |
Browse recent history with the same filters as the CLI (exit=fail, since, cwd, …) |
get_output |
Full recorded output of any command (-1 = your last one), with metadata |
diff_output |
Unified diff between two runs — by default vs. the previous run of the same command line |
All four are read-only — the server never executes anything, it only
reads the local SQLite database. Every tool declares MCP annotations
(readOnlyHint, idempotentHint) so clients can skip confirmation
prompts safely.
Secrets are masked by default. Everything handed to the client passes
through the same redaction patterns as backscroll redact (built-in
token-format patterns plus your ~/.config/backscroll/redact), on top of
the ignore patterns that keep matching commands out of the database
entirely. --no-redact opts out. Nothing leaves the machine except what
your client asks for over stdio.
Setup¶
First make sure backscroll is actually recording your shells — the server is only as useful as the history behind it. Then register it with your client. One gotcha up front:
GUI apps may not see your PATH
Desktop clients (Claude Desktop, Cursor, Windsurf, Zed) are often
launched without your shell's PATH. If the server fails to start,
replace "backscroll" with the absolute path — ~/.local/bin/backscroll
for the script install, /opt/homebrew/bin/backscroll for Homebrew
(command -v backscroll tells you).
Claude Code¶
Codex CLI¶
or in ~/.codex/config.toml:
Claude Desktop¶
Grab the backscroll-<version>.mcpb bundle from the
latest release
and open it with Claude Desktop (Settings → Extensions) — it carries the
binaries for macOS and Linux. Or configure it manually in
claude_desktop_config.json:
Cursor¶
~/.cursor/mcp.json (or .cursor/mcp.json in a project):
Windsurf¶
~/.codeium/windsurf/mcp_config.json:
VS Code (Copilot agent mode)¶
or .vscode/mcp.json:
VS Code's own shell integration is a nice pairing here: backscroll records its OSC 633 marks with no snippet at all, so terminals inside VS Code are covered automatically.
Zed¶
In settings.json:
{
"context_servers": {
"backscroll": {
"source": "custom",
"command": "backscroll",
"args": ["mcp"]
}
}
}
Gemini CLI¶
~/.gemini/settings.json:
Anything else¶
Any MCP client that can spawn a stdio server just needs
backscroll mcp as the command. backscroll is listed in the
official MCP Registry
as io.github.soren-achebe/backscroll. For containerized setups there's a
prebuilt multi-arch image (linux/amd64 + linux/arm64):
docker run -i --rm \
-v ~/.local/share/backscroll:/data/.local/share/backscroll:ro \
ghcr.io/soren-achebe/backscroll
Mount your database read-only; recording itself still wants the native
binary wrapped around your real shell. The image is built from the repo's
Dockerfile
and defaults to backscroll mcp.
Try it without a client¶
The MCP inspector exercises the server directly:
$ npx @modelcontextprotocol/inspector --cli backscroll mcp \
--method tools/call --tool-name list_commands \
--tool-arg exit=fail --tool-arg since=1d
{
"content": [
{
"type": "text",
"text": "1 command(s), most recent first:\n\nid 312 · 2026-07-28 10:41:50 · cwd /tmp · exit 1 · took 5ms · 36B\n$ ./deploy.sh staging\n\nUse get_output with an id to read a full output."
}
]
}
If it errors, run backscroll doctor — the usual cause is an empty
database because no shell is being recorded yet (doctor will also offer
to import your existing shell history
so the agent has something to search on day one).
Design notes¶
- Never re-executes. The server has no tool that runs commands, by design. Pair it with whatever execution tool your agent already has; use backscroll for what already happened.
- Redact-before-serve ordering is pinned by tests: FTS match highlighting happens after redaction, so a highlight span can never split a secret past the redaction patterns.
- Output caps:
get_outputtruncates head+tail around a gap marker at a configurablemax_bytes, so one giant build log can't blow the agent's context window;search_outputwithcontext_linesoften avoids the full fetch entirely.
The server-side implementation is ~one file of dep-free JSON-RPC; the interesting recording machinery it sits on is covered in Anatomy of a PTY recorder.