mii-memory 0.1.0

A local-first memory store for AI agents with CLI, MCP server, and web explorer interfaces.
Documentation

mii-memory

mii-memory is a local-first memory store for AI agents. It gives agents a small, durable place to keep useful facts across global, workspace, and session scopes, then retrieve them later with tag filters, text matching, and semantic ranking from a small MiniLM model.

It can run as a Unix-like CLI, a stdio MCP server, or a small built-in web explorer for browsing the SQLite store.

Contents

Quick Start

Build the binary:

cargo build --release

Builds from this repository include the MiniLM model in the binary by default. The crates.io package is lean enough to publish and does not include the model files, so binaries installed from crates.io need --embeddings <PATH> or MII_MEMORY_EMBEDDINGS=<PATH> pointing to a directory with minilm_model_quint8_avx2.onnx and vocab.txt.

Store a memory in a local SQLite database:

DB="$PWD/.mii-memory.db"

./target/release/mii-memory --db "$DB" set \
  "Use cargo test before changing the storage layer." \
  --mode workspace \
  "$PWD" \
  --tag rust \
  --tag testing

Search for it:

./target/release/mii-memory --db "$DB" get \
  "how should storage changes be tested?" \
  --tag rust \
  --limit 3

List the tags currently available:

./target/release/mii-memory --db "$DB" list-tags --json

Open the explorer:

./target/release/mii-memory --db "$DB" explorer

Then visit http://127.0.0.1:4117.

For everyday use, install the binary from this checkout:

cargo install --path .

Other install options:

# Full embedded binary from the git repository.
cargo install --git https://github.com/mii-nipah/mii-memory

# Lean crates.io binary; pass --embeddings or MII_MEMORY_EMBEDDINGS when running it.
cargo install mii-memory --locked

GitHub Releases also provide a prebuilt embedded binary for the release target, which keeps the classic no-extra-files experience without pushing the large model through crates.io.

What It Does

mii-memory is designed for agent memory that should outlive a single context window without becoming a giant unstructured log. Each memory has content, tags, a scope, optional metadata, optional expiration rules, and embeddings that make later retrieval less brittle than exact text search alone.

Feature snapshot:

  • SQLite-backed storage with schema migrations.
  • Global, workspace, and session memory scopes.
  • Required tags for navigation and filtering.
  • Semantic ranking from a 384-dimensional MiniLM model embedded by default in source and release builds.
  • Positive and negative relevance scores that evolve as memories are retrieved or superseded.
  • Optional expiration based on time, usage count, file existence, file freshness, or active period.
  • One-shot session alerts for reminders that clear when read.
  • Sub-session lineage, using IDs such as parent/child, for agent forks and subagents.
  • CLI, MCP, and web explorer interfaces over the same store.

Core Concepts

Scopes

Scope Use it for Mode reference
global Preferences and facts useful everywhere. None.
workspace Project-specific memory. Defaults to the current directory when omitted.
session Conversation or agent-run memory. Defaults to MII_MEMORY_SESSION, then MCP_SESSION_ID, then default; MII_MEMORY_SESSION_PARENT prefixes the inferred reference when set.

MCP calls infer the mode reference for the current server process, so agent tools only choose the mode.

Tags

Tags are required on writes. They behave like lightweight directories: agents can list tags, filter by positive tags, downrank negative tags, and use tag names as retrieval clues. Tags are normalized to lowercase and deduplicated.

Search and Relevance

On write, mii-memory embeds both the content and tags, then stores a blended vector. On read, it scores memories using semantic similarity, text matches, tag filters, and the memory's accumulated positive and negative scores.

Retrieval increases a memory's positive score. Adding a very similar memory increases the older related memory's negative score, which lets newer or competing information gradually reshape what is considered relevant without deleting history.

Expiration

Expiration is checked when memories are read or browsed. Supported conditions are:

Condition Value examples Meaning
time 30m, 2h, 7d, 2026-06-01, 2026-06-01T12:00:00Z Hide after a duration or instant.
usage 3 Hide after that many retrievals.
file_exist src/lib.rs Hide when the path no longer exists.
file_pristine src/lib.rs Hide when the file changes from its write-time fingerprint.
period 2026-05-01..2026-06-01, 2026-05-01,2026-06-01, { "start": "2026-05-01", "end": "2026-06-01" } Hide outside the active period.

Example:

mii-memory set \
  "This reminder should only be returned twice." \
  --tag reminder \
  --expiration-condition usage 2

Alerts

Alerts are one-shot session reminders. They are separate from normal memories, have no tags or embeddings, and are deleted as soon as they are returned.

mii-memory alert set my-session "Review the storage migration before compacting."
mii-memory alerts my-session

Session references share lineage. A session such as parent/child can see alerts and session memories tied to parent, and the parent can see child entries.

Set MII_MEMORY_SESSION_PARENT=parent to require inferred session references to live under that parent. For example, a CLI session of child becomes parent/child, and an MCP server's generated process session also becomes a child of parent. Already-qualified refs such as parent/child are not prefixed again.

CLI Reference

All CLI commands accept --db <PATH> or MII_MEMORY_DB=<PATH>. Without either, mii-memory uses .mii-memory.db in the current directory.

Store a Memory

mii-memory set <CONTENT> [MODE_REF] \
  --tag <TAG> \
  [--tag <TAG> ...] \
  [--mode global|workspace|session] \
  [--expiration-condition <CONDITION> <VALUE>] \
  [--metadata <TEXT>]

The command prints line-delimited JSON:

{"id":1}

Retrieve Memories

mii-memory get <QUERY> \
  [--tag <TAG> ...] \
  [--n-tag <TAG> ...] \
  [--limit <N>] \
  [--offset <N>] \
  [--mode global|workspace|session] \
  [--mode-ref <REF>]

--tag is a positive filter. --n-tag does not remove memories outright; it downranks matching results.

List Tags

mii-memory list-tags [--filter <TEXT>] [--json]

Without --json, each tag is printed on its own line. With --json, each line includes the tag and current count.

Alerts

mii-memory alert set <SESSION_REF> <CONTENT>
mii-memory alerts <SESSION_REF>

alerts returns matching alerts as JSON lines and clears the returned rows.

Other Commands

mii-memory mcp
mii-memory explorer [--host 127.0.0.1] [--port 4117]

MCP Server

Start the stdio MCP server with:

mii-memory --db /path/to/memory.db mcp

Example MCP client configuration:

{
  "mcpServers": {
    "mii-memory": {
      "command": "mii-memory",
      "args": ["--db", "/path/to/memory.db", "mcp"]
    }
  }
}

The server supports JSON-RPC tool discovery through tools/list and tools/call, plus these tools:

Tool Purpose
memory_set Store a memory with content, mode, tags, optional expiration, and optional metadata.
memory_get Retrieve ranked memories by query, tags, limit, offset, and optional mode.
list_tags List available tags, optionally filtered by text.
alert_set Store a one-shot alert for the current MCP session.
alerts_get Return and clear one-shot alerts for the current MCP session.

For simple scripting, the server also accepts newline-delimited direct commands:

printf '%s\n' '{"command":"list_tags","arguments":{}}' | mii-memory mcp

MCP session references are generated per server process unless MII_MEMORY_SESSION is set. workspace mode references are inferred from the current directory, and session mode references use the configured or generated process session ID. When MII_MEMORY_SESSION_PARENT is set, the MCP session is nested under that parent.

Explorer

The explorer is a small HTTP UI compiled into the binary. It serves the main page, memory browsing endpoints, tag endpoints, and a server-sent-events stream for live updates.

mii-memory explorer --host 127.0.0.1 --port 4117

The UI can:

  • Search memories semantically and by text.
  • Filter by scope and tags.
  • Show scores, usage counts, metadata, expiration rules, and mode references.
  • Refresh automatically when the underlying store changes.

Configuration

Setting Used by Default
--db <PATH> All commands Overrides the database path.
--embeddings <PATH> All commands that embed or search memories Uses external MiniLM files when the binary was built without bundled embeddings.
MII_MEMORY_DB All commands Used when --db is not provided.
MII_MEMORY_EMBEDDINGS All commands that embed or search memories Environment equivalent of --embeddings.
MII_MEMORY_SESSION CLI and MCP session scope Used to infer CLI session mode_ref; overrides the generated MCP server session when set.
MCP_SESSION_ID CLI session scope Fallback session ID when MII_MEMORY_SESSION is not set.
MII_MEMORY_SESSION_PARENT CLI and MCP session scope Prefixes inferred or explicit session refs unless they are already under that parent.

If no database path is configured, mii-memory creates or opens .mii-memory.db in the current directory.

--embeddings <PATH> may point either to a directory containing minilm_model_quint8_avx2.onnx and vocab.txt, or directly to the ONNX file when vocab.txt sits next to it. Repository builds, cargo install --git, and GitHub Release binaries embed these files by default; crates.io builds require an external path because crates.io limits upload size.

Architecture

flowchart LR
    CLI[CLI commands] --> Store[MemoryStore]
    MCP[MCP stdio server] --> Store
    Explorer[Web explorer] --> Store
    Store --> SQLite[(SQLite database)]
    Store --> Expiration[Expiration checks]
    Store --> Embeddings[MiniLM ONNX model]
    Embeddings --> Ranking[Semantic ranking]
    Expiration --> Ranking
    SQLite --> Ranking

Important modules:

Module Responsibility
src/cli.rs Clap command definitions, argument parsing, and CLI output.
src/store.rs SQLite migrations, writes, reads, scoring, browsing, alerts, and scope inference.
src/embedding.rs MiniLM model loading, tokenization, vector encoding, and similarity helpers.
src/expiration.rs Expiration validation and runtime checks.
src/mcp.rs Stdio JSON-RPC/direct-command MCP interface and tool schemas.
src/explorer.rs Minimal HTTP server for the built-in explorer.
src/explorer/index.html Explorer UI.
weights/ ONNX model and vocabulary embedded into local, git, and GitHub Release builds. Excluded from crates.io packages.

The database schema is versioned with SQLite PRAGMA user_version. Data changes should be handled through migrations so existing memory stores stay readable.

Development

Common commands:

cargo fmt
cargo test
cargo test --no-default-features
cargo clippy --all-targets -- -D warnings

The default feature set includes embedded model assets when weights/ is present. Use --no-default-features to exercise the crates.io build, which compiles without bundled embeddings and expects --embeddings at runtime.

Run the CLI during development:

cargo run -- --db ./.mii-memory.dev.db set \
  "Development memory" \
  --tag dev

cargo run -- --db ./.mii-memory.dev.db get "development"

Run the explorer during development:

cargo run -- --db ./.mii-memory.dev.db explorer

Contributing

Contributions are welcome. The most important rule is to protect existing user data: storage changes should be migration-based, non-destructive, and covered by behavior-focused tests.

A good pull request usually includes:

  • A short description of the behavior being changed.
  • Focused tests for storage, expiration, scoring, CLI, MCP, or explorer behavior as appropriate.
  • No unrelated formatting churn or broad refactors mixed into feature work.
  • Clear notes for any database schema migration.

Related Projects