If you run coding agents across more than one project, you have hit this: months of sessions, hundreds of files, four clients, no way to ask "where was I?"
The tools you already have each solve one slice. grep finds exact strings inside files. AgentSessions' FTS finds sessions by content. QMD or a RAG pipeline finds semantically similar prose. None of them tell you which file on disk is the real deliverable, which session actually touched it, or whether that 400 MB archived log is searchable without restoring it.
I built a small glue layer that does exactly that join. It is ~500 lines of Python on top of two mature OSS tools (Recoll and AgentSessions). It is not a new search engine, not a dashboard, not a database. It reads your existing indexes, adds the missing cross-references, and gets out of the way.
The problem, specifically

Here is the state I was in on a Tuesday: 2,137 agent sessions across 8 providers. Roughly 40 project folders under ~/Work, ~/Projects, ~/Code. A handful of client deliverables (pptx, docx, xlsx, pdf) scattered across output directories. Six archived Codex sessions, one of them 403 MiB, deliberately moved out of normal indexing because they were crashing the reader.
I could ask any one tool a question and get part of the answer:
grep -r "executive brief"found the phrase inside markdown, but also inside Python build scripts and JSON config. It told me nothing about which file was the current deliverable.- AgentSessions' search returned 153 sessions mentioning CHANEL. It truncated excerpts at 48 KB and silently skipped two events over 8 MiB — one of which contained the answer I was looking for.
- QMD found semantically similar markdown about the project, but returned prose chunks, not file paths I could open.
What I actually wanted was: "the executive brief for CHANEL Grasp, modified Sep 14, in this folder, here is the session that last touched it, and it is not confirmed finished."
No single tool answered that. The information existed across all three. The join was missing.
The join layer

The insight is that none of the hard problems were unsolved. Recoll has been indexing Office documents and PDFs on macOS since 2005. AgentSessions already has a SQLite index across eight providers. QMD is fine for what it does. The missing piece was a ~500-line adapter that:
- Walks configured roots and records metadata (path, size, mtime, whether it's a repo or worktree, whether it's a cloud placeholder) — without reading file content or hydrating placeholders.
- Reads AgentSessions' existing SQLite index in read-only mode and produces session cards linked to projects by explicit root, not by guessed cwd.
- Streams archived JSONL into bounded text chunks with line-offset provenance, so a 403 MiB file is searchable in 1 second using 269 MiB of RSS, and you can open the raw original without re-parsing.
- Generates a Recoll config that indexes only the real deliverables and skips generated mirrors, then drives
recollindexandrecollq.
Measured results on real data
I ran this against my actual workload: 3 client projects, 2,132 real sessions, 8 archived files, and one 403 MiB session log.
| Target | Result |
|---|---|
| Warm search p95 across 20 queries | 147 ms (target: ≤ 2 s) |
| 403 MiB archive export peak RSS | 269 MiB (target: ≤ 512 MiB) |
| Sessions indexed | 2,132 across 8 providers |
| Archive manifest entries reconciled | 8 (6 archived with chunks extracted, 2 restored) |
| Time to index pilot roots | ~30 seconds |
| Network calls during operation | 0 |
The 147 ms p95 is the number that changed my behaviour. At that speed, searching is cheaper than remembering. I stopped trying to keep a mental map of which folder held which deliverable and just asked.
What it does not do
I want to be clear about the boundaries, because the failure mode of this kind of tool is silent scope creep:
- No cloud processing. Everything runs offline. No embeddings sent to an API, no remote index, no telemetry.
- No file migration. The tool never moves, renames, or restructures anything. Sources are read-only.
- No version history. Recoverable deliverable versions are a real problem but a separate one; it is tracked in its own issue, not smuggled into v1.
- No session-to-project auto-linkage yet. The data is there (session
cwdfields), but the alias map that connects.omp-lmm-chanelto the CHANEL Grasp root needs to be configured, not guessed. This is a refinement, not a blocker — the raw data is in the index.
Making agents use it
Building the index was the easy part. The harder question was: how do coding agents discover it mid-task?
The answer that worked was not an MCP server (overkill for four CLI commands) and not a prompt injection (fragile). It was a skill — a markdown file that teaches the agent what commands exist and when to use them, installed into each agent's skill directory.
I wrote one SKILL.md describing the four commands, when to reach for each, and what the output format looks like. Then I copied it into ~/.codex/skills/, ~/.claude/skills/, ~/.omp/agent/managed-skills/, and ~/.codeium/windsurf/skills/. The skill search hook picks it up automatically, and agents invoke the CLI directly. No protocol, no server, no API to maintain.
The first draft failed in an instructive way. I gave it to a Flash-class agent and asked it to find a CHANEL media guidelines session. It burned twelve tool calls trying recoll -q (not on PATH), then my wrapper (which re-indexes from scratch every call), then which and --help probes. The problem wasn't the index — it was that the skill didn't include exact binary paths or warn about the re-indexing trap. The rewrite leads with /Applications/recoll.app/Contents/MacOS/recollq as a copy-paste command, adds a "Common Pitfalls" section, and tells the agent to prefer recollq over anything that rebuilds. That's the difference between twelve calls and two.
A thin wrapper script at ~/.local/bin/project-recall handles the PYTHONPATH setup so the command works from any directory.
Reuse, don't rebuild
The most useful thing I learned building this: the hard problems were already solved by mature OSS. Recoll has been indexing documents since 2005. AgentSessions already normalises eight providers into one SQLite schema. The only new work was the join — and that was small, boring, and testable.
If you are about to build a custom search engine, a vector database, or an agent memory layer: check whether the mature tool already covers 90% of the job. The remaining 10% is usually a few hundred lines of glue, and glue is testable in a way that a from-scratch system is not.