ctxttools 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ctxttools-0.4.0/PKG-INFO +434 -0
- ctxttools-0.4.0/README.md +416 -0
- ctxttools-0.4.0/ctools/__main__.py +4 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/agents.py +364 -35
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/backup.py +10 -7
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/ccat.py +2 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/ccopy.py +56 -14
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/cdir.py +444 -78
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/cdu.py +45 -8
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/cextract.py +74 -5
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/cgrep.py +126 -4
- ctxttools-0.4.0/ctools/config.py +127 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/crecover.py +3 -3
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/crm.py +134 -4
- ctxttools-0.4.0/ctools/ctools-web.py +30 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/ctools_mcp.py +162 -0
- ctxttools-0.4.0/ctools/dispatch.py +95 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/filterlib.py +33 -1
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/lib.py +47 -0
- ctxttools-0.4.0/ctools/paths.py +51 -0
- ctxttools-0.4.0/ctools/remote_search.py +97 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/strategy.py +22 -3
- ctxttools-0.4.0/ctools/webui.py +3633 -0
- ctxttools-0.4.0/ctxttools.egg-info/PKG-INFO +434 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctxttools.egg-info/SOURCES.txt +6 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctxttools.egg-info/entry_points.txt +1 -0
- ctxttools-0.4.0/ctxttools.egg-info/requires.txt +13 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/pyproject.toml +5 -2
- ctxttools-0.3.0/PKG-INFO +0 -257
- ctxttools-0.3.0/README.md +0 -241
- ctxttools-0.3.0/ctools/webui.py +0 -1811
- ctxttools-0.3.0/ctxttools.egg-info/PKG-INFO +0 -257
- ctxttools-0.3.0/ctxttools.egg-info/requires.txt +0 -9
- {ctxttools-0.3.0 → ctxttools-0.4.0}/LICENSE.MIT +0 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/__init__.py +0 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/cconnect.py +0 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/cli.py +0 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/log.py +0 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctools/testing.py +0 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctxttools.egg-info/dependency_links.txt +0 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/ctxttools.egg-info/top_level.txt +0 -0
- {ctxttools-0.3.0 → ctxttools-0.4.0}/setup.cfg +0 -0
ctxttools-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ctxttools
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: CLI tools for LLM conversations
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE.MIT
|
|
8
|
+
Requires-Dist: rich>=13.0.0
|
|
9
|
+
Requires-Dist: tiktoken>=0.5.0
|
|
10
|
+
Requires-Dist: structlog>=24.0
|
|
11
|
+
Requires-Dist: platformdirs>=3.0.0
|
|
12
|
+
Requires-Dist: tomli>=2.0.0; python_version < "3.11"
|
|
13
|
+
Provides-Extra: mcp
|
|
14
|
+
Requires-Dist: mcp<2.0,>=1.2.0; extra == "mcp"
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
|
|
19
|
+
# ctools
|
|
20
|
+
|
|
21
|
+
<p align="center">
|
|
22
|
+
<img width="500" alt="ctools" src="https://github.com/user-attachments/assets/ee781bbe-6364-44ed-be2d-72114f1e6d8a" /><br/>
|
|
23
|
+
<a href=https://pypi.org/project/ctxttools><img src=https://badge.fury.io/py/ctxttools.svg/></a>
|
|
24
|
+
<br/><br/><b>Try it now</b><br/>
|
|
25
|
+
<code>uvx --from ctxttools cdir</code><br/>
|
|
26
|
+
<code>uvx --from ctxttools ctools-web</code>
|
|
27
|
+
<br/><br/><b>Then install it</b><br/>
|
|
28
|
+
<code>uv tool install ctxttools</code>
|
|
29
|
+
</p>
|
|
30
|
+
|
|
31
|
+
------
|
|
32
|
+
**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.
|
|
33
|
+
|
|
34
|
+
It supports [Claude Desktop](https://claude.com/download), [Claude Code](https://github.com/anthropics/claude-code), [Codex](https://github.com/openai/codex), [Pi](https://github.com/earendil-works/pi), [Hermes](https://github.com/NousResearch/hermes-agent), [Goose](https://github.com/aaif-goose/goose), [Kilo](https://github.com/Kilo-Org/kilocode), [FreeBuff](https://github.com/CodebuffAI/freebuff), [Cline](https://github.com/cline/cline), [omp](https://github.com/can1357/oh-my-pi), and [OpenClaw](https://openclaw.ai/).
|
|
35
|
+
|
|
36
|
+
You can use it from the terminal, from a small web dashboard, or from any AI coding agent (via an MCP server).
|
|
37
|
+
|
|
38
|
+
Here's an example:
|
|
39
|
+
|
|
40
|
+
> I look for mentions of snake game in opencode using cgrep
|
|
41
|
+
<pre>
|
|
42
|
+
$ <b>cgrep</b> "snake game" opencode
|
|
43
|
+
opencode/ses_a1d1a5a4df984ee698cab4a7:1:user: make a simple snake game in python
|
|
44
|
+
opencode/ses_a1d1a5a4df984ee698cab4a7:2:assistant: I'll make a terminal-based snake game using `curses` (standard library, no dependencies).
|
|
45
|
+
opencode/ses_a1d1a5a4df984ee698cab4a7:3:assistant: Done — `snake.py` is a terminal snake game using Python's built-in `curses` module (no dependencies).
|
|
46
|
+
</pre>
|
|
47
|
+
|
|
48
|
+
> cool let's look at the status of that session using cdir
|
|
49
|
+
<pre>
|
|
50
|
+
$ <b>cdir</b> -l opencode/ses_a1d1a5a4df984ee698cab4a7
|
|
51
|
+
ID NAME MODIFIED SIZE MSGS PATH
|
|
52
|
+
ses_a1d1a5a4df984ee698cab4a7 make a simple snake game in python 2026-10-07 16:56 2.7 KB 3 /home/chris/.local/share/opencode
|
|
53
|
+
|
|
54
|
+
1 session(s)
|
|
55
|
+
</pre>
|
|
56
|
+
|
|
57
|
+
> Alright let's copy that session from opencode into pi!
|
|
58
|
+
<pre>
|
|
59
|
+
$ <b>ccopy</b> opencode/ses_a1d1a5a4df984ee698cab4a7 pi
|
|
60
|
+
Copied 3 message(s) from opencode/ses_a1d1a5a4df984ee698cab4a7 to a new pi session: e357f435-f813-463a-b313-f97f1051f3cb
|
|
61
|
+
Resume it with:
|
|
62
|
+
pi --session e357f435-f813-463a-b313-f97f1051f3cb
|
|
63
|
+
</pre>
|
|
64
|
+
|
|
65
|
+
As you can see, these are unix-friendly tools using simple paradigms that you are already familiar with.
|
|
66
|
+
|
|
67
|
+
## What it can do
|
|
68
|
+
|
|
69
|
+
| Capability | What you get |
|
|
70
|
+
|---|---|
|
|
71
|
+
| **Discover** | See every agent installed on your machine and how many sessions each holds. |
|
|
72
|
+
| **Find** | Search every session at once with grep-style regex, narrowed by agent, session glob, or role. |
|
|
73
|
+
| **Read** | Print a conversation as JSON (pipe it anywhere) or as a readable transcript. |
|
|
74
|
+
| **Continue** | Get the exact command to resume a session in its own tool, or open it in the web UI. |
|
|
75
|
+
| **Copy** | Copy a conversation into a new session in another tool, or the same tool on another machine. |
|
|
76
|
+
| **Measure** | See token usage per agent, per session, and per role. |
|
|
77
|
+
| **Concepts** | Pull out the *intent* of a session: its goal, its constraints, and what was decided. |
|
|
78
|
+
| **Recover** | List and restore the storage backups ctools takes before every local write. |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## A quick tour
|
|
83
|
+
|
|
84
|
+
**The overview**: every tool ctools can see, with session counts and token
|
|
85
|
+
totals, plus quick links into the most common actions:
|
|
86
|
+
|
|
87
|
+

|
|
88
|
+
|
|
89
|
+
**Sessions**: browse every conversation from any tool, sorted by recency.
|
|
90
|
+
Click one to open it.
|
|
91
|
+
|
|
92
|
+

|
|
93
|
+
|
|
94
|
+
**A conversation**: the full message stream, with the original tool's
|
|
95
|
+
resume command and copy-to-another-tool options.
|
|
96
|
+
|
|
97
|
+

|
|
98
|
+
|
|
99
|
+
**Search**: type a phrase and see every matching message across all tools.
|
|
100
|
+
|
|
101
|
+

|
|
102
|
+
|
|
103
|
+
**Concepts**: ask a session what it's *about*. ctools extracts the intent,
|
|
104
|
+
constraints, and decisions so you can pick up where you left off without
|
|
105
|
+
re-reading everything.
|
|
106
|
+
|
|
107
|
+

|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Install
|
|
112
|
+
|
|
113
|
+
**Python 3.10+** is required.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
uv tool install ctxttools # or: pip install ctxttools
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
That gives you the `ctools` command, a short command for each of its verbs,
|
|
120
|
+
and the dashboard and MCP server:
|
|
121
|
+
|
|
122
|
+
| Command | Purpose |
|
|
123
|
+
|---|---|
|
|
124
|
+
| `ctools` | The front door: `ctools <verb> [args...]`. Run `ctools --help` for the list. |
|
|
125
|
+
| `cdir`, `cgrep`, `ccat`, `cdu`, `ccopy`, `cextract`, `cconnect`, `crm`, `crecover` | Shortcuts for the verbs (`cgrep` is `ctools grep`). |
|
|
126
|
+
| `ctools-web` | The dashboard, same as `ctools web`. |
|
|
127
|
+
| `ctools-mcp` | The MCP server, same as `ctools mcp`. Needs the `mcp` extra. |
|
|
128
|
+
|
|
129
|
+
The MCP server's dependency is optional:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
uv tool install "ctxttools[mcp]" # or: pip install "ctxttools[mcp]"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
From a local checkout, `uv` keeps it editable:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
uv tool install --editable ".[mcp]"
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
> **Heads up:** `ctools-mcp` needs `mcp<2` (see
|
|
142
|
+
> [mcp dependency](#mcp-dependency) below).
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## The CLI
|
|
147
|
+
|
|
148
|
+
`ctools` has one verb per job. Each verb is also installed as its own short
|
|
149
|
+
command, named `c` plus the verb, so `ctools grep` and `cgrep` are the same
|
|
150
|
+
program with the same flags. Use whichever you prefer: the long form is easier
|
|
151
|
+
to discover, and the short form is quicker to type.
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
$ ctools --help
|
|
155
|
+
usage: ctools <command> [args...]
|
|
156
|
+
|
|
157
|
+
query:
|
|
158
|
+
dir list agents and sessions (cdir)
|
|
159
|
+
grep search session content (cgrep)
|
|
160
|
+
cat print a session (ccat)
|
|
161
|
+
du context usage per session (cdu)
|
|
162
|
+
|
|
163
|
+
transform:
|
|
164
|
+
copy copy a session to another agent (ccopy)
|
|
165
|
+
extract extract concepts from a session (cextract)
|
|
166
|
+
connect pipe concepts between sessions (cconnect)
|
|
167
|
+
rm cut sections out of a session (crm)
|
|
168
|
+
recover restore from a backup (crecover)
|
|
169
|
+
|
|
170
|
+
long-running:
|
|
171
|
+
web run the web dashboard (ctools-web)
|
|
172
|
+
mcp run the MCP server (ctools-mcp)
|
|
173
|
+
|
|
174
|
+
Run 'ctools <command> --help' for a command's options.
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Each verb has its own page in [`docs/`](docs/): [dir](docs/cdir.md),
|
|
178
|
+
[grep](docs/cgrep.md), [cat](docs/ccat.md), [du](docs/cdu.md),
|
|
179
|
+
[copy](docs/ccopy.md), [extract](docs/cextract.md),
|
|
180
|
+
[connect](docs/cconnect.md), [rm](docs/crm.md), and
|
|
181
|
+
[recover](docs/crecover.md). Sessions are addressed as `agent/session_id`
|
|
182
|
+
throughout.
|
|
183
|
+
|
|
184
|
+
### Discover your agents and sessions
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
ctools dir # every known agent, and whether it's installed
|
|
188
|
+
ctools dir opencode # that agent's sessions, and the command that resumes one
|
|
189
|
+
ctools dir -l opencode # with modified time, size, message count, path
|
|
190
|
+
ctools dir . # sessions that ran in this directory, across all agents
|
|
191
|
+
ctools dir opencode/ses_abc # one session's row
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Find a session
|
|
195
|
+
|
|
196
|
+
`grep` works the way `grep` does, over conversation content instead of files.
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
ctools grep "bug report" # every installed agent
|
|
200
|
+
ctools grep -i "deploy" claude-code # one agent
|
|
201
|
+
ctools grep -C 2 "flaky test" opencode # with context
|
|
202
|
+
ctools grep -l "parser" pi # just the session ids
|
|
203
|
+
ctools grep --user "refactor" # only what you typed
|
|
204
|
+
ctools grep --hosts "mcp config" # also the hosts in ctools.toml
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Read a session
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
ctools cat opencode/ses_abc # JSON list of {role, content}
|
|
211
|
+
ctools cat --text opencode/ses_abc # a readable transcript
|
|
212
|
+
ctools cat ssh://me@box/pi/<id> # a session on another machine
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Copy a session to another tool
|
|
216
|
+
|
|
217
|
+
`copy` creates a **new** session in the destination. The source is never
|
|
218
|
+
touched, and ctools prints the command that resumes the copy.
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
ctools copy opencode/ses_abc claude-code # into another tool
|
|
222
|
+
ctools copy opencode/ses_abc codex --dry-run # preview first
|
|
223
|
+
ctools copy opencode/ses_abc ssh://me@box/codex # into a tool on another machine
|
|
224
|
+
ctools copy opencode/ses_abc ssh://me@box/ # into opencode on that machine
|
|
225
|
+
ctools copy ssh://me@box/pi/<id> claude-code # pull one in from another machine
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The remote side doesn't need ctools installed; plain `ssh` and `tar` will do.
|
|
229
|
+
See [docs/ccopy.md](docs/ccopy.md) for how that works and where the new
|
|
230
|
+
session lands.
|
|
231
|
+
|
|
232
|
+
### Token usage
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
ctools du # total across all agents
|
|
236
|
+
ctools du opencode # sessions by token count
|
|
237
|
+
ctools du opencode/ses_abc # breakdown by role
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## The web dashboard
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
ctools web # opens at http://127.0.0.1:8765
|
|
246
|
+
ctools web --port 9000 # a different port
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
`ctools-web` is the same command. The dashboard is a read-mostly surface over
|
|
250
|
+
the same data the CLI uses. You can:
|
|
251
|
+
|
|
252
|
+
- Browse and search sessions (the "Conversation" view mirrors the CLI).
|
|
253
|
+
- Copy a session to another tool right from the UI.
|
|
254
|
+
- Export/download a session.
|
|
255
|
+
- Run **concept extraction** on a session (with optional LLM-backed
|
|
256
|
+
strategies and filters).
|
|
257
|
+
|
|
258
|
+
It binds to `127.0.0.1` only by default, so it's not exposed to your
|
|
259
|
+
network. Use `--host` to change that deliberately.
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Concepts: extract the intent of a session
|
|
264
|
+
|
|
265
|
+
A raw session is thousands of tokens. **Concepts** distills it into the few
|
|
266
|
+
things that matter for picking it back up: the goal, the constraints, and
|
|
267
|
+
what was decided.
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
ctools extract @<agent>/<session-id> # or: cextract @<agent>/<session-id>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Concepts are extracted one of three ways. Regex is the default; `-s` and `-F`
|
|
274
|
+
select the others:
|
|
275
|
+
|
|
276
|
+
1. **Regex (default)**: built-in patterns for goal, decision, constraint,
|
|
277
|
+
and preference. No setup.
|
|
278
|
+
2. **LLM strategy**: you define a chunking strategy that an LLM applies to
|
|
279
|
+
the session. Best for richer, contextual extraction.
|
|
280
|
+
3. **Filter**: narrow the regex/LLM output with a rule (drop boilerplate,
|
|
281
|
+
keep only certain types, etc.).
|
|
282
|
+
|
|
283
|
+
Strategies and filters are stored as JSON config files that ctools reads at
|
|
284
|
+
runtime, in the config dir (see below). Create them in the dashboard (the
|
|
285
|
+
**Concepts** tab) or by hand.
|
|
286
|
+
|
|
287
|
+
**Where ctools keeps its config.** Config and data live in a per-user
|
|
288
|
+
directory resolved via `platformdirs` (no hand-rolled platform checks):
|
|
289
|
+
|
|
290
|
+
- Linux: `~/.config/ctools/` (config), `~/.local/share/ctools/` (data)
|
|
291
|
+
- macOS: `~/Library/Application Support/ctools/` (the macOS convention)
|
|
292
|
+
- Windows: `%APPDATA%\ctools\` (config), `%LOCALAPPDATA%\ctools\` (data)
|
|
293
|
+
|
|
294
|
+
Set `$CTOOLS_CONFIG` (and `$CTOOLS_DATA`) to relocate. This holds
|
|
295
|
+
`resume-commands.json`, `strategies/`, `filters/`, and the general
|
|
296
|
+
**`ctools.toml`** config — one file, multiple sections. The first section,
|
|
297
|
+
`[hosts]`, lists the machines `ctools grep --hosts` searches too:
|
|
298
|
+
|
|
299
|
+
```toml
|
|
300
|
+
# ~/.config/ctools/ctools.toml
|
|
301
|
+
[hosts]
|
|
302
|
+
fatty = "ssh://bobby@fatty.local"
|
|
303
|
+
workie = "ssh://10.0.0.4"
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Each value is an `ssh://[user@]host[:port]` reference (the same form `ccat`
|
|
307
|
+
and `ccopy` use for a remote side), so the host may be a `~/.ssh/config`
|
|
308
|
+
alias. A missing/malformed config never breaks a search — it just means
|
|
309
|
+
"local only".
|
|
310
|
+
|
|
311
|
+
The dashboard shows the full extraction pipeline (conversation → extraction
|
|
312
|
+
→ filter → concepts) so you can see exactly what was kept and why.
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## MCP server
|
|
317
|
+
|
|
318
|
+
The MCP server exposes the same capabilities to any MCP-capable coding agent
|
|
319
|
+
(Pi, Claude, OpenCode, etc.). It needs the `mcp` extra (see [Install](#install)).
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
ctools mcp # run the server on stdio (same as ctools-mcp)
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Install and register with Pi
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
ctools-mcp install
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
If no working `ctxttools[mcp]` install is found, this installs one with
|
|
332
|
+
`uv tool`. It then registers the server in `~/.pi/agent/mcp.json`. Verify with:
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
pi mcp list # "ctools-mcp … connected"
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
`ctools-mcp uninstall` removes the entry again (`--all` also removes it from
|
|
339
|
+
Claude Code's and opencode's configs).
|
|
340
|
+
|
|
341
|
+
### Manual registration (any host)
|
|
342
|
+
|
|
343
|
+
If you'd rather wire it up yourself, `print-config` emits the `mcpServers` JSON
|
|
344
|
+
snippet:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
ctools-mcp print-config
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Add that to your host's MCP config. The server is started with
|
|
351
|
+
`python -m ctools.ctools_mcp` from the install environment.
|
|
352
|
+
|
|
353
|
+
### Tools exposed
|
|
354
|
+
|
|
355
|
+
| Tool | What it does |
|
|
356
|
+
|---|---|
|
|
357
|
+
| `list_agents` | Agents available and whether they're installed. |
|
|
358
|
+
| `list_sessions` | Recent sessions for one agent. |
|
|
359
|
+
| `search_sessions` | Find sessions by pattern or phrase. |
|
|
360
|
+
| `export_session` | Get the messages of a session. |
|
|
361
|
+
| `extract_concepts` | Extract concepts from a session. |
|
|
362
|
+
| `get_session_concepts` | Get a session's concepts, optionally of one type. |
|
|
363
|
+
| `copy_concepts` | Copy extracted concepts into a destination session. |
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## MCP dependency
|
|
368
|
+
|
|
369
|
+
`ctools-mcp` pins `mcp>=1.2,<2.0`. The `mcp` package 2.x renamed
|
|
370
|
+
`FastMCP` to `MCPServer`, which breaks the v1 API ctools uses. If a fresh
|
|
371
|
+
install pulls `mcp>=2` and `ctools-mcp` won't start, pin the major version
|
|
372
|
+
(`pip install "mcp<2"`); the released package already does this.
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## The agents ctools knows about
|
|
377
|
+
|
|
378
|
+
| Name | Tool | Storage |
|
|
379
|
+
|---|---|---|
|
|
380
|
+
| `claude` | Claude Desktop | JSON |
|
|
381
|
+
| `claude-code` | Claude Code CLI | JSONL |
|
|
382
|
+
| `codex` | OpenAI Codex CLI | JSONL |
|
|
383
|
+
| `pi` | Pi coding agent | JSONL |
|
|
384
|
+
| `omp` | omp (oh-my-pi) | JSONL |
|
|
385
|
+
| `opencode` | OpenCode CLI | SQLite |
|
|
386
|
+
| `kilo` | Kilo CLI | SQLite |
|
|
387
|
+
| `goose` | Goose AI agent | SQLite |
|
|
388
|
+
| `hermes` | Hermes agent | SQLite |
|
|
389
|
+
| `openclaw` | OpenClaw | SQLite |
|
|
390
|
+
| `cline` | Cline | JSON |
|
|
391
|
+
| `freebuff` | Freebuff | JSON |
|
|
392
|
+
|
|
393
|
+
An agent is "installed" if ctools can find its session directory (or DB
|
|
394
|
+
file); `ctools dir` shows which are found and where. Only claude-code,
|
|
395
|
+
opencode, kilo, codex, and pi can be a `copy` destination.
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## How the data is handled
|
|
400
|
+
|
|
401
|
+
- **Read-only by default.** `dir`, `grep`, `cat`, `du`, the MCP read tools,
|
|
402
|
+
and the dashboard's read paths never modify your session files.
|
|
403
|
+
- **Writes are explicit.** `copy` writes a *new* session and never touches the
|
|
404
|
+
source. `extract` and `connect` write only when you name a session as the
|
|
405
|
+
destination, and `rm` only to the session you name.
|
|
406
|
+
- **Backed up first.** Before a local `copy` writes, it snapshots the
|
|
407
|
+
destination agent's storage and restores it automatically if the write goes
|
|
408
|
+
wrong. `ctools recover` lists and restores those snapshots.
|
|
409
|
+
- **Local unless you say otherwise.** The dashboard binds to `127.0.0.1`, and
|
|
410
|
+
the MCP server reads your local storage. Data only crosses the network when you
|
|
411
|
+
name an `ssh://` host or pass `grep --hosts`, and then only over your own ssh.
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## Development
|
|
416
|
+
|
|
417
|
+
```bash
|
|
418
|
+
git clone https://github.com/day50-dev/ctools
|
|
419
|
+
cd ctools
|
|
420
|
+
python -m venv .venv && . .venv/bin/activate
|
|
421
|
+
pip install -e ".[dev]"
|
|
422
|
+
python -m pytest
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
The code is deliberately simple: each agent adapter is a class in
|
|
426
|
+
`ctools/agents.py`, each verb is one module (`ctools/cgrep.py`, …), and
|
|
427
|
+
`ctools/dispatch.py` routes `ctools <verb>` to them. The CLI, dashboard, and
|
|
428
|
+
MCP layers are thin over the shared `ctools.agents` registry.
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## License
|
|
433
|
+
|
|
434
|
+
[MIT](LICENSE)
|