A terminal manager for your Claude Code conversation history.
ccmanager reads the .jsonl transcripts Claude Code writes under
~/.claude/projects/ and gives you a fast TUI to search, view,
star, rename, delete, export, and resume them. It
also ships a local web UI with the same data, and an MCP stdio
server so Claude Code itself can search its own history when you ask
it to.
Everything is local. No network calls, no account, no telemetry.
curl -fsSL https://raw.githubusercontent.com/NormalUhr/ccmanager/main/scripts/install.sh | bash && exec $SHELLIf ccmanager isn't found afterward, just restart your shell.
Update with:
ccmanager updatePrefer to build from source, or install on an air-gapped machine? See Other install methods below.
ccmanager # browse all conversations
ccmanager -L # only conversations from the current project
ccmanager serve --open # local web UI on http://127.0.0.1:7878In the TUI, type to fuzzy-search. enter opens the viewer; ctrl+r
resumes a session in a new terminal tab; ? shows all keybindings.
Find a past session. Just type. Search matches project name, session title, custom alias, and conversation text — all at once.
Show only this project's sessions. ccmanager -L from the project
directory, or hit tab inside the TUI to toggle.
Star a session so you can find it later. Hover the row in the
list (or open it in the viewer) and press f2. Press f2 again to
unstar. A ★ shows up in the leftmost column.
Show only starred sessions. f3. Press again to clear. Stacks
with the project filter and the search query.
Give a session a memorable alias. Focus it, press r, type a
name. The alias shows in the list header and is fuzzy-searchable.
Open and read a session. enter. Scroll with ↑ ↓ or j k.
Skim just my questions (skip Claude's answers). In the viewer,
press shift+q.
Search inside an open session. / then type. n / shift+n
jump to the next / previous match.
Resume a session in a new terminal tab. ctrl+r. Use alt+r if
you want the standard tool-permission prompts instead of the
skip-permissions default.
Fork off a session instead of resuming. ctrl+f — creates a new
session ID branched from the same starting point.
Copy one message. In the viewer, jump to it with shift+j /
shift+k, then press y.
Export the whole dialogue. e, then pick a format: Ledger /
Plain / Markdown / JSONL. Tool calls and thinking blocks are filtered
out of the readable formats.
Refresh to pick up a message Claude Code just wrote in another
tab. f5. Your search query, filter, and selection are preserved.
Delete a session. Focus it, ctrl+x, confirm.
The full table is in the ? overlay. Uppercase letters always mean
"hold shift" — lowercase never does.
| Key | What it does |
|---|---|
| (just type) | Fuzzy-search across all conversations |
↑ ↓ / j k |
Move selection (list) / scroll (viewer) |
enter |
Open viewer |
tab |
Toggle all-projects ↔ current-project filter |
f2 |
Star / unstar the focused (or open) session |
f3 |
Toggle starred-only filter |
f5 |
Reload list + viewer from disk |
ctrl+r / alt+r |
Resume in a new tab (fast / with permission prompts) |
ctrl+f / alt+f |
Fork — branch a new session ID |
r |
Rename — set a custom alias |
ctrl+x |
Delete (with confirm) |
e |
Copy whole conversation (format menu) |
y |
Copy focused message (after shift+j / shift+k), or open format menu |
shift+y / shift+i / p |
Copy file path / copy session ID / show path |
t / shift+t / i |
Tool display (off / truncated / full) / thinking / timestamps |
shift+q |
Questions-only view (hide Claude's answers) |
/ then type |
In-viewer search; auto-jumps to first match |
enter (after /) |
Confirm search; switch to nav mode |
n / shift+n |
Next / previous match |
shift+j / shift+k / [ / ] |
Jump between messages |
? |
Help overlay |
q / esc |
Back / quit |
ctrl+r opens a new tab in your current terminal window running
claude --resume <id>, switches focus to it, and leaves the
ccmanager TUI running in the original tab (returning to the list).
- macOS Terminal.app: Cmd+T is synthesized via AppleScript + System
Events. macOS will prompt for Accessibility permission on
osascriptthe first time — grant it once. - macOS iTerm: native
create tabAPI, no Accessibility prompt. - Linux:
gnome-terminal --taborkonsole --new-tabif present; other emulators (xterm, alacritty, kitty, wezterm, foot) fall back to opening a new window.
cd and claude are typed to the new tab as two separate lines
with a small delay between them, so shell hooks like direnv / nvm /
asdf / mise get a prompt redraw to fire and update PATH before
claude runs. This is what makes a project-local claude reachable
even when ccmanager was launched from outside the project folder.
By default the resume passes --dangerously-skip-permissions (Claude
won't re-ask about every tool, which matches the common case of
continuing work you'd already approved). Use alt+r for the standard
permission flow, or set [resume].skip_permissions = false in the
config to flip the default.
ctrl+f forks instead — creates a new session ID that branches from
the original transcript. When the conversation's original project
directory no longer exists or you fork cross-project, the session
files are first copied into your CWD's project directory so
Claude Code can find them there.
The CLI flag ccmanager --resume is different from the TUI key: it
replaces the current process with claude --resume <id> via
execvp, which is what shell scripts and aliases want.
Keep a ccmanager window open while a separate Claude Code session
keeps appending turns to disk. Hit f5 and ccmanager re-scans
~/.claude/projects/ and re-renders the active viewer in place. No
quit-and-relaunch.
Preserved across refresh: the search query, the workspace filter
(tab), the view-mode toggles (t / shift+t / i / shift+q),
and the selected-or-open conversation (re-selected by file path, with
a sensible fallback if the file is gone).
All export operations land on the system clipboard — no files are
written to your cwd. Paste with Cmd+V / Ctrl+V.
| Key | What it copies |
|---|---|
e |
Whole conversation. Opens a format menu: Ledger (formatted, speaker-prefixed), Plain (You: / Claude: lines), Markdown (## You / ## Claude), or JSONL (raw). For the three readable formats, tool calls / thinking / intermediate narration are filtered out so what you paste is just the dialogue. |
y |
In message-nav mode (after shift+j / shift+k): the focused message as raw markdown. Otherwise: opens the same format menu as e. |
shift+y |
The conversation file's full path on disk. |
shift+i |
The session UUID. |
p |
Prints the file path into the status bar (no copy). |
For a file instead of the clipboard, pipe ccmanager --plain to one:
ccmanager --plain > conversation.txt # pick from the TUI
ccmanager --render <file.jsonl> > out.txt # render a specific fileccmanager serve --openSame data, in a browser. Defaults to 127.0.0.1:7878. Non-local
binds (--host 0.0.0.0) require --token <T> for auth, so you
can't accidentally expose your history.
Supports live fuzzy search, viewer with syntax highlighting,
collapsible tool blocks, rename, delete (or --read-only), export
downloads (Markdown / plain / ledger / JSONL), and keyboard
navigation. Search state persists across back-navigation so you can
click a row, hit back, and the filtered list is restored from the URL.
ccmanager mcp runs as a Model Context Protocol stdio server
so Claude Code can search and read your past conversations when you
ask it to. Register it once in ~/.claude.json:
Restart Claude Code. It exposes three read-only tools:
search_history(query, limit?, project?)— fuzzy-search past conversations. Returns JSON withsession_id, title, project, age, message count, and a short snippet per match.get_session(session_id, max_chars?)— fetch one conversation as a markdown transcript. Dialogue-only by default, truncated tomax_chars(default 50k).list_recent_sessions(limit?, project?)— recent-first list, same JSON shape as search.
Claude won't call these on its own — you drive it. Try "check history for our caching discussion" or "open the rename conversation from last week."
Optional. Create ~/.config/ccmanager/config.toml with any subset of:
[display]
# show_thinking = true # show <thinking> blocks in the viewer
# no_tools = false # show tool calls in full (default: hidden)
# plain = false # plain-text output (no ledger formatting)
# pager = true # pipe output through `less -R` when stdout is a TTY
# last = true # preview the *last* messages in the list (vs first)
[resume]
# default_args = ["--dangerously-skip-permissions"]
# skip_permissions = true # ctrl+r uses --dangerously-skip-permissions
[keys]
# resume = "ctrl+r" # primary resume binding
# fork = "ctrl+f" # primary fork-resume binding
# delete = "ctrl+x" # delete binding
# resume_alt = "alt+r" # alt binding — inverts skip_permissions
# fork_alt = "alt+f"CLI flags override the config. CLAUDE_CONFIG_DIR is respected if you
keep Claude's data in a non-default location.
For the full flag list: ccmanager --help.
git clone https://github.com/NormalUhr/ccmanager.git
cd ccmanager
cargo install --path . --lockedThis drops a ccmanager binary at ~/.cargo/bin/. On Linux you also
need the X11 clipboard headers arboard links against —
libxcb-shape0-dev libxcb-render0-dev libxcb-xfixes0-dev on
Debian/Ubuntu, libxcb-devel on Fedora/RHEL.
Vendor every Cargo dependency once on a machine that has internet, then build offline on the server.
On the internet-connected machine:
cd ccmanager
cargo vendor --locked > .cargo/config.toml
cd .. && tar --exclude='ccmanager/target' --exclude='ccmanager/.git' \
-czf ccmanager-offline.tar.gz ccmanagerTransfer ccmanager-offline.tar.gz to the server (scp / USB / internal
mirror). Then on the server (with rustc ≥ 1.85 and the clipboard libs
above):
tar -xzf ccmanager-offline.tar.gz
cd ccmanager
cargo build --release --offline --locked
install -m 755 target/release/ccmanager ~/.local/bin/ccmanagerIf the server has no Rust toolchain either, also ship the matching
rust-<version>-<triple>.tar.gz from https://static.rust-lang.org/dist/
and run its ./install.sh --prefix="$HOME/.local" first.
| Version | Released | Highlights |
|---|---|---|
| 1.1.1 | 2026-05-23 13:04 PDT | New warm Claude-orange palette across TUI + web UI; lifted gray-text contrast in both light and dark modes. |
| 1.1.0 | 2026-05-23 11:43 PDT | Star / favorite sessions (f2) and starred-only filter (f3); persisted as JSONL markers. |
| 1.0.0 | 2026-05-22 18:03 PDT | First public release. TUI + web UI + MCP server; rename, delete, export, resume, fork. |
Full notes per release: CHANGELOG.md.
See CONTRIBUTING.md. Short version:
cargo build
cargo test
just check # fmt + clippy + build
just install-dev # symlink target/debug/ccmanager into ~/.cargo/bin/Open an issue with the bug or feature template, or start a thread in Discussions for open-ended ideas.
MIT — see LICENSE.
{ "mcpServers": { "ccmanager": { "command": "ccmanager", "args": ["mcp"] } } }