Ragger is local-first semantic memory for AI agents — and for the humans working with them. Think of it as running compaction with tiered recall: every turn your agent has gets captured and summarized in the background while it stays warm, then served back as a layered "what just happened?" payload that fades the way a person's memory fades — while keeping the verbatim transcript a single query away. Embeddings run locally by default (ONNX, no network); an external engine is optional for those who'd rather point at their own inference server. The whole database is one SQLite file you own.
C++ port of the original Python Ragger Memory, diverged at v0.9.4 — now the sole focus.
- RAG database accessible by agent through MCP (stdio, socket, and tcp). done
- Automatic capture of all conversations so that good decisions can be repeated and bad ones avoided. done
- Automatic local (roll your own!) or remote summarizing at various levels of detail at once in the background. done
- Auto-insert stored details into context based on user's prompt. done
- Auto-build new contexts on the fly when the provider cache is known to have expired. This will use the "fading memory" paradigm based on the user's chosen recipe, ie. # of most recent turns, then # of summarized turns, then a summary of the remainder of the session.
- Improve capture of stored decisions and skill.
- Discovery and auto-summarizing recurring threads.
- Constant improvements in importing conversations from other sources. (in progress)
- Multi-user sharing of RAG documents.
- Search GUI for fine-tuning of search parameters.
- Captured turns, summarized live. Turns land in the DB as they happen; an in-daemon worker writes per-turn summaries immediately and closes session summaries on idle, all without blocking the agent. If the summarizer model is unreachable, a draft is stored and rewritten later — the agent never waits on inference it didn't ask for.
- Hybrid search. A custom TF-IDF inverted index (stemmed unigrams + bigrams and DoubleMetaphone "sounds-like" codes sharing one flat term table) blended with dense vector cosine via Eigen3. Configurable weights; all signals normalized before blending.
- Local or external embeddings. Internal engine runs an ONNX model on disk (
all-MiniLM-L6-v2,all-MiniLM-L12-v2, etc., 384-dim by default); external engine calls any OpenAI-compatible/v1/embeddingsendpoint (llama.cpp, llama-swap, LM Studio, OpenAI). Stored as IEEE half (f16) by default; in-memory math stays f32. Storage type can bef32,f16,bf16, andint8. Re-encode any time withragger rebuild-embeddingsor the dashboard's "Update now". - HTTP and MCP, same data. Daemon serves a REST API;
ragger mcpspeaks JSON-RPC over stdio. Bearer-token auth on remote requests; unix-socket and loopback are pre-authenticated. - Markdown-aware import. Heading-aware chunking; Claude Code and claude.ai conversation archives import with original timestamps.
Single binary. Single-user out of the box. No external services required; internal embeddings mean no network calls once the model is on disk.
Three seams are built to be replaced without touching the rest of the code:
- Storage backend. All memory storage goes through the abstract
StorageBackendinterface (include/storage_backend.h);sqlite::Backendis the only implementation today. Dropping in another engine — MariaDB, MongoDB, or a dedicated vector DB for large corpora — means implementing that one interface. - Interface language. All CLI and daemon strings — help, status, progress, warnings, errors —
live in one file,
include/lang/en.h. To localize, copy it toxx.h, translate the values, and include that instead inlang.h. Caveat: the browser dashboard carries its own inline English (web/dashboard.html) and isn't covered by this, so a full translation is currently two files. - Context recipes (fading memory). How a session's past is rebuilt into a context payload is not
hardcoded — it's a JSON recipe that layers raw turns → turn summaries → episodes
→ decisions, walking the latest prompt backward so recent detail stays sharp while older
context fades to summary.
build_contextreads it; five recipes ship (natural_fading,reconnect,deep_recall,tldr,raw_only) and you can drop your own in~/.ragger/recipes/to tune the fade curve without recompiling.
Note: the default branch (
dev) holds in-progress work. For the latest stable release, clonemaster(as below) or check out a release tag.
Per-user, no sudo (binary → ~/.local/bin, data → ~/.ragger/):
git clone -b master https://github.com/diskerror/ragger.cpp.git && cd ragger.cpp
./scripts/build.sh # check deps, build
./scripts/install-bin.sh # install binary + user service unit + recipes
ragger start # start the daemoninstall-bin.sh — re-run after a rebuild to refresh the binary, the service unit, and the shipped
recipes. Your config, database, and any custom recipe files are preserved.
Pass --stats to build.sh and install-bin.sh to enable retrieval-stats instrumentation
(RAGGER_STATS, logged to ~/.ragger/stats.db); it builds into a separate build-stats/ tree so a
stats and non-stats binary can coexist.
ragger store "The deploy script needs Node 18+"
ragger search "deployment requirements"
ragger import-docs notes.md
ragger recipe # interactive picker over available recipes
ragger recipe reconnect # set the active recipe (persisted in the DB)
ragger start | stop | restart | statusDev build (manual cmake):
cmake --preset dev && cmake --build build -j8
./build/ragger versionEvery on-disk path is hardcoded relative to a single base directory (~/.ragger by default).
There's no per-path config — the only way to relocate the whole tree is the hidden
--ragger-base <path> flag (testing only; not documented in --help). Symlink ~/.ragger or a
sub-directory elsewhere if you need the data on a different disk.
| What | Where |
|---|---|
| Binary | ~/.local/bin/ragger |
| Config | settings table in ~/.ragger/memories.db (edit via dashboard or ragger config set) |
| Database | ~/.ragger/memories.db |
| Embedding models | ~/.ragger/models/<provider>/<model>/ |
| Recipes | ~/.ragger/recipes/ |
| Inference formats | ~/.ragger/formats/ |
| Log | ~/.ragger/logs/activity.log |
| Bearer token | ~/.ragger/token |
| Unix socket | ~/.ragger/ragger.sock |
| Retrieval stats (opt-in build) | ~/.ragger/stats.db |
Ragger supports two embedding engines, switchable from the dashboard or
ragger config set (embedding_engine / desired_embedding_engine):
- internal — ONNX models on disk under
~/.ragger/models/<provider>/<model>/, e.g.sentence-transformers/all-MiniLM-L12-v2/.install-bin.shdownloads a starter set from HuggingFace; the dashboard's Embedding tab can search HuggingFace and download additional ONNX models directly. - external — any OpenAI-compatible
/v1/embeddingsendpoint. The dashboard queries/v1/modelsand auto-probes the selected model with a test embedding to determine its actual dimensions.
Caveat with LM Studio as an external endpoint: LM Studio does not reliably honor the model
field on /v1/embeddings requests — it may silently serve whichever embedding model is already
loaded, regardless of what you asked for, instead of returning an error. Ragger's probe compares the
model it requested against the model the server actually reports back and surfaces a mismatch
warning in the dashboard when they differ. If you see this warning, either load the desired
embedding model explicitly in LM Studio first, or point the external engine at a stricter endpoint
(llama.cpp / llama-swap honor per-request model selection correctly). The embedder choice menu is
populated by a subset of models that either have the "embed" flag or who's name contains words
common to embedding models.
- System: Eigen3, Boost (program_options), OpenSSL, libcurl, Rust (for tokenizers-cpp; rustup stable is fine).
- c_lib (diskerror/c_lib, shared C++ utilities + the
vendored SQLite, foreign keys on by default): with a sibling checkout at
../c_lib, Ragger links its prebuilt libraries from../c_lib/buildand runs../c_lib/build_libs.sh(incremental) before each build; without one, it is fetched from GitHub and built as a subproject. - Auto-fetched at configure time (needs network +
giton the first configure; cached in the build dir): tokenizers-cpp (cloned at the commit pinned incmake/pins.cmake) and ONNX Runtime (release archive for your platform, SHA-256 verified). Drop a matchingvendor/onnxruntime/in place, or pass-DFETCHCONTENT_SOURCE_DIR_TOKENIZERS_CPP=/path, for an offline build. - Vendored (checked in): cpp-httplib, nlohmann/json.
- Dependency pinning: configure with
-DDEPS_LATEST=ON(or set it in your localCMakeUserPresets.json) to track upstream's newest commits while developing; before tagging, runscripts/pin-deps.shand commitcmake/pins.cmake.cmake --build build --target update_depsre-fetches on demand.
# macOS — MacPorts
sudo port install boost eigen3 rust openssl curl cmake
# macOS — Homebrew
brew install boost eigen openssl@3 curl cmake rustup-init && rustup-init -y
# Debian / Ubuntu
sudo apt install build-essential cmake pkg-config \
libboost-program-options-dev libeigen3-dev \
libssl-dev libcurl4-openssl-dev
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
# Fedora / RHEL
sudo dnf install gcc-c++ cmake pkgconf-pkg-config \
boost-devel eigen3-devel \
openssl-devel libcurl-devel
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -yThen:
./scripts/build.sh # check deps, configure, build
./scripts/install-bin.sh # places binary + downloads starter ONNX embedding modelsCheck out diskerror/c_lib next to this repo (../c_lib).
It is picked up automatically: c_lib builds its optimized libraries once into ../c_lib/build
and Ragger links them. Cleaning Ragger never touches them; to rebuild c_lib from scratch, run
../c_lib/build_libs.sh --clean. c_lib's own tests: ../c_lib/build_tests.sh.
The build script auto-detects this file and passes the variable to cmake. CLion also picks up the
dev preset from its CMake profile dropdown.
Manual cmake (without the build script):
cmake --preset dev # or: cmake -B build
cmake --build build -j8
./build/ragger versionmacOS (arm64 and x86_64) and Linux (x86_64 and aarch64) are supported. Windows needs porting
(fork(), the bash/launchctl/systemd install scripts).
| Guide | |
|---|---|
| Getting started | Setup and first run |
| Configuration | Config keys reference (DB-backed) |
| Search & RAG | How hybrid search works |
| HTTP API | REST endpoints, MCP, auth, /turn and /session/<id>?recipe= |
| Importing conversations | Claude Code / claude.ai history |
| Deployment | Daemon lifecycle, sub-users, reverse proxy |
| TLS setup | HTTPS via reverse proxy or native cert/key |
| Agent integration | MCP and Claude Desktop |
| Agent memory instructions | Guidance served to agents over MCP |
| OpenClaw | OpenClaw plugin setup |
| Testing your install | End-to-end smoke check |
cd build && ctest --output-on-failure # 14 suitesGPL v3. Commercial (non-GPL) licenses available — contact [email protected].