Skip to main content

anima

Long-term, structured memory for AI agents. Extract facts from conversations, deduplicate and supersede them over time, search with hybrid semantic + BM25 retrieval, maintain user profiles, and expose everything over a clean Python library or MCP server.

Features

  • Fact extraction — LLM-backed extraction from conversation turns (OpenRouter by default)
  • Deduplication — embedding similarity + slot rules + LLM review; supersede outdated facts
  • Temporal validity — facts are superseded, not deleted, so you can answer “what did we know before?”
  • Production embeddings — local sentence-transformers or OpenAI by default (not random vectors)
  • Hybrid search — FAISS semantic recall + BM25 rerank, fused with confidence and recency
  • Document ingestion — chunk and index Markdown (extensible ingester registry)
  • User profiles — incremental O(1) profile updates on every add() (requires LLM)
  • Entity graph — optional NetworkX graph of entities and relationships (requires LLM)
  • Lifecycle — confidence decay, TTL expiry, signal-based watch() auto-save
  • MCP server — six tools for Cursor, Claude Desktop, or any MCP client
  • Export / import — JSON backup and restore of memories + profile

Requirements

  • Python 3.12+
  • uv (recommended for development) or pip

Quickstart

Install

pip install anima-mem

Optional extras:

pip install "anima-mem[dev]"        # pytest, pytest-asyncio, python-dotenv
pip install "anima-mem[benchmark]"  # LoCoMo benchmark runner deps (see Development)

Python API

import asyncio
from anima import Config, Memory

async def main():
    mem = Memory(config=Config.from_env())

    await mem.add("User: I moved to Berlin last week.", user_id="alice")
    result = mem.search("Where does Alice live?", user_id="alice")
    print(result.injected_prompt)

    page = mem.list("alice", limit=20)
    print(f"{len(page.items)} of {page.total} memories")

asyncio.run(main())

Without OPENROUTER_API_KEY, Memory() still works for storage and search: each message is stored as a single raw fact and embeddings default to local sentence-transformers. LLM extraction, dedup review, profiles, and entity graph population require OPENROUTER_API_KEY.

MCP server

After installing from PyPI:

{
  "mcpServers": {
    "anima": {
      "command": "anima-mcp"
    }
  }
}

From a local clone (stdio transport):

{
  "mcpServers": {
    "anima": {
      "command": "uv",
      "args": ["run", "anima-mcp"],
      "cwd": "/path/to/anima"
    }
  }
}

Tools: memory_add, memory_search, memory_profile, memory_ingest_file, memory_list, memory_delete

User-controlled memory API

Method Description
mem.list(user_id, offset=0, limit=50) Paginated memory list
mem.pin(memory_id) Mark permanent (no decay / TTL deletion)
mem.export(user_id) MemoryExport JSON snapshot
mem.import_memories(data) Restore from export
export_data = mem.export("alice").model_dump(mode="json")
# ... later or on another machine ...
mem.import_memories(export_data)

Configuration

Set environment variables before creating Memory(config=Config.from_env()). The library reads os.environ only — export variables in your shell or use a tool that loads .env (e.g. uv run).

Variable Default Purpose
OPENROUTER_API_KEY — LLM extraction, dedup, profiles, graph
DATABASE_URL sqlite:///./anima.db SQLAlchemy URL
VECTOR_STORE_PATH ./data/faiss FAISS index directory
GRAPH_STORE_PATH ./data/graph Entity graph JSON
EMBEDDER st (or openai if OPENAI_API_KEY set) st or openai
EMBEDDING_DIM 1536 (OpenAI) / auto for ST Set for OpenAI; ST uses model dim
ST_MODEL all-MiniLM-L6-v2 Local embedding model
DECAY_RATE_PER_WEEK 0.05 Confidence decay rate
WATCH_KEYWORDS remember,... watch() trigger phrases

Memory(config=Config.from_env()) picks a production embedder automatically. Override explicitly if needed:

from anima import Memory, Config, build_embedder

embed_fn, dim = build_embedder()
cfg = Config.from_env()
cfg.embedding_dim = dim
mem = Memory(config=cfg, embed_fn=embed_fn)

Development

Clone the repository (required for tests, benchmarks, and lint):

git clone https://github.com/themillenniumfalcon/anima.git
cd anima
cp .env.example .env   # OPENROUTER_API_KEY — extraction, dedup, profile, graph
uv sync --extra dev    # or: pip install -e ".[dev]"
uv run pytest -v
uv run ruff check src tests

Benchmarks

LoCoMo evaluation requires a repo checkout (the runner is not shipped on PyPI):

uv sync --extra benchmark   # or: pip install -e ".[benchmark]"
uv run python benchmarks/run_locomo.py

Methodology: benchmarks/README.md

License

MIT — see LICENSE.

Metadata

Release files for anima-mem 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for anima-mem 0.1.1
File Size Uploaded Provenance
anima_mem-0.1.1.tar.gz 59.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for anima-mem 0.1.1
File Interpreter ABI Platform
anima_mem-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 133.1 kB

Release files / anima_mem-0.1.1.tar.gz

Download URL anima_mem-0.1.1.tar.gz
Size 59.4 kB
Tags Source
SHA-256 checksum
How to use checksums
16e7095e499eb4f217fc0b9c6355db274c68ad37d0c84b68e595bae30ef9e7dd
BLAKE2b-256 checksum
How to use checksums
4ea37b3661bff9971475c4344496ef232989e952eb386f0823732482bf9c20c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.6.0

Release files / anima_mem-0.1.1-py3-none-any.whl

Download URL anima_mem-0.1.1-py3-none-any.whl
Size 73.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
73b32ed16f394282bd06c48067d71f16228c141bed9ec2f83c5b23d0f99145e3
BLAKE2b-256 checksum
How to use checksums
1a7e1f4f846a037a1643ffe07a45f2a590a4916555359ebac8688ce7da4f599d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.6.0

Security for anima-mem 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page