origin-memorycore
Provides an optional per-turn memory prefetch plugin for Hermes Agent, allowing the agent to recall relevant cold-tier memories with an adaptive semantic threshold.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@origin-memorycoreremember that I prefer dark mode"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
origin-memorycore
MemoryCore is a memory governance layer for LLM agents.
Agents accumulate memory fast — preferences, facts, decisions — and memory that isn't maintained quietly degrades: duplicates accumulate, stale facts linger, the hot tier fills up and starts rejecting writes. MemoryCore keeps that from happening.
It works as a two-tier memory system:
Hot tier — frequently-used behavioral knowledge (preferences, rules, corrections) in a fast local file, always in context.
Cold tier — low-frequency facts, automatically migrated out, stored in an in-process SQLite engine (or a remote memory service if you configure one).
Between the two, a governance core keeps memory healthy:
Write-time dedup — similar facts are deduplicated via full-width/half-width normalization, whitespace folding, and post-punctuation space removal (
normalize_for_compare) before storing; the original content is kept.Capacity control — soft/hard thresholds trigger overflow before the hot tier is full, so it never rejects writes.
Cold-tier governance — periodic dedup/cleanup passes keep the cold tier findable as it grows.
Recycle bin — deleted entries get a 30-day grace period; recalling a trashed entry revives it.
The result: the hot tier stays within budget, the cold tier stays findable, and memory remains maintainable no matter how much the agent accumulates.
Built on the MCP (Model Context Protocol) streamable-http / stdio standard. Works with any MCP client, tested with Hermes Agent.
Features
Memory governance (the core) — three layers of protection for cold-tier data integrity:
Cold-write dedup: before writing to the cold tier, a semantic recall + LLM judge checks for duplicates and updates existing entries instead of creating redundant ones.
Hot-tier dedup normalization:
normalize_for_compareapplies full-width→half-width conversion, whitespace folding, and post-punctuation space removal — ensuring dedup works across CJK punctuation variants and input noise. The original content is always preserved.Capacity hard gate: cold tier enforces a soft limit (6000 entries, triggers one maintenance pass) and a hard limit (10000 entries, forces maintenance loops) — prevents unbounded growth.
Recycle bin (
trash_store.py): deleted cold-tier entries are moved to~/.memorycore/trash.jsonwith a 30-day expiry. Recalling a trashed entry with fresh semantic evidence restores it ("recall to revive").
Cold/hot routing — every write is classified: high-importance or preference-like → hot (local); low-frequency fact → cold (remote); stale status record → dropped.
Six-step overflow — capacity baseline → dedup → stale filtering → merge → safe write (cold first, then delete local) → verification.
Cold-tier maintenance — dedup merge, stale cleanup, conflict resolution, embedding integrity check.
Hot-tier rule budget (LRU cache model) — the hot tier is a cache, not a ranking: rules live under a character budget (default 3200) and lifetime is decided by activity, not age. Inactive low-weight rules are evicted to the cold tier as pointer stubs and restored automatically the moment a recall hits them — no rule is permanent (protection is a weight multiplier, never an exemption).
Capacity control — soft threshold (overflow once before writing) / hard threshold (force overflow) / target ratio. Defaults: 60% / 80% / 40% of a 5000-char limit.
Graceful degradation — cold tier unreachable? Writes fail loudly (never silently dropped), overflow keeps local entries, health check returns local status with
cold.error.Zero core modification — designed as a drop-in companion; your agent's built-in memory tools keep working.
Related MCP server: AI Long-Term Memory MCP Server
Architecture
┌─────────────────────────────── Mac / local ──────────────────────────────┐
│ LLM agent (e.g. Hermes) │
│ │ MCP client │
│ ▼ │
│ MemoryCore MCP server │
│ ├─ local_store.py hot tier: MEMORY.md / USER.md (chars-based) │
│ ├─ classifier.py cold/hot/stale routing rules │
│ ├─ overflow.py six-step overflow │
│ ├─ maintenance.py cold-tier governance │
│ └─ cold_store_client.py → LocalBackend (SQLite, in-process) │
│ or RemoteBackend (MCP streamable-http) │
└──────────────────────────────────────────────────────────────────────────┘
LocalBackend: mnemosyne-memory (in-process engine)
RemoteBackend: remote MCP memory service
Optional (Hermes Agent only): hermes-plugin/memorycore-prefetch
┌───────────────────────────────────────────────────────────────────────┐
│ MemoryProvider plugin (single-model qwen3, enabled by default) │
│ system_prompt_block → static index (always active) │
│ prefetch → ColdStoreClient.recall_results(top_k=20) │
│ → dense ranking → session + hot-tier dedup → top-5 │
│ Disable: MEMORYCORE_PREFETCH_ENABLED=0 │
└───────────────────────────────────────────────────────────────────────┘Quick Start
Prerequisites
ollama — embedding API (install: https://ollama.com)
qwen3-embedding:0.6b — recommended embedding model (1024-dim)
# Install ollama (macOS/Linux)
curl -fsSL https://ollama.com/install.sh | sh
# Pull the embedding model
ollama pull qwen3-embedding:0.6bInstall & run
pip install "origin-memorycore @ git+https://github.com/moonandecho/origin-memorycore.git"
# That's it! MemoryCore runs with ollama for embeddings:
# - Hot tier: MEMORY.md / USER.md (default ~/.hermes/memories)
# - Cold tier: SQLite via mnemosyne-memory (default ~/.memorycore/data/)
# - Embedding: qwen3-embedding:0.6b via ollama (http://localhost:11434/v1)
python -m memorycore.server # stdio transport (default)Data directory layout (all under ~/.memorycore/):
~/.memorycore/
├── data/ # SQLite database (MNEMOSYNE_DATA_DIR)
└── ...Override with MNEMOSYNE_DATA_DIR.
Model switching
Default embedding model is qwen3-embedding:0.6b (1024-dim). Use any
ollama model by setting environment variables:
export MEMORYCORE_EMBED_URL="http://localhost:11434/v1"
export MEMORYCORE_EMBED_MODEL="nomic-embed-text" # or your preferred modelOr point at any OpenAI-compatible embedding API:
export MEMORYCORE_EMBED_URL="https://api.openai.com/v1"
export MEMORYCORE_EMBED_MODEL="text-embedding-3-small"Register it in your MCP client (example for Hermes Agent config.yaml):
mcp_servers:
memorycore:
command: python
args: ["-m", "memorycore.server"]Remote mode (optional)
If you prefer a shared remote Mnemosyne MCP service instead of the local
engine, set MEMORYCORE_COLD_BACKEND=remote:
export MEMORYCORE_COLD_BACKEND=remote
export MNEMOSYNE_URL="http://your-memory-service:9000/mcp"
python -m memorycore.serverExposed tools:
Tool | Purpose |
| Unified write entry: routes cold / hot / stale |
| Actively recall cold-tier memories (read-only, complements per-turn prefetch) |
| Run six-step overflow, target ≤40% |
| Cold-tier governance pass |
| Hot-tier usage + cold-tier stats + thresholds |
| Hot-tier health check: entry types, age, keep/sink plan, LRU observability, sink candidates |
| Rule weight distribution (read-only LRU monitor): w_eff, rule_chars vs budget, next eviction candidates |
Hermes integration — per-turn prefetch
The MCP server is client-agnostic. For Hermes Agent there is an optional companion plugin that provides dual-channel cold-tier access:
Dual-channel design
Static index channel (always active, zero overhead) — a system prompt block listing available topics (configurable via
MEMORYCORE_INDEX_TOPICS, comma-separated), with guidance to usememorycore_recall(query)for on-demand recall.Per-turn prefetch channel (enabled by default) — recalls the cold tier every turn, ranks by dense score, and injects the top-5 into context, so the agent "remembers" relevant content before it speaks. Set
MEMORYCORE_PREFETCH_ENABLED=0to disable and use on-demand recall only.
Prefetch pipeline
query → preprocess → cold-tier recall (20 candidates)
→ dense ranking (qwen3) → top-5
→ session dedup → hot-tier dedup → inject into contextMemoryCore uses a single-model qwen3 architecture (no reranker). Dense scores from qwen3 are used for relative ranking within a batch; there is no absolute threshold — the top-5 candidates by dense score are always injected after dedup.
Graceful degradation
When ollama is unreachable (not installed, not running, or model not pulled), prefetch silently returns an empty string — the conversation proceeds without injected memories, and no error is surfaced to the user. A DEBUG-level log records the probe failure.
Deployment (Hermes Agent)
# 1. install origin-memorycore (provides the cold tier + ColdStoreClient)
pip install "origin-memorycore @ git+https://github.com/moonandecho/origin-memorycore.git"
# 2. put the plugin in Hermes' user plugin dir
mkdir -p ~/.hermes/plugins
cp -r hermes-plugin/memorycore-prefetch ~/.hermes/plugins/
# 3. activate (takes effect next session)
hermes config set memory.provider memorycore-prefetchThree postures after deployment:
Posture | Configuration | Behaviour |
Default (recommended) | no extra config | static index + per-turn prefetch with top-5 injection |
On-demand only |
| static index only, agent queries cold tier via |
Custom embedding |
| point at a different ollama instance or OpenAI-compatible API |
Plugin configuration
Variable | Default | Description |
| (unset) | Set to |
|
| Ollama or OpenAI-compatible embedding API base URL |
|
| Embedding model name (1024-dim recommended) |
| (unset) | Comma-separated topics for the system prompt index block |
Requirements & notes:
Hermes-specific: the plugin imports Hermes runtime modules (
agent.memory_provider) and does not work as a standalone package — it is the Hermes integration side of MemoryCore. Full details: hermes-plugin/memorycore-prefetch/README.md.Every recall keeps a 5s timeout; failures degrade silently to an empty injection and never block the conversation.
Hot-Tier Governance
The hot tier (MEMORY.md / USER.md) is injected into the context every turn, so it must stay small and current. MemoryCore layers three mechanisms on top of the six-step overflow so historical records retire deterministically instead of piling up:
Hot-tier metadata aging
Sidecar metadata:
MEMORY.meta.json/USER.meta.jsonsit next to the .md files, keyed by the SHA-256 of the entry content. Atomic writes plus file locks keep them safe across processes; the §-delimited .md format is untouched, so host memory tools keep working unchanged.Every entry is typed
state(historical decisions / status records) orrule(precepts / preferences):state: retires to the cold tier 7 days after being written (configurable:STATE_TTL_DAYS)rule: never retires by age; after 30 days without an update, long entries (>200 chars) become LLM-compression candidates (configurable:RULE_COMPRESS_DAYS). Rules also get a sustainable exit through the invalidation-signal ladder below — without ever mis-retiring an active preference.
When an entry's content changes, its key changes — the next reconcile re-types the new content and garbage-collects orphaned keys.
Dual write-entry governance
store_factwrite entry: content that looks like a completed decision/status record (a date plus completion markers such as 拍板/已配置, with no behavior instructions) is routed straight to the cold tier — it never enters the hot tier.Plugin
on_memory_writedirect-write channel: after every built-in memory tool add/replace, the entry is typed immediately.stateentries migrate to the cold tier in the background (dedup → cold write confirmed → removed from hot; on cold failure the entry stays with a state stamp as a 7-day backstop). This runs independent of usage thresholds. A single worker thread drains a bounded queue (size 128); when the queue is full the write is skipped and the next overflow reconcile stamps it as a backstop.
Metadata-first overflow
Each overflow run first reconciles metadata (stamps untyped legacy entries, garbage-collects orphans), then retires entries by metadata — keywords only remain as the fallback for untyped entries. A sidecar failure degrades to the keyword path and never blocks the overflow.
Rule invalidation signals (tiered protection)
A hot tier made of pure rule entries has no exit by design ("never sink
a preference"), so short rules that are never edited would otherwise stay
forever and eventually fill the tier. MemoryCore closes that gap with a
pressure ladder: every overflow run measures the real usage (the
baseline) and opens deeper exits as pressure rises (the response). Five
observable signals decide eligibility and ordering — pressure decides
whether to act:
Signal | What it observes | Action |
S1 idle time |
| eligibility gate for compression (30d) and stub-sink (45d) |
S2 completion re-check | embedded date ≥ 60d + ≥ 2 completion markers + zero behavior words | a historical record mis-typed as |
S3 same-topic clustering | lexical similarity (+ optional embedding channel) | same-topic entries merge into one; merged long entries become compression candidates later |
S4 topic activity | local query-activity log (prefetch/recall, rolling 45 days, optional) + LLM dormancy judge | dormant B-class rules under hard pressure: full text to the cold tier (confirmed first), a ≤40-char pointer stub stays hot |
S5 cross-tier redundancy | cold-tier recall match | an equivalent cold copy already exists → drop the hot copy (zero information loss) |
Tiered protection: A-class meta-rules (behavior / interaction / writing-style precepts), red-line rules and importance ≥ 0.9 entries are protected by a weight multiplier (×3.0) — harder to evict, never exempt. Under the Phase 4 budget model they still decay and can retire if they stop being used; the multiplier only makes that take much longer. Stub pointers have a lifecycle of their own (oldest-first GC under hard pressure; the cold tier is never touched), so pointers cannot fill the tier a second time. Every exit is cold-write-first: the local entry changes only after the cold tier confirms, and any failure keeps the original. When a signal is unavailable (no activity log, no LLM key), the ladder degrades to the previous behaviour instead of guessing.
Constants (memorycore/core/config.py): RULE_RETYPE_DAYS=60,
RULE_STUB_IDLE_DAYS=45, ACTIVITY_WINDOW_DAYS=30, MAX_STUB_PER_RUN=3,
STUB_MAX_CHARS=40, IMPORTANCE_PROTECT=0.9.
Rule budget — LRU cache model
Phase 4 (2026-08-26) turns rule retention into a budgeted LRU: the cold tier is the full record, the hot tier keeps only what is actively being used.
No permanent rules. Every rule can retire. Protection is a weight multiplier (×3.0 for A-class / red-line / importance ≥ 0.9), never an exemption — a rule that stops being used decays and eventually leaves.
Character budget. Rule ecology (rules + stubs) is capped at
RULE_BUDGET_CHARS=3200(64% of the 5000-char limit). Writes that overflow the budget trigger immediate eviction of the lowest-weight rules (≤3 per run, cold-write-first, confirmed write before any local change).Activity decides lifetime, not age. Each overflow run scans the queries logged since the last scan (incremental, local
activity.jsonl) and embeds them in one batch against cached rule vectors — semantic cosine ≥HIT_STRONG_COS=0.48counts as a strong hit (+1.0, at most once per scan per rule); when the embedding service is unreachable, lexical bigram evidence degrades to a weak hit (+0.3, no anchor refresh). Weight decays with a 30-day half-life since the last strong touch.Retire to a pointer, restore on use. Evicted rules go to the cold tier first; a ≤40-char stub keeps the cold_id. When a recall — manual
memorycore_recallor the per-turn prefetch — hits that cold_id, the full text returns to the hot tier with a fresh weight and a 7-day residency. A rule comes back the moment it is genuinely used again.Guardrails. New/restored rules hold a 7-day minimum residency (temporary, not permanent); at most 3 rules are evicted per run; the whole mechanism rolls back with
MEMORYCORE_RULE_BUDGET_ENABLED=0; and without an activity log the budget layer disables itself, leaving the hard 5000-char limit as the backstop.
Constants (memorycore/core/config.py): RULE_BUDGET_CHARS=3200,
RULE_MIN_RESIDENCY_DAYS=7, WEIGHT_HALF_LIFE_DAYS=30,
HIT_STRONG_COS=0.48, HIT_WEAK_MODE=degraded, MAX_EVICT_PER_RUN=3.
Health check: memorycore_memory_audit
A read-only tool listing every hot-tier entry with its type, age, retirement plan and keep/sink classification, plus Phase 4 LRU observability per rule (weight / effective weight / last active / residency days) and a rule-chars-vs-budget summary — the observability anchor for diagnosing an overflow that finds nothing to sink.
Activity-dimension sink candidates (2026-08-28): for rule-type entries
where weight < 1.5 and last_active_at is older than 30 days and
the entry is not protected, the audit marks sink_candidate: true with
sink_reason: "low_weight+inactive" and aggregates them into the
lru_sink_candidates counter — visibility-only, does not change
overflow execution.
Scale test & optimisation results
MemoryCore was stress-tested and recall-optimised at ten-thousand-entry cold-tier scale (isolated test environment, zero contact with production data, reproducible results).
Write & capacity
Metric | Result |
Write throughput | 10k entries in 467s, ≈21.4 entries/s (embedding-bound) |
Database size | 300MB / 10k entries |
Memory footprint | process RSS +19MB only, flat throughout — no leak signature |
Query latency — median 48ms at top_k=5; ten-thousand-entry scale matches hundred-entry scale, no latency regression.
Recall quality — three probes:
Exact match (self-recall): 20/20 hit top-1 — exact matching is intact.
Noise rejection (unrelated queries): mean top-1 dense score 0.056, most return 0.0 — unrelated content almost never leaks into results.
Short-query recall (before → after) — the key optimisation outcome:
Stage | Short-query hit rate |
Before | 0/8 |
After | 5/8 (62.5%) |
What was optimised: at high topic density, the fixed candidate
truncation k=max(top_k, 20) pushed detailed memories out of the candidate
pool, so short queries failed to recall them. The fix enlarges the
candidate truncation to k=max(top_k*4, 300) and expands candidates
internally at the recall entry point before truncating the return — every
recall channel (per-turn prefetch + on-demand recall) benefits from a
single fix. The fix is confined to the recall stage; ranking logic is
untouched, behaviour is predictable and reversible.
Note: tests ran on a synthetic 10k-entry database (80 "golden" memories + 9920 filler memories in daily-log tone, same config as production); production data was untouched.
Notes for sqlite-vec users
If you enable sqlite-vec vector indexing for the Mnemosyne cold tier, be aware
that beam.py's _wm_vec_search_sqlite uses a raw similarity formula
sim = 1 - distance / (2 * EMBEDDING_DIM) that collapses float32 distances to
~1.0, making the dynamic threshold effectively useless (all results pass).
Patch: in the float32 branch, replace the formula with
sim = 1 - d² / 2 — this gives the exact cosine similarity for normalised
vectors and restores correct threshold behaviour.
Cold Store Contract
Any service that exposes these five MCP tools can act as the cold tier:
Tool | Semantics |
| Store a memory, return |
| Semantic recall |
| Merge-update an existing memory |
| Delete a memory |
|
|
See examples/cold-store-contract.md for the full contract and a reference client.
Configuration
Env var | Default | Meaning |
|
| Cold-tier backend: |
| (empty) | Cold-tier MCP endpoint (required for |
|
| Local SQLite data directory |
|
| Ollama or OpenAI-compatible embedding API base URL |
|
| Embedding model name (1024-dim) |
|
| Hot-tier directory ( |
|
| Query-activity log for topic-activity signals; |
|
| Cold-tier request timeout (remote mode, seconds) |
Capacity constants live in memorycore/core/config.py (CHAR_LIMIT_*, SOFT_THRESHOLD, HARD_THRESHOLD, TARGET_RATIO).
How It Works
Write —
store_factclassifies the content:importance ≥ 0.8 or matches hot keywords (preferences / rules / corrections / red lines) → hot, kept local
stale markers (short entry, e.g. "已修复 / fixed") → dropped (not migrated)
anything else → cold, written directly to the remote service
Overflow — when hot usage passes the soft threshold, overflow migrates low-frequency entries to the cold tier; at the hard threshold it force-overflows until ≤ target. Order is always write cold first, verify, then delete local — nothing is lost if the cold tier fails.
Maintenance — a periodic pass over the cold tier merges duplicates, removes stale entries, resolves conflicts, and verifies embedding integrity.
License
MIT © 2026 moonandecho
Third-party licenses
mnemosyne-memory — MIT, by AxDSan. The in-process memory engine used by
LocalBackend.MCP Python SDK — MIT.
ollama — MIT. Local embedding API server.
qwen3-embedding — Apache-2.0, by Alibaba Cloud. Default embedding model (not bundled; pulled via ollama).
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceOpen-source AI memory layer for LLM agents. Importance scoring, temporal decay, hierarchical memory (facts, summaries, themes), YMYL prioritization, and active retrieval with contradiction detection. Supports OpenAI, Anthropic, Ollama. Local-first with SQLite + FAISS.48Apache 2.0
- AlicenseNot gradedqualityCmaintenanceProvides persistent long-term memory for AI agents with semantic search and activation-based decay. Enables AI systems to remember across sessions through layered memory architecture and automatic context-aware retrieval.31MIT

Mnemexa MCPofficial
AlicenseAqualityDmaintenanceProvides persistent, self-optimizing memory for AI agents, enabling them to remember preferences and context across sessions and share knowledge across multiple agents.414ISC- AlicenseAqualityBmaintenanceEnables AI agents to manage hierarchical memory with Markdown-based storage, tiered architecture (L0-L3), and hybrid retrieval for transparent and persistent context.8MIT
Related MCP Connectors
Persistent memory and knowledge graphs for AI agents. Hybrid search, context checkpoints, and more.
Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.
Long-term memory for AI agents: semantic facts, episodic events, and procedural workflows
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/moonandecho/origin-memorycore'
If you have feedback or need assistance with the MCP directory API, please join our Discord server