What is loci?
loci is a typed long-term memory layer for AI agents. It extracts durable facts from conversations, stores them in SQLite, ranks them for later recall, and removes information that is no longer useful.
The project is based on the idea that memories need both a place and a structure. Instead of treating every saved statement alike, loci distinguishes preferences, deadlines, goals, relationships, and other types of information so they can follow appropriate lifecycles.
loci was ported from the memory system used in production by Lima and rewritten to be independent of any particular host application.
How the memory system works
Typed memories
Every memory belongs to one of eight categories:
- routine
- study
- preferences
- finance
- goals
- relationships
- constraints
- ephemeral
Memories also have four importance tiers and a status lifecycle. This structure lets the system treat a lasting preference differently from a temporary deadline or short-lived fact.
Two extraction paths
Extraction combines two mechanisms. A model-based extractor reads an exchange for meaning, while regular-expression heuristics detect explicitly supported phrasings. The results are merged with model output taking precedence.
The regex path can continue running when the model provider is unavailable. Model calls, provider SDKs, and API keys are deliberately left to the host application, which can inject a ModelExtractor.
Filtering, ranking, and decay
A write filter prevents transient moods and similar short-lived statements from becoming permanent profile data. For example, a statement such as “Tired today” may be true for a few hours but misleading months later.
When memories are added to model context, loci limits the result to twelve facts. It ranks them by importance, then considers deadline proximity and recency. This cap prevents the prompt from growing without bound.
Daily consolidation and decay keep the store useful:
- Exact duplicates are merged.
- Unconfirmed guesses eventually expire.
- Ephemeral facts have a 24-hour time-to-live.
- Completed goals expire after 90 days.
Choose an integration
loci provides one shared core and two adapters.
MCP server
The MCP adapter works with any compatible MCP client. It exposes three tools: remember, recall, and forget.
MCP is request-and-response based, so it has no automatic end-of-turn hook. The agent must call remember intentionally. Memory can be recalled and injected into context on request.
Hermes plugin
The Hermes adapter provides the same three tools, but it also supports automatic extraction and injects context before every call. This is possible because Hermes offers a post_llm_call hook that can inspect an exchange after the model responds.
Direct Python integration
Use the core library directly when you control the agent loop and want to decide when extraction, persistence, recall, and context injection occur.
Installation and setup
Install the core package
pip install mowave-lociInstall MCP support
pip install mowave-loci[mcp]After installing the MCP extra, add loci to your MCP client configuration:
{
"mcpServers": {
"loci": {
"command": "python",
"args": ["-m", "loci.adapters.mcp_server.server"]
}
}
}Restart or reload the client so it discovers the remember, recall, and forget tools.
Install the Hermes plugin
hermes plugins install <you>/loci
hermes plugins enable lociReplace <you>/loci with the appropriate plugin repository or source for your installation.
Configure storage
By default, loci stores memories in a SQLite database at ~/.loci/memory.db. Set the LOCI_DB environment variable to use a different file.
export LOCI_DB=/path/to/memory.dbNo separate database server is required.
Basic usage in Python
The core workflow is to create a store, extract candidate memories, filter them, save accepted memories, and add active memories to the system prompt.
from loci import Store, extract, should_persist, context_block
store = Store()
for memory in extract(
"eu prefiro respostas curtas",
assistant_text=reply,
):
if should_persist(memory):
store.upsert(memory)
system_prompt += "\n\n" + context_block(store.active())In this example, reply represents the assistant text associated with the exchange. The Portuguese user message means that the user prefers short answers.
Store()opens the configured SQLite memory store.extract(...)produces candidate memories from the exchange.should_persist(memory)applies the write filter.store.upsert(memory)inserts or updates an accepted memory.store.active()retrieves active memories.context_block(...)formats those memories for prompt injection.
Using the MCP tools
Once the MCP server is configured, the connected agent can use three operations:
- remember: deliberately save a fact that should persist.
- recall: retrieve stored information when it is relevant.
- forget: remove information that should no longer be retained.
Because the MCP adapter does not extract memories automatically, agent instructions should make clear when the agent is expected to call remember. Do not assume that every completed conversation turn will be inspected and saved.
Advanced integration tips
Keep provider logic outside the core
The loci core uses only the Python standard library. Your application owns model calls, API keys, and provider SDKs. If semantic extraction requires a model, inject a ModelExtractor from the host rather than adding provider dependencies to the core.
Run lifecycle jobs from the host
loci defines memory shape, consolidation, and decay behavior, but it does not schedule daily work. Use the host's cron, s6, systemd, or equivalent scheduler to trigger daily jobs.
Preserve the context cap
Avoid bypassing the ranked context block by adding the entire database to every prompt. The twelve-fact cap exists to control context growth while favoring important, timely, and recent information.
Use the appropriate adapter
- Choose MCP when portability across MCP clients matters and explicit memory operations are acceptable.
- Choose Hermes when you want automatic extraction after model calls and memory injection before every call.
- Choose the direct Python API when your application owns the agent loop and needs precise control over persistence and prompt construction.
Let the host own transport and sessions
The agent loop, tool dispatch, sessions, transport, and authentication are outside the core's responsibility. Hosts such as Hermes, OpenClaw, or Claude Code manage the surrounding runtime, while adapters handle host-specific transport and authentication.
Run the test suite
pytest -qThe project includes 92 tests that run against a real SQLite store in a temporary file. The store itself is not mocked, which helps verify behavior against the same storage technology used in actual deployments.
Conclusion
loci gives AI agents a compact, typed, and durable memory layer without requiring a separate server. Its shared core handles memory structure and lifecycle, while MCP, Hermes, or your own Python agent supplies the surrounding runtime. Start with the adapter that matches your host, keep extraction and scheduling responsibilities explicit, and use ranked context injection to prevent memory from overwhelming the prompt.
