Skip to main content

ctools

ctools


Try it now
uvx --from ctxttools cdir
uvx --from ctxttools ctools-web

Then install it
uv tool install ctxttools


ctools is a suite of simple tools for navigating through the sessions of the most popular LLM agents and coding tools. It allows you to search your history, transfer conversations, filter them, and even share them among machines and users.

It supports Claude Desktop, Claude Code, Codex, Pi, Hermes, Goose, Kilo, FreeBuff, Cline, omp, and OpenClaw.

You can use it from the terminal, from a small web dashboard, or from any AI coding agent (via an MCP server).

Here's an example:

I look for mentions of snake game in opencode using cgrep

$ cgrep "snake game" opencode
opencode/ses_a1d1a5a4df984ee698cab4a7:1:user: make a simple snake game in python
opencode/ses_a1d1a5a4df984ee698cab4a7:2:assistant: I'll make a terminal-based snake game using `curses` (standard library, no dependencies).
opencode/ses_a1d1a5a4df984ee698cab4a7:3:assistant: Done — `snake.py` is a terminal snake game using Python's built-in `curses` module (no dependencies).

cool let's look at the status of that session using cdir

$ cdir -l opencode/ses_a1d1a5a4df984ee698cab4a7
  ID                            NAME                                MODIFIED            SIZE  MSGS  PATH
  ses_a1d1a5a4df984ee698cab4a7  make a simple snake game in python  2026-10-07 16:56  2.7 KB     3  /home/chris/.local/share/opencode

  1 session(s)

Alright let's copy that session from opencode into pi!

$ ccopy opencode/ses_a1d1a5a4df984ee698cab4a7 pi
Copied 3 message(s) from opencode/ses_a1d1a5a4df984ee698cab4a7 to a new pi session: e357f435-f813-463a-b313-f97f1051f3cb
Resume it with:
  pi --session e357f435-f813-463a-b313-f97f1051f3cb

As you can see, these are unix-friendly tools using simple paradigms that you are already familiar with.

What it can do

Capability What you get
Discover See every agent installed on your machine and how many sessions each holds.
Find Search every session at once with grep-style regex, narrowed by agent, session glob, or role.
Read Print a conversation as JSON (pipe it anywhere) or as a readable transcript.
Continue Get the exact command to resume a session in its own tool, or open it in the web UI.
Copy Copy a conversation into a new session in another tool, or the same tool on another machine.
Measure See token usage per agent, per session, and per role.
Concepts Pull out the intent of a session: its goal, its constraints, and what was decided.
Recover List and restore the storage backups ctools takes before every local write.

A quick tour

The overview: every tool ctools can see, with session counts and token totals, plus quick links into the most common actions:

Overview

Sessions: browse every conversation from any tool, sorted by recency. Click one to open it.

Sessions

A conversation: the full message stream, with the original tool's resume command and copy-to-another-tool options.

Conversation

Search: type a phrase and see every matching message across all tools.

Search

Concepts: ask a session what it's about. ctools extracts the intent, constraints, and decisions so you can pick up where you left off without re-reading everything.

Concepts


Install

Python 3.10+ is required.

uv tool install ctxttools        # or: pip install ctxttools

That gives you the ctools command, a short command for each of its verbs, and the dashboard and MCP server:

Command Purpose
ctools The front door: ctools <verb> [args...]. Run ctools --help for the list.
cdir, cgrep, ccat, cdu, ccopy, cextract, cconnect, crm, crecover Shortcuts for the verbs (cgrep is ctools grep).
ctools-web The dashboard, same as ctools web.
ctools-mcp The MCP server, same as ctools mcp. Needs the mcp extra.

The MCP server's dependency is optional:

uv tool install "ctxttools[mcp]"   # or: pip install "ctxttools[mcp]"

From a local checkout, uv keeps it editable:

uv tool install --editable ".[mcp]"

Heads up: ctools-mcp needs mcp<2 (see mcp dependency below).


The CLI

ctools has one verb per job. Each verb is also installed as its own short command, named c plus the verb, so ctools grep and cgrep are the same program with the same flags. Use whichever you prefer: the long form is easier to discover, and the short form is quicker to type.

$ ctools --help
usage: ctools <command> [args...]

query:
  dir       list agents and sessions           (cdir)
  grep      search session content             (cgrep)
  cat       print a session                    (ccat)
  du        context usage per session          (cdu)

transform:
  copy      copy a session to another agent    (ccopy)
  extract   extract concepts from a session    (cextract)
  connect   pipe concepts between sessions     (cconnect)
  rm        cut sections out of a session      (crm)
  recover   restore from a backup              (crecover)

long-running:
  web       run the web dashboard              (ctools-web)
  mcp       run the MCP server                 (ctools-mcp)

Run 'ctools <command> --help' for a command's options.

Each verb has its own page in docs/: dir, grep, cat, du, copy, extract, connect, rm, and recover. Sessions are addressed as agent/session_id throughout.

Discover your agents and sessions

ctools dir                      # every known agent, and whether it's installed
ctools dir opencode             # that agent's sessions, and the command that resumes one
ctools dir -l opencode          # with modified time, size, message count, path
ctools dir .                    # sessions that ran in this directory, across all agents
ctools dir opencode/ses_abc     # one session's row

Find a session

grep works the way grep does, over conversation content instead of files.

ctools grep "bug report"                    # every installed agent
ctools grep -i "deploy" claude-code         # one agent
ctools grep -C 2 "flaky test" opencode      # with context
ctools grep -l "parser" pi                  # just the session ids
ctools grep --user "refactor"               # only what you typed
ctools grep --hosts "mcp config"            # also the hosts in ctools.toml

Read a session

ctools cat opencode/ses_abc           # JSON list of {role, content}
ctools cat --text opencode/ses_abc    # a readable transcript
ctools cat ssh://me@box/pi/<id>       # a session on another machine

Copy a session to another tool

copy creates a new session in the destination. The source is never touched, and ctools prints the command that resumes the copy.

ctools copy opencode/ses_abc claude-code          # into another tool
ctools copy opencode/ses_abc codex --dry-run      # preview first
ctools copy opencode/ses_abc ssh://me@box/codex   # into a tool on another machine
ctools copy opencode/ses_abc ssh://me@box/        # into opencode on that machine
ctools copy ssh://me@box/pi/<id> claude-code      # pull one in from another machine

The remote side doesn't need ctools installed; plain ssh and tar will do. See docs/ccopy.md for how that works and where the new session lands.

Token usage

ctools du                     # total across all agents
ctools du opencode            # sessions by token count
ctools du opencode/ses_abc    # breakdown by role

The web dashboard

ctools web                    # opens at http://127.0.0.1:8765
ctools web --port 9000        # a different port

ctools-web is the same command. The dashboard is a read-mostly surface over the same data the CLI uses. You can:

  • Browse and search sessions (the "Conversation" view mirrors the CLI).
  • Copy a session to another tool right from the UI.
  • Export/download a session.
  • Run concept extraction on a session (with optional LLM-backed strategies and filters).

It binds to 127.0.0.1 only by default, so it's not exposed to your network. Use --host to change that deliberately.


Concepts: extract the intent of a session

A raw session is thousands of tokens. Concepts distills it into the few things that matter for picking it back up: the goal, the constraints, and what was decided.

ctools extract @<agent>/<session-id>      # or: cextract @<agent>/<session-id>

Concepts are extracted one of three ways. Regex is the default; -s and -F select the others:

  1. Regex (default): built-in patterns for goal, decision, constraint, and preference. No setup.
  2. LLM strategy: you define a chunking strategy that an LLM applies to the session. Best for richer, contextual extraction.
  3. Filter: narrow the regex/LLM output with a rule (drop boilerplate, keep only certain types, etc.).

Strategies and filters are stored as JSON config files that ctools reads at runtime, in the config dir (see below). Create them in the dashboard (the Concepts tab) or by hand.

Where ctools keeps its config. Config and data live in a per-user directory resolved via platformdirs (no hand-rolled platform checks):

  • Linux: ~/.config/ctools/ (config), ~/.local/share/ctools/ (data)
  • macOS: ~/Library/Application Support/ctools/ (the macOS convention)
  • Windows: %APPDATA%\ctools\ (config), %LOCALAPPDATA%\ctools\ (data)

Set $CTOOLS_CONFIG (and $CTOOLS_DATA) to relocate. This holds resume-commands.json, strategies/, filters/, and the general ctools.toml config — one file, multiple sections. The first section, [hosts], lists the machines ctools grep --hosts searches too:

# ~/.config/ctools/ctools.toml
[hosts]
fatty  = "ssh://bobby@fatty.local"
workie = "ssh://10.0.0.4"

Each value is an ssh://[user@]host[:port] reference (the same form ccat and ccopy use for a remote side), so the host may be a ~/.ssh/config alias. A missing/malformed config never breaks a search — it just means "local only".

The dashboard shows the full extraction pipeline (conversation → extraction → filter → concepts) so you can see exactly what was kept and why.


MCP server

The MCP server exposes the same capabilities to any MCP-capable coding agent (Pi, Claude, OpenCode, etc.). It needs the mcp extra (see Install).

ctools mcp          # run the server on stdio (same as ctools-mcp)

Install and register with Pi

ctools-mcp install

If no working ctxttools[mcp] install is found, this installs one with uv tool. It then registers the server in ~/.pi/agent/mcp.json. Verify with:

pi mcp list        # "ctools-mcp … connected"

ctools-mcp uninstall removes the entry again (--all also removes it from Claude Code's and opencode's configs).

Manual registration (any host)

If you'd rather wire it up yourself, print-config emits the mcpServers JSON snippet:

ctools-mcp print-config

Add that to your host's MCP config. The server is started with python -m ctools.ctools_mcp from the install environment.

Tools exposed

Tool What it does
list_agents Agents available and whether they're installed.
list_sessions Recent sessions for one agent.
search_sessions Find sessions by pattern or phrase.
export_session Get the messages of a session.
extract_concepts Extract concepts from a session.
get_session_concepts Get a session's concepts, optionally of one type.
copy_concepts Copy extracted concepts into a destination session.

MCP dependency

ctools-mcp pins mcp>=1.2,<2.0. The mcp package 2.x renamed FastMCP to MCPServer, which breaks the v1 API ctools uses. If a fresh install pulls mcp>=2 and ctools-mcp won't start, pin the major version (pip install "mcp<2"); the released package already does this.


The agents ctools knows about

Name Tool Storage
claude Claude Desktop JSON
claude-code Claude Code CLI JSONL
codex OpenAI Codex CLI JSONL
pi Pi coding agent JSONL
omp omp (oh-my-pi) JSONL
opencode OpenCode CLI SQLite
kilo Kilo CLI SQLite
goose Goose AI agent SQLite
hermes Hermes agent SQLite
openclaw OpenClaw SQLite
cline Cline JSON
freebuff Freebuff JSON

An agent is "installed" if ctools can find its session directory (or DB file); ctools dir shows which are found and where. Only claude-code, opencode, kilo, codex, and pi can be a copy destination.


How the data is handled

  • Read-only by default. dir, grep, cat, du, the MCP read tools, and the dashboard's read paths never modify your session files.
  • Writes are explicit. copy writes a new session and never touches the source. extract and connect write only when you name a session as the destination, and rm only to the session you name.
  • Backed up first. Before a local copy writes, it snapshots the destination agent's storage and restores it automatically if the write goes wrong. ctools recover lists and restores those snapshots.
  • Local unless you say otherwise. The dashboard binds to 127.0.0.1, and the MCP server reads your local storage. Data only crosses the network when you name an ssh:// host or pass grep --hosts, and then only over your own ssh.

Development

git clone https://github.com/day50-dev/ctools
cd ctools
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
python -m pytest

The code is deliberately simple: each agent adapter is a class in ctools/agents.py, each verb is one module (ctools/cgrep.py, …), and ctools/dispatch.py routes ctools <verb> to them. The CLI, dashboard, and MCP layers are thin over the shared ctools.agents registry.


License

MIT

Metadata

Release files for ctxttools 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ctxttools 0.4.0
File Size Uploaded Provenance
ctxttools-0.4.0.tar.gz 159.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ctxttools 0.4.0
File Interpreter ABI Platform
ctxttools-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 327.0 kB

Release files / ctxttools-0.4.0.tar.gz

Download URL ctxttools-0.4.0.tar.gz
Size 159.9 kB
Tags Source
SHA-256 checksum
How to use checksums
956cfc5f1ea7a58f3f9b41a15b03fa573ca4f7597dd73f3cfaa9dbd55d302995
BLAKE2b-256 checksum
How to use checksums
654b2c32310eb51f26673d4de0403be8ec15b78d16a836dfd5e10d52a972c516
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.15

Release files / ctxttools-0.4.0-py3-none-any.whl

Download URL ctxttools-0.4.0-py3-none-any.whl
Size 167.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2eab24af2e755a9c0b7a58671c5a110303db3b80709c699efdd4df3409f1c26f
BLAKE2b-256 checksum
How to use checksums
fa08b88a8edb2272cc6968dbc8dfc1aaeae0b5f634f2f9cd64fd9e3fcbdfb2d4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.15

Security for ctxttools 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page