# ai‑memory Crates Explained: A Complete Guide to the 9 Rust Crate Architecture

> Explore the ai-memory Rust workspace and its 9 crates. Understand the architecture behind this long-term memory service for coding agents.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: deep-dive
- Published: 2026-08-28

---

**The ai‑memory project is organized as a Rust workspace of nine independent crates—ai‑memory‑core, ai‑memory‑store, ai‑memory‑wiki, ai‑memory‑mcp, ai‑memory‑hooks, ai‑memory‑llm, ai‑memory‑consolidate, ai‑memory‑workstream, and ai‑memory‑cli—each with a single responsibility that together implement a long‑term memory service for coding agents.**

The **ai‑memory crates** follow a strict separation of concerns documented in [[`docs/ARCHITECTURE.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/ARCHITECTURE.md)](https://github.com/akitaonrails/ai-memory/blob/main/docs/ARCHITECTURE.md#L33-L45). Every crate exposes a typed public API and never reaches into another crate's internals, enforcing architectural invariants like single‑writer SQLite access and one source‑of‑truth for markdown files.

## ai‑memory‑core: Domain Types and Pure Data Models

The **ai‑memory‑core** crate defines the foundational types used across the entire system. It contains no I/O operations—only pure data structures, error types, and identifier types.

Key types include `PageId`, `WorkspaceId`, `NewObservation`, and `ActorContext`. These types establish the domain vocabulary that all other crates depend on.

```rust
// From crates/ai-memory-core/src/lib.rs
use ai_memory_core::{PageId, WorkspaceId, NewObservation, ActorContext};

```

By isolating domain logic in this crate, ai‑memory ensures type safety and consistent semantics without circular dependencies.

## ai‑memory‑store: SQLite Storage Layer with Single‑Writer Actor

The **ai‑memory‑store** crate manages all persistence. It implements a single‑writer actor pattern for SQLite operations, a read‑only connection pool, database migrations, and decay mathematics for memory relevance.

Core APIs include `Store::open` for initialization, `WriterHandle` for exclusive write access, and `ReaderPool` for concurrent reads. The crate also exposes `auto_improve` helper functions.

```rust
use ai_memory_store::Store;
use std::path::Path;

let data_dir = Path::new("/tmp/ai-memory-data");
let store = Store::open(data_dir).expect("failed to open store");

```

All database access flows through this crate—no other component opens SQLite connections directly.

## ai‑memory‑wiki: Atomic Markdown Handling and Git Integration

The **ai‑memory‑wiki** crate serves as the authoritative source‑of‑truth for wiki pages. It provides atomic file operations, filesystem watching, and Git integration for versioned markdown storage.

Primary APIs include `Wiki::write_page` for atomic writes and `extract_links` for analyzing page relationships. This crate ensures that markdown files remain the ground truth regardless of database state.

```rust
use ai_memory_wiki::Wiki;
use ai_memory_core::{NewPage, PagePath, Tier};

let page = NewPage {
    workspace_id: workspace_id,
    project_id: project_id,
    path: PagePath::new("notes/todo.md").unwrap(),
    title: "TODO".into(),
    body: "Add more tests".into(),
    tier: Tier::Episodic,
    frontmatter_json: serde_json::json!({}),
    pinned: false,
    links: vec![],
    author_id: None,
    expires_at: None,
    entities: vec![],
};

Wiki::write_page(&data_dir, page).expect("write failed");

```

## ai‑memory‑mcp: MCP Transport and Tool Router

The **ai‑memory‑mcp** crate implements the Model Context Protocol (MCP) transport layer. It exposes the memory service as a set of MCP tools that coding agents can invoke.

Tool definitions include `memory_query` for semantic search and `memory_write_page` for creating new pages. This crate bridges external AI systems with the internal memory operations.

```rust
use ai_memory_mcp::tools::memory_query;

let result = memory_query(
    "search term",
    None,               // optional workspace
    None,               // optional project
    Some(10),           // limit
    false,              // include expired?
    false,              // explain?
).await?;

```

## ai‑memory‑hooks: Incoming Event Sanitization

The **ai‑memory‑hooks** crate handles external events submitted to the `/hook` endpoint. It defines schemas for incoming payloads and sanitizes raw JSON into valid observations.

The `Sanitizer` type validates and normalizes hook payloads, producing `NewObservation` instances that downstream components can safely process.

```rust
use ai_memory_hooks::{Sanitizer, NewObservation, ObservationKind};

let raw = r#"{
    "event": "session-start",
    "payload": { "cwd": "/my/project" }
}"#;

let sanitized = Sanitizer::sanitize(raw).expect("sanitization failed");
let obs = NewObservation {
    kind: ObservationKind::SessionStart,
    body: sanitized.body,
    // … other fields …
};
store.writer.submit_observation(obs).await?;

```

## ai‑memory‑llm: Provider‑Agnostic LLM and Embedding Traits

The **ai‑memory‑llm** crate abstracts over language model providers. It defines traits for chat completion (`LlmProvider`) and text embedding (`Embedder`), plus authentication boundary types.

This crate enables the system to work with multiple LLM backends without hardcoding provider‑specific logic throughout the codebase.

```rust
use ai_memory_llm::{LlmProvider, ProviderConfig};

let cfg = ProviderConfig::from_env().expect("missing LLM config");
let provider = LlmProvider::new(cfg);
let response = provider.chat("Summarize the recent session").await?;

```

## ai‑memory‑consolidate: Auto‑Improvement Pipeline

The **ai‑memory‑consolidate** crate implements the background memory maintenance pipeline. It handles ingestion, linting, sweeping, and LLM‑driven page rewriting to improve memory quality over time.

Entry points include `memory_consolidate` for the full pipeline and `auto_improve` structs for configurable consolidation runs.

## ai‑memory‑workstream: Native Transcript Handling

The **ai‑memory‑workstream** crate manages read‑only access to native transcripts and provides launch adapters for the managed workstream loop. This enables the `ai‑memory run` command to integrate with external coding sessions.

Key types include `WorkstreamSelection` and `ManagedRunContext`.

```rust
use ai_memory_workstream::run;

run()
    .await
    .expect("workstream run failed");

```

## ai‑memory‑cli: Binary Entry Point and HTTP Glue

The **ai‑memory‑cli** crate provides the `ai‑memory` binary and thin HTTP subcommands that orchestrate the other crates. It contains the main entry point at [[`src/main.rs`](https://github.com/akitaonrails/ai-memory/blob/main/src/main.rs)](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-cli/src/main.rs).

Available subcommands include:
- `init` — initialize a new data directory
- `run` — start the managed workstream loop
- `backup` — create database archives
- `serve` — run the HTTP server

```bash

# Initialise a new data directory

ai-memory init --data-dir /tmp/ai-memory-data

# Show recent pages

ai-memory read-page --path notes/todo.md

# Backup the database

ai-memory backup --to backup.tar.gz

```

## Crate Dependency Patterns and Architectural Constraints

The **ai‑memory crate** architecture enforces several cross‑cutting invariants:

- **Single‑writer SQLite**: Only `ai‑memory‑store` opens write connections
- **Markdown source‑of‑truth**: Only `ai‑memory‑wiki` modifies markdown files
- **Explicit provider auth**: LLM credentials never leak outside `ai‑memory‑llm`
- **No internal reach**: Crates use public APIs exclusively

These constraints prevent the tight coupling that typically degrades long‑term maintainability in multi‑crate Rust projects.

## Summary

- **ai‑memory‑core** — domain types and identifiers with zero I/O
- **ai‑memory‑store** — exclusive SQLite access with single‑writer actor pattern
- **ai‑memory‑wiki** — atomic markdown operations and Git integration
- **ai‑memory‑mcp** — MCP tool exposure for external AI agents
- **ai‑memory‑hooks** — event sanitization for incoming webhooks
- **ai‑memory‑llm** — provider‑agnostic chat and embedding abstractions
- **ai‑memory‑consolidate** — background memory improvement pipeline
- **ai‑memory‑workstream** — transcript handling for managed sessions
- **ai‑memory‑cli** — binary entry point and command orchestration

Each crate's public API is defined in its respective [`src/lib.rs`](https://github.com/akitaonrails/ai-memory/blob/main/src/lib.rs) file under the `crates/` directory, with implementation details hidden behind typed interfaces.

## Frequently Asked Questions

### What is the purpose of splitting ai‑memory into multiple crates?

The workspace structure enforces architectural boundaries at the compiler level. By isolating SQLite access to `ai‑memory‑store` and markdown handling to `ai‑memory‑wiki`, the codebase prevents accidental coupling and maintains clear data flow invariants documented in [`ARCHITECTURE.md`](https://github.com/akitaonrails/ai-memory/blob/main/ARCHITECTURE.md).

### Which ai‑memory crate should I import for custom integrations?

Import `ai‑memory-mcp` for adding memory capabilities to external tools via the Model Context Protocol. For direct database access, use `ai‑memory-store` with `Store::open`. The `ai‑memory-core` crate provides shared types when you need domain primitives without storage dependencies.

### How does ai‑memory‑store handle concurrent access?

`ai‑memory‑store` implements a single‑writer actor pattern: one dedicated task owns the SQLite write connection, while `ReaderPool` manages multiple read‑only connections. This eliminates write contention without sacrificing read parallelism, as enforced by the crate's private constructor for `WriterHandle`.

### Can I use ai‑memory‑llm with providers other than OpenAI?

Yes—`ai‑memory‑llm` defines provider‑agnostic traits (`LlmProvider`, `Embedder`) and uses `ProviderConfig` for authentication boundaries. The trait design allows adding new backends without modifying downstream crates that depend on LLM capabilities.