> For the complete documentation index, see [llms.txt](https://docs.onerpa.ru/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.onerpa.ru/mcp-servery-1c/servery/code-metadata-search/konfiguraciya.md).

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

## Переменные окружения

### Обязательные

| Переменная                 | Описание                                                                                                                                                                                                                                                             | Пример                     |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
| `LICENSE_KEY`              | Лицензионный ключ                                                                                                                                                                                                                                                    | `YOUR_LICENSE_KEY`         |
| `LICENSE_KEY_FILE`         | Предпочтительный способ передачи ключа: путь к смонтированному файлу, который содержит только лицензионный ключ. Значение ключа не попадает в окружение процесса. Файл должен быть обычным, непустым, небольшим и на POSIX недоступным для чтения группе и остальным | `/run/secrets/license_key` |
| `LICENSE_KEY_FILE_CONSUME` | Удалить файл ключа сразу после чтения                                                                                                                                                                                                                                | `false`                    |
| `CODE_PATH`                | Корень Designer XML-выгрузки или проекта 1C:EDT                                                                                                                                                                                                                      | `/app/code`                |

`METADATA_PATH` больше не обязателен. Он нужен только для совместимого режима `METADATA_SOURCE=report` с готовым текстовым отчётом.

### Настройки сервера

| Переменная                         | Описание                                                                                                                                                                                                                                              | По умолчанию                |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| `MCP_HOST`                         | Хост для привязки сервера                                                                                                                                                                                                                             | `0.0.0.0`                   |
| `MCP_PORT`                         | Порт сервера и адресата встроенной проверки здоровья контейнера                                                                                                                                                                                       | `8000`                      |
| `MCP_PATH`                         | Путь MCP-эндпоинта                                                                                                                                                                                                                                    | `/mcp`                      |
| `USESSE`                           | Включить SSE-транспорт для legacy-клиентов. По умолчанию используется `streamable-http`                                                                                                                                                               | `false`                     |
| `FASTMCP_STATELESS_HTTP`           | Не хранить состояние между HTTP-вызовами; уменьшает число долгоживущих сессий                                                                                                                                                                         | `true`                      |
| `MCP_STRUCTURED_CONTENT`           | Дублировать ответы-словари и списки в `structuredContent`; по умолчанию сервер отдаёт один JSON-блок `text content`, чтобы большие ответы не попадали клиенту дважды                                                                                  | `false`                     |
| `MCP_SESSION_IDLE_TTL_SEC`         | Время простоя сессии до освобождения; `0` отключает ограничение                                                                                                                                                                                       | `1800`                      |
| `MCP_SESSION_MAX_LIFETIME_SEC`     | Максимальное время жизни сессии; `0` отключает ограничение                                                                                                                                                                                            | `86400`                     |
| `MCP_SESSION_MAX_CONCURRENT`       | Максимум одновременных MCP-сессий                                                                                                                                                                                                                     | `64`                        |
| `MCP_SESSION_CLEANUP_INTERVAL_SEC` | Интервал очистки завершённых и просроченных сессий                                                                                                                                                                                                    | `60`                        |
| `MCP_SESSION_BOUNDS_MODE`          | `enforce` применяет лимиты, `report` только считает нарушения                                                                                                                                                                                         | `enforce`                   |
| `MCP_IMAGE_REF`                    | Неизменяемая ссылка на образ с digest для проверки release identity в `stats`                                                                                                                                                                         | *(не задано)*               |
| `METADATA_SOURCE`                  | Источник метаданных: `xml` — читать их из `CODE_PATH`; `report` — требовать готовый отчёт в `METADATA_PATH`; `auto` — выгрузка в `CODE_PATH`, иначе отчёт                                                                                             | `xml`                       |
| `SOURCE_FORMAT`                    | Формат `CODE_PATH`: `auto`, `designer_xml` или `edt`                                                                                                                                                                                                  | `auto`                      |
| `PROJECT_ID`                       | Явно закрепить идентификатор проекта индекса. Если не задан — выводится из каталогов `CODE_PATH` и `METADATA_PATH`; закрепление переживает перенос точки монтирования                                                                                 | *(выводится)*               |
| `GENERATION_RETENTION_COUNT`       | Сколько поколений индекса хранить на диске (обслуживаемое плюс предыдущие, для отката); значение меньше 1 повышается до 1. Лишние поколения удаляются по окончании ближайшего прогона индексации — стартового или планового, даже если строить нечего | `2`                         |
| `EMBEDDING_JOURNAL`                | Вести журнал документных эмбеддингов (`embedding-journal/`, см. [Место на диске](#место-на-диске)); `false` — дорожки работают без него, существующие файлы журнала не трогаются                                                                      | `true`                      |
| `GENERATION_LEASE_RENEW_SEC`       | Интервал продления аренды поколения                                                                                                                                                                                                                   | `30`                        |
| `GENERATION_LEASE_TIMEOUT_SEC`     | Таймаут аренды поколения                                                                                                                                                                                                                              | `300`                       |
| `FILE_TRACKER_DB_PATH`             | Совместимый путь к устаревшей базе трекера файлов                                                                                                                                                                                                     | *(внутри `VECTOR_DB_PATH`)* |
| `VECTOR_DB_PATH`                   | Путь к общей директории векторного хранилища и служебных индексов                                                                                                                                                                                     | `/app/chroma_db`            |
| `CHROMA_DB_PATH`                   | Совместимый старый алиас для `VECTOR_DB_PATH`; внутри каталога теперь используются zvec-коллекции и SQLite-индексы                                                                                                                                    | `/app/chroma_db`            |

### Управление индексацией

| Переменная                         | Описание                                                                                                                                                                                                                                                                                                                                                                                                                                         | По умолчанию               |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- |
| `RESET_DATABASE`                   | Переиндексировать при запуске                                                                                                                                                                                                                                                                                                                                                                                                                    | `false`                    |
| `BACKGROUND_INDEXING`              | Выполнять стартовую индексацию в фоне, не блокируя запуск MCP                                                                                                                                                                                                                                                                                                                                                                                    | `true`                     |
| `INCREMENTAL_INDEXING`             | Сверять SHA-256 файлов и обновлять только изменившиеся данные. Переключение этого флага само по себе не делает сохранённые embeddings несовместимыми и не требует их повторного расчёта                                                                                                                                                                                                                                                          | `true`                     |
| `INCREMENTAL_HASH_CHUNK_BYTES`     | Размер блока чтения при расчёте SHA-256                                                                                                                                                                                                                                                                                                                                                                                                          | `65536`                    |
| `REINDEX_INTERVAL_SEC`             | Интервал периодической инкрементальной индексации в секундах. `0` — явное отключение (остаётся только ручной `reindex()`). Тик без изменений в исходниках стоит только расчёта SHA-256 и сверки инвентаря: поколение не создаётся и полосы индексации не запускаются                                                                                                                                                                             | `3600`                     |
| `REINDEX_INTERVAL_HOURS`           | Пользовательский алиас интервала в часах; явный `REINDEX_INTERVAL_SEC` имеет приоритет                                                                                                                                                                                                                                                                                                                                                           | *(не задано)*              |
| `PARSE_WORKERS`                    | Число параллельных обработчиков файлов                                                                                                                                                                                                                                                                                                                                                                                                           | от 1 до 8, по числу CPU    |
| `EMBEDDING_CONCURRENCY`            | Максимум параллельных запросов эмбеддингов                                                                                                                                                                                                                                                                                                                                                                                                       | `6`                        |
| `EMBED_BATCH_SIZE_API`             | Размер пакета для внешнего embedding API                                                                                                                                                                                                                                                                                                                                                                                                         | `64`                       |
| `EMBED_BATCH_SIZE_LOCAL`           | Размер пакета для локальной embedding-модели                                                                                                                                                                                                                                                                                                                                                                                                     | `64`                       |
| `EMBED_QUEUE_CAPACITY`             | Ёмкость очереди подготовленных пакетов; если не задана, вычисляется как четыре размера активного пакета                                                                                                                                                                                                                                                                                                                                          | *(авто)*                   |
| `BATCH_MAX_RETRIES`                | Максимум попыток пакета при временной ошибке embedding-провайдера                                                                                                                                                                                                                                                                                                                                                                                | `10`                       |
| `BATCH_BACKOFF_BASE`               | Основание экспоненциальной паузы между попытками                                                                                                                                                                                                                                                                                                                                                                                                 | `2.0`                      |
| `BATCH_BACKOFF_MAX`                | Максимальная пауза между попытками, секунды                                                                                                                                                                                                                                                                                                                                                                                                      | `60.0`                     |
| `SUB_INDEX_WORKERS`                | Число параллельно строящихся вспомогательных индексов                                                                                                                                                                                                                                                                                                                                                                                            | `4`                        |
| `SUB_INDEX_PROGRESS_WARN_SEC`      | Через сколько секунд непрерывной работы над одним файлом или стадией вывести предупреждение с относительным путём, стадией, временем, прогрессом и числом активных воркеров. Это только диагностика: она не прерывает и не отменяет работу. `0` полностью отключает монитор                                                                                                                                                                      | `300`                      |
| `SUB_INDEX_PROGRESS_HEARTBEAT_SEC` | Минимальный интервал повторных предупреждений, пока та же работа остаётся активной. Пока проход живой, INFO с `N/M file(s) done` пишется не реже чем раз в минуту (или с этим интервалом, если он короче минуты). Значения меньше 5 секунд поднимаются до 5, чтобы исключить лавину сообщений                                                                                                                                                    | `300`                      |
| `SUB_INDEX_LIVENESS_WITNESS`       | Запускать независимый свидетель живости — отдельный процесс, который читает публикуемую родителем запись о стадии и единице работы и сообщает о зависании, даже когда наблюдаемый интерпретатор не выполняет ни одной строки Python. Пороги те же, что у внутрипроцессного монитора; `0` в них выключает и монитор, и свидетеля. Если процесс не удалось запустить, сервер один раз предупреждает и продолжает работу                            | `false`                    |
| `SUB_INDEX_BULK_LOAD`              | Загружать вспомогательные индексы пакетно                                                                                                                                                                                                                                                                                                                                                                                                        | `true`                     |
| `SHUTDOWN_GRACE_SEC`               | Время ожидания активных HTTP-запросов при остановке                                                                                                                                                                                                                                                                                                                                                                                              | `5`                        |
| `INDEX_METADATA`                   | Индексировать метаданные                                                                                                                                                                                                                                                                                                                                                                                                                         | `true`                     |
| `INDEX_CODE`                       | Индексировать BSL-код                                                                                                                                                                                                                                                                                                                                                                                                                            | `true`                     |
| `INDEX_STRUCTURAL`                 | Строить структурный индекс символов. `false` полностью исключает запись и финализацию этой дорожки, переводит readiness-дорожку `symbols` в `disabled`; `search_function` использует ограниченный grep-fallback                                                                                                                                                                                                                                  | `true`                     |
| `STRUCTURAL_PARSE_TIMEOUT_SEC`     | Жёсткая граница времени на структурный разбор одного BSL-модуля. Положительное значение выносит разбор в отдельный дочерний процесс: модуль, не уложившийся в границу, снимает процесс вместе с деревом, дорожка `structural` помечается `failed` с причиной `parse_failure`, сборка не публикуется, а ранее опубликованное поколение продолжает обслуживать запросы. `0` отключает границу — разбор идёт внутри процесса индексации, как раньше | `0`                        |
| `STRUCTURAL_EXCLUDE`               | Аварийное исключение отдельных BSL-модулей из структурного парсера. Значение — строго JSON-массив строк (не больше 64) с glob-шаблонами относительно `CODE_PATH`, через прямой слэш; `*`, `?` и `[...]` поддерживаются, `*` пересекает разделитель каталогов. Не JSON, не список или превышение лимита отвергают политику целиком; пустой, абсолютный или выходящий за корень элемент отбрасывается отдельно                                     | *(не задано)*              |
| `INDEX_DEPENDENCY_GRAPH`           | Строить граф зависимостей. `false` полностью исключает его запись и финализацию, а также запись объектов расширений из XML-прохода графа                                                                                                                                                                                                                                                                                                         | `true`                     |
| `INDEX_FORM_INDEX`                 | Строить индекс форм. `false` полностью исключает запись и финализацию этой дорожки и переводит readiness-дорожку `forms` в `disabled`                                                                                                                                                                                                                                                                                                            | `true`                     |
| `INDEX_XSD_SCHEMAS`                | Генерировать XSD-схемы в help-фазе. Применяется вместе с `INDEX_HELP`: `false` отключает только XSD-дорожку, оставляя индекс HTML-справки включённым                                                                                                                                                                                                                                                                                             | `true`                     |
| `INDEX_HELP`                       | Индексировать HTML-справку                                                                                                                                                                                                                                                                                                                                                                                                                       | `true`                     |
| `INDEX_PHASE_ORDER`                | Порядок фаз; метаданные всегда выполняются первыми                                                                                                                                                                                                                                                                                                                                                                                               | `metadata,code,help`       |
| `INDEX_NESTED_CONFIGURATIONS`      | Индексировать вложенные конфигурации поставщика отдельными источниками                                                                                                                                                                                                                                                                                                                                                                           | `false`                    |
| `NESTED_CONFIGURATION_PATHS`       | Список относительных каталогов-контейнеров вложенных конфигураций через запятую                                                                                                                                                                                                                                                                                                                                                                  | `Ext/ParentConfigurations` |
| `CHUNK_SIZE`                       | Совместимая настройка отпечатка и предела контекстного окна. Текущий splitter создаёт фрагменты фиксированного размера 1000 символов, поэтому изменение переменной не меняет их нарезку, но делает сохранённое поколение несовместимым                                                                                                                                                                                                           | `1000`                     |
| `CHUNK_OVERLAP`                    | Совместимая настройка отпечатка. Текущий splitter использует фиксированное перекрытие 200 символов; изменение переменной не меняет нарезку, но делает сохранённое поколение несовместимым                                                                                                                                                                                                                                                        | `200`                      |
| `SUB_INDEX_INTEGRITY_GATE`         | Режим проверки целостности вспомогательных индексов: `auto`, `blocking`, `report_only` или `off`                                                                                                                                                                                                                                                                                                                                                 | `auto`                     |

`INDEX_CODE` остаётся общим переключателем векторной индексации BSL-кода. Три вспомогательные дорожки управляются независимо: выключенная дорожка не создаёт и не финализирует свои артефакты и не блокирует `/ready`. Если выключить все три, общий проход вспомогательных индексов пропускается целиком, но векторная индексация кода продолжается.

**Область действия `STRUCTURAL_EXCLUDE` — только структурный парсер.** Исключённый `.bsl` по-прежнему читается, попадает в векторный индекс кода и в граф зависимостей; дорожки `metadata`, `help` и `forms` не затрагиваются. Теряются символы самого модуля, рёбра иерархии вызовов, *исходящие* из него, и объявленные в нём аннотации расширений (аннотация из другого модуля, целящаяся в исключённый, получает `unresolved_target`). `get_module_structure` для такого модуля отвечает `reason="structural_excluded"`, а не «не найдено». Дорожка `symbols` остаётся `ready`/`complete` — это решение оператора, а не деградация, — но получает `source_complete=false` и блок `omissions` с именем политики и счётчиками в `/ready` и в `stats()`. Без политики оба поля отсутствуют. Политика входит в отпечаток дорожки `structural`, поэтому её изменение перестраивает дорожку, а уже записанные исключённые модули удаляются из хранилища на ближайшем проходе.

**Живой структурный проход пишет в журнал сам.** Строки `code progress` / `metadata progress` / `help progress` относятся к векторным дорожкам. Структурный проход пишет другое: `Sub-index pass: started` и примерно раз в минуту INFO `N/M file(s) done` с числом воркеров и секундами с старта. Для этих строк переменные менять не нужно. Отсутствие `code progress` не означает, что структурная дорожка стоит.

**Диагностика зависшей единицы, не всего прохода.** Warning `still active past` называет относительный путь, стадию, время и число воркеров, когда *одна* единица держится дольше `SUB_INDEX_PROGRESS_WARN_SEC` (по умолчанию 300 секунд). Чтобы warning появился раньше, поставьте `SUB_INDEX_PROGRESS_WARN_SEC=60`; `SUB_INDEX_PROGRESS_HEARTBEAT_SEC` задаёт интервал повтора того же warning и, если он короче минуты, также частоту INFO. Стадии: `source_walk`, `source_attribution`, `origin_purge`, `store_prepare`, `structural_read`, `structural_parse`, `structural_write`, `dependency_graph`, `form_index`, `worker_wait`, `fts_rebuild`, `extension_resolution`, `sub_index_gate`. При `SUB_INDEX_LIVENESS_WITNESS=true` то же самое повторит отдельный процесс. `0` в пороге выключает и INFO, и warning. Имя модуля из строки `structural_parse` подставляется в `STRUCTURAL_EXCLUDE`; если таких модулей много, дорожку целиком выключает `INDEX_STRUCTURAL=false`. Один подозрительный модуль измеряется отдельно, без полного прохода: `python src/structural_probe.py <путь>/Module.bsl --json` (по умолчанию таймаут 600 секунд, отключает его только явный `--timeout 0`); печатаются размер, время по стадиям, счётчики и типизированный отказ, исходный текст и абсолютные пути — никогда. После изменения переменных пересоздайте контейнер с сохранением тома данных: `docker restart` новые переменные не применяет.

**Границы процедур в выгруженных модулях форм.** Парсер считает концом процедуры и функции не только `КонецПроцедуры` / `КонецФункции` с начала строки, но и хвост той же строки: `Вызов(...);КонецПроцедуры`. Такие однострочные обработчики типичны для Designer XML. Строковый литерал `"КонецПроцедуры"` концом не считается. Старый разбор без этого правила писал ложное `Overlapping definition` на следующей процедуре и после двух таких предупреждений мог часами не печатать прогресс.

### Индексация расширений конфигурации

Расширения индексируются вместе с основной конфигурацией: явно указанные корни берутся первыми, а остальное сервер находит сам рядом с `CODE_PATH`. Происхождение каждого результата возвращается в блоке `origin` — см. [провенанс расширений](https://docs.onerpa.ru/mcp-servery-1c/servery/code-metadata-search/pages/djaqTA3ObVXuMD3hd6mc#провенанс-расширений).

| Переменная                  | Описание                                                                                                                                                                 | По умолчанию  |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- |
| `INDEX_EXTENSIONS`          | Индексировать найденные расширения. `false` отключает индексацию, но не отключает их обнаружение: состав расширений по-прежнему виден в `stats`                          | `true`        |
| `EXTENSION_PATHS`           | Явные корни расширений через запятую; путь абсолютный или относительный к `CODE_PATH`. Несуществующий путь пропускается с предупреждением, а не останавливает индексацию | *(не задано)* |
| `EXTENSION_DISCOVERY_DEPTH` | На сколько уровней выше `CODE_PATH` подниматься при поиске соседних выгрузок расширений. `0` отключает поиск по соседям — тогда работают только `EXTENSION_PATHS`        | `1`           |
| `EXTENSION_EXCLUDE`         | Идентификаторы или объявленные имена расширений через запятую, которые не индексируются. Обнаружение по-прежнему сообщает о них                                          | *(не задано)* |

Набор расширений — свойство прогона, построившего индекс, а не запроса: изменение этих переменных не меняет происхождение уже сохранённых строк, оно применяется при следующей индексации.

{% hint style="info" %}
В 1C:EDT элемент `configurationExtensionPurpose` в `src/Configuration/Configuration.mdo` не пишется, когда назначение — значение по умолчанию «Исправление» (`Patch`). Такой корень всё равно считается расширением: проект с nature `V8ExtensionNature` или с элементом `namePrefix` получает назначение `Patch`. Соседняя база с `V8ConfigurationNature` (или без этих признаков) расширением не становится и при `INDEX_NESTED_CONFIGURATIONS=false` остаётся `nested_configuration` / `policy_excluded`. Явный путь в `EXTENSION_PATHS` не отменяет это распознавание: Patch без тега индексируется как `extension`, а не как вложенная конфигурация. В выгрузке Конфигуратора признак по-прежнему обязателен.
{% endhint %}

### Бюджет ответа по умолчанию

Параметры вызова `max_chars`, `max_items` и `detail_level` со значением `0` / `""` берут значение из этих переменных. Явный параметр запроса всегда имеет приоритет.

| Переменная              | Описание                                                                                                                                               | По умолчанию        |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------- |
| `RESPONSE_MAX_CHARS`    | Предел размера ответа в символах для всей установки. Значение ограничивается сервером диапазоном 2048–262144; выход за него отмечается полем `clamped` | `0` *(без предела)* |
| `RESPONSE_MAX_ITEMS`    | Максимум элементов на странице для всей установки; серверный потолок — `500`                                                                           | `0` *(без предела)* |
| `RESPONSE_DETAIL_LEVEL` | Уровень детализации по умолчанию: `outline` или `full`                                                                                                 | `full`              |

### Качество поиска

| Переменная                      | Описание                                                                                                                                                                             | По умолчанию |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ |
| `BM25_ALPHA`                    | Вес семантического поиска при гибридном ранжировании (0–1). Остаток `1 - alpha` уходит на BM25. Меньше — больший вес точным совпадениям, больше — больший вес семантической близости | `0.5`        |
| `MMR_ENABLED`                   | Включить MMR: похожие по нормализованным словам фрагменты уступают место другим релевантным результатам. Дополнительные запросы к embedding API не выполняются                       | `false`      |
| `MMR_LAMBDA`                    | Вес релевантности в MMR (0–1). `1` сохраняет порядок по оценке; меньшие значения сильнее снижают повторение. Первый результат всегда выбирается по релевантности                     | `0.5`        |
| `CONTEXT_EXPANSION`             | `siblings`: фрагменты той же процедуры для кода и соседи для справки; `window`: соседи во всех трёх поисках; `none`: отключить                                                       | `siblings`   |
| `CONTEXT_WINDOW_SIZE`           | Число соседних фрагментов с каждой стороны для режима окна                                                                                                                           | `1`          |
| `OVERFETCH_MULTIPLIER`          | Множитель расширения выборки для запросов по пути или идентификатору                                                                                                                 | `4`          |
| `SEMANTIC_OVERFETCH_MULTIPLIER` | Множитель расширения выборки для семантических запросов                                                                                                                              | `6`          |
| `OVERFETCH_HARD_CAP`            | Жёсткий предел пула кандидатов до ранжирования                                                                                                                                       | `200`        |
| `OVERFETCH_COLLECTION_FRACTION` | Максимальная доля коллекции в пуле кандидатов                                                                                                                                        | `0.1`        |
| `MAX_CHUNKS_PER_SOURCE`         | Максимум фрагментов одного источника в итоговой выдаче                                                                                                                               | `2`          |
| `RRF_K`                         | Константа reciprocal-rank fusion                                                                                                                                                     | `20`         |
| `FUSION_PRIOR_WEIGHT`           | Вес априорной релевантности при объединении результатов                                                                                                                              | `0.2`        |
| `FALLBACK_ON_EMPTY`             | Выполнять резервный поиск, если основной маршрут ничего не вернул                                                                                                                    | `true`       |
| `MIN_SCORE_THRESHOLD`           | Минимальный порог combined\_score для включения результата (0–1). `0` — без отсечения, `0.3` — агрессивное                                                                           | `0.15`       |
| `EMBEDDING_CACHE_SIZE`          | Размер LRU-кэша для эмбеддингов поисковых запросов. Сокращает вызовы API при повторных запросах. `0` — отключить                                                                     | `256`        |
| `LIVE_XML_FALLBACK`             | Дочитывать XML-выгрузку напрямую, когда индекс не содержит нужного факта                                                                                                             | `true`       |
| `LIVE_XML_CACHE_SIZE`           | Размер кэша разобранных XML-файлов                                                                                                                                                   | `2000`       |
| `LIVE_XML_MAX_FILES`            | Максимум файлов, просматриваемых при live-чтении XML                                                                                                                                 | `50000`      |
| `GREP_FILE_CACHE_SIZE`          | Размер кэша файлов текстового поиска по коду                                                                                                                                         | `500`        |
| `GREP_BROAD_DIR_THRESHOLD`      | Порог числа файлов, после которого каталог считается слишком широким для текстового поиска                                                                                           | `10000`      |
| `GREP_MAX_RESULTS`              | Предел числа результатов слоя точного текстового поиска (grep)                                                                                                                       | `50`         |
| `GREP_DEADLINE_SEC`             | Общий бюджет одного fallback-сканирования в секундах; `0` отключает предел                                                                                                           | `10`         |
| `GREP_MAX_CACHED_FILE_MB`       | Файлы крупнее этого размера читаются, но не остаются в LRU-кэше                                                                                                                      | `8`          |
| `MCP_TOOL_WORKERS`              | Число потоков для тел MCP-инструментов; долгий синхронный поиск не блокирует `/live` и другие вызовы                                                                                 | `4`          |
| `INJECT_GRAPH_DEPENDENCIES`     | Добавлять в индексируемый текст связи графа зависимостей объекта                                                                                                                     | `false`      |

Поле `context` дополняет исходный `document` и ограничено размером `3 × CHUNK_SIZE` (по умолчанию 3000 символов). Совпавший фрагмент остаётся в центре при обрезке. Контекст соблюдает область запроса и читается из того же опубликованного поколения. Если у старых чанков ещё нет числового порядка или один файл достигает предела чтения 10000 чанков, возвращается исходный фрагмент без неполного контекста. После обновления beta обычная индексация перестроит затронутые векторные поколения; неизменившиеся embeddings могут быть взяты из журнала.

{% hint style="warning" %}
`INDEX_STRUCTURAL`, `INDEX_DEPENDENCY_GRAPH`, `INDEX_FORM_INDEX`, `INDEX_XSD_SCHEMAS`, `SUB_INDEX_PROGRESS_WARN_SEC`, `SUB_INDEX_PROGRESS_HEARTBEAT_SEC`, `SUB_INDEX_LIVENESS_WITNESS`, `STRUCTURAL_PARSE_TIMEOUT_SEC`, `STRUCTURAL_EXCLUDE`, `GREP_DEADLINE_SEC`, `GREP_MAX_CACHED_FILE_MB` и `MCP_TOOL_WORKERS` описывают текущую beta-кандидатную реализацию исходников. Перед применением к опубликованному образу проверьте наличие переменных в его release notes или `/release`; stable и ранее опубликованные beta-теги могут их не содержать.
{% endhint %}

Если grep-fallback упирается в время или ширину дерева, он возвращает уже найденное и помечает ответ `partial`: `reason=scan_deadline_reached` или `reason=scan_scope_capped`. Бюджет общий для всех проходов одного вызова, поэтому синонимы не умножают допустимое время. Файлы крупнее `GREP_MAX_CACHED_FILE_MB` по-прежнему читаются — ограничивается только кэширование.

### Векторное хранилище zvec

| Переменная                            | Описание                                                                                                                                                                                                                                                                            | По умолчанию  |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `VECTOR_PROFILE`                      | Профиль zvec: `fast_index`, `balanced`, `memory_saver` или `quality`                                                                                                                                                                                                                | `fast_index`  |
| `VECTOR_INDEX_TYPE`                   | Тип индекса: `hnsw`, `ivf` или `flat`                                                                                                                                                                                                                                               | из профиля    |
| `VECTOR_QUANTIZATION`                 | Квантизация: `none`, `fp16` или `int8`                                                                                                                                                                                                                                              | из профиля    |
| `VECTOR_STORAGE_MODE`                 | Режим хранения: `memory` или `mmap`                                                                                                                                                                                                                                                 | из профиля    |
| `VECTOR_HNSW_M`                       | Параметр связности HNSW                                                                                                                                                                                                                                                             | из профиля    |
| `VECTOR_HNSW_EF_CONSTRUCTION`         | Глубина построения HNSW                                                                                                                                                                                                                                                             | из профиля    |
| `VECTOR_HNSW_EF_SEARCH`               | Явная глубина поиска HNSW; иначе `max(порог профиля, множитель × topk)`. В любом случае не больше 2048 — предел zvec (образы от 19.09.2026; раньше расширенное окно поиска с фильтром по области могло запросить больше, и векторная полоса такого запроса молча отвечала пустотой) | *(авто)*      |
| `VECTOR_IVF_NLIST`                    | Число кластеров IVF                                                                                                                                                                                                                                                                 | из профиля    |
| `VECTOR_IVF_NPROBE`                   | Число просматриваемых кластеров IVF                                                                                                                                                                                                                                                 | из профиля    |
| `VECTOR_MEMORY_LIMIT_MB`              | Ограничение памяти zvec в МБ                                                                                                                                                                                                                                                        | *(не задано)* |
| `VECTOR_QUERY_THREADS`                | Число потоков поиска                                                                                                                                                                                                                                                                | *(авто)*      |
| `VECTOR_OPTIMIZE_THREADS`             | Число потоков оптимизации                                                                                                                                                                                                                                                           | *(авто)*      |
| `VECTOR_OPTIMIZE_ENABLED`             | Разрешить периодическую оптимизацию zvec и финальную оптимизацию кандидата перед публикацией поколения                                                                                                                                                                              | `true`        |
| `VECTOR_OPTIMIZE_EVERY`               | Число новых документов между оптимизациями; `0` — только финальная                                                                                                                                                                                                                  | `100000`      |
| `VECTOR_FLUSH_EVERY`                  | Число новых документов между промежуточными сбросами на диск; `0` — только финальный сброс                                                                                                                                                                                          | `2000`        |
| `VECTOR_OPTIMIZE_DEADLINE_SEC`        | Максимальное ожидание оптимизации в фоновой индексации                                                                                                                                                                                                                              | `1800`        |
| `VECTOR_OPTIMIZE_CANCEL_DEADLINE_SEC` | Максимальное ожидание оптимизации из запроса или принудительной переиндексации                                                                                                                                                                                                      | `5`           |
| `VECTOR_WRITE_FAILURE_THRESHOLD`      | Последовательные ошибки записи до перевода коллекции в терминальное состояние                                                                                                                                                                                                       | `5`           |
| `INDEX_STALL_HEARTBEAT_SEC`           | Через сколько секунд без завершённого файла фаза индексации пишет в журнал, чего ждёт: очередь, файлы в работе, идущее слияние векторного индекса. `0` — выключить                                                                                                                  | `300`         |

Перед публикацией нового поколения сервер завершает оптимизацию и переоткрывает хранилище кандидата. Это сохраняет изменения FTS, которые одного `flush()` в zvec 0.6 недостаточно перенести в следующую копию поколения. Поиск в это время обслуживается предыдущим поколением. Если старый образ уже пометил коллекции как `fts_index_incompatible`, после обновления выполните `reindex(force=true)`.

`VECTOR_OPTIMIZE_ENABLED=false` оставляет запись и поиск по буферизованным документам доступными, но отключает уплотнение и построение ANN-индекса. На большом корпусе это может увеличивать время поиска, расход памяти и диска. Такой обход не даёт гарантии ограниченного роста ресурсов; после обновления и восстановления повреждённых дорожек оптимизацию можно включить обратно.

{% hint style="warning" %}
**Слияние векторного индекса и запись.** zvec складывает новые документы во временный плоский буфер и переносит их в HNSW-индекс при оптимизации; периодическая оптимизация запускается каждые `VECTOR_OPTIMIZE_EVERY` документов в фоновом потоке. В образах до 18.09.2026 (zvec 0.6) вставка была сериализована с оптимизацией внутри самого хранилища: пока шло слияние, потоки записи ждали, обращений к эмбеддингам не было, очередь заполнялась. В zvec 0.7 запись продолжается во время слияния; в образах от 18.09.2026 он стоит на обеих платформах: `arm64-beta` — из опубликованного пакета, x86 (`latest-beta`, `light-beta`) — собранный из исходников без обязательного AVX2 (совместимость с CPU без AVX2; такая сборка сливает медленнее опубликованного пакета, но запись во время слияния идёт). Хранилище, созданное 0.6, открывается на 0.7 без переиндексации. Какое поведение у вашей инсталляции, видно по строке `zvec optimize DONE … (writers waited N s for it)`. Длительность одного слияния растёт с размером индекса и размерностью векторов: на корпусе в миллион фрагментов с 4096-мерными эмбеддингами последние слияния занимают часы; на прежних образах именно так выглядел «хвост» фазы кода — счётчик файлов стоит, CPU низкий, размер хранилища растёт. Это не зависание, и в журнале это видно: в журнале есть `zvec optimize START … (merging N buffered docs …)`, при первом ожидающем писателе — `zvec add on <lane> waits for the background merge in flight (…)`, по завершении — `zvec optimize DONE … (writers waited N s for it)`, а каждые `INDEX_STALL_HEARTBEAT_SEC` без завершённого файла — строка `<lane> phase: no file completed for N min … merge in flight: …`. Строка прогресса ведёт скорость и ETA по последнему интервалу (`files/min (recent; avg)`), а не по среднему за фазу.

Что с этим делать. Не останавливайте контейнер во время слияния: прерванное слияние оставляет маркер, и на следующем старте полоса переносится в rebuild-лейн, то есть переиндексируется целиком. `VECTOR_OPTIMIZE_EVERY` задаёт число слияний (больше значение — меньше слияний, каждое дольше; суммарная работа та же), `VECTOR_OPTIMIZE_THREADS` — число потоков слияния (по умолчанию `min(8, cpu)`). Фаза не считается завершённой, а поколение не публикуется, пока не завершены все файлы и финальная оптимизация — это видно в `get_indexing_status`.
{% endhint %}

### Нейронный реранкер (cross-encoder)

Опциональный нейронный реранкер для повышения качества семантического поиска. При включении оценивает пары (запрос, документ) совместно, что значительно улучшает релевантность результатов.

| Переменная                          | Описание                                                                                      | По умолчанию  |
| ----------------------------------- | --------------------------------------------------------------------------------------------- | ------------- |
| `ENABLE_RERANKER`                   | Включить нейронный реранкер. `true` — использовать cross-encoder, `false` — использовать BM25 | `false`       |
| `RERANKER_MODEL`                    | Модель реранкера. Если не указано — автовыбор в зависимости от окружения                      | *(авто)*      |
| `RERANKER_TOP_K`                    | Максимальное количество кандидатов, передаваемых реранкеру                                    | `20`          |
| `RERANKER_API_BASE`                 | URL API реранкера, если он отличается от `EMBEDDING_API_BASE` / `OPENAI_API_BASE`             | *(не задано)* |
| `RERANKER_API_KEY`                  | Ключ API реранкера, если он отличается от ключа эмбеддингов                                   | *(не задано)* |
| `RERANKER_REQUEST_TIMEOUT_S`        | Таймаут одного запроса к реранкеру, секунды                                                   | `10`          |
| `RERANKER_MAX_CONSECUTIVE_FAILURES` | Число подряд идущих ошибок до временного отключения реранкера                                 | `3`           |
| `RERANKER_COOLDOWN_SECONDS`         | Пауза перед повторной попыткой после отключения реранкера                                     | `30`          |

{% hint style="info" %}
**Автовыбор модели реранкера:**

* Если `OPENAI_API_BASE` задан → API-режим, модель по умолчанию: `Qwen/Qwen3-Reranker-8B`
* Если `OPENAI_API_BASE` не задан → локальный режим, модель: `Qwen/Qwen3-Reranker-0.6B`

Цепочка деградации: cross-encoder → BM25 → только вектор
{% endhint %}

### Embedding модели (LM Studio / Ollama)

| Переменная                     | Описание                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | Пример                                                        |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `EMBEDDING_API_BASE`           | URL API сервера. При использовании OpenRouter: `https://openrouter.ai/api`. Суффикс `/v1` добавляется автоматически                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `http://host.docker.internal:1234/v1`                         |
| `EMBEDDING_API_KEY`            | Ключ API (для LM Studio — любой, для OpenRouter — ваш ключ)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `lm-studio`                                                   |
| `EMBEDDING_MODEL`              | Название модели для API или локального режима (для OpenRouter: `qwen/qwen3-embedding-8b`)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | `sentence-transformers/paraphrase-multilingual-mpnet-base-v2` |
| `EMBEDDING_DIMENSIONS`         | Явное указание размерности эмбеддингов. Поддерживается моделями с переменной размерностью (Qwen3, text-embedding-3). Если не указано — определяется автоматически: по профилю модели, а для модели, которой нет в таблице профилей (например, `text-embedding-qwen3-embedding-4b` в LM Studio), — одним пробным запросом эмбеддинга при старте. Размерность входит в fingerprint поколения индекса, поэтому вычисляется одинаково при холодном старте и в работающем процессе; для неизвестной модели при недоступном в момент старта провайдере она записывается как `0` с предупреждением в журнале — задайте переменную явно, чтобы fingerprint не зависел от доступности провайдера | *(авто)*                                                      |
| `EMBEDDING_PROVIDER`           | Явно выбрать `remote` или `local`; если не задано, сервер выводит режим из варианта образа и настроек endpoint                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | *(авто)*                                                      |
| `EMBEDDING_PROVIDER_AMBIGUITY` | Поведение при неоднозначной legacy-конфигурации: ошибка или вывод режима                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `error`                                                       |
| `EMBEDDING_MEMORY_BUDGET_MB`   | Допустимая оценка памяти для локальной модели до загрузки весов                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `4096`                                                        |
| `EMBEDDING_MEMORY_BUDGET_MODE` | `refuse`, `warn` или `off` при превышении бюджета                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | `refuse`                                                      |
| `EMBEDDING_MEMORY_SAMPLE_SEC`  | Интервал измерения памяти локального embedding-процесса                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `30`                                                          |
| `EMBEDDING_MEMORY_WARN_RATIO`  | Доля бюджета, после которой состояние помечается предупреждением                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | `0.9`                                                         |
| `EMBEDDING_QUERY_PREFIX`       | Переопределить префикс запроса для модели (профиль модели используется, если не задано)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | *(из профиля модели)*                                         |
| `EMBEDDING_DOCUMENT_PREFIX`    | Переопределить префикс документа для модели                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | *(из профиля модели)*                                         |

{% hint style="info" %}
**Поддержка OpenRouter:** Сервер автоматически определяет OpenRouter по URL и добавляет необходимые HTTP-заголовки (`HTTP-Referer`, `X-Title`).
{% endhint %}

### Embedding модели (CPU)

| Переменная        | Описание                                                               | Пример                                                        |
| ----------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------- |
| `EMBEDDING_MODEL` | Модель с Hugging Face; та же переменная выбирает модель и в API-режиме | `sentence-transformers/paraphrase-multilingual-mpnet-base-v2` |

Старые имена `OPENAI_API_BASE`, `OPENAI_API_KEY` и `OPENAI_MODEL` пока принимаются как совместимые алиасы, но новые конфигурации следует создавать с `EMBEDDING_*`.

{% hint style="warning" %}
Здесь есть два разных значения по умолчанию. Если `EMBEDDING_MODEL` не задан в полном образе, исходники используют локальную `sentence-transformers/paraphrase-multilingual-mpnet-base-v2`; удалённый профиль поставки явно закрепляет `qwen/qwen3-embedding-8b`. По измерению от 31.08.2026 ни одна проверенная замена не прошла общий gate, поэтому `qwen/qwen3-embedding-8b` остаётся удалённой моделью поставки.

Смена `EMBEDDING_MODEL` или `EMBEDDING_DIMENSIONS` — миграция, а не дешёвая настройка: меняется fingerprint и полностью переэмбеддируются дорожки `metadata`, `metadata_xml`, `code`, `help` и `form_index`. Для отката верните прежние модель и размерность; после этого потребуется обратная пересборка тех же дорожек.
{% endhint %}

Профиль совместимости — это то, что реестр принимает и с чем сервер умеет работать. Рекомендация качества — отдельное решение: модель становится удалённым умолчанием только если прошла заранее зафиксированный gate. Измерение 31.08.2026 сравнило, среди прочих, `qwen/qwen3-embedding-8b`, `baai/bge-m3` и `openai/text-embedding-3-small`. Замены отклонены; превосходства без этих цифр документация не обещает.

| Модель                          | Размерность | Префиксы query / document | Совместима | Рекомендация качества        |
| ------------------------------- | ----------- | ------------------------- | ---------- | ---------------------------- |
| `qwen/qwen3-embedding-8b`       | 4096        | `query:` / `document:`    | да         | удалённое умолчание поставки |
| `baai/bge-m3`                   | 1024        | нет                       | да         | нет: не прошла gate          |
| `openai/text-embedding-3-small` | 1536        | нет                       | да         | нет: не прошла gate          |

Флаг `rerank_capable` в профиле при поставке по умолчанию не читается: кросс-энкодер включается только `ENABLE_RERANKER=true`. Ни одна модель из этого замера флаг не несёт, поэтому смена эмбеддинга сама по себе реранкер не меняет.

### Плагины

| Переменная                    | Описание                                                                                                                                                                                                      | По умолчанию   |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
| `PLUGIN_DIR`                  | Каталог, из которого читаются файлы плагинов                                                                                                                                                                  | `/app/plugins` |
| `PLUGIN_STRICT_DERIVED_STATE` | `true` — упавший derived-state хук (`on_source_file`, `on_chunk`, `on_metadata_object`) роняет сборку целиком; при `false` единица индексируется без изменений, а ошибка считается и попадает в сводку сборки | `false`        |
| `PLUGIN_HOOK_TIMEOUT_SECONDS` | Бюджет времени одного вызова хука в секундах; превысивший его хук считается упавшим и call-scoped отключается до следующей перезагрузки каталога                                                              | `5.0`          |

Каталог читается при каждом старте, флага включения нет: пустой или отсутствующий каталог ничего не загружает и ничего не меняет. Подробности: [Доработка MCP: система плагинов](/mcp-servery-1c/sistema-pluginov.md).

## Монтируемые тома

| Хост                        | Контейнер        | Назначение                                                                     |
| --------------------------- | ---------------- | ------------------------------------------------------------------------------ |
| `E:/1C_Export/Report`       | `/app/metadata`  | Необязательный legacy-отчёт только для `METADATA_SOURCE=report`                |
| `E:/1C_Export/Files`        | `/app/code`      | Выгрузка в файлы                                                               |
| `E:/bases/mcp_codemetadata` | `/app/chroma_db` | Векторная база данных                                                          |
| `./my-plugins`              | `/app/plugins`   | Свой каталог плагинов; монтирование поверх сохраняет плагины при `docker pull` |

## Примеры конфигураций

### Минимальная (CPU)

```powershell
docker run -d -p 8000:8000 `
  --name 1c_code_metadata_mcp `
  -e LICENSE_KEY=YOUR_LICENSE_KEY `
  -e CODE_PATH="/app/code" `
  -e METADATA_SOURCE=xml `
  -e SOURCE_FORMAT=auto `
  -v "E:/1C_Export/Files:/app/code" `
  comol/1c_code_metadata_mcp:latest-beta
```

### Рекомендуемая (LM Studio)

```powershell
docker run -d -p 8000:8000 `
  --name 1c_code_metadata_mcp `
  -e LICENSE_KEY=YOUR_LICENSE_KEY `
  -e CODE_PATH="/app/code" `
  -e METADATA_SOURCE=xml `
  -e SOURCE_FORMAT=auto `
  -e RESET_DATABASE=false `
  -e EMBEDDING_API_BASE=http://host.docker.internal:1234/v1 `
  -e EMBEDDING_API_KEY=lm-studio `
  -e EMBEDDING_MODEL=Qwen3-Embedding-4B `
  -v "E:/1C_Export/Files:/app/code" `
  -v "E:/bases/mcp_codemetadata:/app/chroma_db" `
  comol/1c_code_metadata_mcp:latest-beta
```

### С OpenRouter (облачные эмбеддинги)

```powershell
docker run -d -p 8000:8000 `
  --name 1c_code_metadata_mcp `
  -e LICENSE_KEY=YOUR_LICENSE_KEY `
  -e CODE_PATH="/app/code" `
  -e METADATA_SOURCE=xml `
  -e SOURCE_FORMAT=auto `
  -e RESET_DATABASE=false `
  -e EMBEDDING_API_BASE=https://openrouter.ai/api `
  -e EMBEDDING_API_KEY=YOUR_OPENROUTER_KEY `
  -e EMBEDDING_MODEL=qwen/qwen3-embedding-8b `
  -v "E:/1C_Export/Files:/app/code" `
  -v "E:/bases/mcp_codemetadata:/app/chroma_db" `
  comol/1c_code_metadata_mcp:latest-beta
```

### Облегчённый образ (light) с LM Studio

```powershell
docker run -d -p 8000:8000 `
  --name 1c_code_metadata_mcp `
  -e LICENSE_KEY=YOUR_LICENSE_KEY `
  -e CODE_PATH="/app/code" `
  -e METADATA_SOURCE=xml `
  -e SOURCE_FORMAT=auto `
  -e RESET_DATABASE=false `
  -e EMBEDDING_API_BASE=http://host.docker.internal:1234/v1 `
  -e EMBEDDING_API_KEY=lm-studio `
  -e EMBEDDING_MODEL=Qwen3-Embedding-4B `
  -v "E:/1C_Export/Files:/app/code" `
  -v "E:/bases/mcp_codemetadata:/app/chroma_db" `
  comol/1c_code_metadata_mcp:light-beta
```

### С реранкером и тюнингом поиска

```powershell
docker run -d -p 8000:8000 `
  --name 1c_code_metadata_mcp `
  -e LICENSE_KEY=YOUR_LICENSE_KEY `
  -e CODE_PATH="/app/code" `
  -e METADATA_SOURCE=xml `
  -e SOURCE_FORMAT=auto `
  -e RESET_DATABASE=false `
  -e ENABLE_RERANKER=true `
  -e BM25_ALPHA=0.5 `
  -e EMBEDDING_API_BASE=http://host.docker.internal:1234/v1 `
  -e EMBEDDING_API_KEY=lm-studio `
  -e EMBEDDING_MODEL=Qwen3-Embedding-4B `
  -v "E:/1C_Export/Files:/app/code" `
  -v "E:/bases/mcp_codemetadata:/app/chroma_db" `
  comol/1c_code_metadata_mcp:latest-beta
```

### С настройкой индексации

```powershell
docker run -d -p 8000:8000 `
  --name 1c_code_metadata_mcp `
  -e LICENSE_KEY=YOUR_LICENSE_KEY `
  -e CODE_PATH="/app/code" `
  -e METADATA_SOURCE=xml `
  -e SOURCE_FORMAT=auto `
  -e RESET_DATABASE=false `
  -e INDEX_CODE=true `
  -e INDEX_METADATA=true `
  -e INDEX_HELP=true `
  -e EMBEDDING_API_BASE=http://host.docker.internal:1234/v1 `
  -e EMBEDDING_API_KEY=lm-studio `
  -e EMBEDDING_MODEL=Qwen3-Embedding-4B `
  -v "E:/1C_Export/Files:/app/code" `
  -v "E:/bases/mcp_codemetadata:/app/chroma_db" `
  comol/1c_code_metadata_mcp:latest-beta
```

## Возобновление расчёта эмбеддингов

При SIGTERM сервер прекращает приём новых работ, а текущая запись или нативное слияние индекса завершается до выхода процесса. `SHUTDOWN_GRACE_SEC` задаёт только ожидание HTTP-запросов. Для остановки во время длительного слияния увеличьте Docker stop timeout, например `docker stop --time 600 <контейнер>` или `stop_grace_period: 10m` в Compose. По истечении внешнего срока Docker применяет SIGKILL, который приложение обработать не может; срок выбирается с учётом длительности слияния на вашей конфигурации.

Успешные батчи документных эмбеддингов сохраняются до записи в zvec в SQLite-журнале `<VECTOR_DB_PATH>/projects/<project_id>/embedding-journal/<lane>.sqlite3`. Монтируйте постоянный том для всего `/app/chroma_db`: журнал находится за пределами удаляемых поколений индекса.

Если индексацию прервали перезапуском контейнера, SIGTERM или недоступностью embedding-модели, поколение не удаляется. После инициализации (инвентарь, recovery) сервер продолжает ту же сборку: завершённые дорожки берутся из их чекпоинтов, а прерванная дорожка кода — из `file_tracker` этого поколения (уже учтённые файлы не разбираются и не эмбеддятся заново). Журнал дополнительно подставляет уже оплаченные векторы, если файл всё же попал в повтор. Частичный прогресс не делает индекс готовым к публикации.

Журнал требует дополнительного места: 4 байта на измерение вектора плюс ключи и служебные данные SQLite (в образах до 18.09.2026 — 8 байт; такие записи остаются читаемыми и заменяются по мере изменения файлов). Устаревшие записи очищаются при успешной обработке дорожки, а очистка старых поколений сохраняет журнал. Освобождённые страницы SQLite переиспользуются, но файл не уменьшается. `EMBEDDING_JOURNAL=false` выключает журнал. Удаление тома или смена проекта лишает восстановления сохранённых данных. Запрос, который провайдер уже обработал, но сервер ещё не сохранил, может повториться; однократная оплата внешнего API не гарантируется.

## Место на диске

Внутри `<VECTOR_DB_PATH>/projects/<project_id>/` живут две крупные сущности:

* `generations/<id>/` — поколения индекса: zvec-коллекции (векторы в типе профиля — `fp16` для `fast_index`, HNSW-граф, тексты фрагментов), FTS и служебные SQLite-индексы. Обслуживается одно поколение; новое строится рядом и публикуется атомарно, так что во время сборки на диске всегда два. После публикации предыдущие хранятся в количестве `GENERATION_RETENTION_COUNT` (по умолчанию `2`, то есть текущее и одно предыдущее для отката) и удаляются по окончании ближайшего прогона индексации — стартового после перезапуска или планового ежечасного, даже если строить нечего. `GENERATION_RETENTION_COUNT=1` оставляет только обслуживаемое поколение; поколение, которое ещё удерживает читатель, не удаляется до освобождения.
* `embedding-journal/<lane>.sqlite3` — журнал документных эмбеддингов (раздел выше): по одной записи на текущий фрагмент каждой дорожки с векторами, `4 байта × размерность`. Он не временный буфер и после `INDEXING COMPLETE` не сокращается: его назначение — при следующей полной пересборке (смена версии раскладки индекса в новом образе, `reindex(force=true)`, прерванная дорожка) подставить уже посчитанные векторы вместо повторных обращений к embedding-модели. Удалять его можно только при остановленном контейнере (или между сборками, когда в `get_indexing_status` нет активного поколения); ничего в индексе от этого не меняется, а цена — следующая полная пересборка посчитает эмбеддинги заново. Чтобы журнал не рос снова, задайте `EMBEDDING_JOURNAL=false`.

Ориентир для планирования на 100 000 фрагментов при 4096-мерных эмбеддингах: поколение в профиле `fast_index` (fp16) — 2–2,7 ГБ (измерено на корпусах 350 тыс. и 1 млн фрагментов), журнал — 1,7 ГБ (`4 байта × 4096 × 100 000` плюс служебные данные SQLite; в образах до 18.09.2026 — 3,4 ГБ). При `GENERATION_RETENTION_COUNT=2` и включённом журнале: около 7 ГБ на 100 000 фрагментов; при `GENERATION_RETENTION_COUNT=1` без журнала — 2,7 ГБ, но во время пересборки в любом случае нужно место под два поколения. Размерность вектора входит линейно: при 1024 измерениях делите цифры на четыре.

## Восстановление FTS после обновления кодека

В прежней portable amd64-сборке zvec поддержка AVX2 была отключена при компиляции, но диспетчер FTS всё равно мог выбрать AVX2-заглушки на современном процессоре. Это вызывало SIGSEGV, дубликаты и пропуск совпадений. Простая замена библиотеки не восстанавливает уже повреждённые полнотекстовые блоки.

Сборка с исправлением проверяет ревизию FTS-поля. Если её нет, обычный инкрементальный проход создаёт новую генерацию и пересоздаёт FTS из сохранённых текстов. Неизменившиеся файлы не отправляются на повторный расчёт embeddings. До успешной публикации остаются доступны векторный поиск и поиск подстроки; полнота полнотекстового поиска восстанавливается после переключения поколения. В диагностике коллекции состояние обозначается `fts_repair_required`.

Оставьте `RESET_DATABASE=false` и `INCREMENTAL_INDEXING=true`. Для этой ошибки удалять том или принудительно пересчитывать всю конфигурацию не требуется. Ремонт использует место для копии поколения и сохраняет число документов. При сбое кандидат не публикуется; опубликованное поколение не изменяется. Отдельные повреждения, уже отмеченные как `rebuild_required` или `quarantined`, этот ремонт кодека не устраняет — для них сохраняется штатное восстановление.

Для известных повреждённых коллекций используйте `reindex(force=true)`. При неизменных модели, проекте и отпечатках здоровых коллекций сервер перестраивает только повреждённые, сохраняя остальные. Изменение модели или проекта по-прежнему требует полной перестройки.

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

```json
{
  "mcpServers": {
    "1c-code-metadata-mcp": {
      "url": "http://localhost:8000/mcp",
      "connection_id": "1c_metadata_service_001"
    }
  }
}
```

## Доработка

Сервер поддерживает [систему плагинов](/mcp-servery-1c/sistema-pluginov.md). В отличие от остальных серверов справочник лежит не в корне образа, а в `/app/src/plugin_api.py` — команда `docker run --rm comol/1c_code_metadata_mcp:latest-beta ls /app/plugin_api.py` даст ложное «нет плагинов». Проверять нужно так:

```powershell
docker run --rm comol/1c_code_metadata_mcp:latest-beta ls /app/src/plugin_api.py /app/plugins
```

Без плагинов поведение сервера настраивается форматом источника (`METADATA_SOURCE`, `SOURCE_FORMAT`, `CODE_PATH`, вложенные конфигурации) и параметрами поиска: `BM25_ALPHA`, `MIN_SCORE_THRESHOLD`, `ENABLE_RERANKER`, `VECTOR_PROFILE` и множителями выборки.
