▍ record · seq=0001 · type=meta
Agents start every session with amnesia — so you re-paste your stack, conventions, and past decisions into every prompt, and pay for it in tokens. AegisDB is the memory layer that keeps that knowledge and feeds back only what's relevant, per prompt.
▍ record · seq=0002 · type=semantic
You almost certainly run a database already. None of them was built to remember the way an agent needs to.
A vector store recalls by similarity but has no notion of an event, a fact that gets corrected, or context that should expire. A cache forgets on its own timer. A relational table stores rows but can't rank by meaning. Agent memory is all of these at once — so AegisDB makes each its own kind, with the lifecycle it actually needs.
what each one remembers
redis → fast, but evicts on its own TTL sqlite → durable rows, no recall by meaning pgvector → similarity only — no events, TTL, or graph aegisdb → events, facts, working + a graph, each lifecycled
▍ record · seq=0003 · type=semantic
Every session normally re-pastes your stack, conventions, and past decisions into the prompt. AegisDB keeps that knowledge out of the window and feeds back only what's relevant, per prompt — so you pay for the work, not for re-establishing context.
▍ record · seq=0004 · type=semantic
Three kinds of memory, each with the lifecycle it actually needs — not one generic store with a TTL bolted on. Persisted memories are durable by default, and can be set to auto-archive after a deadline when you want them to fade.
Append-only records of what happened. Written once, never rewritten — the source of truth every index is rebuilt from.
Updatable knowledge where the latest version wins. Correct a fact and the old one steps aside, no duplicates left behind.
A per-session ring buffer with a TTL. Keep scratch context close, then promote what proves worth keeping.
Search by vector similarity, by tags (all/any), or by time range — each on a purpose-built index, not a scan.
Exact cosine while a set is small; past a threshold it switches to an HNSW graph for sublinear approximate-nearest-neighbour search, so recall stays fast as memories accumulate. The graph is checkpointed — a restart reloads it instead of rebuilding — and vectors can be int8-quantized to cut its memory ~4×.
Link memories with directed edges and walk them breadth-first to pull in what's related to what you just recalled.
▍ record · seq=0005 · type=semantic
Recall sits in the agent's inner loop, so latency is the whole game. AegisDB keeps vector search sub-millisecond as memories pile up — exact while a set is small, an HNSW graph past a threshold, so recall stays fast without losing accuracy.
These are AegisDB's own numbers, not a comparison — and you can reproduce them yourself: make bench (vector recall + latency) and make wire-bench (end-to-end over TCP).
make bench · make wire-bench
vector recall → 0.14 ms @ 10k · 0.22 ms @ 100k recall@10 → 1.00 (384-dim, HNSW) ping → 158k ops/s · p50 0.05 ms read (get) → p50 0.8 ms over the wire measured on a 2023 laptop i7, loopback
▍ record · seq=0006 · type=semantic
The wire protocol is newline-delimited JSON over TCP. No SDK, no driver — any language that can open a socket can speak it.
store a memory, then recall it
# write an episodic memory {"operation":"insert", "type":"episodic", "tags":["user"], "data":"Prefers dark mode"} → {"ok":true, "record":{"id":1, "type":"episodic"}} # recall it by tag {"operation":"search", "tags":["user"], "top_k":5} → {"ok":true, "total":1, "records":[ … ]}
operations · ping insert get update delete search count promote relate traverse stats
insert takes a batch of records in one call; delete and count work by id or by filter (tags / type / time range).
stats reports durability lag, live & tombstone counts, log size, and per-index sizes — for monitoring and capacity planning.
▍ record · seq=0007 · type=semantic
An MCP server plus session hooks: relevant memories are recalled into context on every prompt, and the ones worth keeping are captured when the session ends.
.mcp.json — scaffolded by aegisdb-init
{
"mcpServers": {
"memory": {
"command": "uvx",
"args": ["aegisdb-mcp"],
"env": {
"AEGIS_NAMESPACE": "my-project",
"AEGIS_EMBEDDING_DIMENSIONS": "1024"
}
}
}
}
▍ record · seq=0008 · type=episodic
Pull the image or build from source — either way you're holding a connection in seconds.
Run it — prebuilt multi-arch image, no toolchain
docker run -d --name aegisdb -p 9470:9470 -v aegis-data:/data ghcr.io/d4n-larsson/aegisdb:latest
…or build from source
git clone https://github.com/d4n-larsson/aegisdb && cd aegisdb && make
./build/aegisdb --data-dir ./data --port 9470
Talk to it — the binary is also the client
docker exec aegisdb aegisdb client put --tags user "prefers dark mode"
docker exec aegisdb aegisdb client search --tags user
Read the reference
The wire-protocol reference and quickstart cover every operation.
▍ record · seq=0009 · type=meta
One server, one tenant token per project, and Claude Code wired in with uvx — no clone anywhere. Uses the published image and the aegisdb-mcp PyPI package.
Mint a tenant token
docker run --rm ghcr.io/d4n-larsson/aegisdb \
gen-token --namespace my-project --scope rw
Prints a hashed token-file line and the one-time token. Append the line to tokens.txt; keep the token for step 3.
Run the server — authenticated, durable
docker run -d --name aegisdb -p 9470:9470 \
-v aegis-data:/data -v "$PWD/tokens.txt:/tokens.txt:ro" \
ghcr.io/d4n-larsson/aegisdb:latest \
--data-dir /data --embedding-dim 1024 --auth-token-file /tokens.txt
Tokens travel in plaintext — keep the port on a private network or behind a TLS-terminating proxy. For a shared box, add --encryption-key-file (see gen-key) to encrypt the data volume at rest.
Point Claude Code at it — .mcp.json
{
"mcpServers": {
"memory": {
"command": "uvx",
"args": ["aegisdb-mcp"],
"env": {
"AEGIS_HOST": "memory.internal",
"AEGIS_PORT": "9470",
"AEGIS_AUTH_TOKEN": "<token from step 1>",
"AEGIS_EMBEDDING_DIMENSIONS": "1024"
}
}
}
}
The token's namespace is authoritative — no AEGIS_NAMESPACE needed. uvx fetches the package on demand (install uv once). Or skip the hand-editing: uvx --from aegisdb-mcp aegisdb-init --host memory.internal --auth-token <token> writes this and the hooks.
Enable auto recall & capture — .claude/settings.json
{
"hooks": {
"UserPromptSubmit": [
{ "hooks": [ { "type": "command", "command": "uvx --from aegisdb-mcp aegisdb-recall-hook" } ] }
],
"SessionEnd": [
{ "hooks": [ { "type": "command", "command": "uvx --from aegisdb-mcp aegisdb-capture-hook" } ] }
]
}
}
Relevant memories are recalled into context each prompt; salient outcomes are captured at session end.
Onboard a teammate
They repeat step 1 for their own token (their own --namespace for isolation, or a shared one to pool memory) and steps 3–4. No clone, no build.
Full step-by-step walkthrough — quotas, encryption at rest, backups & troubleshooting: the team server tutorial.