# https://github.com/d4n-larsson/aegisdb Project Manual

Generated at: 2026-06-28 19:19:40 UTC

## Table of Contents

- [AegisDB Overview & System Architecture](#page-1)
- [Storage Engine, Wire Protocol & Query Operations](#page-2)
- [Deployment, Configuration & Multi-Tenant Authentication](#page-3)
- [Claude Code Memory Integration (MCP Server & Hooks)](#page-4)

<a id='page-1'></a>

## AegisDB Overview & System Architecture

### Related Pages

Related topics: [Storage Engine, Wire Protocol & Query Operations](#page-2), [Deployment, Configuration & Multi-Tenant Authentication](#page-3), [Claude Code Memory Integration (MCP Server & Hooks)](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/d4n-larsson/aegisdb/blob/main/README.md)
- [CLAUDE.md](https://github.com/d4n-larsson/aegisdb/blob/main/CLAUDE.md)
- [site/index.html](https://github.com/d4n-larsson/aegisdb/blob/main/site/index.html)
- [include/aegisdb/db.h](https://github.com/d4n-larsson/aegisdb/blob/main/include/aegisdb/db.h)
- [include/aegisdb/types.h](https://github.com/d4n-larsson/aegisdb/blob/main/include/aegisdb/types.h)
- [include/aegisdb/config.h](https://github.com/d4n-larsson/aegisdb/blob/main/include/aegisdb/config.h)
- [include/aegisdb/recovery.h](https://github.com/d4n-larsson/aegisdb/blob/main/include/aegisdb/recovery.h)
- [include/aegisdb/query_engine.h](https://github.com/d4n-larsson/aegisdb/blob/main/include/aegisdb/query_engine.h)
- [include/aegisdb/json_response.h](https://github.com/d4n-larsson/aegisdb/blob/main/include/aegisdb/json_response.h)
- [src/main.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/main.c)
- [src/storage/db.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/storage/db.c)
- [src/util/client.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/util/client.c)
- [src/util/status.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/util/status.c)
- [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md)
</details>

# AegisDB Overview & System Architecture

## Purpose & Scope

AegisDB is a standalone C database server purpose-built for **AI agent memory**. It targets an append-heavy write profile (episodic events, semantic facts, and short-lived working context) and exposes a small, deterministic surface: a newline-delimited JSON-over-TCP wire protocol that any client can speak in one line per request. The published container image (`ghcr.io/d4n-larsson/aegisdb:0.3.0`, started with `docker run -p 9470:9470 -v aegis-data:/data …`) is the canonical deployment artifact and binds the public TCP port `9470`.

Conceptually AegisDB models memory the way the human cognitive system does — three complementary lifecycles that the codebase calls *working*, *episodic*, and *semantic*. The landing copy summarises it as "a memory model shaped like memory" (Source: [site/index.html:1-1]()), and the README states the implementation promise directly: append-heavy writes, fast ID lookup, temporal/tag search, semantic similarity, and volatile working memory behind a log-structured storage engine with purpose-built indexes (Source: [README.md:1-7]()).

## High-Level Architecture

The runtime is layered so each stage has one responsibility and a clear header boundary. `CLAUDE.md` describes the layout as `src/` mirroring the runtime pipeline "network → protocol → query → storage" with public headers under `include/aegisdb/` (Source: [CLAUDE.md:18-21]()).

```mermaid
flowchart LR
    Client[TCP Client / built-in client] -->|NDJSON line| Net[Network layer]
    Net --> Proto[Protocol parser]
    Proto --> QE[Query engine / dispatcher]
    QE --> Log[Append-only log]
    QE --> Hash[Hash index id→loc]
    QE --> Time[Time index]
    QE --> Tag[Tag index]
    QE --> Sem[Semantic ANN index]
    QE --> Work[Working store / TTL]
    Log --> Recovery[Startup recovery]
    Recovery --> Hash
    Recovery --> Time
    Recovery --> Tag
    Recovery --> Sem
```

The aggregate type `AegisDB` is the single root that wires these layers together: it holds the active `Config`, the `LogFile`, four in-memory indexes (`hash`, `time`, `tags`, `sem`), the `WorkingStore`, and the runtime state (`started_ms`, `next_id`, an `index_lock` reader/writer lock, and a `running` flag) (Source: [include/aegisdb/db.h:9-35]()). The entry point `main()` parses CLI flags into a `Config`, opens the DB (which triggers recovery), installs a signal handler for graceful shutdown, and starts the TCP server — or alternatively dispatches to `client_main` or `gen-token` subcommands (Source: [src/main.c:9-56]()).

## Memory Model & Storage Pipeline

The memory type model is a stable enum persisted in the log encoding: `MEM_WORKING = 0` (RAM only, overwritable/evictable), `MEM_EPISODIC = 1` (disk, immutable after insert), `MEM_SEMANTIC = 2` (disk, updateable — newer log entries supersede older ones). The string forms (`"working"`, `"episodic"`, `"semantic"`) are wired through `memory_type_from_string` / `memory_type_to_string` so the on-wire names map deterministically to on-disk values (Source: [include/aegisdb/types.h:9-22]()).

Operations route through a single dispatcher. `query_engine_dispatch` takes a parsed request object, walks the `operation` field, and produces a response `cJSON` node that the protocol layer finishes by appending `request_id` and serialising one NDJSON line (Source: [include/aegisdb/query_engine.h:17-22]()). The lower-level entry points `qe_insert`, `qe_get`, and the update variant take an explicit `MemoryRecord` plus a `session_id`/`ttl_ms` for working inserts — designed so the same operations are reachable from C unit tests as from the wire (Source: [include/aegisdb/query_engine.h:25-44]()).

Response shaping is centralised in `json_response.h`: `json_record` serialises a `MemoryRecord`, `json_ok` / `json_error` build the two base shapes, and `json_finish_line` owns the conversion to a malloc'd NDJSON line terminated by `\n` (Source: [include/aegisdb/json_response.h:9-23]()). The status-code vocabulary that drives error responses is mapped to a stable wire string in `src/util/status.c` (e.g. `AEGIS_ERR_NOT_FOUND → "NOT_FOUND"`, `AEGIS_ERR_UNAUTHORIZED → "UNAUTHORIZED"`) so wire errors are predictable for clients (Source: [src/util/status.c:5-22]()).

## Startup, Durability & Recovery

Opening a database is a recovery event. `db_open` (declared alongside the `AegisDB` aggregate) creates the data directory, opens the log, and builds the in-memory indexes; `recovery_run` then scans the append-only log, validates magic + CRC32 framing, drops any torn tail, and sets `db->next_id` to `max(persisted id) + 1`, returning the count of live records loaded (Source: [include/aegisdb/recovery.h:9-16]()). The recovery header notes that it was extended beyond Phase 1 to rebuild the time/tag (Phase 2) and semantic (Phase 3) indexes from the same log scan (Source: [include/aegisdb/recovery.h:1-3]()).

Durability is policy-driven rather than hard-coded. `AegisDurability` exposes `SYNC` (fsync before every ack — no acknowledged loss), `BATCH` (fsync once per `fsync_batch_size` writes — bounds loss by count), and `INTERVAL` (fsync at most every `fsync_interval_ms` via the maintenance thread — bounds loss by time regardless of write rate) (Source: [include/aegisdb/config.h:9-17]()). Identity allocation is centralised and thread-safe: `db_next_id` takes the `id_lock` mutex around a monotonic counter on `AegisDB`, so concurrent inserts cannot collide (Source: [src/storage/db.c:24-30]()).

The binary doubles as its own client. `src/util/client.c` implements the TCP client and the token-hashing helpers used by `gen-token`; the same executable can therefore build, run, and exercise the server without a separate toolchain (Source: [src/util/client.c:1-15]()).

## Claude Code Integration

The companion integration under `integrations/claude-code/` plugs AegisDB into an agent loop without coupling it to the C server. A Python MCP server exposes `mcp__memory__memory_save / _search / _get / _update / _relate` tools, and two Claude Code hooks (`UserPromptSubmit` for automatic recall, `SessionEnd` for capture) augment the model-driven path. Embeddings are pluggable (Voyage / local / none), so the integration never asks the agent for vectors (Source: [integrations/claude-code/README.md:1-17]()). Failures are surfaced through a stable error vocabulary: wire codes such as `NOT_FOUND`, `PAYLOAD_TOO_LARGE`, `IMMUTABLE`, and `UNAUTHORIZED` are mapped to integration codes like `not_found`, `payload_too_large`, `immutable`, `unauthorized` so the agent sees a predictable failure surface (Source: [integrations/claude-code/aegis_mcp/results.py:8-23]()). Recall is bounded by a wall-clock budget — `recall_time_budget_ms` doubles as the read timeout, and a deadline guard ensures a slow backend can never block the turn; on timeout it returns an empty `degraded` result (Source: [integrations/claude-code/aegis_mcp/recall.py:1-13]()).

## See Also

- Wire Protocol Reference — [docs/wire-protocol.md](https://github.com/d4n-larsson/aegisdb/blob/main/docs/wire-protocol.md)
- Quickstart — [docs/quickstart.md](https://github.com/d4n-larsson/aegisdb/blob/main/docs/quickstart.md)
- Configuration & Durability Modes — wiki page covering `AegisDurability` and the `Config` knobs
- Memory Types & Lifecycle — wiki page covering `working` / `episodic` / `semantic`
- Claude Code Integration — wiki page covering MCP tools, hooks, and recall

---

<a id='page-2'></a>

## Storage Engine, Wire Protocol & Query Operations

### Related Pages

Related topics: [AegisDB Overview & System Architecture](#page-1), [Deployment, Configuration & Multi-Tenant Authentication](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/query/query_engine.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/query/query_engine.c)
- [src/util/client.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/util/client.c)
- [src/util/config.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/util/config.c)
- [include/aegisdb/semantic_index.h](https://github.com/d4n-larsson/aegisdb/blob/main/include/aegisdb/semantic_index.h)
- [README.md](https://github.com/d4n-larsson/aegisdb/blob/main/README.md)
- [CLAUDE.md](https://github.com/d4n-larsson/aegisdb/blob/main/CLAUDE.md)
- [site/index.html](https://github.com/d4n-larsson/aegisdb/blob/main/site/index.html)
- [integrations/claude-code/aegis_mcp/results.py](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/aegis_mcp/results.py)
- [integrations/claude-code/aegis_mcp/server.py](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/aegis_mcp/server.py)
</details>

# Storage Engine, Wire Protocol & Query Operations

AegisDB is a C database server purpose-built for AI-agent memory. Three concerns work together as one pipeline: the **storage engine** persists records durably and maintains purpose-built indexes; the **wire protocol** carries requests and responses over a single TCP socket using newline-delimited JSON; and the **query operations** are the verbs (insert, get, search, relate, etc.) routed through a single query engine. This page documents how the three layers fit together.

## Architecture & Data Flow

A request travels through the runtime pipeline described in [CLAUDE.md](https://github.com/d4n-larsson/aegisdb/blob/main/CLAUDE.md): `network → protocol → query → storage`. The query engine ([src/query/query_engine.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/query/query_engine.c)) is the operation router and the place where validation, phase gating, and result shaping happen before the storage layer is touched.

```mermaid
flowchart LR
    Client[TCP Client\nNDJSON] --> Net[network/server\nworker pool]
    Net --> Proto[protocol layer\nJSON request parsing]
    Proto --> QE[query_engine\noperation router]
    QE --> Log[storage/log\nappend-only memory.log]
    QE --> HIdx[hash_index]
    QE --> TIdx[time_index]
    QE --> GIdx[tag_index]
    QE --> SIdx[semantic_index\nexact cosine scan]
    QE --> Proto
    Proto --> Net
    Net --> Client
```

## Storage Engine & Indexes

AegisDB persists `episodic` and `semantic` records to an append-only `memory.log` with per-frame magic bytes and CRC32 checksums ([README.md](https://github.com/d4n-larsson/aegisdb/blob/main/README.md)). `working` records are volatile per-session state and are not persisted to the log.

Four purpose-built indexes are kept in memory and rebuilt from the log on startup:

| Index | Lookup it serves | Source of truth |
|---|---|---|
| `hash_index` | Get/Delete by record ID | Log |
| `time_index` (sorted) | Time-range search | Log |
| `tag_index` (inverted) | Tag search with `all` / `any` match | Log |
| `semantic_index` | Top-K cosine similarity | Log |

The semantic index is a self-contained exact cosine scan declared in [include/aegisdb/semantic_index.h](https://github.com/d4n-larsson/aegisdb/blob/main/include/aegisdb/semantic_index.h). The header explicitly notes that HNSW is the SC-006 scale target, but vendoring a C++ HNSW library conflicts with the single-C17-binary goal — so this exact scan is a drop-in replacement. API surface: `semantic_index_add` / `_remove` / `_search`, returning freshly allocated `out_ids` / `out_scores` arrays that the caller frees.

**Crash recovery.** On startup, AegisDB loads the `memory.index` checkpoint and replays only the log tail written since the checkpoint; if the checkpoint is missing or corrupt it falls back to a full scan. A torn tail from a mid-write crash is trimmed; interior corruption is skipped frame by frame so surrounding records still load ([README.md](https://github.com/d4n-larsson/aegisdb/blob/main/README.md)). The README documents a four-step manual verification: insert, `kill -9`, restart, and `get` each ID — startup logs `recovery complete: N records loaded`.

## Wire Protocol (NDJSON / TCP)

The server speaks newline-delimited JSON over a single TCP port. Default port is **9470**; environment variables `$AEGIS_HOST` / `$AEGIS_PORT` / `$AEGIS_TOKEN` override host, port, and bearer token respectively for the CLI ([src/util/client.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/util/client.c)).

Every request is a JSON object with an `"operation"` field; every response is `{"ok": true, ...}` on success or `{"ok": false, "error": {"code": ..., "message": ...}}` on failure. The Claude Code integration maps wire-protocol error codes into a stable integration vocabulary in [integrations/claude-code/aegis_mcp/results.py](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/aegis_mcp/results.py):

| Wire code | Integration code |
|---|---|
| `NOT_FOUND` | `not_found` |
| `INVALID_REQUEST` | `invalid` |
| `PAYLOAD_TOO_LARGE` | `payload_too_large` |
| `IMMUTABLE` | `immutable` |
| `NOT_READY` | `unavailable` |
| `UNAUTHORIZED` | `unauthorized` |
| `FORBIDDEN` | `forbidden` |
| `INTERNAL` | `unavailable` |

An `INVALID_REQUEST` carrying an embedding is flagged in `from_aegis_error` as the most common sign of a dimension mismatch.

## Query Operations

The router in [src/query/query_engine.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/query/query_engine.c) supports several verbs identified by `"operation"`:

- **`ping` / `stats`** — health and counters.
- **`get` / `delete`** — by numeric `id`.
- **`put`** — insert/update. Requires `type` (`episodic` | `semantic` | `working`), `data`, and optional `tags`, `importance`, `confidence`, `session`, `ttl-ms`. `semantic` upserts and supersedes the previous version (latest wins, no duplicates); `working` enqueues into the per-session ring buffer with TTL.
- **`search`** — by vector (`query`), tags (`all` / `any`), and/or time range (`start` / `end`); ranked by `top_k` and scored by similarity × importance × confidence.

The header comments on `query_engine.c` enumerate the user-stories covered (T016 router; T020–T022/T026 insert/get/ping/errors; T029–T031 semantic update + time/tag search; T037–T038 semantic search + re-ranking; T043–T044 working insert/promote; T047–T049 relate/traverse/agent scoping; T055 phase gating). Validation helpers reject malformed tags (length 1–64, `[A-Za-z0-9_-]` only) and payloads larger than `config.max_payload_bytes`. **Phase gating** (`require_phase`, T055) returns `AEGIS_ERR_NOT_READY` when the operation needs a higher `enabled_phase` than is currently configured.

### Memory lifecycle

The landing page ([site/index.html](https://github.com/d4n-larsson/aegisdb/blob/main/site/index.html)) summarises the three memory types as: **episodic** (append-only immutable events, source of truth for every index), **semantic** (updatable facts where latest version wins), **working** (per-session ring buffer with TTL, promote what proves worth keeping). Recall is exposed three ways — vector similarity, tags (`all` / `any`), and time range — each on its own purpose-built index, not a scan.

## Client, Auth, and Configuration

The bundled CLI ([src/util/client.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/util/client.c)) builds the JSON request object per operation and prints the server response. Default endpoints are `127.0.0.1:9470`, with no token unless `--auth-token` / `--auth-token-file` is supplied ([src/util/config.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/util/config.c)). Tokens are sent in plaintext, so the README explicitly recommends running the server behind an encrypted channel (VPN, SSH tunnel, or TLS proxy).

Multi-tenant isolation is enforced through bearer tokens bound to a **namespace** and a **scope** of `ro`, `rw`, or `admin`. The MCP integration in [integrations/claude-code/aegis_mcp/server.py](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/aegis_mcp/server.py) loads its config, opens an authenticated `AegisClient`, validates that the selected embedding provider's dimension matches `config.embedding_dimensions`, and surfaces startup warnings on stderr before handing off to `MemoryTools`. The MCP server is the only place in the integration that requires the `mcp` SDK; the recall/capture hooks run on the standard library only.

**Embedding dimensions** must be agreed across three places — the server (`--embedding-dim`), the client (`AEGISDB_EMBEDDING_DIMENSIONS` in the integration), and the embedding provider — or semantic search will return `INVALID_REQUEST` as a dimension mismatch. A v0.3.0 container image is published as `ghcr.io/d4n-larsson/aegisdb:0.3.0`, exposing port 9470 and mounting a `/data` volume.

## See Also

- [README.md](https://github.com/d4n-larsson/aegisdb/blob/main/README.md) — features, build instructions, and recovery walkthrough.
- [CLAUDE.md](https://github.com/d4n-larsson/aegisdb/blob/main/CLAUDE.md) — build/test commands and the header-dependency gotcha.
- [docs/wire-protocol.md](https://github.com/d4n-larsson/aegisdb/blob/main/docs/wire-protocol.md) — full wire-protocol reference.
- [docs/quickstart.md](https://github.com/d4n-larsson/aegisdb/blob/main/docs/quickstart.md) — getting started.
- [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md) — Claude Code MCP integration.

---

<a id='page-3'></a>

## Deployment, Configuration & Multi-Tenant Authentication

### Related Pages

Related topics: [AegisDB Overview & System Architecture](#page-1), [Storage Engine, Wire Protocol & Query Operations](#page-2), [Claude Code Memory Integration (MCP Server & Hooks)](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [CLAUDE.md](https://github.com/d4n-larsson/aegisdb/blob/main/CLAUDE.md)
- [Dockerfile](https://github.com/d4n-larsson/aegisdb/blob/main/Dockerfile)
- [docker-compose.yml](https://github.com/d4n-larsson/aegisdb/blob/main/docker-compose.yml)
- [Makefile](https://github.com/d4n-larsson/aegisdb/blob/main/Makefile)
- [CMakeLists.txt](https://github.com/d4n-larsson/aegisdb/blob/main/CMakeLists.txt)
- [src/util/config.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/util/config.c)
- [src/util/client.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/util/client.c)
- [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md)
- [integrations/claude-code/aegis_mcp/server.py](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/aegis_mcp/server.py)
- [integrations/claude-code/aegis_mcp/capture.py](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/aegis_mcp/capture.py)
- [site/index.html](https://github.com/d4n-larsson/aegisdb/blob/main/site/index.html)
</details>

# Deployment, Configuration & Multi-Tenant Authentication

AegisDB is a small, embeddable memory database written in C that exposes a newline-delimited JSON (NDJSON) protocol over TCP. Because it is distributed as a single binary and a published container image, deployment is intentionally minimal, while its authentication subsystem is built for multi-tenant agent fleets where every project gets its own isolated namespace. This page covers how to ship the server, how to configure it, and how the token/namespace model provides isolation.

## Building and Shipping the Server

AegisDB can be built with either a hand-written `Makefile` or CMake, then run directly or as a container. The project root contains both build descriptors, and the latest release (v0.3.0) is published as an OCI image to GitHub Container Registry.

```sh
# Native build
make            # or: cmake -B build && cmake --build build

# Run tests
make test           # C unit tests
make integration    # wire-protocol contract tests
make check          # both
```

A common production invocation looks like this (the `--embedding-dim` value must match across server, MCP integration, and embedding provider — see the dimension note in the integration guide):

```sh
./build/aegisdb --data-dir ./data --port 9470 --embedding-dim 1024
```

Container deployment uses the published image and a named volume for persistence:

```sh
docker run -p 9470:9470 -v aegis-data:/data \
  ghcr.io/d4n-larsson/aegisdb:0.3.0
```

The `Makefile` does not track header dependencies, so after editing any header under `include/`, run `make clean && make` to avoid silent ABI drift between rebuilt object files. Source: [CLAUDE.md](https://github.com/d4n-larsson/aegisdb/blob/main/CLAUDE.md).

## Command-Line Configuration

Configuration is parsed in `src/util/config.c` (`config_parse_args`) and exposed as CLI flags with environment-variable fallbacks. Every option is positional in the help text printed by `usage()`; common flags are summarized below.

| Flag | Purpose | Default / Env |
|------|---------|---------------|
| `--data-dir <path>` | Root directory for the append-only log and indexes | `./data` |
| `--port <p>` | TCP port to listen on | `9470` / `$AEGISDB_PORT` |
| `--embedding-dim <n>` | Vector width used for semantic memory | required |
| `--auth-token <tok>` | Single inline auth token (plaintext at rest) | off |
| `--auth-token-file <path>` | File of one hashed token per line (`sha256$<hex>`) | off |
| `--hash-token <tok>` | Print `sha256$<hex>` for a token and exit | — |
| `--log-level <lvl>` | `error\|warn\|info\|debug` | `info` / `$AEGISDB_LOG_LEVEL` |
| `--health-check` | Probe a local server (`--port`) and exit | — |

When neither `--auth-token` nor `--auth-token-file` is supplied, the server runs **without authentication**. The usage banner explicitly warns that tokens are sent in plaintext and recommends running behind an encrypted channel (VPN, SSH tunnel, or TLS proxy). Source: [src/util/config.c](https://github.com/d4n-larsson/aegisdb/blob/main/src/util/config.c).

A separate `aegisdb gen-token` subcommand is implemented in `src/util/client.c` (`gen_token_main`); it mints a random hex token (via `/dev/urandom`), prints the plaintext once, and expects the operator to paste its `sha256$…` form into the token file.

## Multi-Tenant Authentication Model

AegisDB's auth model is namespace-scoped and token-bound. Each token is issued against a specific namespace and a scope of `ro`, `rw`, or `admin` (no namespace ⇒ global `admin`). The server pins every write and filters every read to the token's tenant, so clients do not need to declare `AEGIS_NAMESPACE` in their MCP config when a token is supplied — the token's namespace is authoritative. Source: [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md).

```mermaid
flowchart LR
  A[Claude Code client] -->|AEGIS_AUTH_TOKEN| M[MCP server<br/>aegis_mcp.server]
  M -->|NDJSON/TCP, plaintext token| S[AegisDB<br/>token + namespace enforced]
  S -->|insert/search/update/relate| N[(Append-only log<br/>namespaced)]
  Admin[Operator] -->|gen-token| S
  S -->|read-only filter| N
```

The MCP wrapper (`integrations/claude-code/aegis_mcp/server.py`) reads `AEGIS_HOST`, `AEGIS_PORT`, `AEGIS_AUTH_TOKEN`, `AEGIS_NAMESPACE`, and `AEGIS_EMBEDDING_DIMENSIONS` from the environment when it builds `MemoryTools`, and validates that the configured embedding provider's dimension matches the server's. If the server is unreachable, the integration degrades gracefully: the agent stays fully usable, tools simply error, and a warning is printed to stderr. Source: [integrations/claude-code/aegis_mcp/server.py](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/aegis_mcp/server.py).

### Shared Pools and Isolation

To have several agents or operators share one memory pool, give them tokens in the **same namespace** and set the same `AEGIS_NAMESPACE` on every client. `admin` tokens are **not** isolated: they can read and write any namespace, so they should be handed only to trusted operators. A read-only token (`--scope ro`) refuses writes with a `forbidden` error. Source: [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md).

## Security, Persistence, and Failure Modes

Because the wire protocol carries tokens in plaintext, the recommended posture is to keep AegisDB on a trusted network segment. The append-only log format means corruption cannot cascade — partial writes are isolated to the segment that was being written, and the rest of the database keeps serving reads. The client CLI (`src/util/client.c`) accepts `--auth-token` and reads `$AEGIS_HOST` / `$AEGIS_PORT` / `$AEGIS_TOKEN` from the environment for scripting; exit code `0` indicates a successful `ok` response, which is the canonical way to script health probes (`aegisdb --health-check` is the built-in equivalent).

Common failure modes to anticipate:

- **Dimension mismatch** — the server, MCP client, and embedding provider must agree on `--embedding-dim`; `server.py` raises `SystemExit` if they do not. Source: [integrations/claude-code/aegis_mcp/server.py](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/aegis_mcp/server.py).
- **Stale header rebuilds** — header changes under `include/` require `make clean && make` to avoid silent struct mismatches. Source: [CLAUDE.md](https://github.com/d4n-larsson/aegisdb/blob/main/CLAUDE.md).
- **Ephemeral capture bleed** — the capture hook (in `aegis_mcp/capture.py`) honours markers like "don't remember", "ephemeral", "scratch", and "secret" to avoid persisting content the user did not intend to keep. Source: [integrations/claude-code/aegis_mcp/capture.py](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/aegis_mcp/capture.py).
- **AegisDB unreachable** — the MCP integration is best-effort; if the backend is down, warnings are logged and the agent remains usable.

## See Also

- [README](https://github.com/d4n-larsson/aegisdb) — overview and quickstart
- [docs/quickstart.md](https://github.com/d4n-larsson/aegisdb/blob/main/docs/quickstart.md) — end-to-end walkthrough
- [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md) — MCP server, hooks, and embedding providers

---

<a id='page-4'></a>

## Claude Code Memory Integration (MCP Server & Hooks)

### Related Pages

Related topics: [AegisDB Overview & System Architecture](#page-1), [Deployment, Configuration & Multi-Tenant Authentication](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md)
- [integrations/claude-code/aegis_mcp/__init__.py](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/aegis_mcp/__init__.py)
- [integrations/claude-code/aegis_mcp/server.py](https://github.com/d4n-larsson/aegis_mcp/server.py)
- [integrations/claude-code/aegis_mcp/hooks.py](https://github.com/d4n-larsson/aegis_mcp/hooks.py)
- [integrations/claude-code/aegis_mcp/capture.py](https://github.com/d4n-larsson/aegis_mcp/capture.py)
- [CLAUDE.md](https://github.com/d4n-larsson/aegisdb/blob/main/CLAUDE.md)
- [integrations/claude-code/examples/mcp.json](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/examples/mcp.json)
- [integrations/claude-code/examples/settings.json](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/examples/settings.json)
</details>

# Claude Code Memory Integration (MCP Server & Hooks)

## Purpose and Scope

The Claude Code Memory Integration turns [AegisDB](https://github.com/d4n-larsson/aegisdb) into the **persistent long-term memory** of Claude Code. Without it, every Claude Code session starts cold: decisions, conventions, fixes, and user preferences the agent has previously learned are lost. The integration gives the agent both **explicit** memory tools and **automatic** context injection, so knowledge persists across sessions and projects remain isolated. Source: [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md).

The package `aegis_mcp` ships two surfaces:

1. A **FastMCP server** that exposes agent-callable memory tools over the Model Context Protocol (stdio). Source: [integrations/claude-code/aegis_mcp/server.py](https://github.com/d4n-larsson/aegis_mcp/server.py).
2. **Hook entry points** that integrate with Claude Code's lifecycle: `UserPromptSubmit` for recall and `SessionEnd` for capture. Source: [integrations/claude-code/aegis_mcp/hooks.py](https://github.com/d4n-larsson/aegis_mcp/hooks.py).

Only `server.py` imports the optional `mcp` SDK; every other module runs on the Python standard library, keeping logic testable in any environment. Source: [integrations/claude-code/aegis_mcp/__init__.py](https://github.com/d4n-larsson/aegis_mcp/__init__.py).

## Architecture

```mermaid
flowchart LR
  CC[Claude Code] -- "MCP stdio" --> MCP[aegis_mcp.server]
  CC -- "UserPromptSubmit hook" --> RH[recall_hook.py]
  CC -- "SessionEnd hook" --> CH[capture_hook.py]
  RH --> CORE[aegis_mcp core<br/>recall.py]
  CH --> CAP[aegis_mcp core<br/>capture.py]
  MCP --> TOOLS[MemoryTools]
  TOOLS --> CLIENT[AegisClient NDJSON/TCP]
  CORE --> CLIENT
  CAP --> CLIENT
  EMB[Embeddings Provider<br/>Voyage / local / fake] --> CLIENT
  CLIENT -- TCP :9470 --> AEGIS[AegisDB C server]
```

The integration is always **best-effort**: if AegisDB is unreachable, hooks silently exit `0` and the agent stays fully usable. Source: [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md).

## MCP Tools (US1 Surface)

The FastMCP server registers five tools, each delegating straight to `MemoryTools` (the only protocol glue is in `server.py`). Source: [integrations/claude-code/aegis_mcp/server.py](https://github.com/d4n-larsson/aegis_mcp/server.py).

| Tool | Purpose |
|------|---------|
| `memory_save` | Persist a memory so it can be recalled in future sessions. |
| `memory_search` | Recall relevant memories by meaning, tags, and/or recency. |
| `memory_get` | Fetch a record by numeric ID. |
| `memory_update` | Update an existing semantic record (latest version wins). |
| `memory_relate` | Create a typed relationship between two records. |

These surface to the model with the `mcp__memory__` prefix (e.g. `mcp__memory__memory_save`). Source: [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md).

## Hooks: Automatic Recall and Capture

Hooks automate the memory loop without requiring the model to call a tool.

**Recall (`UserPromptSubmit`)** — Before each user turn, `hooks.recall()` parses the event JSON on stdin, loads config from the project's `cwd`, and calls `run_recall(prompt, config, provider)`. When the recall returns a non-empty context, the hook emits `hookSpecificOutput.additionalContext`, which Claude Code injects into the prompt. Source: [integrations/claude-code/aegis_mcp/hooks.py](https://github.com/d4n-larsson/aegis_mcp/hooks.py). Recall is bounded by a time budget so slow embeddings cannot stall a turn.

**Capture (`SessionEnd`)** — The `capture.py` module scans session content with a salience heuristic (`_SALIENCE_MARKERS`, `_EPHEMERAL_MARKERS`, `_TAG_RULES`) to decide what to persist. Content matching ephemeral markers (e.g. "don't remember", "secret") is filtered; tag inference maps phrases like "decided" → `decision` and "fixed" → `fix`. Source: [integrations/claude-code/aegis_mcp/capture.py](https://github.com/d4n-larsson/aegis_mcp/capture.py).

Both hooks wrap their bodies in `try/except Exception` and **always exit 0** — a memory failure must never break a turn. Source: [integrations/claude-code/aegis_mcp/hooks.py](https://github.com/d4n-larsson/aegis_mcp/hooks.py).

## Configuration

The integration is configured entirely through environment variables, which is what makes the `uvx aegisdb-mcp` zero-install path work. Source: [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md).

| Variable | Purpose |
|----------|---------|
| `AEGIS_NAMESPACE` | Per-project isolation key; defaults to a global namespace. |
| `AEGIS_EMBEDDING_DIMENSIONS` | Must match the `--embedding-dim` the server was started with. |
| `AEGIS_EMBEDDING_MODE` | Selects provider: `voyage`, `local`, or `fake`/`none`. |
| `VOYAGE_API_KEY` | Required only for the `voyage` provider. |
| `AEGIS_HOST` / `AEGIS_PORT` | AegisDB endpoint (defaults `127.0.0.1:9470`). |
| `AEGIS_AUTH_TOKEN` | Optional bearer token for the AegisDB server. |

At startup, the server validates that the selected provider's `dimension()` equals `AEGIS_EMBEDDING_DIMENSIONS` and exits otherwise. Source: [integrations/claude-code/aegis_mcp/server.py](https://github.com/d4n-larsson/aegis_mcp/server.py).

## Setup (Six Steps)

1. **Start AegisDB** with a fixed embedding dimension that everything else will share, e.g. `./build/aegisdb --data-dir ./data --port 9470 --embedding-dim 1024`. Source: [CLAUDE.md](https://github.com/d4n-larsson/aegisdb/blob/main/CLAUDE.md).
2. **Install** the package — usually skipped by using `uvx aegisdb-mcp` (published on PyPI), or installed editable for local development.
3. **Pick an embedding provider**: Voyage (cloud), local model (e.g. 384-dim), or `fake`/`none` for tag/time-only recall.
4. **Register the MCP server** either with `claude mcp add memory --scope project -e AEGIS_NAMESPACE=my-project -e AEGIS_EMBEDDING_DIMENSIONS=1024 -- uvx aegisdb-mcp` or by committing a project-scope `.mcp.json`. Source: [integrations/claude-code/examples/mcp.json](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/examples/mcp.json).
5. **Enable hooks** in `.claude/settings.json` for `UserPromptSubmit` and `SessionEnd`, pointing at `uvx --from aegisdb-mcp aegisdb-recall-hook` and `aegisdb-capture-hook`. Source: [integrations/claude-code/examples/settings.json](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/examples/settings.json).
6. **Verify** by running `/mcp` inside Claude Code — the `memory` server should list `connected`. Save a fact in one session, start a new session, and ask for it back. Source: [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md).

## Common Failure Modes

- **`/mcp` shows the server but tools error** — AegisDB is unreachable. Check host/port; the agent remains usable either way. Source: [integrations/claude-code/README.md](https://github.com/d4n-larsson/aegisdb/blob/main/integrations/claude-code/README.md).
- **Embedding dimension mismatch at startup** — provider returns a vector length different from `AEGIS_EMBEDDING_DIMENSIONS`; the server exits with an explanatory error. Source: [integrations/claude-code/aegis_mcp/server.py](https://github.com/d4n-larsson/aegis_mcp/server.py).
- **Stale C objects after editing headers** — unrelated to the integration, but the project's `Makefile` does not track header dependencies, so always `make clean && make` after touching `include/`. Source: [CLAUDE.md](https://github.com/d4n-larsson/aegisdb/blob/main/CLAUDE.md).

## See Also

- [AegisDB Wire Protocol & Server Overview](#)
- [Embedding Providers & Configuration](#)
- [Shared Team AegisDB Deployment](#)

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: d4n-larsson/aegisdb

Summary: Found 12 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.

## 1. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: runtime_trace
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Repro command: `docker run -p 9470:9470 -v aegis-data:/data ghcr.io/d4n-larsson/aegisdb:latest # or pin a release: ghcr.io/d4n-larsson/aegisdb:0.1.0`
- Evidence: identity.distribution | https://github.com/d4n-larsson/aegisdb

## 2. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.host_targets | https://github.com/d4n-larsson/aegisdb

## 3. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/d4n-larsson/aegisdb

## 4. Runtime risk - Runtime risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a runtime risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: packet_text.keyword_scan | https://github.com/d4n-larsson/aegisdb

## 5. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/d4n-larsson/aegisdb

## 6. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/d4n-larsson/aegisdb

## 7. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/d4n-larsson/aegisdb

## 8. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/d4n-larsson/aegisdb

## 9. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/d4n-larsson/aegisdb

## 10. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: Developers should check this maintenance risk before relying on the project: v0.1.0
- User impact: Upgrade or migration may change expected behavior: v0.1.0
- Evidence: failure_mode_cluster:github_release | https://github.com/d4n-larsson/aegisdb/releases/tag/v0.1.0

## 11. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: Developers should check this maintenance risk before relying on the project: v0.2.0
- User impact: Upgrade or migration may change expected behavior: v0.2.0
- Evidence: failure_mode_cluster:github_release | https://github.com/d4n-larsson/aegisdb/releases/tag/v0.2.0

## 12. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: Developers should check this maintenance risk before relying on the project: v0.3.0
- User impact: Upgrade or migration may change expected behavior: v0.3.0
- Evidence: failure_mode_cluster:github_release | https://github.com/d4n-larsson/aegisdb/releases/tag/v0.3.0

<!-- canonical_name: d4n-larsson/aegisdb; human_manual_source: deepwiki_human_wiki -->
