Skip to main content
Glama
moonandecho

origin-memorycore

by moonandecho

origin-memorycore

English | 简体中文

MemoryCore es una capa de gobernanza de memoria para agentes LLM.

Los agentes acumulan memoria rápido — preferencias, hechos, decisiones — y la memoria que no se mantiene se degrada silenciosamente: se acumulan duplicados, los hechos obsoletos permanecen, la capa caliente se llena y empieza a rechazar escrituras. MemoryCore evita que eso ocurra.

Funciona como un sistema de memoria de dos niveles:

  • Capa caliente — conocimiento conductual de uso frecuente (preferencias, reglas, correcciones) en un archivo local rápido, siempre en contexto.

  • Capa fría — hechos de baja frecuencia, migrados automáticamente, almacenados en un motor SQLite en proceso (o un servicio de memoria remoto si se configura uno).

Entre ambas, un núcleo de gobernanza mantiene la memoria saludable:

  • Deduplicación en escritura — los hechos similares se fusionan antes de almacenarse, no se duplican.

  • Control de capacidad — los umbrales suave/duro activan el desbordamiento antes de que la capa caliente esté llena, de modo que nunca rechaza escrituras.

  • Gobernanza de la capa fría — pasadas periódicas de deduplicación/limpieza mantienen la capa fría localizable a medida que crece.

  • Papelera de reciclaje — las entradas eliminadas tienen un período de gracia de 30 días; recuperar una entrada en la papelera la revive.

El resultado: la capa caliente se mantiene dentro del presupuesto, la capa fría sigue siendo localizable y la memoria sigue siendo mantenible sin importar cuánto acumule el agente.

Construido sobre el estándar MCP (Model Context Protocol) streamable-http / stdio. Funciona con cualquier cliente MCP, probado con Hermes Agent.

Características

  • Gobernanza de memoria (el núcleo) — tres capas de protección para la integridad de los datos de la capa fría:

    • Deduplicación en escritura en frío: antes de escribir en la capa fría, una recuperación semántica + un juez LLM comprueban si hay duplicados y actualizan las entradas existentes en lugar de crear otras redundantes.

    • Puerta dura de capacidad: la capa fría aplica un límite suave (6000 entradas, activa una pasada de mantenimiento) y un límite duro (10000 entradas, fuerza bucles de mantenimiento) — evita el crecimiento ilimitado.

    • Papelera de reciclaje (trash_store.py): las entradas eliminadas de la capa fría se mueven a ~/.memorycore/trash.json con una caducidad de 30 días. Recuperar una entrada en la papelera con nueva evidencia semántica la restaura ("recuperar para revivir").

  • Enrutamiento frío/caliente — cada escritura se clasifica: alta importancia o similar a preferencia → caliente (local); hecho de baja frecuencia → frío (remoto); registro de estado obsoleto → descartado.

  • Desbordamiento en seis pasos — línea base de capacidad → deduplicación → filtrado de obsoletos → fusión → escritura segura (primero en frío, luego borrar local) → verificación.

  • Mantenimiento de la capa fría — fusión de duplicados, limpieza de obsoletos, resolución de conflictos, comprobación de integridad de embeddings.

  • Control de capacidad — umbral suave (desbordar una vez antes de escribir) / umbral duro (forzar desbordamiento) / ratio objetivo. Valores por defecto: 60% / 80% / 40% de un límite de 5000 caracteres.

  • Degradación elegante — ¿Capa fría inalcanzable? Las escrituras fallan de forma ruidosa (nunca se descartan silenciosamente), el desbordamiento conserva las entradas locales, la comprobación de salud devuelve el estado local con cold.error.

  • Modificación cero del núcleo — diseñado como acompañante de integración directa; las herramientas de memoria integradas de tu agente siguen funcionando.

Related MCP server: AI Long-Term Memory MCP Server

Arquitectura

┌─────────────────────────────── 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                              │
  └───────────────────────────────────────────────────────────────────────┘

Inicio rápido

Requisitos previos

  • ollama — API de embeddings (instalación: https://ollama.com)

  • qwen3-embedding:0.6b — modelo de embeddings recomendado (1024 dimensiones)

# Install ollama (macOS/Linux)
curl -fsSL https://ollama.com/install.sh | sh

# Pull the embedding model
ollama pull qwen3-embedding:0.6b

Instalación y ejecución

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)

Estructura del directorio de datos (todo bajo ~/.memorycore/):

~/.memorycore/
├── data/          # SQLite database (MNEMOSYNE_DATA_DIR)
└── ...

Se puede sobrescribir con MNEMOSYNE_DATA_DIR.

Cambio de modelo

El modelo de embeddings por defecto es qwen3-embedding:0.6b (1024 dimensiones). Usa cualquier modelo de ollama estableciendo variables de entorno:

export MEMORYCORE_EMBED_URL="http://localhost:11434/v1"
export MEMORYCORE_EMBED_MODEL="nomic-embed-text"   # or your preferred model

O apunta a cualquier API de embeddings compatible con OpenAI:

export MEMORYCORE_EMBED_URL="https://api.openai.com/v1"
export MEMORYCORE_EMBED_MODEL="text-embedding-3-small"

Regístralo en tu cliente MCP (ejemplo para Hermes Agent config.yaml):

mcp_servers:
  memorycore:
    command: python
    args: ["-m", "memorycore.server"]

Modo remoto (opcional)

Si prefieres un servicio MCP Mnemosyne remoto compartido en lugar del motor local, establece MEMORYCORE_COLD_BACKEND=remote:

export MEMORYCORE_COLD_BACKEND=remote
export MNEMOSYNE_URL="http://your-memory-service:9000/mcp"
python -m memorycore.server

Herramientas expuestas:

Tool

Propósito

memorycore_store_fact(content, importance, scope, target)

Punto de entrada de escritura unificado: enruta frío / caliente / obsoleto

memorycore_recall(query, top_k)

Recupera activamente memorias de la capa fría (solo lectura, complementa la precarga por turno)

memorycore_trigger_overflow(target)

Ejecuta el desbordamiento en seis pasos, objetivo ≤40%

memorycore_run_cold_storage_maintenance()

Pasada de gobernanza de la capa fría

memorycore_get_memory_usage()

Uso de la capa caliente + estadísticas de la capa fría + umbrales

Integración con Hermes — precarga por turno

El servidor MCP es independiente del cliente. Para Hermes Agent existe un plugin complementario opcional que proporciona acceso de doble canal a la capa fría:

Diseño de doble canal

  • Canal de índice estático (siempre activo, cero sobrecarga) — un bloque de prompt de sistema que lista los temas disponibles (configurable mediante MEMORYCORE_INDEX_TOPICS, separados por comas), con indicaciones para usar memorycore_recall(query) para la recuperación bajo demanda.

  • Canal de precarga por turno (habilitado por defecto) — recupera la capa fría en cada turno, ordena por puntuación densa e inyecta el top-5 en el contexto, de modo que el agente "recuerda" el contenido relevante antes de hablar. Establece MEMORYCORE_PREFETCH_ENABLED=0 para deshabilitarlo y usar solo la recuperación bajo demanda.

Canalización de precarga

query → preprocess → cold-tier recall (20 candidates)
  → dense ranking (qwen3) → top-5
  → session dedup → hot-tier dedup → inject into context

MemoryCore utiliza una arquitectura de modelo único qwen3 (sin reranker). Las puntuaciones densas de qwen3 se usan para la clasificación relativa dentro de un lote; no hay un umbral absoluto: los 5 mejores candidatos por puntuación densa se inyectan siempre después de la deduplicación.

Degradación elegante

Cuando ollama es inalcanzable (no está instalado, no se está ejecutando o el modelo no se ha descargado), la precarga devuelve silenciosamente una cadena vacía: la conversación continúa sin memorias inyectadas y no se muestra ningún error al usuario. Un registro de nivel DEBUG documenta el fallo de la comprobación.

Despliegue (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-prefetch

Tres posturas tras el despliegue:

Postura

Configuración

Comportamiento

Predeterminada (recomendada)

sin configuración adicional

índice estático + precarga por turno con inyección del top-5

Solo bajo demanda

MEMORYCORE_PREFETCH_ENABLED=0

solo índice estático, el agente consulta la capa fría mediante memorycore_recall

Embedding personalizado

MEMORYCORE_EMBED_URL + MEMORYCORE_EMBED_MODEL

apuntar a una instancia diferente de ollama o a una API compatible con OpenAI

Configuración del plugin

Variable

Por defecto

Descripción

MEMORYCORE_PREFETCH_ENABLED

(sin establecer)

Establécelo en 0 para deshabilitar la precarga por turno

MEMORYCORE_EMBED_URL

http://localhost:11434/v1

URL base de la API de embeddings de Ollama o compatible con OpenAI

MEMORYCORE_EMBED_MODEL

qwen3-embedding:0.6b

Nombre del modelo de embeddings (1024 dimensiones recomendado)

MEMORYCORE_INDEX_TOPICS

(sin establecer)

Temas separados por comas para el bloque de índice del prompt de sistema

Requisitos y notas:

  • Específico de Hermes: el plugin importa módulos de runtime de Hermes (agent.memory_provider) y no funciona como paquete independiente: es el lado de integración con Hermes de MemoryCore. Detalles completos: hermes-plugin/memorycore-prefetch/README.md.

  • Cada recuperación mantiene un tiempo de espera de 5 s; los fallos degradan silenciosamente a una inyección vacía y nunca bloquean la conversación.

Gobernanza de la capa caliente

La capa caliente (MEMORY.md / USER.md) se inyecta en el contexto en cada turno, por lo que debe mantenerse pequeña y actualizada. MemoryCore superpone tres mecanismos sobre el desbordamiento en seis pasos para que los registros históricos se retiren de forma determinista en lugar de acumularse:

Envejecimiento de metadatos de la capa caliente

  • Metadatos sidecar: MEMORY.meta.json / USER.meta.json se encuentran junto a los archivos .md, indexados por el SHA-256 del contenido de la entrada. Las escrituras atómicas y los bloqueos de archivo los mantienen seguros entre procesos; el formato .md delimitado por § no se toca, por lo que las herramientas de memoria del host siguen funcionando sin cambios.

  • Cada entrada se tipifica como state (decisiones históricas / registros de estado) o rule (preceptos / preferencias):

    • state: se retira a la capa fría 7 días después de escribirse (configurable: STATE_TTL_DAYS)

    • rule: nunca se retira por antigüedad; después de 30 días sin actualización, las entradas largas (>200 caracteres) se convierten en candidatas a compresión LLM (configurable: RULE_COMPRESS_DAYS). Las reglas también tienen una salida sostenible mediante la escalera de señales de invalidación que aparece a continuación — sin retirar erróneamente una preferencia activa.

  • Cuando el contenido de una entrada cambia, su clave cambia: la siguiente reconciliación vuelve a tipificar el nuevo contenido y elimina las claves huérfanas.

Gobernanza dual de entrada de escritura

  • Entrada de escritura store_fact: el contenido que parece un registro de decisión/estado completado (una fecha más marcadores de finalización como 拍板/已配置, sin instrucciones de comportamiento) se enruta directamente a la capa fría — nunca entra en la capa caliente.

  • Canal de escritura directa del plugin on_memory_write: después de cada adición/reemplazo de una herramienta de memoria integrada, la entrada se tipifica inmediatamente. Las entradas state migran a la capa fría en segundo plano (deduplicación → escritura en frío confirmada → retirada de la capa caliente; si falla el frío, la entrada permanece con un sello de estado como respaldo de 7 días). Esto se ejecuta independientemente de los umbrales de uso. Un único hilo de trabajo drena una cola acotada (tamaño 128); cuando la cola está llena, la escritura se omite y la siguiente reconciliación de desbordamiento la sella como respaldo.

Desbordamiento con metadatos primero

Cada ejecución de desbordamiento primero reconcilia los metadatos (sella las entradas heredadas sin tipificar, elimina las huérfanas) y luego retira las entradas según los metadatos: las palabras clave solo permanecen como respaldo para las entradas sin tipificar. Un fallo del sidecar degrada a la ruta de palabras clave y nunca bloquea el desbordamiento.

Señales de invalidación de reglas (protección escalonada)

Una capa caliente compuesta exclusivamente por entradas rule no tiene salida por diseño ("nunca hundir una preferencia"), por lo que las reglas cortas que nunca se editan permanecerían para siempre y acabarían llenando la capa. MemoryCore cierra esa brecha con una escalera de presión: cada ejecución de desbordamiento mide el uso real (la línea base) y abre salidas más profundas a medida que aumenta la presión (la respuesta). Cinco señales observables deciden elegibilidad y orden — la presión decide si actuar:

Señal

Qué observa

Acción

S1 tiempo de inactividad

updated_at en el sidecar

puerta de elegibilidad para compresión (30d) y stub-sink (45d)

S2 re-verificación de finalización

fecha incrustada ≥ 60d + ≥ 2 marcadores de finalización + cero palabras de comportamiento

un registro histórico mal tipado como rule se re-etiqueta como state → sumidero TTL normal de 7 días

S3 agrupación por mismo tema

similitud léxica (+ canal de embeddings opcional)

las entradas del mismo tema se fusionan en una; las entradas largas fusionadas se convierten en candidatas a compresión más tarde

S4 actividad del tema

registro local de actividad de consultas (prefetch/recall, ventana móvil de 45 días, opcional) + juez de inactividad LLM

reglas de clase B inactivas bajo presión fuerte: texto completo al nivel frío (confirmado primero), un puntero stub de ≤40 caracteres permanece caliente

S5 redundancia entre niveles

coincidencia de recuperación en el nivel frío

ya existe una copia fría equivalente → eliminar la copia caliente (cero pérdida de información)

Protección por niveles: las meta-reglas de clase A (preceptos de comportamiento / interacción / estilo de escritura), las reglas de línea roja y las entradas con importancia ≥ 0.9 nunca reciben S2/S4/S5 — solo se fusionan o comprimen. Los punteros stub tienen su propio ciclo de vida (GC de los más antiguos primero bajo presión fuerte; el nivel frío nunca se toca), por lo que los punteros no pueden llenar el nivel por segunda vez. Toda salida es cold-write-first: la entrada local solo cambia después de que el nivel frío confirma, y cualquier fallo conserva el original. Cuando una señal no está disponible (sin registro de actividad, sin clave LLM), la escalera degrada al comportamiento anterior en lugar de adivinar.

Constantes (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.

Comprobación de salud: memorycore_memory_audit

Una herramienta de solo lectura que lista cada entrada del nivel caliente con su tipo, antigüedad, plan de retiro y clasificación keep/sink — el ancla de observabilidad para diagnosticar un desbordamiento que no encuentra nada que enviar al sumidero.

Resultados de la prueba de escala y optimización

MemoryCore fue sometido a pruebas de estrés y optimizado para la recuperación a escala de diez mil entradas en el nivel frío (entorno de prueba aislado, cero contacto con datos de producción, resultados reproducibles).

Escritura y capacidad

Métrica

Resultado

Rendimiento de escritura

10k entradas en 467s, ≈21.4 entradas/s (limitado por embeddings)

Tamaño de la base de datos

300MB / 10k entradas

Huella de memoria

RSS del proceso +19MB solamente, plano en todo momento — sin signos de fuga

Latencia de consulta — mediana de 48ms con top_k=5; la escala de diez mil entradas coincide con la escala de cien entradas, sin regresión de latencia.

Calidad de recuperación — tres pruebas:

  1. Coincidencia exacta (auto-recuperación): 20/20 aciertos en top-1 — la coincidencia exacta está intacta.

  2. Rechazo de ruido (consultas no relacionadas): puntuación densa media de top-1 0.056, la mayoría devuelve 0.0 — el contenido no relacionado casi nunca se filtra en los resultados.

  3. Recuperación con consultas cortas (antes → después) — el resultado clave de la optimización:

Etapa

Tasa de aciertos con consultas cortas

Antes

0/8

Después

5/8 (62.5%)

Qué se optimizó: con alta densidad temática, la truncación fija de candidatos k=max(top_k, 20) expulsaba los recuerdos detallados del pool de candidatos, por lo que las consultas cortas no lograban recuperarlos. La corrección amplía la truncación de candidatos a k=max(top_k*4, 300) y expande los candidatos internamente en el punto de entrada de la recuperación antes de truncar el resultado — todos los canales de recuperación (prefetch por turno + recuperación bajo demanda) se benefician de una única corrección. La corrección se limita a la etapa de recuperación; la lógica de ranking no se toca, el comportamiento es predecible y reversible.

Nota: las pruebas se ejecutaron en una base de datos sintética de 10k entradas (80 recuerdos "dorados" + 9920 recuerdos de relleno con tono de registro diario, misma configuración que producción); los datos de producción no se tocaron.

Notas para usuarios de sqlite-vec

Si habilitas la indexación vectorial sqlite-vec para el nivel frío de Mnemosyne, ten en cuenta que _wm_vec_search_sqlite de beam.py usa una fórmula de similitud en bruto sim = 1 - distance / (2 * EMBEDDING_DIM) que colapsa las distancias float32 a ~1.0, haciendo que el umbral dinámico sea efectivamente inútil (todos los resultados pasan).

Parche: en la rama float32, reemplaza la fórmula por sim = 1 - d² / 2 — esto da la similitud coseno exacta para vectores normalizados y restaura el comportamiento correcto del umbral.

Contrato del almacén en frío

Cualquier servicio que exponga estas cinco herramientas MCP puede actuar como nivel frío:

Herramienta

Semántica

remember(content, importance, scope)

Almacena un recuerdo, devuelve memory_id

recall(query, top_k)

Recuperación semántica

update(memory_id, content)

Actualización por fusión de un recuerdo existente

forget(memory_id)

Elimina un recuerdo

stats()

total + integridad de embeddings

Consulta examples/cold-store-contract.md para el contrato completo y un cliente de referencia.

Configuración

Variable de entorno

Por defecto

Significado

MEMORYCORE_COLD_BACKEND

local

Backend del nivel frío: local (en proceso) o remote (MCP)

MNEMOSYNE_URL

(vacío)

Endpoint MCP del nivel frío (requerido para el modo remote)

MNEMOSYNE_DATA_DIR

~/.memorycore/data

Directorio de datos SQLite local

MEMORYCORE_EMBED_URL

http://localhost:11434/v1

URL base de la API de embeddings compatible con Ollama u OpenAI

MEMORYCORE_EMBED_MODEL

qwen3-embedding:0.6b

Nombre del modelo de embeddings (1024-dim)

MEMORY_DIR

~/.hermes/memories

Directorio del nivel caliente (MEMORY.md / USER.md)

ACTIVITY_LOG_ENABLED

1

Registro de actividad de consultas para señales de actividad temática; 0 desactiva el registro y el stub-sink S4 por completo

MNEMOSYNE_TIMEOUT

10.0

Tiempo de espera de solicitudes al nivel frío (modo remoto, segundos)

Las constantes de capacidad se encuentran en memorycore/core/config.py (CHAR_LIMIT_*, SOFT_THRESHOLD, HARD_THRESHOLD, TARGET_RATIO).

Cómo funciona

  1. Escriturastore_fact clasifica el contenido:

    • importancia ≥ 0.8 o coincide con palabras clave calientes (preferencias / reglas / correcciones / líneas rojas) → caliente, se mantiene local

    • marcadores obsoletos (entrada corta, p. ej. "已修复 / fixed") → descartado (no migrado)

    • cualquier otra cosa → frío, se escribe directamente en el servicio remoto

  2. Desbordamiento — cuando el uso del nivel caliente supera el umbral suave, el desbordamiento migra las entradas de baja frecuencia al nivel frío; en el umbral duro fuerza el desbordamiento hasta ≤ objetivo. El orden es siempre escribir primero en frío, verificar, luego eliminar local — nada se pierde si el nivel frío falla.

  3. Mantenimiento — una pasada periódica sobre el nivel frío fusiona duplicados, elimina entradas obsoletas, resuelve conflictos y verifica la integridad de los embeddings.

Licencia

MIT © 2026 moonandecho

Licencias de terceros

  • mnemosyne-memory — MIT, por AxDSan. El motor de memoria en proceso utilizado por LocalBackend.

  • MCP Python SDK — MIT.

  • ollama — MIT. Servidor local de API de embeddings.

  • qwen3-embedding — Apache-2.0, por Alibaba Cloud. Modelo de embeddings por defecto (no incluido; se descarga vía ollama).

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

View all related MCP servers

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

View all MCP Connectors

Latest Blog Posts

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