Skip to content

kcp-memory

Episodic memory daemon for Claude Code — indexes session transcripts into SQLite with FTS5

Field Value
GitHub https://github.com/Cantara/kcp-memory
Language Java
Stars 3
Last updated 2026-03-14

README

kcp-memory

Episodic memory for Claude Code, Gemini CLI, and Codex CLI. Indexes your session transcripts and tool-call events into a local SQLite database — searchable in milliseconds. Available as a CLI, an HTTP API, and an MCP server so Claude can query its own history inline.

# CLI
kcp-memory search "OAuth implementation"
kcp-memory events search "kubectl apply"
kcp-memory stats

# MCP — Claude queries directly during a session (8 tools)
# Register once in ~/.claude/settings.json, then call inline:
#   kcp_memory_search · kcp_memory_events_search · kcp_memory_list
#   kcp_memory_stats · kcp_memory_session_detail · kcp_memory_project_context
#   kcp_memory_subagent_search · kcp_memory_session_tree          (v0.5.0)

Part of the KCP ecosystem.


The three-layer memory model

Layer What it is Provided by
Working Current context window Claude Code
Episodic What happened in past sessions kcp-memory
Semantic What this codebase means Synthesis

kcp-memory fills the episodic layer. Without it, every session starts from zero. With it, Claude can answer "what was I doing in this project last week?" and "which projects did I run kubectl apply in?" in milliseconds.


Quick start

1. Install

curl -fsSL https://raw.githubusercontent.com/Cantara/kcp-memory/main/bin/install.sh | bash

Downloads the JAR to ~/.kcp/, starts the daemon on port 7735, and runs an initial scan of ~/.claude/projects/.

2. Index your sessions

kcp-memory scan

Scans these transcript roots:

  • ~/.claude/projects/**/*.jsonl
  • ~/.gemini/tmp/*/chats/session-*.json
  • ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl

Incremental by default — only new or changed files re-indexed.

3. Search session transcripts

kcp-memory search "authentication refactor"
kcp-memory search "database migration flyway"

4. Search tool-call events (v0.2.0)

Requires kcp-commands v0.9.0 to be writing ~/.kcp/events.jsonl.

kcp-memory events search "kubectl apply"
kcp-memory events search "mvn package"
kcp-memory events search "docker build"

Returns every time Claude ran that command, with project directory, session ID, and timestamp.

5. List and stats

kcp-memory list
kcp-memory list --project /src/myapp
kcp-memory stats
[kcp-memory] statistics
─────────────────────────────────
  Sessions:    847
  Turns:       12,431
  Tool calls:  38,209
  Oldest:      2026-01-15T09:12:00Z
  Newest:      2026-03-03T14:55:00Z

  Top tools:
    Read                      14,821
    Bash                       9,442
    Edit                       7,103

6. Register as MCP server (v0.3.0)

Add to ~/.claude/settings.json:

{
  "mcpServers": {
    "kcp-memory": {
      "command": "java",
      "args": ["-jar", "/home/you/.kcp/kcp-memory-daemon.jar", "mcp"]
    }
  }
}

Claude Code can now call all six tools inline during any session — no manual CLI call, no context-switching: kcp_memory_search, kcp_memory_events_search, kcp_memory_list, kcp_memory_stats, kcp_memory_session_detail, and kcp_memory_project_context.


How it works

Claude Code stores every session as a .jsonl file in ~/.claude/projects/<slug>/. kcp-commands v0.9.0 writes every Bash tool call to ~/.kcp/events.jsonl.

kcp-memory: 1. Scans ~/.claude/projects/ for .jsonl session transcripts 2. Scans ~/.claude/projects/**/<session>/subagents/agent-*.jsonl for subagent transcripts, linking each to its parent session (v0.5.0) 3. Scans ~/.kcp/events.jsonl for tool-call events (incremental, byte-offset cursor) 4. Indexes all three into ~/.kcp/memory.db (SQLite + FTS5) 5. Serves an HTTP API on port 7735 and an MCP stdio server

The daemon runs a background scan every 30 minutes. The PostToolUse hook triggers an async scan after every tool call (near-real-time). The MCP server runs an inline scan before every kcp_memory_events_search call.


MCP server

The MCP server exposes eight tools over stdio (JSON-RPC 2.0):

Tool What it answers
kcp_memory_search "What did we do with OAuth last month?" — FTS5 over session transcripts
kcp_memory_events_search "Which projects did I run kubectl apply in?" — FTS5 over tool-call events
kcp_memory_list Recent sessions, optionally filtered by project directory
kcp_memory_stats Total sessions, turns, tool calls, date range, top tools
kcp_memory_session_detail Full content of a specific session — user messages, files touched, tools used (v0.4.0)
kcp_memory_project_context Auto-detect current project from PWD, return last 5 sessions + 20 events — call at session start (v0.4.0)
kcp_memory_subagent_search FTS5 search within subagent transcripts — finds architectural discoveries, rejected approaches, and reasoning buried in delegated tasks (v0.5.0)
kcp_memory_session_tree Show a parent session and all its child subagents as a tree — reveals delegated scope and per-agent tool usage (v0.5.0)

Registration (~/.claude/settings.json):

{
  "mcpServers": {
    "kcp-memory": {
      "command": "java",
      "args": ["-jar", "/home/you/.kcp/kcp-memory-daemon.jar", "mcp"]
    }
  }
}

The MCP server opens its own database connection — it does not require the HTTP daemon to be running.


Subagent memory (v0.5.0)

When Claude Code delegates tasks via the Task tool, it spawns subagents that write their own transcript files alongside the main session:

~/.claude/projects/<project>/<session-uuid>/
├── <session-uuid>.jsonl          ← main session (already indexed)
└── subagents/
    ├── agent-ae5fb06d98fb195b2.jsonl   ← subagent 1 (now indexed)
    ├── agent-a6036b037ec3f4eed.jsonl   ← subagent 2 (now indexed)
    └── ...

Each subagent file contains the full reasoning trail — tool calls, intermediate discoveries, rejected approaches — that the main session only receives as a compressed summary. In a typical session with heavy agent use, subagents contain 19% of total transcript data at a 40:1 to 100:1 compression ratio in the summaries.

v0.5.0 indexes all subagent files and links them to their parent sessions:

# Search within subagent transcripts
kcp-memory agents search "CatalystOne HRIS"
kcp-memory agents search "Flyway migration V3"

# List agents spawned in a session
kcp-memory agents list --session 624a7854-a7d2-4331-8ddb-7dab21e7064c

# Show a session tree (parent + all child agents)
kcp-memory session-tree 624a7854-a7d2-4331-8ddb-7dab21e7064c

MCP tools (for Claude to use inline):

kcp_memory_subagent_search  — "what did the agent discover about co-events architecture?"
kcp_memory_session_tree     — "show me what agents ran in session 624a and what they investigated"

What was previously lost:

Knowledge type Example Now recoverable?
Reasoning trails "I'll read pom.xml to understand the dependency tree" ✅ FTS5 indexed
Dead ends "PATH NOT FOUND — pivoting to root listing" ✅ FTS5 indexed
Cross-repo discoveries "co-converter depends on Xorcery Alchemy, not just core" ✅ FTS5 indexed
Investigation methodology "Read knowledge.yaml first, then pom.xml, then source tree" ✅ FTS5 indexed

Run kcp-memory scan after upgrading — it will retroactively index all existing subagent files and link them to their parent sessions.


Tool-call events (v0.2.0)

Requires kcp-commands v0.9.0 running as a PreToolUse hook. On every Bash tool call, kcp-commands appends a JSON event to ~/.kcp/events.jsonl:

{"ts":"2026-03-03T14:32:01Z","session_id":"abc123","project_dir":"/src/myapp","tool":"Bash","command":"kubectl apply -f deploy.yaml","manifest_key":"kubectl-apply"}

kcp-memory reads this file using a byte-offset cursor — each scan reads only the bytes appended since last time, typically one event in under 1ms.

For Gemini/Codex hook integrations, this repo also ships a lightweight logger utility:

node /path/to/kcp-memory/bin/kcp-logger.js '{"session_id":"abc123","project_dir":"'$PWD'","tool":"post_tool_use","command":"mvn test"}'

It appends a normalized JSON line to ~/.kcp/events.jsonl, so Gemini AfterTool and Codex post_tool_use hooks can feed the existing event index without any daemon changes.

Search example:

$ kcp-memory events search "kubectl apply"

[kcp-memory] 3 event(s) for "kubectl apply":

  2026-03-03 14:32  /src/cantara/kcp-commands
  abc12345  [kubectl-apply]
  $ kubectl apply -f deploy.yaml

  2026-02-28 11:17  /src/exoreaction/lib-pcb-app
  def67890  [kubectl-apply]
  $ kubectl apply -f k8s/production.yaml

Daemon API

The HTTP daemon runs on http://localhost:7735:

Endpoint Method Description
/health GET Liveness check + session count + version
/search?q=<query>&limit=20 GET FTS5 search over session transcripts
/sessions?project=<dir>&limit=50 GET List recent sessions
/stats GET Aggregate statistics
/scan?force=true POST Trigger an incremental scan (async)
/events/search?q=<query>&limit=20 GET FTS5 search over tool-call events (v0.2.0)
# Check health
curl http://localhost:7735/health

# Search sessions
curl "http://localhost:7735/search?q=OAuth+login&limit=5"

# Search events
curl "http://localhost:7735/events/search?q=kubectl+apply"

PostToolUse hook (optional)

For near-real-time session indexing, add to ~/.claude/settings.json:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": ".*",
        "hooks": [{"type": "command", "command": "~/.kcp/memory-hook.sh"}]
      }
    ]
  }
}

Fires after every tool call, triggers an async POST to /scan. Never blocks — if the daemon is not running the hook exits silently in under 1 second.


Daemon management

# Check if running
curl -sf http://localhost:7735/health

# Start
nohup java -jar ~/.kcp/kcp-memory-daemon.jar daemon > /tmp/kcp-memory-daemon.log 2>&1 &

# Stop
pkill -f kcp-memory-daemon

# View logs
cat /tmp/kcp-memory-daemon.log

CLI alias

Add to ~/.bashrc or ~/.zshrc:

alias kcp-memory='java -jar ~/.kcp/kcp-memory-daemon.jar'

Releases

Version Notes
v0.1.0 Session-level indexing — ~/.claude/projects/**/*.jsonl → SQLite+FTS5
v0.2.0 Tool-level events — ingests ~/.kcp/events.jsonl (kcp-commands v0.9.0), kcp-memory events search CLI + /events/search endpoint
v0.3.0 MCP server — kcp-memory mcp subcommand; four MCP tools for Claude Code inline use
v0.4.0 kcp_memory_session_detail (find → read flow) + kcp_memory_project_context (proactive session-start context from PWD)
v0.5.0 Subagent memory — indexes subagents/agent-*.jsonl files, parent-child session linking, kcp_memory_subagent_search + kcp_memory_session_tree MCP tools, kcp-memory agents CLI commands

Knowledge manifest

This repository ships a knowledge.yaml and llms.txt for AI agent navigation.


How it relates to kcp-commands

kcp-commands saves context window by injecting CLI syntax before Bash tool calls and filtering noisy output after. kcp-memory is complementary — it makes the past retrievable and queryable.

kcp-commands kcp-memory
Port 7734 7735
Hook PreToolUse PostToolUse
Stores Nothing (stateless) ~/.kcp/memory.db (SQLite)
Reads 283 command manifests ~/.claude/projects/**/*.jsonl + ~/.kcp/events.jsonl
Answers "How do I run this?" "What did I do before?"
MCP 8 tools (v0.5.0)

Both use ~/.kcp/ and are part of the KCP ecosystem.


Building from source

cd java
mvn package -q
# Output: target/kcp-memory-daemon.jar

Java 21 required. No Spring, no framework, no cloud calls. Dependencies: sqlite-jdbc, jackson-databind, picocli.



License

Apache 2.0 — Cantara