Back to MCP Servers

Alaya

Neuroscience-inspired memory engine for AI agents. Stores episodes, consolidates knowledge through a Bjork-strength lifecycle (strengthening, transformation, forgetting), and builds a personal knowledge graph with emergent categories, preferences, and semantic recall. Local SQLi…

knowledge-memorygosqliteaiagent
By SecurityRonin
132Updated 2 months agoRustMIT

Installation

npx alaya-mcp

Configuration

{
  "mcpServers": {
    "alaya": {
      "command": "npx",
      "args": ["-y", "alaya"]
    }
  }
}

How to use

  1. Run the installation command above (if needed)
  2. Open your Claude Code settings file (~/.claude/settings.json)
  3. Add the configuration to the mcpServers section
  4. Restart Claude Code to apply changes
<p align="center"> <img src="docs/assets/logo.svg" alt="Alaya logo" width="180"> </p>

Alaya

DOI License: MIT Rust crates.io docs.rs npm PyPI MCP alaya MCP server GitHub stars GitHub Sponsors CI

The only memory engine with neuroscience-grounded memory dynamics — Bjork dual-strength forgetting, retrieval-induced suppression, and Hebbian co-activation — in a zero-dependency embeddable Rust library.

Alaya (Sanskrit: alaya-vijnana, "storehouse consciousness") is an embeddable Rust library. One SQLite file. No external services. Your agent stores conversations, retrieves what matters, and lets the rest fade. The graph reshapes through use, like biological memory.

let alaya = Alaya::open("memory.db")?;
alaya.episodes().store(&episode)?;           // store
let results = alaya.knowledge().query(&query)?; // retrieve
alaya.lifecycle().consolidate(&provider)?;   // distill knowledge
alaya.lifecycle().transform()?;              // dedup, LTD, discover categories
alaya.lifecycle().forget()?;                 // decay what's stale
let cats = alaya.admin().categories(None)?;  // emergent ontology
alaya.admin().purge(PurgeFilter::Session("s1"))?; // cascade delete + tombstones

The Problem

Most AI agents treat memory as flat files. OpenClaw writes to MEMORY.md. Claudesidian writes to Obsidian. Hand-rolled systems write to JSON or Markdown. It works at first.

Then the files grow. Context windows fill. The agent dumps everything into the prompt and hopes the LLM finds what matters.

The cost is measurable. OpenClaw injects ~35,600 tokens of workspace files into every message, 93.5% of which is irrelevant (#9157). Heavy users report $3,600/month in token costs. Community tools like QMD and memsearch cut 70-96% of that waste by replacing full-context injection with ranked retrieval (Levine, 2026).

The structure problem compounds the cost. MEMORY.md conflates decisions, preferences, and knowledge into one unstructured blob. Users independently invent decision.md files, working-context.md snapshots, and 12-layer memory architectures to compensate. Monday you mention "Alice manages the auth team." Wednesday you ask "who handles auth permissions?" The agent retrieves both memories by text similarity but cannot connect them (Chawla, 2026).

How Alaya Solves It

ProblemFile-based memoryAlaya
Token wasteFull-context injection (~35K tokens/message)Ranked retrieval returns only top-k relevant memories
No structureEverything in one file (users invent decision.md workarounds)Three typed stores: episodes, knowledge, preferences
No forgettingFiles grow until you manually curateBjork dual-strength decay separates storage strength from retrieval strength; retrieval-induced forgetting (RIF) actively suppresses competing memories
No associationsFlat files, no links between memoriesHebbian co-retrieval strengthening (LTP/LTD): memories retrieved together strengthen connections; spreading activation finds indirect associations
Brittle preferencesAgent-authored summary, easily driftsImplicit preferences emerge from accumulated impressions via vasana (perfuming), no LLM required; crystallize at threshold
LLM requiredCan't function without oneGraceful degradation at every level. No embeddings? BM25-only. No LLM? Episodes accumulate. Each capability independently optional

Getting Started

MCP Server (recommended for agents)

The fastest way to add Alaya memory to any MCP-compatible agent (Claude Desktop, Claude Code, Cursor, Cline, etc.):

Via npm (no Rust toolchain needed)

Add to your Claude Code config (~/.claude/claude_code_config.json):

{
  "mcpServers": {
    "alaya": {
      "command": "npx",
      "args": ["-y", "alaya-mcp"]
    }
  }
}

Or for Claude Desktop / other MCP clients (with optional LLM auto-consolidation):

{
  "mcpServers": {
    "alaya": {
      "command": "npx",
      "args": ["-y", "alaya-mcp"],
      "env": {
        "ALAYA_LLM_API_KEY": "sk-...",
        "ALAYA_LLM_API_URL": "https://api.openai.com/v1/chat/completions",
        "ALAYA_LLM_MODEL": "gpt-4o-mini"
      }
    }
  }
}

From source (requires Rust 1.75+)

git clone https://github.com/SecurityRonin/alaya.git
cd alaya
cargo build --release --features "mcp llm"

Then add to your MCP config:

{
  "mcpServers": {
    "alaya": {
      "command": "/path/to/alaya/target/release/alaya-mcp"
    }
  }
}

The ALAYA_LLM_* env vars are optional — without them, the server works in prompt mode (reminds the agent to call learn after 10 episodes). With an API key and the llm feature, it auto-consolidates instead.

That's it. Your agent now has 13 memory tools:

ToolWhat it does
rememberStore a conversation message (auto-prompts consolidation after 10 episodes)
recallSearch memory with hybrid retrieval (+ category boost)
learnTeach extracted knowledge directly — agent extracts facts and calls this
statusRich memory statistics: episodes, knowledge breakdown, categories, graph, embeddings
preferencesGet learned user preferences
knowledgeGet distilled semantic facts (+ category filter)
maintainRun memory cleanup (dedup, decay)
purgeDelete memories by session, age, or all
categoriesList emergent categories with stability filter
neighborsGraph neighbors via spreading activation
node_categoryWhich category a node belongs to
import_claude_memImport observations from a claude-mem database
import_claude_codeImport conversation history from Claude Code JSONL files

See docs/mcp-quickstart.md for a full walkthrough with sample interactions and recommended system prompt.

Data is stored in ~/.alaya/memory.db (override with ALAYA_DB env var). Single SQLite file, no external services.

Example interaction — what your agent sees when using Alaya:

Agent: [calls remember(content="User prefers dark mode", role="user", session_id="s1")]
Alaya: Stored episode 1 in session 's1'

Agent: [calls recall(query="user preferences")]
Alaya: Found 1 memories:
  1. [user] (score: 0.847) User prefers dark mode

Agent: [calls status()]
Alaya: Memory Status:
  Episodes: 1 (1 this session, 1 unconsolidated)
  Knowledge: none
  Categories: 0
  Preferences: 0 crystallized, 0 impressions accumulating
  Graph: 0 links
  Embedding coverage: 0/1 nodes (0%)

Environment variables:

VariableDefaultDescription
ALAYA_DB~/.alaya/memory.dbPath to SQLite database
ALAYA_LLM_API_KEY(none)API key for auto-consolidation (enables ExtractionProvider). Requires llm feature.
ALAYA_LLM_API_URLhttps://api.openai.com/v1/chat/completionsOpenAI-compatible chat completions endpoint
ALAYA_LLM_MODELgpt-4o-miniModel name. Any small/fast model works (GPT-4o-mini, Haiku, Gemini Flash, etc.)

Python Bindings

pip install alaya-memory

See alaya-py/README.md for the full Python API.

Rust Library

For embedding Alaya directly into a Rust application:

[dependencies]
alaya = "0.2.2"

Quick Start (Rust)

use alaya::{Alaya, NewEpisode, Role, EpisodeContext, Query, NoOpProvider};

// Open a persistent database (or use open_in_memory() for tests)
let alaya = Alaya::open("memory.db")?;

// Store a conversation episode
alaya.episodes().store(&NewEpisode {
    content: "I've been learning Rust for about six months now".into(),
    role: Role::User,
    session_id: "session-1".into(),
    timestamp: 1740000000,
    context: EpisodeContext::default(),
    embedding: None, // pass Some(vec![...]) if you have embeddings
})?;

// Query with hybrid retrieval (BM25 + vector + graph + RRF)
let results = alaya.knowledge().query(&Query::simple("Rust experience"))?;
for mem in &results {
    println!("[{:.2}] {}", mem.score, mem.content);
}

// Get crystallized preferences
let prefs = alaya.admin().preferences(Some("communication_style"))?;

// Run lifecycle (NoOpProvider works without an LLM)
alaya.lifecycle().consolidate(&NoOpProvider)?;
alaya.lifecycle().transform()?;
alaya.lifecycle().forget()?;

Run the Demo

The demo walks through all eleven capabilities with annotated output and no external dependencies:

git clone https://github.com/SecurityRonin/alaya.git
cd alaya
cargo run --example demo

Architecture

Alaya is a library, not a framework. Your agent owns the conversation loop, the LLM, and the embedding model. Alaya owns memory.

Your Agent                          Alaya
─────────                           ─────

Via MCP (stdio):                    alaya-mcp binary
  remember(content, role, session)    ──▶ episodic store + graph links
  recall(query, boost_category?)      ──▶ BM25 + vector + graph → RRF → rerank
  learn(facts, session_id?)           ──▶ agent-driven knowledge extraction
  status()                            ──▶ rich stats (episodes, knowledge, graph, embeddings)
  preferences(domain?)                ──▶ crystallized behavioral patterns
  knowledge(type?, category?)         ──▶ consolidated semantic nodes
  maintain()                          ──▶ dedup + decay
  purge(scope)                        ──▶ selective or full deletion
  categories(min_stability?)          ──▶ emergent ontology with hierarchy
  neighbors(node, depth?)             ──▶ graph spreading activation
  node_category(node_id)              ──▶ category assignment lookup
  import_claude_mem(path?)            ──▶ import from claude-mem.db
  import_claude_code(path)            ──▶ import from Claude Code JSONL

Via Rust library:                   Alaya coordinator
  alaya.episodes().store(ep)           ──▶ episodic store + graph links
  alaya.knowledge().query(q)           ──▶ BM25 + vector + graph → RRF → rerank
  alaya.admin().preferences(domain?)   ──▶ crystallized behavioral patterns
  alaya.knowledge().filter(f?)         ──▶ consolidated semantic nodes
  alaya.admin().categories(min?)       ──▶ emergent ontology with hierarchy
  alaya.admin().subcategories(id)     

…
View source on GitHub