๐Ÿง  SimpleMem-Cross

February 10, 2026 ยท View on GitHub

๐Ÿง  SimpleMem-Cross

Persistent Cross-Conversation Memory for LLM Agents

Your agents remember everything. Across every conversation.
Context, decisions, and learnings persist automatically โ€” no manual re-injection needed.


License Tests Python Async
FastAPI MCP Tools Storage


Performance


Features โ€ข Quick Start โ€ข API Reference โ€ข Architecture โ€ข Configuration


๐Ÿ† Performance

SystemLoCoMo Scorevs SimpleMem
SimpleMem48โ€”
Claude-Mem29.3+64%

SimpleMem-Cross extends SimpleMem with persistent cross-conversation memory. The original SimpleMem code is preserved byte-identical โ€” all new functionality resides in this cross/ package using composition, not modification.


โœจ Key Features

๐Ÿ”„ Session Lifecycle

Full session management with start โ†’ record โ†’ stop โ†’ end lifecycle. Every event is tracked, timestamped, and persisted.

๐ŸŽฏ Automatic Context Injection

Token-budgeted context from previous sessions is injected automatically at session start. No manual prompt engineering.

๐Ÿ“ Smart Event Collection

Record messages, tool uses, and file changes with 3-tier automatic redaction for secrets and sensitive data.

๐Ÿ” Observation Extraction

Heuristic extraction of decisions, discoveries, and learnings from conversations. Your agent learns from experience.

๐Ÿ”— Provenance Tracking

Every memory entry links back to source evidence. Know exactly where each piece of context originated.

๐Ÿงน Memory Consolidation

Automatic decay, merge, and prune of old memories. Quality over quantity, maintained automatically.


๐Ÿš€ Quick Start

import asyncio
from cross.orchestrator import create_orchestrator

async def main():
    # ๐Ÿ”ง Create the orchestrator for your project
    orch = create_orchestrator(project="my-project")

    # ๐Ÿš€ Start a new session โ€” context from previous sessions is injected automatically
    result = await orch.start_session(
        content_session_id="session-001",
        user_prompt="Continue building the REST API authentication",
    )
    memory_session_id = result["memory_session_id"]
    print(result["context"])  # ๐Ÿ“š Relevant context from previous sessions

    # ๐Ÿ“ Record events during the session
    await orch.record_message(memory_session_id, "User asked about JWT auth")
    await orch.record_tool_use(
        memory_session_id,
        tool_name="read_file",
        tool_input="auth/jwt.py",
        tool_output="class JWTHandler: ...",
    )
    await orch.record_message(memory_session_id, "Implemented token refresh logic", role="assistant")

    # โœ… Finalize โ€” extracts observations, generates summary, stores memory entries
    report = await orch.stop_session(memory_session_id)
    print(f"Stored {report.entries_stored} memory entries, {report.observations_count} observations")

    # ๐Ÿงน Cleanup
    await orch.end_session(memory_session_id)
    orch.close()

asyncio.run(main())

๐Ÿ“ฆ Installation

SimpleMem-Cross uses the same dependencies as SimpleMem, plus standard library sqlite3:

pip install -r requirements.txt

Note: No additional packages required. LanceDB and Pydantic are already in the SimpleMem dependency tree.


๐Ÿ—๏ธ Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           Agent Frameworks (Claude Code / Cursor / custom)      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ–ผ                                       โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”               โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Hook/Lifecycle     โ”‚               โ”‚    HTTP/MCP API         โ”‚
โ”‚  Adapter            โ”‚               โ”‚    (FastAPI)            โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”‚               โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”‚
โ”‚  SessionStart       โ”‚               โ”‚  POST /sessions/start   โ”‚
โ”‚  UserMessage        โ”‚               โ”‚  POST /sessions/{id}/*  โ”‚
โ”‚  ToolUse            โ”‚               โ”‚  POST /search           โ”‚
โ”‚  Stop / End         โ”‚               โ”‚  GET  /stats            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚                                       โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ–ผ
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚         CrossMemOrchestrator          โ”‚
          โ”‚         โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•           โ”‚
          โ”‚  โ€ข Facade for all memory operations   โ”‚
          โ”‚  โ€ข Multi-tenant isolation             โ”‚
          โ”‚  โ€ข Async-first design                 โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ–ผ                         โ–ผ                         โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Session   โ”‚       โ”‚   Context   โ”‚         โ”‚  Consolidation  โ”‚
โ”‚   Manager   โ”‚       โ”‚   Injector  โ”‚         โ”‚     Worker      โ”‚
โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚       โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚         โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚
โ”‚ SQLite DB   โ”‚       โ”‚ Token-      โ”‚         โ”‚ Decay / Merge   โ”‚
โ”‚ โ€ข sessions  โ”‚       โ”‚ budgeted    โ”‚         โ”‚ Prune old       โ”‚
โ”‚ โ€ข events    โ”‚       โ”‚ context     โ”‚         โ”‚ entries         โ”‚
โ”‚ โ€ข summaries โ”‚       โ”‚ bundle      โ”‚         โ”‚                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚                     โ”‚                         โ”‚
       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ–ผ
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚    Cross-Session Vector Store         โ”‚
          โ”‚           (LanceDB)                   โ”‚
          โ”‚    โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•        โ”‚
          โ”‚  โ€ข Semantic search (1024-d vectors)   โ”‚
          โ”‚  โ€ข Keyword matching (BM25-style)      โ”‚
          โ”‚  โ€ข Structured metadata filtering      โ”‚
          โ”‚  โ€ข Provenance fields for tracing      โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ”‚
                             โ–ผ
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚  Reuses SimpleMem 3-Stage Pipeline    โ”‚
          โ”‚  (Composition, not modification)      โ”‚
          โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€    โ”‚
          โ”‚  MemoryBuilder โ†’ HybridRetriever โ†’    โ”‚
          โ”‚  AnswerGenerator                      โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐ŸŽฏ Design Principles

PrincipleImplementation
Composition over modificationOriginal SimpleMem is wrapped, never edited
SQLite for session timelineSessions, events, observations, summaries
LanceDB for vectorsCross-session memory entries with provenance
Hook-based lifecycleSessionStart โ†’ UserMessage/ToolUse โ†’ Stop โ†’ End
Progressive disclosureToken-budgeted context injection at session start
Provenance trackingEvery vector links back to its source evidence

๐Ÿ“š Module Reference

ModuleLinesDescription
types.py227๐Ÿ“‹ Pydantic models โ€” enums, records, ContextBundle, FinalizationReport
storage_sqlite.py805๐Ÿ—„๏ธ SQLite backend โ€” 6 tables (sessions, events, observations, summaries)
storage_lancedb.py542๐Ÿ” LanceDB vector store โ€” semantic/keyword/structured search
hooks.py401๐Ÿช Abstract SessionHooks with 5 async lifecycle methods
collectors.py413๐Ÿ“ RedactionFilter (3-tier regex), thread-safe EventCollector
session_manager.py755๐Ÿ”„ Full lifecycle orchestration โ€” start/record/finalize/end
context_injector.py385๐Ÿ’‰ Token-budgeted ContextBundle builder and renderer
orchestrator.py530๐ŸŽญ Top-level facade CrossMemOrchestrator and factory
api_http.py556๐ŸŒ FastAPI router โ€” 8 REST endpoints with Pydantic models
api_mcp.py620๐Ÿ”Œ MCPToolRegistry โ€” 8 MCP tool definitions with JSON Schema
consolidation.py390๐Ÿงน ConsolidationWorker โ€” decay/merge/prune pipeline

๐Ÿ“– API Reference

CrossMemOrchestrator

MethodParametersReturnsDescription
start_session content_session_id, user_prompt? dict Start session with context injection
record_message memory_session_id, content, role? None Record a chat message event
record_tool_use memory_session_id, tool_name, tool_input, tool_output None Record a tool invocation
stop_session memory_session_id FinalizationReport Finalize: extract observations, generate summary
end_session memory_session_id None Mark session completed, cleanup
search query, top_k? list[CrossMemoryEntry] Semantic search across all sessions
get_context_for_prompt user_prompt? str Build and render context for system prompt
get_stats โ€” dict Storage statistics
close โ€” None Close SQLite connection

๐ŸŒ HTTP API

REST Endpoints
MethodPathDescription
POST/cross/sessions/start๐Ÿš€ Start a new cross-session
POST/cross/sessions/{id}/message๐Ÿ’ฌ Record a message event
POST/cross/sessions/{id}/tool-use๐Ÿ”ง Record a tool-use event
POST/cross/sessions/{id}/stopโœ… Finalize session memory
POST/cross/sessions/{id}/end๐Ÿ End and cleanup session
POST/cross/search๐Ÿ” Search cross-session memories
GET/cross/stats๐Ÿ“Š Get memory system statistics
GET/cross/health๐Ÿ’š Health check with uptime

Running the HTTP Server

from cross.api_http import create_app

app = create_app(project="my-project")

# Run with uvicorn
# uvicorn cross.api_http:app --host 0.0.0.0 --port 8000

Or mount on an existing FastAPI app:

from cross.api_http import create_cross_router
from cross.orchestrator import create_orchestrator

orch = create_orchestrator(project="my-project")
router = create_cross_router(orch)
app.include_router(router, prefix="/cross")

๐Ÿ”Œ MCP Integration

Available MCP Tools
Tool NameDescription
cross_session_start๐Ÿš€ Start a new cross-session memory session
cross_session_message๐Ÿ’ฌ Record a user/assistant message
cross_session_tool_use๐Ÿ”ง Record a tool invocation
cross_session_stopโœ… Finalize and persist session memory
cross_session_end๐Ÿ End session and cleanup
cross_session_search๐Ÿ” Search across all session memories
cross_session_context๐Ÿ“š Get context bundle for system prompt
cross_session_stats๐Ÿ“Š Get memory system statistics

MCP Setup

from cross.api_mcp import create_mcp_tools
from cross.orchestrator import create_orchestrator

orch = create_orchestrator(project="my-project")
tools = create_mcp_tools(orch)

# Get tool definitions for MCP server registration
definitions = tools.get_tool_definitions()

# Dispatch a tool call
result = await tools.call_tool("cross_session_start", {
    "tenant_id": "default",
    "content_session_id": "ses-1",
    "project": "my-project",
    "user_prompt": "Help me debug the auth module",
})

โš™๏ธ Configuration

๐Ÿ“ Default Paths

SettingDefaultDescription
SQLite DB~/.simplemem-cross/cross_memory.dbSession metadata, events, observations
LanceDB~/.simplemem-cross/lancedb_crossVector storage for memory entries
Max context tokens2000Token budget for context injection

๐Ÿ”ง Custom Configuration

orch = create_orchestrator(
    project="my-project",
    tenant_id="team-alpha",
    db_path="/custom/path/memory.db",
    lancedb_path="/custom/path/lancedb",
    max_context_tokens=3000,
)

๐Ÿ‘ฅ Multi-Tenant Support

Pass tenant_id to isolate memory across tenants. Each tenant's memories are stored and retrieved independently.


๐Ÿงน Consolidation

The consolidation worker maintains memory quality over time:

from cross.consolidation import ConsolidationWorker, ConsolidationPolicy

policy = ConsolidationPolicy(
    max_age_days=90,                    # โฐ Decay entries older than 90 days
    decay_factor=0.9,                   # ๐Ÿ“‰ Multiply importance by 0.9 per period
    merge_similarity_threshold=0.95,   # ๐Ÿ”— Merge near-duplicates
    min_importance=0.05,               # ๐Ÿ—‘๏ธ Prune below this threshold
)

worker = ConsolidationWorker(sqlite_storage, vector_store, policy)
result = worker.run(tenant_id="default")

print(f"๐Ÿ“‰ Decayed: {result.decayed_count}")
print(f"๐Ÿ”— Merged: {result.merged_count}")
print(f"๐Ÿ—‘๏ธ Pruned: {result.pruned_count}")

๐Ÿงช Testing

# ๐Ÿงช Run all cross-session tests
pytest cross/tests/ -v

# ๐Ÿ“‹ Run specific test module
pytest cross/tests/test_types.py -v
pytest cross/tests/test_storage.py -v
pytest cross/tests/test_e2e.py -v

Note: Tests use real SQLite (temp databases) and mock LanceDB. No external services, API keys, or GPU required.


๐Ÿ“ Constraints

ConstraintReason
โœ… Original SimpleMem is byte-identicalPublished research paper; never modified
โœ… All code in EnglishNo Chinese in code, comments, docstrings, or strings
โœ… Python-onlyMatches SimpleMem's tech stack
โœ… Composition patternSimpleMem is wrapped via duck typing, never subclassed


โฌ† Back to Top


Made with โค๏ธ by the SimpleMem Team