unified-memory-mcp
Click on "Deploy 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., "@unified-memory-mcpSearch my memory for anything about summarizer endpoint costs"
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.
unified-memory-mcp
Один MCP-сервер вместо двух: хранение + поиск + сжатие информации для любого MCP-клиента (Hermes Agent, Claude Code, ...).
Собрано из уроков двух боевых систем:
hermes-lcm — lossless context management (message store, summary DAG, bounded recall)
mnemosyne — long-term memory (canonical facts, working/episodic memory, triples-граф)
Обе MIT — attribution в NOTICE. Здесь не форк: ядро написано с нуля по их картам
(docs/MODULE_MAP.md, docs/TOOL_MAP.md), без перетаскивания 108k строк.
Установка
git clone https://github.com/sportlotto-ux/unified-memory-mcp
cd unified-memory-mcp
pip install -e . # база: FTS-поиск + extractive-сжатие, всё из коробки
pip install -e .[local-embed] # + семантика: локальный fastembed, CPU, без облаков
pip install -e .[tokens] # рекомендуется: точный tiktoken/cl100k для бюджета и компакшнаТокен-оценщик общий для компакшна и
mem_assemble. Без.[tokens]работает детерминированная RU-aware эвристика — пороги компакшна она держит, но на смешанном RU/EN/коде погрешность накапливается иначе, чем на однородном тексте; для жёсткого бюджетного счёта ставьте.[tokens].
Требования: Python 3.11+, SQLite из коробки. Опционально для настоящего пересказа:
export UM_SUMMARIZER_URL=http://localhost:11434/v1 # OpenAI-совместимый endpoint (ollama и др.)
export UM_SUMMARIZER_MODEL=qwen3:4b # дешёвая локальная модель, НЕ фронтирная (см. «Стоимость»)Related MCP server: MCP Shared Memory Hub
Стоимость суммаризации (прочти до включения endpoint)
Кто суммирует — решаете вы, не агент:
По умолчанию — никто (0 ₽). Extractive-конденсация: офлайн, детерминирована, без LLM вообще. Конденсат, не пересказ — но бесплатный.
С
UM_SUMMARIZER_*— ваша endpoint-модель. Сервер сам шлёт ей текст на каждом триггере давления: 1 вызов на leaf-summary + до 10 condense-проходов (condenseограничен, но при маленьком окне каждый чих = пачка вызовов).
Правила, чтобы не сжечь бюджет:
Endpoint = дешёвая локальная модель (
qwen3:4b,ministral, аналоги через ollama). Никогда не направляйте сюда фронтирную чат-модель: авто-компакшн срабатывает регулярно, и дорогой токен × регулярность = резкий рост счёта.Прикиньте математику: в триггере вход ≈ токены сжимаемого хвоста (кап POST — 12k символов). Частота триггеров ≈ 1 на
порог − хвостновых токенов. Пример: окно 200k × 0.35 = 70k, в триггере ~50k символов входа на 4b-модели локально = 0 ₽; те же 50k на платной флагманской = дорого × десятки раз в день.Держите окно реалистичным. Тестовые
UM_CONTEXT_TOKENS=400— только для тестов: в проде крошечный порог = компакшн на каждом сообщении = пачка LLM-вызовов.Для Hermes-юзеров: тот же принцип у LCM — auxiliary-модель для саммаризации должна быть дешёвой; дорогая модель — только в чат, не в инфраструктуру.
Сломанный/медленный endpoint не роняет запись (
status: degraded), но висящие ретраи — ваши: держитеtimeoutendpoint низким на своей стороне.
Подключение
{
"mcpServers": {
"unified-memory": {
"command": "python",
"args": ["-m", "unified_memory.server"],
"cwd": "/path/to/unified-memory-mcp",
"env": { "UM_DATABASE_PATH": "~/.hermes/unified_memory.db" }
}
}
}Тулы (15)
Тул | Что делает |
| Сохранить сообщение; авто-компакшн при превышении порога давления |
| Слот-факт (одно живое значение на |
| Типизированная связь ( |
| Атомарный батч записей (all-or-nothing): ops |
| Правка факта по id (новая версия, history живёт) или истечение/reopen факта/ребра/связи ( |
| Единый поиск: FTS + вектора + граф + RRF. |
| Temporal: что было в UTC-окне ( |
| Дословно по |
| Проверка опоры на refs: |
| Доложит недостающие вектора (лестница после смены модели) |
| Ручное сжатие старых сообщений (сырьё остаётся) |
| Bounded активный контекст: summaries + свежий хвост в бюджет токенов (бюджет считается токен-оценщиком; для жёсткой арифметики — |
| Удаление по |
| Счётчики + флаги деградации ( |
|
|
Как это работает
Хранение: одна SQLite (WAL):
um_messages+um_summaries(DAG) +um_facts+um_entities/um_edges(граф) +um_links(типизированные связи, traversal-only) +um_vectors+um_fts(FTS5) +um_meta.Эмбеддинги: два бэкенда.
local(дефолт репо) — fastembed, модельparaphrase-multilingual-mpnet-base-v2(768, не дистиллят); для лёгких стендов MiniLM-L12 черезUM_EMBEDDING_MODEL.openai— OpenAI-протокол/v1/embeddingsповерх stdlib (ноль зависимостей): так подключается локальный model2vec-сервер Hermes (UM_EMBEDDING_BASE_URL, дефолтhttp://127.0.0.1:8127, potion = 256 dim, авто-детект). Держи сервер uncapped — static-модели молча режут после 512 токенов при выставленномEMBED_MAX_TOKENS.Поиск: FTS5 (fallback LIKE) + cosine по векторам + RRF, поверх — recency-приор (
UM_RECENCY_HALFLIFE_DAYS, дефолт 30, 0=off), scope-bias текущей сессии (UM_SCOPE_BIAS, дефолт 0.15) и MMR-диверсификация по Жаккару (UM_MMR_LAMBDA, дефолт 0.7, 1=off). Приpip install -e .[local-vec]+mem_reindex— vec0-индекс (KNN-кандидаты + точный косинусный перескоринг, паритет с brute force пробами); без индекса — честный фулскан. Без fastembed — честный FTS-режим,mem_statusтак и скажет (vectors_enabled: false), молчаливого «вроде ищет» нет.Сжатие: давление = токены сессии vs
UM_CONTEXT_TOKENS × UM_COMPACT_THRESHOLD(дефолт 200k × 0.35, как LCM). Токены: приpip install -e .[tokens]— точный tiktoken/cl100k, иначе детерминированная RU-aware эвристика (ASCII/4 + не-ASCII/2; голыйlen//4занижал кириллицу ~2.3x). Накрыло → старые (всё кромеUM_FRESH_TAIL_COUNTсвежих) в summary depth 0; каждыеUM_DAG_FANINнод уровня схлопываются в уровень выше. Frontier вum_meta— каждое сообщение жмётся один раз.mem_assembleсобирает bounded контекст под бюджет тем же оценщиком.Защита от старых болячек: нет жёсткого
importance: 0.95(причина canonical-bloat в mnemosyne) — кап0..1; смена embedding-модели без reindex — громкая ошибка, а не тихая деградация recall.Redaction: гейт на входе (
UM_REDACT_ENABLED, дефолт ON):api_key,bearer_token,password_assignment,private_key— каталог и регулярки как у LCM. Режется до SQLite/FTS/vectors/summaries, плейсхолдер[UM redaction: name=...; chars=N]необратим. Forward-only: что попало в стор раньше — чистить руками + reindex.Retention/архив (lossless-холод):
UM_RETENTION_DAYS= сколько держать ГОРЯЧЕЕ (recall быстрый, БД маленькая), а не срок жизни данных.0(дефолт) = копим всё в горячей вечно.>0→ раз в неделю (ленивый проход) горячее старше N дней уезжает в архив. Архив — отдельный файл, lossless, живёт вечно; автоудаления нет — физическоеpurgeтолько вручную (mem_doctor(mode=purge, apply=true)). При пороге размера (UM_ARCHIVE_SIZE_MB, дефолт 1 ГБ) старейшее добивается до порога. В архив уезжают текст и вектор (вариант a2 — так порог реально держится), в горячей остаётся заглушка[archived],mem_expandпрозрачно достаёт текст из архива. Ручнойpurgeрежет архив по тому жеUM_RETENTION_DAYS— то есть вычищает ровно строки старше N (приretention_days>0это почти весь холод, осознанно); приretention_days=0purge— no-op.Факты = слоты (
mem_fact), сообщения = лог (mem_remember). Один живой факт на(owner, category, name)— гарантирует partial unique index, не код. Новое тело вытесняет старое (valid_until,superseded_by), история lossless;valid_until=0= живое (sentinel).mem_recall/mem_expandпрячут истёкшее (include_expired=True— аудит).mem_forget— жёсткое удаление, истечение — толькоmem_update.Проверка и арифметика (
mem_evidence). Детерминированно, без LLM, только над переданнымиrefs(никакого авто-поиска — иначе инструмент превращается в мини-агента с его fallback-багами).cite: дословное/почти-дословное вхождение claim в тело ref →supported/partial/unsupported(RU-морфология через дешёвый prefix-stem).compute: агрегация чисел из тел тех же refs (count/sum/min/max/avg/median); интент парсит хост-агент.conflicts: высокоточные кандидаты противоречий (смена значения в слоте, точная негация) без вердикта — судью делает LLM-хост, тул не шумит.
Переменные окружения
Переменная | Дефолт | Назначение |
|
| Путь к БД |
|
| База для дефолтных путей ( |
|
| local: модель fastembed строго из реестра; openai: passthrough-имя |
|
|
|
|
| База для backend=openai |
|
| Таймаут HTTP, сек |
| — | Пропустить probe dim (openai), полезно оффлайн |
|
|
|
|
|
|
|
| Порог горячей БД: старейшие сообщения уезжают в архив |
|
| Отдельный файл холода |
|
| Сколько сообщений за один проход архивации |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Гейт секретов на входе (дефолт ON — продукт публичный) |
|
| Подмножество каталога через запятую |
| — | LLM-пересказ; без них extractive |
| — | Bearer для endpoint |
|
| Эффективное окно хоста |
|
| Доля окна — триггер компакшна |
|
| Свежих сообщений не жмём никогда |
|
| Нод уровня → одна выше |
|
| Токенов в |
|
| Кап входного текста (громкий |
|
| Кап головы компакшна за проход (остаток досжимается следующим вызовом) |
Известные ограничения (v0.8)
Полный список отложенного — docs/BACKLOG.md.
Архив выносит только сообщения (текст+вектор) — основной драйвер роста. Истёкшие факты/рёбра и
um_summaries— TODO (docs/BACKLOG.md).mem_doctor(mode=export)пишет стриминговый JSONL (um-export-jsonl: header +{table,row}построчно; вектора base64, um_fts/um_vecidx исключены). Импорт —python -m unified_memory.import_dump <file> [--owner] [--dry-run], аддитивный (fresh-id remap, слот-конфликт → skip), без backend. Чтение дампа — целиком в память (стриминг только на записи).Isolation добровольная:
owner=""(дефолт) — legacy без фильтра, видит всё; строгая изоляция — только при непустомowner. Старые БД мигрируют сами (owner=''), сущности пересобираются подUNIQUE(name, owner).Redaction forward-only: сторa, созданные до v0.4, могут содержать секреты — чистить руками + reindex.
Смена embedding-модели требует reindex (падает громко,
DimensionMismatchError): ранние сторa на MiniLM-384 с дефолтом mpnet-768 несовместимы — пересоздайте БД или задайтеUM_EMBEDDING_MODELявно.Cron-режима нет (демона нет), но age-based проход (а) теперь есть вручную/по cron:
mem_doctor(mode=retention, apply=true)выносит горячее старшеUM_RETENTION_DAYS(dry-run безapplyсчитаетwould_move, идемпотентен). Ленивый недельный проход на ingest остаётся.Пагинации ранжированного
mem_recallнет и не будет: возвращаемый порядок — fused-релевантность, а не стабильный ключ; «следующие N» через offset даст недетерминированную выдачу. Сужайте запрос/увеличивайтеlimit. Пагинация есть только у хронологическогоmem_recent(before_id+before_ts).
Разработка
python -m pytest tests/ -q # 281 passed, 6 skipped без fastembed/vec/tiktoken/hypothesis; UM_LIVE_OPENAI=1 — live против 8127Прогон герметичен: tests/conftest.py снимает ambient UM_* (иначе шелл с
UM_REDACT_ENABLED=off или UM_EMBEDDING_BACKEND=openai молча ронял 12 тестов).
Тестам с env — только monkeypatch.setenv. UM_LIVE_* конфигом не считается.
Roadmap и разбор апстримов: docs/MIGRATION_PLAN.md. Переезд с hermes-lcm/mnemosyne: docs/IMPORT.md.
This server cannot be deployed
Maintenance
Related MCP Connectors
- KogniteOAuthdev.kognite
Hosted agent memory: store, search, and recall facts across sessions from any MCP client.
- memnodeOAuthdev.memnode
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
Private-by-default, local-first memory/context/task orchestrator for MCP apps and agents.
Person-owned AI memory that learns, not just stores — portable context for any MCP client.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides a memory layer for personal agents, enabling MCP-compatible agents to store and query profile, factual, episodic, and procedural memory.MIT
- AlicenseNot gradedqualityCmaintenanceEnables multiple MCP-compatible AI clients to share persistent, versioned project knowledge across sessions with conflict-safe updates, provenance, hybrid retrieval, stale-memory handling, and context-budgeted recall.MIT
- AlicenseAqualityCmaintenanceProvides a local-first, provenance-aware memory layer that enables MCP-capable AIs to store, recall, validate, and reason over facts with contradiction detection, trust weighting, deduplication, and encryption, supporting offline private operation without GPUs or API keys.9Apache 2.0
- AlicenseBqualityCmaintenanceProvides AI agents with durable, searchable project memory, session notes, skills, and bounded context packs over MCP while leaving orchestration to the client.15MIT