mnemory
Memory server
Created by Filip Pytloun
Published in fpytloun/mnemory. Publisher page
283 GitHub stars
What it is
A self-hosted, secure, feature-rich memory system for AI agents and assistants. Provides intelligent fact extraction and deduplication, with an artifact store for detailed content.
AutoGineer overview, from the brain’s own files
mnemory is a self-hosted memory system designed to provide AI agents and assistants with persistent, long-term memory. It functions as an MCP server, allowing it to integrate seamlessly with various AI clients like Claude Code, Cursor, and Open WebUI. The system uses a two-tier architecture: a vector store for fast, semantically searchable summaries and an artifact store for detailed content. It features an intelligent pipeline that performs fact extraction, deduplication, and contradiction resolution in a single LLM call. mnemory also includes a built-in management UI for monitoring and memory maintenance, along with health checks to ensure data quality. It is built for production environments with support for Qdrant, S3/MinIO, and Prometheus monitoring.
How it works
Memory model: Vector store
AutoGineer overview, from the brain’s own files
mnemory operates by intercepting information shared during agent conversations. It uses an LLM pipeline to extract facts, classify them by importance and category, and resolve contradictions against existing data. These facts are stored in a vector database for semantic search, while detailed artifacts are kept in a separate store. During interaction, the system retrieves relevant memories based on the current context and user queries. It also manages memory lifecycles using configurable time-to-live (TTL) settings and provides a health-checking mechanism to detect and fix data inconsistencies.
| Folder | Role | Files |
|---|---|---|
| .github | agent-config | 4 |
| docs | docs | 31 |
| tests | tests | 42 |
| benchmarks | folder | 16 |
| files | folder | 8 |
| integrations | folder | 40 |
| mnemory | folder | 59 |
The agent reads
- get_core_memories evidence: AGENTS.md
The agent writes
- docs/mcp-tools.md evidence: AGENTS.md
- pyproject.toml evidence: AGENTS.md
- docs/configuration.md evidence: AGENTS.md
- add_memory evidence: AGENTS.md
Requirements
Runtimes: Python >=3.11
Databases: Qdrant, Redis
API keys (by name): OPENAI_API_KEY
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Google Antigravity, Kiro, OpenCode, Amp, Roo Code, Cline, JetBrains Junie, Devin (ex-Windsurf)
Set it up
- Not scanned by AutoGineerIts dependencies are installed by pip or uv when you run it and were not scanned by AutoGineer (9 declared). https://pypi.org/project/mnemory/
Created by Filip Pytloun. Published in fpytloun/mnemory. Licence: Apache License 2.0.
Usage
AutoGineer overview, from the brain’s own files
- Connects to AI agents via the Model Context Protocol (MCP).
- Provides a REST API for custom integrations and plugin development.
- Includes a web-based dashboard for memory management and visualization.
- Supports automatic recall and memory persistence across sessions.
- Offers built-in health checks and maintenance tools for memory quality.
- Integrates with monitoring tools like Prometheus and Grafana.
- “What did I decide last week about the database?”
- The agent performs a temporal-aware semantic search across stored memories to retrieve the specific decision made.
- “I drive a Skoda.”
- The system extracts this fact and stores it; if a later statement says 'I bought a Tesla', it updates the record instead of creating a duplicate.
Documentation by Filip Pytloun
<p align="center"> <img src="files/banner.png" alt="mnemory banner" /> </p>
mnemory
Looking for a complete Agent OS? Meet Cognis — a cloud-native, self-hosted workspace where AI agents do real work. Bring together conversations, tools, workflows, and remote executors, with long-term memory powered by mnemory and guardrails provided by Intaris.
Deletion is intentionally best effort, not a verified-erasure or compliance guarantee. Normal deletion retracts and preserves history; explicit privacy erasure attempts physical cleanup. See deletion limits.
Give your AI agents persistent memory. mnemory is a self-hosted MCP server that adds personalization and long-term memory to any AI assistant — Claude Code, ChatGPT, Open WebUI, Cursor, or any MCP-compatible client.
Plug and play. Connect mnemory and your agent immediately starts remembering user preferences, facts, decisions, and context across conversations. No system prompt changes needed.
Self-hosted and secure. Your data stays on your infrastructure. No cloud dependencies, no third-party access to your memories.
Intelligent. Uses a unified LLM pipeline for fact extraction, deduplication, and contradiction resolution in a single call. Memories are semantically searchable, automatically categorized, and expire naturally when no longer relevant.
Features
Zero config —
uvx mnemory, connect your MCP client, done. Works out of the box with any OpenAI-compatible API.Intelligent extraction — A single LLM call extracts facts, classifies metadata, and deduplicates against existing memories.
Contradiction resolution — "I drive a Skoda" + later "I bought a Tesla" = automatic update, not a duplicate.
Two-tier memory — Fast searchable summaries in a vector store + detailed artifact storage (reports, code, research) retrieved on demand.
AI-powered search — Multi-query semantic search with temporal awareness. Ask "What did I decide last week about the database?" and it finds the right memories.
Memory health checks — Built-in three-phase consistency checker (fsck) detects duplicates, contradictions, quality issues, and prompt injection. Run manually or on a schedule with auto-fix.
10+ client support — Claude Code, ChatGPT, Open WebUI, OpenClaw, Cursor, Windsurf, Cline, OpenCode, and more. Native plugins available for automatic recall/remember.
Built-in management UI — Dashboard, semantic search, memory browser with full CRUD, relationship graph visualization, and health check interface. No extra tools needed.
Production ready — Qdrant for vectors, S3/MinIO for artifacts, API key or Cognis JWT authentication, per-user isolation, Kubernetes-friendly stateless HTTP.
Secure by default — API key or Cognis JWT authentication with session-level identity binding, per-user memory isolation, anti-injection safeguards in extraction prompts.
REST API + MCP — Dual interface with the same backend. 16 MCP tools + full REST API with OpenAPI spec. Build plugins, integrations, or use directly.
Prometheus monitoring — Built-in
/metricsendpoint with operation counters and memory gauges. Pre-built Grafana dashboard included.
Quick Start
mnemory needs an OpenAI-compatible API key for LLM and embeddings. It picks up OPENAI_API_KEY from your environment automatically.
uvx mnemoryIf uvx reports No module named 'mcp.server.fastmcp', update uv. Older uv
versions on Alpine can ignore mnemory's MCP v1 dependency constraint. Until
you update uv, run:
uvx --with "mcp<2" mnemoryThat's it. mnemory starts on http://localhost:8050/mcp, stores data in ~/.mnemory/.
Now connect your client — for Claude Code, add to your MCP config:
{
"mcpServers": {
"mnemory": {
"type": "streamable-http",
"url": "http://localhost:8050/mcp",
"headers": {
"X-Agent-Id": "claude-code"
}
}
}
}Start a new conversation. Memory works automatically.
Also available via Docker, pip, or production setup with Qdrant + S3. See the full quick start guide for more clients and options.
Screenshots
<p align="center"> <img src="files/screenshots/ui-dashboard.jpg" alt="Dashboard — memory totals, breakdowns, and operation counts" width="800" /> <br><em>Dashboard with memory breakdowns by type, category, and role</em> </p>
<p align="center"> <img src="files/screenshots/ui-search.jpg" alt="Search — semantic and AI-powered search with filters" width="800" /> <br><em>Semantic search and AI-powered find with filters</em> </p>
<p align="center"> <img src="files/screenshots/ui-graph.jpg" alt="Graph — D3.js force-directed memory relationship visualization" width="800" /> <br><em>Memory relationship graph visualization</em> </p>
See all screenshots and UI features including memory browser, health checks, and artifact management.
Supported Clients
mnemory works with any MCP-compatible client. Some clients also have dedicated plugins for automatic recall/remember.
| Client | MCP | Plugin | Setup Guide |
|---|---|---|---|
| Claude Code | Yes | Yes (hooks) | Guide |
| ChatGPT | Yes (MCP connector) | -- | Guide |
| Claude Desktop | Yes | -- | Guide |
| Hermes Agent | Yes | Yes (plugin) | Guide |
| Open WebUI | Yes | Yes (filter) | Guide |
| OpenCode | Yes | Yes (plugin) | Guide |
| OpenClaw | Yes | Yes (plugin) | Guide |
| Cursor | Yes | -- | Guide |
| Windsurf | Yes | -- | Guide |
| Cline | Yes | -- | Guide |
| Continue.dev | Yes | -- | Guide |
| Codex CLI | Yes | -- | Guide |
MCP = works via Model Context Protocol (LLM-driven tool calls). Plugin = dedicated integration with automatic recall/remember (no LLM tool-calling needed).
How It Works
Storing: You share information naturally. mnemory extracts individual facts, classifies them (type, category, importance), checks for duplicates and contradictions against existing memories, and stores them as searchable vectors — all in a single LLM call.
Searching: Ask a question and mnemory generates multiple search queries covering different angles and associations, runs them in parallel, and reranks results by relevance. Temporal-aware — "what did I decide last week?" just works.
Recalling: At conversation start, your agent loads pinned memories (core facts, preferences, identity) plus recent context. During conversation, relevant memories are found automatically based on what you're discussing.
Maintaining: Memories have configurable TTL — context expires in 7 days, episodic memories in 90. Frequently accessed memories stay alive (reinforcement). The built-in health checker detects and fixes duplicates, contradictions, and quality issues.
Learn more in the architecture docs.
Benchmark
Evaluated on the LoCoMo benchmark — 10 multi-session dialogues with 1540 QA questions across 4 categories:
| System | single_hop | multi_hop | temporal | open_domain | Overall |
|---|---|---|---|---|---|
| mnemory | 63.1 | 53.1 | 74.8 | 78.2 | 73.2 |
| mnemory (gpt-oss-120b) | 66.3 | 59.4 | 68.5 | 73.8 | 70.5 |
| Memobase | 70.9 | 52.1 | 85.0 | 77.2 | 75.8 |
| Mem0-Graph | 65.7 | 47.2 | 58.1 | 75.7 | 68.4 |
| Mem0 | 67.1 | 51.2 | 55.5 | 72.9 | 66.9 |
| Zep | 61.7 | 41.4 | 49.3 | 76.6 | 66.0 |
| LangMem | 62.2 | 47.9 | 23.4 | 71.1 | 58.1 |
Configuration: gpt-5-mini for extraction, text-embedding-3-small for vectors. gpt-oss-120b via Groq is a budget alternative at ~5x lower cost with comparable quality. See configuration docs for model options and benchmarks/ for reproduction.
Documentation
| Document | Description |
|---|---|
| Quick Start | Get running in 5 minutes with any client |
| Configuration | All environment variables — LLM, storage, server, memory behavior |
| Memory Model | Types, categories, importance, TTL, roles, scoping, sub-agents |
| MCP Tools | 16 MCP tools — memory CRUD, search, artifacts |
| REST API | Full REST API, fsck pipeline, recall/remember endpoints |
| Architecture | System diagram, detailed flows for storing/searching/recalling |
| Management UI | Screenshots, features, access, UI development |
| Monitoring | Prometheus metrics, Grafana dashboard |
| Deployment | Production setup, Docker, authentication, Kubernetes |
| Development | Building, testing, linting, contributing |
| Client Guides | Per-client setup instructions (10 clients) |
| System Prompts | Templates for personality agents and custom setups |
License
Apache 2.0
docs/rest-api.md
REST API
mnemory exposes a full REST API alongside the MCP server. The FastAPI sub-app is mounted at /api/ with auto-generated OpenAPI spec at /api/openapi.json and Swagger UI at /api/docs.
Both MCP and REST share the same MemoryService backend and authentication middleware. Authentication may use API keys (Authorization: Bearer <key> / X-API-Key) or Cognis-issued ES256 JWTs (Authorization: Bearer <jwt> with aud=mnemory). The OpenAPI document and Swagger UI are public metadata for client import; documented API operations still require authentication.
Trusted semantic user events
POST /api/user-events/remember/v1 and POST /api/evidence/remember/v1
share semantic ownership for new authenticated event roots. Each route still
requires its own route-bound signed request. Ordinary API keys cannot use either
route or supply trusted provenance.
The service extracts atomic facts, retrieves shared-user Qdrant candidates, and
uses the existing deduplication LLM. Similarity alone does not authorize a write.
The immutable journal plan contains ADD, CONFIRM, UPDATE, or SKIP actions.
ADD establishes provenance with zero confirmations. CONFIRM requires complete
semantic equivalence and an independent root. UPDATE creates a successor revision.
Partial support cannot confirm an entire multi-fact consolidated memory.
Both routes return the same canonical result for one root. A repeated route call
returns replayed without new semantic effects. Historical terminal journals
remain terminal and are not processed again by the new pipeline.
A lease in the existing operations collection serializes trusted semantic decisions within the exact shared user/owner scope. Other users remain independent. This lease does not serialize ordinary tool writes. Target revision checks remain required. Persisted actions and deterministic ADD identities support recovery after a partial write.
The message limit is separate from the extracted-memory limit. Oversized input or extraction output fails explicitly before memory writes; the service does not truncate the signed source or store it unconditionally as one fact.
Cognis can retain paired route delivery, but must sign each request for its actual route. Prefer one ingest call per event to avoid a redundant replay request. The evidence route now shares ADD/UPDATE semantics for new authenticated roots, not only CONFIRM semantics. No credential scope changes are required.
Terminal pre-write rejection
Both trusted routes return HTTP 422 with a structured detail object for a
durable budget rejection. Its fields are:
| Field | Value |
|---|---|
status | rejected |
outcome | rejected_before_write |
operation_id | Canonical event operation UUID |
reason | One reason from the list below |
terminal | true |
retryable | false |
fallback_allowed | false |
semantic_effects | none |
source_retention | caller_queue |
Reasons: input_budget_exceeded, extraction_fact_budget_exceeded,
action_limit_exceeded, or plan_budget_exceeded.
The canonical journal atomically commits an empty rejection record before any semantic actions for this root exist. Its committed state means durable failure, not successful extraction. Both routes replay the identical HTTP failure without another LLM call, even after configuration changes. Existing sealed actions cannot be replaced by a rejection. Historical journal recovery remains unchanged.
Client handling:
Match HTTP
422anddetail.outcome == "rejected_before_write", not HTTP status alone.Mark the existing queue work as terminal failed and retain its complete original signed payload, provenance, operation ID, and reason.
Surface the failure. Do not acknowledge successful memory extraction.
Do not invoke ordinary remember as fallback. Its input truncation is not lossless.
On a timeout, HTTP
503, or any unknown outcome, resume the same authenticated root. Never infer that no effects occurred.
source_retention names the existing caller queue's responsibility. Mnemory keeps
the canonical fingerprint/root binding, not another copy of the rejected source
as a memory. The Cognis failure-retention change must accompany deployment.
Schema-level HTTP 422 validation errors do not carry this durable outcome.
Arbitrarily large messages are not guaranteed successful extraction.
Memory CRUD
| Endpoint | Method | Description |
|---|---|---|
/api/memories | POST | Add a memory |
/api/memories/batch | POST | Batch add memories |
/api/memories/search | POST | Semantic search |
/api/memories/find | POST | AI-powered multi-query search |
/api/memories/core | GET | Core memories (pinned + recent) |
/api/memories/recent | GET | Recent memories |
/api/memories | GET | List memories |
/api/memories/by-ids | POST | Fetch memories by ID list (batch) |
/api/memories/{id} | PUT | Create a successor revision |
/api/memories/{id} | DELETE | Retract without erasing history |
/api/memories/{id}/privacy | DELETE | Best-effort physical lineage and unshared-artifact cleanup |
/api/memories/{id}/history | GET | Get immutable revisions and audit records |
/api/memories/{id}/links | GET | Get exact supersession and derivation links |
/api/memories/{id}/artifacts | POST | Save artifact |
/api/memories/{id}/artifacts | GET | List artifacts |
/api/memories/{id}/artifacts/{aid} | GET | Get artifact (JSON with base64 for binary) |
/api/memories/{id}/artifacts/{aid}/download-token | POST | Generate a signed download token |
/api/memories/{id}/artifacts/{aid}/raw | GET | Download raw artifact bytes (token or API key auth) |
/api/memories/{id}/artifacts/{aid} | DELETE | Delete artifact |
/api/categories | GET | List categories |
Artifact deletion removes the reference from the selected revision. Immutable history can retain the artifact bytes. Lineage privacy erasure attempts physical cleanup; it does not guarantee permanent absence. See deletion limits.
Revision preconditions
The four REST mutation classes accept an optional If-Match header:
PUT /api/memories/{id}DELETE /api/memories/{id}POST /api/memories/{id}/artifactsDELETE /api/memories/{id}/artifacts/{aid}
The value is the positive integer revision returned by memory and mutation
responses. A bare value (If-Match: 3) or strong quoted value
(If-Match: "3") is valid. Weak entity tags, lists, wildcards, snapshot
hashes, zero, negative values, and other strings return HTTP 400.
Memory update bodies and memory delete queries retain expected_revision.
When a request supplies both forms, their integer values must match. A
conflict returns HTTP 409 before mutation. A valid but stale revision also
returns HTTP 409. Artifact mutation responses retain lineage_id, revision,
artifact_revision, and replay state. Signed artifact download URLs are not
affected by this contract.
Fsck operation recovery
POST /api/fsck/audit starts a bounded audit for the exact memory IDs and
revisions of one existing fsck operation. The request accepts at most 20
targets. The audit does not search a neighbor corpus, stamp checked_at, or
change memory metadata. Its completed journal record contains fingerprints and
counts, but no memory content.
POST /api/fsck/operations/{operation_id}/re-evaluate compares an old fsck
operation with a newer completed exact audit bound to that operation. A normal
or historically rehydrated check is rejected. The default
terminalize=false is mutation-free and does not apply actions. With explicit
terminalize=true, the endpoint marks the old journal entry superseded.
Applying the fresh issue remains a separate explicit request.
Failed-session diagnostics and retry
GET /api/sessions/failed/diagnostics returns aggregate failure metadata.
GET /api/sessions/failed/retry-eligibility returns authorized, content-free
candidate metadata. Eligibility validates every linked raw-memory revision for
existence, exact scope, raw layer, active state, and supersession. Diagnostics
include stable ineligibility reason counts.
POST /api/sessions/failed/retry defaults to
dry_run=true, which creates no operation record and changes no session.
Mutation requires LEGACY_FAILED_RETRY_ENABLED=true, an idempotency key, and
an explicit list of no more than ten eligible sessions. Retries run
sequentially and stop on configured failure, revision, or timeout conditions.
The execution path repeats linked-input validation immediately before it
creates or claims the retry journal.
GET /api/memories/core supports:
recent_days— how many days of recent context to includeinclude_stats— whentrue, also return structured stats for the assembled core context
Example response with include_stats=true:
{
"text": "## User Facts\n- User lives in Prague\n...",
"stats": {
"memory_count": 4,
"char_count": 1840,
"estimated_tokens": 460,
"by_type": {"fact": 2, "preference": 1, "episodic": 1},
"by_role": {"user": 4},
"by_section": {"user_facts": 2, "user_preferences": 1, "recent_user_activity": 1},
"section_labels": {"user_facts": "User Facts", "user_preferences": "User Preferences", "recent_user_activity": "User Activity"},
"sections": {"user_facts": ["mem_1", "mem_2"], "user_preferences": ["mem_3"], "recent_user_activity": ["mem_4"]},
"memory_ids": ["mem_1", "mem_2", "mem_3", "mem_4"]
}
}Core memories exclude memory_layer=raw by default, so only consolidated (and legacy no-layer) memories are included in the default injected context.
Session Summaries
Persistent session summaries from the remember endpoint, used by the consolidation service.
| Endpoint | Method | Description |
|---|---|---|
/api/sessions | GET | List session summaries with pagination, search, and sorting (offset, limit, consolidation_state, q, sort_by, sort_dir) |
/api/sessions/{id} | GET | Get a single session summary |
/api/sessions/{id} | DELETE | Delete a session summary (optional delete_memories=true to also delete linked raw memories) |
/api/sessions/{id}/consolidate | POST | Trigger consolidation for a specific session (returns result) |
GET /api/sessions returns:
{
"sessions": [
{
"session_id": "ses_...",
"summary": "...",
"created_at": "2026-03-28T10:00:00+00:00",
"updated_at": "2026-03-28T10:05:00+00:00",
"consolidation_state": "idle"
}
],
"total": 123,
"offset": 0,
"limit": 25,
"has_more": true,
"total_truncated": false
}q: case-insensitive substring match against the stored session summary text and session IDsort_by:updated_at(default) orcreated_atsort_dir:desc(default) orasctotal: count after all filters/search are applied, before pagingtotal_truncated: true if the server hit its internal safety cap while scanning very large session sets
Memory Check (fsck)
Built-in memory consistency checker. Runs a three-phase pipeline to detect quality issues and suggest fixes:
| Endpoint | Method | Description |
|---|---|---|
/api/fsck | POST | Start a memory check (runs in background) |
/api/fsck/audit | POST | Start an exact-target, audit-only check |
/api/fsck/auto-run | POST | Trigger an immediate auto-fsck run for the current user |
/api/fsck/{id} | GET | Poll check status, progress, and results |
/api/fsck/{id}/apply | POST | Apply selected fixes from a completed check |
Four-Phase Pipeline
Security scan (instant) — regex-based detection of prompt injection patterns, confirmed via LLM re-evaluation
Duplicate detection — vector similarity clustering + LLM evaluation of each cluster for duplicates and contradictions
Content quality — LLM batch evaluation for broken, meaningless, or unsalvageable memories
Metadata normalization — LLM batch evaluation for wrong memory_type, categories, importance, pinned, or role
Phases 2–4 run LLM calls in parallel (FSCK_LLM_CONCURRENCY, default 4 workers) for ~4x speedup on large memory sets. Results are cached with configurable TTL (FSCK_CACHE_TTL, default 24 hours) so you can review issues in the UI and apply fixes without re-running the check.
By default, fsck focuses on durable memories (consolidated memories plus legacy memories without a memory_layer field). Raw provisional memories are excluded unless the caller explicitly opts in with include_raw=true.
Incremental mode: Auto-fsck defaults to incremental processing — only memories changed since the last maintenance run are checked. Manual fsck runs a full scan. The checked_at metadata field tracks when each memory was last checked. LLM budget is bounded by FSCK_MAX_LLM_CALLS (default 200 per run); phases execute in priority order (security → duplicates → content quality → metadata normalization), so under budget pressure earlier phases take precedence and later phases catch up in subsequent runs.
Issue types: duplicate, contradiction, quality, reclassify, security
Workflow: Start check → poll until completed → review issues in UI → select and apply fixes. Each fix is a set of actions (update content, update metadata, delete memory). Auto-fsck applies qualifying fixes automatically based on confidence and severity thresholds.
Intelligence Layer
Two high-level endpoints designed for plugin-driven automatic memory management:
POST /api/recall
Combined initialize + search. Call on each user message.
{
"session_id": null,
"query": "Should I buy a dog?",
"include_instructions": true,
"managed": true,
"score_threshold": 0.5,
"labels": {"project": "myapp"}
}First call (no
session_id): creates session, returns instructions + core memories +find_memoriesresultsSubsequent calls: returns only NEW relevant memories via fast
search_memories(no LLM), filtering out already-returned IDsscore_threshold: optional per-request minimum score (0.0-1.0) for search results, applied on top of server'sSEARCH_SCORE_THRESHOLD. Prevents context bloat from weak matches on follow-up messages.labels: optional label filter — only return memories matching these key-value pairs. See Memory Model — Labels.Graceful degradation:
find_memoriesfails ->search_memories-> core memories only -> empty response
POST /api/remember
Fire-and-forget memory storage. Call after each exchange.
{
"session_id": "sess_abc123",
"messages": [
{"role": "user", "content": "I just moved to Berlin"},
{"role": "assistant", "content": "That's exciting!"}
],
"role": null,
"labels": {"conversation_id": "conv-123"}
}The role parameter controls the extraction point of view:
| Value | Behavior |
|---|---|
null (default) | Auto mode — extracts facts from ALL participants. Each fact is attributed to the correct role (user or assistant). Assistant facts are silently dropped if no agent_id is set in the session. |
"user" | Extracts only user facts, suppresses assistant content. |
"assistant" | Extracts only assistant facts (identity, recommendations, conclusions). Requires agent_id via X-Agent-Id header. |
Returns
{"accepted": true}immediately, processes in backgroundReuses the same extraction pipeline as
add_memory(infer=True)— no extra LLM callslabels: optional key-value metadata attached to all extracted memories. Bypasses LLM — stored as-is. See Memory Model — Labels.Stored memory IDs are added to the session to prevent echo on next recall
Rate limited per user (configurable via
REMEMBER_RATE_LIMIT)
Memory Sessions
The recall/remember endpoints use server-side sessions (MemorySession) to track which memories the client already has. This prevents context bloat by only returning new memories on subsequent calls.
Sessions are created on first recall and expire after idle timeout (default 24 hours, configurable via
MEMORY_SESSION_TTL)Both recall and remember calls reset the idle timer (auto-prolong), so active conversations never expire
Sessions are persisted to a pluggable backend (SQLite by default, Redis for clustered deployments) and survive server restarts
Losing a session is harmless — next recall creates a new one
Periodic background sweep cleans up expired sessions from both the in-memory cache and the backend
Session Persistence
Sessions use a write-through cache: an in-memory dict for fast reads, with all mutations written to the backend for durability. On cache miss (e.g., after restart), sessions are loaded lazily from the backend.
| Backend | Use case | Config |
|---|---|---|
sqlite (default) | Single-node, local development, uvx mnemory | SESSION_PATH (default ~/.mnemory/sessions.db) |
redis | Clustered deployments, multiple replicas | REDIS_URL (e.g., redis://host:6379/0) |
memory | Tests, no persistence needed | No additional config |
Auto-detection: if REDIS_URL is set and SESSION_BACKEND is not explicitly set, defaults to redis. See Configuration for all session env vars.
Periodic Maintenance
mnemory includes a built-in background maintenance service that automatically runs memory consistency checks and applies fixes on a configurable schedule.
Enable it by setting FSCK_AUTO_INTERVAL to a non-zero number of hours:
FSCK_AUTO_INTERVAL=24 # Run every 24 hours
FSCK_AUTO_MIN_CONFIDENCE=0.95 # Only apply fixes with >=95% confidence
FSCK_AUTO_MIN_SEVERITY=medium # Only apply medium or high severity fixesHow it works:
The maintenance loop sleeps for the configured interval, then wakes up
All users in the collection are enumerated via a Qdrant scroll
For each user, a full fsck check is run (security scan -> duplicate detection -> quality check)
Issues that meet both the confidence and severity thresholds are automatically applied
Results are recorded in Prometheus metrics (
mnemory_autofsck_*counters + last-run timestamp)Per-user errors are isolated — one failing user does not stop the run
The loop is sleep-first: it waits the full interval before the first run, so startup is not impacted. Auto-applied fixes are visible in the management UI (Check tab status banner) and in the Grafana dashboard (Auto-fsck row).
212 files · 196 not served here
- .dockerignore (not served here)
- .github/workflows/docker-publish.yml (not served here)
- .github/workflows/npm-publish.yml (not served here)
- .github/workflows/openclaw-test.yml (not served here)
- .github/workflows/python-publish.yml (not served here)
- .gitignore (not served here)
- AGENTS.md (not served here)
- ATTRIBUTION.md
- CHANGELOG.md
- Dockerfile (not served here)
- LICENSE
- Makefile (not served here)
- README.md
- benchmarks/README.md (not served here)
- benchmarks/__init__.py (not served here)
- benchmarks/fsck_allocations.py (not served here)
- benchmarks/locomo/__init__.py (not served here)
- benchmarks/locomo/__main__.py (not served here)
- benchmarks/locomo/answer.py (not served here)
- benchmarks/locomo/config.py (not served here)
- benchmarks/locomo/dataset.py (not served here)
- benchmarks/locomo/evaluate.py (not served here)
- benchmarks/locomo/ingest.py (not served here)
- benchmarks/locomo/report.py (not served here)
- benchmarks/locomo/runner.py (not served here)
- benchmarks/locomo/search.py (not served here)
- benchmarks/maintenance_fencing.py (not served here)
- benchmarks/maintenance_fsck.py (not served here)
- benchmarks/maintenance_scan.py (not served here)
- docker-compose.yaml (not served here)
- docs/README.md
- docs/architecture.md
- docs/cache-expiry-bound.md
- docs/clients/chatgpt.md (not served here)
- docs/clients/claude-code.md (not served here)
- docs/clients/claude-desktop.md (not served here)
- docs/clients/cline.md (not served here)
- docs/clients/codex.md (not served here)
- docs/clients/continue.md (not served here)
- docs/clients/cursor.md (not served here)
- docs/clients/hermes.md (not served here)
- docs/clients/open-webui.md (not served here)
- docs/clients/openclaw.md (not served here)
- docs/clients/opencode.md (not served here)
- docs/clients/windsurf.md (not served here)
- docs/configuration.md (not served here)
- docs/deletion.md
- docs/deployment.md (not served here)
- docs/development.md (not served here)
- docs/maintenance-performance.md
- docs/maintenance-recovery.md
- docs/management-ui.md
- docs/mcp-tools.md
- docs/memory-model.md
- docs/monitoring.md
- docs/quickstart.md (not served here)
- docs/resource-audit-optimizations.md
- docs/rest-api.md
- docs/system-prompts/claude-code.md (not served here)
- docs/system-prompts/openwebui-basic.md (not served here)
- docs/system-prompts/openwebui-personality.md (not served here)
- files/banner.png (not served here)
- files/screenshots/ui-check-detail.jpg (not served here)
- files/screenshots/ui-check-progress.jpg (not served here)
- files/screenshots/ui-check-results.jpg (not served here)
- files/screenshots/ui-dashboard.jpg (not served here)
- files/screenshots/ui-graph.jpg (not served here)
- files/screenshots/ui-memories.jpg (not served here)
- files/screenshots/ui-search.jpg (not served here)
- integrations/claude-code/README.md (not served here)
- integrations/claude-code/hooks.json (not served here)
- integrations/claude-code/scripts/recall.sh (not served here)
- integrations/claude-code/scripts/remember.sh (not served here)
- integrations/grafana/README.md (not served here)
- integrations/grafana/dashboard.json (not served here)
- integrations/hermes/README.md (not served here)
- integrations/hermes/__init__.py (not served here)
- integrations/hermes/client.py (not served here)
- integrations/hermes/config.py (not served here)
- integrations/hermes/helpers.py (not served here)
- integrations/hermes/hooks.py (not served here)
- integrations/hermes/plugin.yaml (not served here)
- integrations/hermes/pyproject.toml (not served here)
- integrations/hermes/tests/__init__.py (not served here)
- integrations/hermes/tests/test_config.py (not served here)
- integrations/hermes/tests/test_helpers.py (not served here)
- integrations/hermes/tools.py (not served here)
- integrations/openclaw/README.md (not served here)
- integrations/openclaw/client.ts (not served here)
- integrations/openclaw/config.ts (not served here)
- integrations/openclaw/index.test.ts (not served here)
- integrations/openclaw/index.ts (not served here)
- integrations/openclaw/openclaw.plugin.json (not served here)
- integrations/openclaw/openclaw.test.mjs (not served here)
- integrations/openclaw/package-lock.json (not served here)
- integrations/openclaw/package.json (not served here)
- integrations/openclaw/package.test.mjs (not served here)
- integrations/opencode/README.md (not served here)
- integrations/opencode/client.ts (not served here)
- integrations/opencode/helpers.test.ts (not served here)
- integrations/opencode/helpers.ts (not served here)
- integrations/opencode/hooks.test.ts (not served here)
- integrations/opencode/hooks.ts (not served here)
- integrations/opencode/index.ts (not served here)
- integrations/opencode/opencode.json (not served here)
- integrations/opencode/package.json (not served here)
- integrations/opencode/tools.ts (not served here)
- integrations/openwebui/README.md (not served here)
- integrations/openwebui/mnemory_filter.py (not served here)
- mnemory/__init__.py (not served here)
- mnemory/api/__init__.py (not served here)
- mnemory/api/auth.py (not served here)
- mnemory/api/deps.py (not served here)
- mnemory/api/evidence.py (not served here)
- mnemory/api/fsck.py (not served here)
- mnemory/api/memories.py (not served here)
- mnemory/api/recall.py (not served here)
- mnemory/api/remember.py (not served here)
- mnemory/api/schemas.py (not served here)
- mnemory/api/sessions.py (not served here)
- mnemory/api/ui.py (not served here)
- mnemory/api/ui_projections.py (not served here)
- mnemory/api/user_events.py (not served here)
- mnemory/auth.py (not served here)
- mnemory/cache.py (not served here)
- mnemory/categories.py (not served here)
- mnemory/config.py (not served here)
- mnemory/consolidation.py (not served here)
- mnemory/embeddings.py (not served here)
- mnemory/fsck.py (not served here)
- mnemory/inference.py (not served here)
- mnemory/instructions.py (not served here)
- mnemory/llm.py (not served here)
- mnemory/maintenance.py (not served here)
- mnemory/maintenance_state.py (not served here)
- mnemory/memory.py (not served here)
- mnemory/metrics.py (not served here)
- mnemory/migration.py (not served here)
- mnemory/prompts.py (not served here)
- mnemory/revisions.py (not served here)
- mnemory/sanitize.py (not served here)
- mnemory/server.py (not served here)
- mnemory/session.py (not served here)
- mnemory/sparse.py (not served here)
- mnemory/storage/__init__.py (not served here)
- mnemory/storage/artifact.py (not served here)
- mnemory/storage/session.py (not served here)
- mnemory/storage/vector.py (not served here)
- mnemory/tokens.py (not served here)
- mnemory/trusted_events.py (not served here)
- mnemory/ttl.py (not served here)
- mnemory/ui/__init__.py (not served here)
- mnemory/ui/src/input.css (not served here)
- mnemory/ui/static/css/app.css (not served here)
- mnemory/ui/static/index.html (not served here)
- mnemory/ui/static/js/api.js (not served here)
- mnemory/ui/static/js/app.js (not served here)
- mnemory/ui/static/js/fsck.js (not served here)
- mnemory/ui/static/js/graph.js (not served here)
- mnemory/ui/static/js/memories.js (not served here)
- mnemory/ui/static/js/metrics.js (not served here)
- mnemory/ui/static/js/search.js (not served here)
- mnemory/ui/static/js/sessions.js (not served here)
- mnemory/ui/static/js/user.js (not served here)
- mnemory/ui/static/vendor/alpine.min.js (not served here)
- mnemory/ui/static/vendor/chart.umd.min.js (not served here)
- mnemory/ui/static/vendor/d3.min.js (not served here)
- mnemory/ui/tailwind.config.js (not served here)
- pyproject.toml (not served here)
- tests/__init__.py (not served here)
- tests/conftest.py (not served here)
- tests/contract/fixtures/evidence_remember_v1.json (not served here)
- tests/test_agent_scoping.py (not served here)
- tests/test_api.py (not served here)
- tests/test_artifact.py (not served here)
- tests/test_cache.py (not served here)
- tests/test_cache_bounded.py (not served here)
- tests/test_categories.py (not served here)
- tests/test_config.py (not served here)
- tests/test_consolidation.py (not served here)
- tests/test_e2e.py (not served here)
- tests/test_evidence_transport.py (not served here)
- tests/test_fsck.py (not served here)
- tests/test_fsck_journal.py (not served here)
- tests/test_ghcr_workflow_contract.py (not served here)
- tests/test_jwt_auth.py (not served here)
- tests/test_labels.py (not served here)
- tests/test_llm.py (not served here)
- tests/test_maintenance.py (not served here)
- tests/test_maintenance_scheduling.py (not served here)
- tests/test_maintenance_state.py (not served here)
- tests/test_managed_inference.py (not served here)
- tests/test_memory.py (not served here)
- tests/test_memory_management_api.py (not served here)
- tests/test_metrics.py (not served here)
- tests/test_migration.py (not served here)
- tests/test_prompts.py (not served here)
- tests/test_resource_audit.py (not served here)
- tests/test_revision_preconditions.py (not served here)
- tests/test_revisions.py (not served here)
- tests/test_revisions_remote.py (not served here)
- tests/test_sanitize.py (not served here)
- tests/test_session.py (not served here)
- tests/test_sessions_api.py (not served here)
- tests/test_sparse.py (not served here)
- tests/test_tokens.py (not served here)
- tests/test_trusted_rejection.py (not served here)
- tests/test_trusted_semantic.py (not served here)
- tests/test_ttl.py (not served here)
- tests/test_user_event_ingestion.py (not served here)
- tests/test_validation_decay.py (not served here)
- uv.lock (not served here)
Advantages
- Intelligent extraction and contradiction resolution ensure memory accuracy and prevent duplicate entries. evidence: README.md
- Self-hosted architecture ensures data privacy with no third-party access to stored memories. evidence: README.md
- Supports a wide range of clients through the Model Context Protocol and dedicated plugins. evidence: README.md
Limitations
- Deletion is best-effort and does not guarantee verified erasure or compliance. evidence: README.md
- Most MCP clients require a specific system prompt instruction to initialize memory correctly. evidence: docs/README.md
Security
Risk level: Low risk
This brain runs
Agent instructions that run or fetch something (8)
AGENTS.md:docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/fpytloun/mnemory:latest .AGENTS.md:docker buildx build --platform linux/amd64,linux/arm64 --push -t ghcr.io/fpytloun/mnemory:latest .AGENTS.md:# Unit tests (fast, no API key needed, default pytest run)AGENTS.md:They are **excluded from the default `pytest` run** via `addopts = "-m 'not e2e'"` in `pyproject.toml`.AGENTS.md:**When to run e2e tests:**AGENTS.md:Migrations run automatically on startup before the server accepts requests.AGENTS.md:Each migration has a unique ID (e.g., `001_add_sparse_vectors`), a `description`, and a `run()` methodAGENTS.md:Migrations must be **idempotent** — safe to re-run if interrupted mid-way or if multiple instances start simultaneously
MCP servers (1)
README.md(mnemory):http://localhost:8050/mcp· uses the network
- Low risk: network-instructions (AGENTS.md:88)
Attribution and licence
- Created by
- Filip Pytloun
- Declared authors
- Filip Pytloun (declared in pyproject.toml)
- Publisher
- Filip Pytloun (Community)
- Source
- fpytloun/mnemory · commit 2d83c47
- Licence
- Apache License 2.0 (files served here)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Filip Pytloun.
Install from source
196 of its files are not served here, so there is no ZIP. fpytloun/mnemory at 2d83c47