Skip to main content
Glama
marc-shade

Enhanced Memory MCP Server

by marc-shade

Enhanced Memory MCP Server

MCP Python 3.11+ License Tools

Постоянная, доступная для поиска память для AI-агентов, через Model Context Protocol. Сущности и их наблюдения хранятся в сжатой SQLite-базе данных с контрольными суммами и историей версий; поверх этого расположены многоуровневое хранилище и многокомпонентный конвейер извлечения; и всё это предоставляется вашему клиенту как инструменты MCP.

Количество инструментов зависит от того, что вы установили, и разница не является ошибкой: инструмент, чей бэкенд отсутствует, вообще не регистрируется. Базовая установка (requirements.txt) регистрирует 186; добавление опциональных бэкендов (requirements-optional.txt) увеличивает это число до 204. Если после простого pip install -r requirements.txt вы насчитали 186, ничего не сломано.

Оба значения были измерены на Python 3.11.11 через tools/list по stdio, с переменной AGENTIC_SYSTEM_PATH не установленной. Последнее условие — не педантизм. Если эта переменная указывает на отдельную систему, описанную в разделе GraphRAG, регистрируются ещё семь инструментов, и вы получаете 193 и 211 вместо указанных. В предыдущих черновиках этого файла говорилось о 188 и 206, потому что измерения проводились на машинах, где эта переменная была экспортирована, и двое из нас воспроизвели одно и то же неверное число, не заметив общей причины. Сбросьте её перед повторным измерением.

Всё основное работает локально, без ключей API и без сети. Опциональный векторный стек (Qdrant плюс ollama) улучшает поиск с ключевых слов до смыслового, а его отсутствие приводит к плавной деградации, а не к поломке.

Первое, что нужно знать

Это два процесса, а не один. Почти каждый вопрос поддержки по этому проекту возникает из-за запуска только половины.

   your MCP client  (Claude Code, Claude Desktop, an SDK, curl)
            |
            |   stdio JSON-RPC, one server process per client session
            v
   +-------------------------------------------------------+
   |  MCP server            server.py                       |
   |  start with            setup/bin/mcp-server.sh          |
   +-------------------------------------------------------+
            |
            |   JSON over a Unix socket: $MEMORY_DB_SOCKET_PATH
            |   (default /tmp/memory-db.sock)
            v
   +-------------------------------------------------------+
   |  memory-db daemon      memory_db_service.py            |
   |  start with            setup/bin/memory-db-daemon.sh    |
   |  REQUIRED. Owns the database file exclusively so that   |
   |  several clients can share it without corrupting it.    |
   +-------------------------------------------------------+
            |
            v
     memory.db   (SQLite, default ~/.claude/enhanced_memories/)


   optional, off to the side:
     Qdrant  http://localhost:6333    vector index for semantic recall
     ollama  http://127.0.0.1:11434   local embeddings that feed that index

Демон не является опциональным, и MCP-сервер не запускает его за вас. Без него сервер всё равно запускается, отвечает и возвращает объекты, подобные этим:

{"query": "anything", "count": 0, "results": [],
 "error": "Memory-DB service error: [Errno 2] No such file or directory"}

{"error": "Memory-DB service error: ...", "entities": {"total": 0},
 "compression": {"ratio": "N/A"}}

Хорошо сформированные, разбираемые и пустые. Агент, читающий это, делает вывод, что ваша память пуста, а не глуха. ./healthcheck.sh существует, чтобы различать эти два случая.

Related MCP server: Strata Memory MCP Server

Предварительные требования

  • Python 3.11 или новее. На некоторых macOS-машинах просто python3 всё ещё является версией 3.9, поэтому установщик сначала ищет версионированные имена.

  • git и место на диске для виртуального окружения. Измерено на macOS arm64 с Python 3.11: 83 МБ для базовой установки, 964 МБ с опциональными бэкендами, так как они тянут sentence-transformers и torch. На Linux x86_64 базовый размер составляет 131 МБ (измерено в контейнере python:3.11-slim) — колеса различаются в зависимости от платформы, так что ожидайте, что число будет меняться в зависимости от вашей. Сам репозиторий занимает 5 МБ.

  • Опционально: podman или docker, если вы хотите использовать контейнерный путь или локальный Qdrant.

  • Опционально: ollama для локальных эмбеддингов.

Ни на одном этапе не требуется sudo. Ничего не устанавливается системно.

Уже запущена система enhanced-memory?

Прочитайте это перед шагом 2 ниже, если на этой машине уже может быть такая система: старая копия репозитория, второй клон, сервис, установленный месяцы назад. По умолчанию каждая установка хочет одни и те же два ресурса — сокет /tmp/memory-db.sock и базу данных ~/.claude/enhanced_memories/memory.db — и они не могут быть общими.

Сначала проверьте:

lsof /tmp/memory-db.sock        # macOS or Linux
ss -xl | grep memory-db.sock    # Linux
pgrep -af memory_db_service.py

Любой перечисленный элемент означает, что установка активна. Запуск второго демона на занятом сокете отклоняется: он завершается с ненулевым кодом и выводит путь к сокету и базу данных, которую использует отвечающий демон, а не захватывает сокет. Это защита, а не сосуществование — второй демон вообще не запускается.

Чтобы запустить две установки рядом, дайте этой свои собственные параметры в .env:

ENHANCED_MEMORY_DIR=/home/you/.enhanced-memory-second
MEMORY_DB_SOCKET_PATH=/tmp/memory-db-second.sock
# Only if you want the Neural Memory Fabric somewhere else again; by default it
# follows ENHANCED_MEMORY_DIR:
# NMF_SQLITE_PATH=/home/you/.enhanced-memory-second/nmf.db
# NMF_FILES_ROOT=/home/you/.enhanced-memory-second/nmf_files

ENHANCED_MEMORY_DIR — это то, что часто забывают. Два демона на двух сокетах, использующие одну memory.db, — это не сосуществование: это два эксклюзивных владельца одного файла, что именно и призван предотвратить демон.

Быстрый старт

git clone <this-repo> enhanced-memory-mcp
cd enhanced-memory-mcp

# 1. venv, dependencies, .env, database directory. Idempotent, re-runnable.
setup/setup.sh

# 2. start the daemon (foreground). Leave it running, or install it as a
#    background service: setup/service/install-services.sh
setup/bin/memory-db-daemon.sh &

# 3. prove the install works before you trust it
./healthcheck.sh

Успешный запуск завершается сообщением Required checks passed. и кодом возврата 0. Всё остальное — реальная проблема: см. Устранение неполадок.

Настройки хранятся в .env, который шаг 1 создаёт из .env.example только при отсутствии .env. Редактирование этого файла — способ сохранить настройку; повторный запуск setup/setup.sh никогда не перезаписывает его.

Затем зарегистрируйте сервер в вашем MCP-клиенте. В ~/.claude.json:

{
  "mcpServers": {
    "enhanced-memory": {
      "command": "/absolute/path/to/enhanced-memory-mcp/setup/bin/mcp-server.sh"
    }
  }
}

Укажите клиенту на запускатор, а не на python server.py. Запускатор применяет .env из этой копии репозитория, что гарантирует, что MCP-сервер и демон используют один и тот же файл базы данных. Клиент, который напрямую выполняет python, наследует только то окружение, которое было у этого клиента, и два процесса незаметно расходятся. См. ловушку разделённого мозга.

На этом установка завершена, и инструменты работают при вызове. Ничто не вызывает их само по себе: каждый сеанс начинается с чистого листа, и ничего не записывается обратно, если только агент не решит это сделать. Это не ошибка, и ни одна проверка не сообщает об этом, поэтому легко принять работающую установку за работающую память. docs/AUTOMATION.md описывает, как устранить этот разрыв, начиная с хука recall, который выполняется при каждом запросе.

Альтернатива: один общий HTTP-сервер

stdio порождает один процесс сервера на сеанс клиента, что и ожидают настольные клиенты. Если вы предпочитаете запускать один общий сервер через HTTP, используйте транспорт SSE:

MCP_TRANSPORT=sse setup/bin/mcp-server.sh     # or setup/bin/mcp-server-sse.sh
{
  "mcpServers": {
    "enhanced-memory": { "type": "sse", "url": "http://127.0.0.1:9106/sse" }
  }
}

На этом порту нет аутентификации. Держите MCP_HOST равным 127.0.0.1.

Конфигурация

Конфигурация задаётся переменными окружения. setup/setup.sh записывает .env из .env.example, который документирует каждую настройку встроенно. Редактирование .env — это постоянный механизм: копирование происходит только при отсутствии .env, поэтому ваши правки переживают каждый повторный запуск установщика (и по той же причине значения по умолчанию из нового релиза не появляются сами — сравните два файла после обновления). Переменная, уже установленная в вашем окружении, переопределяет файл для данного вызова:

MEMORY_DB_SOCKET_PATH=/tmp/other.sock ./healthcheck.sh

Переменная

По умолчанию

Назначение

ENHANCED_MEMORY_DIR

~/.claude/enhanced_memories

Каталог, содержащий memory.db.

ENHANCED_MEMORY_DB_PATH

(не задано)

Полный путь к файлу базы данных. Переопределяет настройку каталога.

MEMORY_DB_SOCKET_PATH

/tmp/memory-db.sock

Unix-сокет между двумя процессами. Должен быть коротким, см. примечание AF_UNIX ниже. Для второй установки на той же машине укажите свой собственный.

NMF_SQLITE_PATH

$ENHANCED_MEMORY_DIR/nmf.db

Необязательно. База данных Neural Memory Fabric. По умолчанию следует за ENHANCED_MEMORY_DIR; задавайте только для размещения в другом месте.

NMF_FILES_ROOT

$ENHANCED_MEMORY_DIR/nmf_files

Необязательно. Хранилище файлов NMF, то же правило.

MCP_TRANSPORT

stdio

stdio, sse или streamable-http.

MCP_HOST

127.0.0.1

Только для HTTP-транспортов. Не открывайте доступ к сети.

MCP_PORT

9106

Только для HTTP-транспортов.

ENHANCED_MEMORY_SURFACE

frontdoor

frontdoor регистрирует все инструменты и помечает пять как всегда загруженные (search_nodes, semantic_recall, create_entities, get_memory_status, execute_code), остальные оставляет для поиска инструментов клиента; consolidated предоставляет 7 и скрывает остальные за одним диспетчером; full регистрирует всё и ничего не помечает.

MEMORY_PROFILE

full

minimal пропускает необязательные интеграции и запускается быстрее.

MEMORY_QDRANT_URL

http://localhost:6333

Необязательное векторное хранилище.

MEMORY_OLLAMA_URL

http://127.0.0.1:11434

Необязательный провайдер эмбеддингов.

MEMORY_EMBED_MODEL

embeddinggemma

Модель эмбеддингов для загрузки и использования.

MEMORY_LOW_CONF_THRESHOLD

0.50

Порог, ниже которого результат помечается как низкодостоверный.

MEMORY_TOOL_REGISTRY_FILE

(не задано)

JSON-файл, объявляющий, какие другие MCP-серверы может вызывать код внутри execute_code. Если не задано, то ни один не объявлен, что является честным значением по умолчанию для пакета, который не может знать, что работает на вашей машине.

MEMORY_LOG_STDERR

1

Отправляет WARNING и выше также в stderr вместе с файлом журнала, чтобы пропущенные группы инструментов были видны. Установите 0, если ваш MCP-клиент считает stderr ошибками.

AGENTIC_SYSTEM_PATH

(не задано)

Включает только GraphRAG, реализация которого не поставляется здесь. Его установка увеличивает количество инструментов со 186 до 193, или с 204 до 211 с дополнительными бэкендами.

EXPECTED_TOOL_COUNT

(не задано)

Фиксирует количество инструментов, требуемое ./healthcheck.sh.

ENHANCED_MEMORY_SURFACE и MEMORY_PROFILE оба изменяют, сколько инструментов возвращает tools/list, а также какие необязательные зависимости установлены: инструменты, чей бэкенд отсутствует, не регистрируются. Установка только ядра и установка с дополнительными компонентами сообщают разное количество при одном и том же коде. Ожидаемое количество инструментов имеет смысл только в сочетании с обоими.

Необязательные сервисы и что вы теряете без них

Ни один не является обязательным. Оба стоят того, чтобы их иметь.

При наличии

При отсутствии

Qdrant

Поиск ранжируется по смыслу: запрос о «разрешении доступа» может найти сущность, которая никогда не использует эти слова.

Поиск всё ещё работает и возвращает результаты, но ранжирование возвращается к лексическому сопоставлению. Никаких ошибок, поэтому это легко не заметить.

ollama

Генерирует эмбеддинги, которые индексирует Qdrant.

Qdrant нечего индексировать, поэтому поиск остаётся лексическим даже при работающем Qdrant.

Предоставьте один или оба:

setup/setup.sh --with-qdrant     # container on 127.0.0.1:6333, named volume
setup/setup.sh --with-ollama     # verifies ollama, pulls the embedding model

./healthcheck.sh сообщает оба как НЕОБЯЗАТЕЛЬНЫЕ и никогда не завершается ошибкой при их отсутствии. Используйте --require-optional, если нужен более строгий контракт.

Уже запущен Qdrant? Укажите MEMORY_QDRANT_URL на него и полностью пропустите --with-qdrant; здесь не нужно владеть экземпляром. Конфликт портов, описанный в профиле контейнера ниже, характерен именно для этого профиля, который публикует свой собственный контейнер на порту 6333 и не может занять порт, уже занятый другим. Установка на хосте только выполняет исходящие запросы.

GraphRAG является необязательным и внешним

Инструменты GraphRAG (graph_enhanced_search, get_entity_neighbors) не поставляются здесь. graphrag_tools.py загружает их реализацию из $AGENTIC_SYSTEM_PATH/scripts/graph-rag.py, файла, принадлежащего отдельной системе и не являющегося частью этого пакета. AGENTIC_SYSTEM_PATH по умолчанию указывает на родительский каталог checkout, поэтому в автономной установке этот путь не существует.

Ничего не ломается. Регистрация обёрнута, сервер регистрирует GraphRAG integration skipped: ... и запускается без этих инструментов. Если у вас есть эта система, укажите AGENTIC_SYSTEM_PATH на её корень, и они будут зарегистрированы. Обратите внимание, что сообщение о пропуске отправляется в файл журнала, а не в ваш терминал, поэтому отсутствующие инструменты выглядят как инструменты, которых никогда не было.

Запуск в контейнере

Путь доставки для общих сред. Podman в первую очередь, совместимый с docker.

podman-compose up --build                              # core only
WITH_OPTIONAL=1 podman-compose --profile qdrant up     # with a USABLE vector store

WITH_OPTIONAL=1 является критическим для профиля qdrant. Образ по умолчанию устанавливает только requirements.txt, который не включает qdrant-client — поэтому --profile qdrant без него даёт вам здоровый, доступный, но полностью неиспользуемый Qdrant: проверка работоспособности сообщает, что сервис доступен (true), в то время как сервер регистрирует «qdrant-client not installed - vector search disabled» и каждый поиск остаётся лексическим. Зелёный сигнал рядом с неактивной возможностью — это именно тот режим отказа, который этот проект призван устранить, поэтому он указан здесь, а не оставлен для вас. WITH_OPTIONAL=1 собирает образ с requirements-optional.txt, и векторный путь действительно активируется. (Измерено: образ ядра вместе с профилем qdrant отвечал на /readyz «all shards are ready» и не использовал его ни для чего.)

Используйте дефис. На Fedora 44 podman compose (с пробелом) передаёт управление внешнему провайдеру /usr/libexec/docker/cli-plugins/docker-compose, который требует сокет API, совместимый с Docker. При неактивном podman.socket, что является значением по умолчанию, podman compose up завершается ошибкой:

failed to connect to the docker API at unix:///run/user/1000/podman/podman.sock:
  connect: no such file or directory

systemctl --user start podman.socket исправляет это, или просто используйте podman-compose (здесь версия 1.6.0), который управляет podman напрямую и не требует сокета. Измерено на Fedora 44 с podman 5.8.4: podman compose up завершился ошибкой, как описано выше, podman-compose up -d запустил стек, и контейнер сообщил healthy.

Образ запускает оба процесса через container-entrypoint.sh, который запускает демон, ожидает ответа от сокета и только затем запускает MCP-сервер на транспорте SSE. Если любой из процессов завершается, контейнер завершается, потому что живой MCP-сервер рядом с мёртвым демоном — это именно то состояние, которое возвращает корректные нули навсегда.

Заметки, которые сэкономят вам время:

  • podman build игнорирует HEALTHCHECK. Podman по умолчанию использует формат образа OCI, в котором нет поля для него. Он предупреждает один раз во время сборки:

    HEALTHCHECK is not supported for OCI image format and will be ignored.
    Must use `docker` format

    Пропустите эту строку в выводе сборки — и больше о ней никто не упомянет: образ не содержит проверки здоровья, и podman ps никогда не показывает состояние здоровья. Измерено на podman 5.8.4, Fedora 44: .HealthCheck образа OCI при инспекции равен nil, а пересборка с помощью podman build --format docker даёт [CMD /app/setup/lib/container-health.sh].

    Три способа решения, все проверены: собирать с --format docker; использовать compose, у которого проверка здоровья на уровне сервиса определена в compose.yaml и применяется независимо от формата образа (контейнер, управляемый compose, сообщает healthy из того же образа, который при инспекции равен nil); или проверять по запросу с помощью podman exec <имя> /app/healthcheck.sh --skip-mcp.

  • Порт MCP публикуется только на loopback хоста (127.0.0.1:9106:9106). Внутри контейнера сервер привязывается к 0.0.0.0, что там правильно, но на рабочей станции — нет.

  • Хостовые порты Qdrant — ${QDRANT_PORT:-6333} и ${QDRANT_ADMIN_PORT:-6334}. Установите их в .env, если вы уже запускаете Qdrant на порту 6333, иначе это приведёт к конфликту привязки, который остановит запуск профиля.

  • Образ — это базовая установка, поэтому профиль qdrant ничего не делает сам по себе. podman-compose --profile qdrant up запускает Qdrant, который стартует, проходит проверку здоровья и отвечает на своём порту, но при этом у сервера нет qdrant-client, чтобы с ним общаться. Всё выглядит зелёным, а ничего не индексируется. Собирайте с опциональным стеком, чтобы реально его использовать:

    podman build --build-arg WITH_OPTIONAL=1 -t enhanced-memory:local -f Containerfile .
    # or, through compose:
    WITH_OPTIONAL=1 podman-compose up --build

    ./healthcheck.sh различает эти два случая: он сообщает, что Qdrant доступен и полезен, только когда клиентская библиотека импортируема, и предупреждает, когда сервис работает, но никто не может им воспользоваться.

  • База данных живёт в именованном томе enhanced-memory-data. Без тома ваша память умирает вместе с контейнером.

  • ollama работает на вашем хосте, и контейнер не может до него добраться по адресу 127.0.0.1. Раскомментируйте MEMORY_OLLAMA_URL в compose.yaml (host.containers.internal для podman, host.docker.internal для docker).

  • Проверяйте работающий контейнер так же, как вы проверяете установку на хосте. Используйте абсолютный путь: не каждый движок разрешает относительный путь относительно WORKDIR.

    podman exec enhanced-memory /app/healthcheck.sh --skip-mcp
  • Ваш локальный .env не является конфигурацией для контейнера. Образ намеренно поставляется с пустым .env, а всё реальное берётся из окружения времени выполнения в compose.yaml. .containerignore и .dockerignore исключают файл, но не все движки это соблюдают (Apple container build не соблюдал, проверено 2026-08-14), поэтому Containerfile также очищает его в отбрасываемой стадии сборки, а затем завершает сборку ошибкой, если заполненный .env сохранился.

Запуск в качестве фонового сервиса

setup/service/install-services.sh              # daemon only
setup/service/install-services.sh --with-sse   # and a shared SSE server
setup/service/uninstall-services.sh

Пользовательские агенты launchd на macOS (~/Library/LaunchAgents), пользовательские юниты systemd на Linux (~/.config/systemd/user). Никакого root, никаких системных юнитов. Каждый путь формируется из расположения текущего checkout, так что два checkout могут сосуществовать, если задать им разные значения --label-prefix, разные значения MEMORY_DB_SOCKET_PATH и разные значения ENHANCED_MEMORY_DIR. Все три, а не только первые два: отдельные сокеты приводят к тому, что оба демона открывают один и тот же memory.db, а каждый из них должен владеть этим файлом исключительно.

Установщик ожидает сокета и громко завершается ошибкой с хвостом лога, если сервис не запускается. Логи попадают в ~/Library/Logs/enhanced-memory или ${XDG_STATE_HOME:-~/.local/state}/enhanced-memory/log, намеренно не в checkout: launchd не может создать файл лога на внешнем томе в момент запуска, и задача умирает с кодом выхода 78 до того, как ваш код вообще выполнится.

На Linux пользовательские юниты останавливаются при выходе из системы, если не включено lingering:

loginctl enable-linger $USER

Проверка вашей установки

Два этапа, в таком порядке.

./healthcheck.sh                 # the post-install gate
python3 comprehensive_test.py    # the functional suite (needs the daemon running)

Третий, предназначенный для разработчиков набор тестов находится в tests/ и требует сначала pip install -r dev-requirements.txt — pytest намеренно отсутствует в файле зависимостей времени выполнения, и два этапа выше выполняются только на stdlib.

Судите о comprehensive_test.py по коду возврата, а не по количеству пройденных проверок. Количество проверок зависит от выбранного режима: если не заданы переменные ENHANCED_MEMORY_* или MEMORY_DB_*, он создаёт свою собственную песочницу и выполняет всё, а если они заданы, он запускается против вашего развёртывания и пропускает проверки, описывающие песочницу, которую он не создавал. Измерено на одной машине, одном коммите: 106 изолированных и 102 ориентированных на оператора, оба с кодом выхода 0. Запуск выводит свой режим и называет то, что пропустил.

Установка опциональных бэкендов изменяет это количество на ноль, измерено в обоих направлениях. Более ранняя версия этого файла утверждала, что причина в бэкендах. Это не так, и та же неверная догадка была приписана количеству пропусков в pytest до того, как кто-либо это проверил; см. раздел о тестовом наборе в RELEASE_NOTES.md о том, что на самом деле меняет это число.

./healthcheck.sh построен так, чтобы он мог завершиться ошибкой. Он записывает тестовую сущность через сокет демона, ищет её обратно и удаляет. Он считает ключ error или daemon в любом ответе как ошибку независимо от остального ответа, и сравнивает путь к базе данных, который сообщает демон, с тем, который разрешает ваше окружение. Он проверяет:

  1. venv, версию интерпретатора, .env, длину пути к сокету, наличие исходников

  2. круговой тест демона (статус, согласованность базы данных, запись, чтение, очистка) и проверку схемы: каждый литеральный INSERT в двух файлах, которые владеют этой базой данных, сравнивается с определениями таблиц в реальном времени, потому что столбец, отсутствующий в схеме, приводит к ошибке каждой записи, при этом демон сообщает об ошибке построчно, а не выбрасывает исключение

  3. рукопожатие MCP через stdio, количество инструментов и то, что ничего не загрязнило stdout

  4. Qdrant и ollama, помечены как ОПЦИОНАЛЬНЫЕ, никогда не фатальные

Полезные флаги: --skip-mcp для быстрой проверки только демона, --expect-tools N для фиксации количества, --require-optional для требования векторного стека.

Где находятся логи

/tmp/enhanced-memory-mcp.log, всегда, для любой установки на хосте.

MCP-сервер очищает все обработчики логирования при запуске и отправляет всё в этот один ротационный файл (50 МБ, две резервных копии), потому что на транспорте stdio всё, что попадает в stdout, нарушает протокол. Обычные INFO сообщения находятся только там, и путь фиксирован, поэтому два checkout на одной машине перемешиваются в один файл, и единственным разделителем служат временные метки и PID.

WARNING и выше дополнительно отправляются на stderr, если только вы не установите MEMORY_LOG_STDERR=0. Это сделано намеренно: каждая строка ... integration skipped: <причина> — это функция, которая не загрузилась, и направление их только в файл в /tmp означало, что их никто никогда не читал. Если ваш MCP-клиент считает любой вывод stderr ошибкой, установите переменную в 0 и читайте файл.

./healthcheck.sh также сообщает о них как о строке WARN mcp-startup, перечисляющей различные предупреждения, так что отсутствующая функция отображается на этапе проверки, а не только в логе. Измерено на этой ветке: базовая установка выдаёт 11 таких предупреждений (numpy, qdrant-client, sentence-transformers, redis, neo4j и т.д.), полная установка — 3. Ни одно из них не приводит к ошибке на этапе проверки. Это инвентаризация того, чего нет в вашей установке, что стоит прочитать один раз и затем игнорировать.

Проверка подписей этого релиза

Коммиты подписаны с помощью SSH. Git не будет их проверять, пока вы не укажете, каким ключам доверять, и эта конфигурация не передаётся с клоном:

git config gpg.ssh.allowedSignersFile .allowed_signers
git log --show-signature -1

Без первой строки git log --format=%G? сообщает N для каждого коммита, что означает «не удалось проверить», а не «не подписано». Подписи присутствуют в любом случае: git cat-file commit HEAD показывает блок gpgsig.

Устранение неполадок

Каждый инструмент возвращает нули или поле error

Демон не запущен. Это самый распространённый случай с большим отрывом.

{"count": 0, "results": [], "error": "Memory-DB service error: ..."}
setup/bin/memory-db-daemon.sh          # foreground, watch it
./healthcheck.sh --skip-mcp            # confirm the round trip

Сервер и демон не согласны по поводу базы данных

Симптом: записи как будто успешны, но поиск никогда их не находит, или get_memory_status сообщает количество, не соответствующее тому, что вы сохранили. Два процесса разрешили разные файлы, и ни один не сообщил об ошибке.

./healthcheck.sh обнаруживает это напрямую:

FAIL db-agreement  SPLIT BRAIN: daemon holds /path/A/memory.db,
                   this environment resolves /path/B/memory.db

Причина: что-то запустило один процесс с другим значением ENHANCED_MEMORY_DIR, ENHANCED_MEMORY_DB_PATH или HOME, чем другой. Обычно MCP-клиент настроен на выполнение python server.py напрямую, минуя лаунчер, который применяет .env. Исправьте конфигурацию клиента, чтобы использовался setup/bin/mcp-server.sh, затем перезапустите оба процесса.

Запросы содержимого возвращают ноль, а запросы имени работают

Начиная с e9ca30c это не может произойти незаметно: когда поиск не видит содержимое наблюдения, в ответе об этом сообщается:

{"count": 0, "results": [], "degraded": "name-only (observations_fts missing)"}

degraded означает, что база данных старше полнотекстового индекса и ни один демон не инициализировался против неё после обновления. Перезапустите демон: init_database() теперь создаёт индекс и заполняет все существующие строки. Другое значение, name-only (FTS query error), относится к конкретному запросу и означает, что текст запроса нарушил синтаксис FTS после санитизации; поиск по имени/типу всё равно выполнился.

Повторный импорт начальных данных приводит к дублированию наблюдений

Исправлено в e9ca30c: create_entities пропускает наблюдения, чьё точное содержимое уже существует для этой сущности, и сообщает о пропусках как observations_deduped в своём ответе, так что повторные начальные импорты становятся идемпотентными. Действительно новые наблюдения всё ещё добавляются. Дубликаты, созданные повторными импортами до исправления, не удаляются автоматически — в issue #8 есть одноразовый SQL для очистки.

Перефразированные повторные импорты (тот же начальный файл, слегка отредактированный) также обнаруживаются с помощью детерминированного simhash — без участия LLM. По умолчанию они сохраняются и сообщаются в поле ответа near_duplicates, которое указывает, на какую существующую строку похожа каждая из них: исправление («62Gi» → «125Gi») неотличимо от перефразирования на этом уровне, и хранилище памяти не должно молча отбрасывать исправление. Конвейер импорта, который знает, что выполняет повторный импорт, может установить ENHANCED_MEMORY_NEAR_DUP_POLICY=skip, чтобы отбрасывать их; любое другое значение этой переменной возвращается к безопасному сохранению и сообщению. Порог расстояния и измеренные калибровочные диапазоны находятся в simhash_dedup.py.

OSError при запуске демона без полезного сообщения

Путь к сокету слишком длинный. AF_UNIX ограничивает строку пути до 104 байт на macOS и 108 на Linux, и bind() завершается ошибкой с сообщением, которое не упоминает ни ограничение, ни путь. Глубокие checkout сталкиваются с этим, как только сокет размещается внутри них.

Держите MEMORY_DB_SOCKET_PATH коротким и вне checkout, например /tmp/em-myproject.sock. setup/setup.sh измеряет его и отказывается продолжать, если он слишком длинный.

macOS: сервис устанавливается, но демон никогда не запускается

Если в логе отображается Operation not permitted для пути к лаунчеру, значит, checkout находится в месте, откуда launchd не разрешено выполнять код. Проверено 2026-08-14: checkout на внешнем томе в /Volumes устанавливается и загружается нормально, но каждый запуск завершается с EPERM, потому что launchd работает без доступа к диску, который есть у вашего терминала.

Переместите checkout в домашнюю директорию или другой локальный путь и переустановите, или предоставьте launchd полный доступ к диску, если местоположение не подлежит обсуждению. Установщик выявляет это, а не скрывает: он ожидает сокета, завершается ошибкой через 30 секунд и выводит хвост лога ошибок.

ConnectionRefusedError при существующем файле сокета

Убитый демон оставил файл. Запустите демон снова, и он удалит файл самостоятельно, записав в лог removed stale socket <path>; программа-запускатель делает то же самое перед exec. Не удаляйте файл сокета вручную по привычке — файл, который всё ещё обслуживается, выглядит точно так же, как устаревший, и его удаление отключает всех клиентов демона, которому он принадлежит.

REFUSING TO START: another daemon is already serving ...

Работает как задумано: что-то другое отвечает по этому пути сокета. Сообщение называет сокет и, когда другой демон отвечает на запрос статуса, базу данных, которую он держит. Либо остановите тот демон, либо дайте этому его собственные MEMORY_DB_SOCKET_PATH и ENHANCED_MEMORY_DIR — см. Already running an enhanced-memory system?.

Клиент MCP выходит из строя при рукопожатии с ошибкой разбора JSON

Что-то вывелось в stdout, который принадлежит исключительно потоку JSON-RPC по транспорту stdio. ./healthcheck.sh проверка 3 сообщает об этом как FAIL mcp-stdout вместе с оскорбительной строкой.

python3 — это 3.9

Обычно на macOS. Установите поддерживаемый интерпретатор (brew install python@3.11) и перезапустите setup/setup.sh, который предпочитает именованные версии. Чтобы принудительно: setup/setup.sh --python /path/to/python3.11.

Пробелы и известные проблемы

Написано для перепроверки, а не для доверия.

  • Проверка работоспособности не использует транспорт SSE, не вызывает отдельные инструменты (она их перечисляет), не тестирует одновременный доступ от нескольких клиентов и не измеряет качество извлечения с векторным стеком или без него.

  • Показатели производительности, приведенные в более старых версиях этого README, не были воспроизведены здесь и были удалены, а не повторены. Ничто в этом файле не утверждает пропускную способность, задержку или коэффициент сжатия.

  • Путь контейнера проверен с podman 5.8.4 на Fedora 44, linux/amd64: собран, запущен, полная проверка зеленая внутри него, тест супервизора дал Exited (1), а точка входа называет, какая половина умерла, и podman-compose поднял стек здоровым. Также был собран и запущен под container от Apple и под Docker на macOS/arm64 во время разработки. Не охвачено: любой дистрибутив, кроме Fedora 44, и rootful podman (все вышеупомянутое было без root).

  • Сервисные юниты устанавливаются и запускаются установщиком, который ждет сокет и громко сообщает об ошибке, если он не появляется. Выживание после реальной перезагрузки или выхода из системы не проверялось.

  • Количество инструментов варьируется в зависимости от поверхности, профиля и того, какие дополнительные зависимости установлены. Относитесь к любому отдельному числу как к специфичному для конфигурации одной машины.

Лицензия

MIT

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

Maintenance

Maintainers
1hResponse time
Release cycle
Releases (12mo)
Commit activity
Issues opened vs closed

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 management for AI agents with semantic search and 50+ tools.

  • Persistent memory and knowledge graphs for AI agents. Hybrid search, context checkpoints, and more.

  • Universal memory for AI agents and tools. Save, organize and search context anywhere.

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/marc-shade/enhanced-memory-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server