> 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/ssl-search-server/konfiguraciya.md).

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

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

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

| Переменная    | Описание          | Пример             |
| ------------- | ----------------- | ------------------ |
| `LICENSE_KEY` | Лицензионный ключ | `YOUR_LICENSE_KEY` |
| `SSL_VERSION` | Версия БСП        | `3.1.11`           |

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

| Переменная                            | Описание                                                                                                                                                                                                                                                                                                                                         | По умолчанию |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ |
| `RESET_DATABASE`                      | Переиндексировать при запуске                                                                                                                                                                                                                                                                                                                    | `false`      |
| `FORCE_REINDEX_ON_DIMENSION_MISMATCH` | Автоматически пересоздать коллекцию zvec при несовпадении размерности эмбеддингов. По умолчанию `false` — старт останавливается и сообщает, что нашёл, вместо того чтобы решать за оператора. Не действует, если старт перешёл на локальную модель поверх коллекции, построенной через API: такую коллекцию сервер не пересоздаёт (с 27.09.2026) | `false`      |
| `INDEXING_THREADS`                    | Число параллельных потоков генерации эмбеддингов при индексации                                                                                                                                                                                                                                                                                  | `5`          |
| `MIGRATE_VECTOR_STORE`                | Выполнить на этом старте миграцию векторного хранилища — перестроение корпуса рядом с обслуживающим поколением. Не выводится из манифеста: момент перестроения выбирает оператор                                                                                                                                                                 | `false`      |
| `DEMOTE_VECTOR_STORE`                 | Вернуть обслуживание предыдущему поколению. Ничего не удаляет: переписывается только то, какое имя обслуживает                                                                                                                                                                                                                                   | `false`      |

Текущий рантайм zvec, обслуживающее поколение, запись манифеста и итог последней миграции показывает инструмент `vector_store_state`.

### Транспорт

| Переменная | Описание                            | По умолчанию |
| ---------- | ----------------------------------- | ------------ |
| `USESSE`   | SSE транспорт (для legacy клиентов) | `false`      |

Внутри контейнера сервер и его healthcheck используют фиксированный порт `8008`. Переменные `MCP_PORT` и `HTTP_PORT` SSLSearchServer не читает. Чтобы подключаться с хоста через другой порт, измените левую часть проброса Docker, например `-p 127.0.0.1:18008:8008`, и укажите клиенту `http://localhost:18008/mcp`. Встроенная проверка `/ready` при этом продолжает обращаться к внутреннему `8008`. При `--network host` проброса портов нет: сервер занимает порт `8008` самого хоста.

### Поиск и журналирование

| Переменная             | Описание                                                                                                                                                                                                                               | По умолчанию |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `MIN_SCORE`            | Порог cosine similarity для `ssl_search`; некорректное значение заменяется калиброванным                                                                                                                                               | `0.3826`     |
| `EXACT_LOOKUP`         | Точный поиск по каноническому имени символа перед остальными маршрутами (`lane=exact`). `false` отключает только exact lane; hybrid/BM25 продолжает работать, пока отдельно не задано `HYBRID_SEARCH=false`                            | `true`       |
| `HYBRID_SEARCH`        | Опрашивать обе дорожки — векторную и полнотекстовую (BM25) — с объединением по reciprocal rank fusion. `false` оставляет только векторную, ничего не перестраивая: полнотекстовый индекс остаётся на месте, меняется лишь путь запроса | `true`       |
| `MAX_RESPONSE_CHARS`   | Бюджет длины ответа `ssl_search` в символах. Значение ниже 1024 поднимается до этого предела с записью в журнал: бюджет, в который не помещается один размеченный результат, — это отказ отвечать, а не бюджет                         | `4000`       |
| `MAX_QUERY_CHARS`      | Максимальная длина запроса до и после plugin/alias rewrite. Значение ниже 256 поднимается до 256; превышение даёт `query_too_long` без текста запроса в ошибке                                                                         | `2048`       |
| `MAX_GUARDED_SEARCHES` | Максимум поисков внутри deadline guard; ограничивает одновременно потоки и обращения к хранилищу                                                                                                                                       | `64`         |
| `LOG_QUERIES`          | Разрешить запись полного текста запросов в журнал; по умолчанию журналируются только длина и хеш                                                                                                                                       | `false`      |
| `LOG_DIR`              | Каталог файла журнала. Относительный путь отсчитывается от корня приложения, а не от рабочего каталога                                                                                                                                 | `<app>/logs` |

### HTTP-сессии

Границы и счётчики сессий показывает инструмент `session_state`.

| Переменная                 | Описание                                      | По умолчанию |
| -------------------------- | --------------------------------------------- | ------------ |
| `SESSION_IDLE_TTL`         | Время простоя сессии до освобождения, секунды | `900`        |
| `SESSION_MAX_LIFETIME`     | Максимальное время жизни сессии, секунды      | `14400`      |
| `SESSION_MAX_CONCURRENT`   | Максимум одновременных сессий                 | `128`        |
| `SESSION_CLEANUP_INTERVAL` | Интервал очистки просроченных сессий, секунды | `30`         |

### Таймауты обращений к embedding-провайдеру

| Переменная                     | Описание                                                                                                                                                                                                                                                                                                                                                                                                                                                 | По умолчанию |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `EMBEDDING_SEARCH_DEADLINE`    | Бюджет времени на кодирование запроса в одном `ssl_search`, секунды. Повторы при временной ошибке идут внутри этого бюджета. С внешним API через агрегатор (OpenRouter, BotHub, RouterAI) и большой моделью (Qwen3-Embedding-8B) задавайте `30`, чтобы единичная задержка провайдера не превращалась в отказ поиска. Таймаут вызова инструмента в MCP-клиенте должен быть больше этого значения. Неуложившийся поиск возвращается как ошибка инструмента | `15`         |
| `EMBEDDING_PROBE_DEADLINE`     | Таймаут стартовой проверки провайдера, секунды                                                                                                                                                                                                                                                                                                                                                                                                           | `60`         |
| `EMBEDDING_BATCH_DEADLINE`     | Таймаут одного пакета при индексации, секунды                                                                                                                                                                                                                                                                                                                                                                                                            | `300`        |
| `EMBEDDING_MAX_ATTEMPTS`       | Сколько раз повторять один запрос к провайдеру при временной ошибке (1–10)                                                                                                                                                                                                                                                                                                                                                                               | `4`          |
| `EMBEDDING_BATCH_MAX_ATTEMPTS` | Сколько раз пробовать один пакет индексации, прежде чем пропустить его (1–10; раньше всегда 5). Пакет делает не больше `EMBEDDING_BATCH_MAX_ATTEMPTS` × `EMBEDDING_MAX_ATTEMPTS` запросов, все — в пределах `EMBEDDING_BATCH_DEADLINE`; повторов внутри клиента OpenAI нет. Чтобы оплачиваемых запросов на пакет было не больше одного, задайте обе переменные равными `1`. Перестроения индекса нет                                                     | `5`          |
| `EMBEDDING_BACKOFF_BASE`       | Базовая пауза между попытками, секунды                                                                                                                                                                                                                                                                                                                                                                                                                   | `0.25`       |
| `EMBEDDING_BACKOFF_CAP`        | Предел паузы между попытками, секунды                                                                                                                                                                                                                                                                                                                                                                                                                    | `8`          |

### Размер пакетов и чанкование при индексации

| Переменная                       | Описание                                                                                                     | По умолчанию |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------ |
| `EMBEDDING_MAX_BATCH_TOKENS`     | Максимум токенов в одном пакете к провайдеру                                                                 | `8192`       |
| `EMBEDDING_MAX_BATCH_CHARACTERS` | Максимум символов в одном пакете                                                                             | `131072`     |
| `MAX_BATCH_SPLITS`               | Сколько раз пакет может быть разделён при отказе провайдера по размеру                                       | `8`          |
| `EMBEDDING_TOKEN_LIMIT`          | Явный лимит токенов модели. `0` — определить автоматически; задавайте, если провайдер не сообщает свой лимит | `0` *(авто)* |
| `CHUNK_OVERLAP_TOKENS`           | Перекрытие соседних чанков длинной записи, в токенах (но не больше четверти лимита)                          | `48`         |

### Остановка контейнера

| Переменная               | Описание                                                                                                                                                                               | По умолчанию |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `SHUTDOWN_GRACE_SECONDS` | Общий бюджет корректного завершения. Значение по умолчанию выбрано под `docker stop`, который даёт 10 секунд до SIGKILL                                                                | `10`         |
| `SHUTDOWN_FLUSH_SECONDS` | Часть этого бюджета на сброс данных хранилища. Меньше общего: зависшее хранилище должно стоить свой собственный лимит и быть честно об этом сообщено, а не съедать всё время оператора | `5`          |

{% hint style="info" %}
По сигналу остановки сервер перестаёт принимать новые пакеты индексации, доводит начатое до контрольной точки и сбрасывает хранилище. Прерванная индексация не портит обслуживающее поколение.
{% endhint %}

### Плагины

| Переменная                    | Описание                                               | По умолчанию   |
| ----------------------------- | ------------------------------------------------------ | -------------- |
| `PLUGIN_DIR`                  | Каталог Python-плагинов внутри контейнера              | `/app/plugins` |
| `PLUGIN_STRICT_DERIVED_STATE` | Останавливать индексацию при ошибке derived-state hook | `false`        |

Свой каталог можно подключить томом в `/app/plugins`. Текущее состояние показывает `plugin_state`, а `plugin_reload` перечитывает каталог без перезапуска контейнера.

Сервер расширяется плагинами: плагин — **один Python-файл** в `/app/plugins`, без базового класса, декоратора, регистрации и манифеста. Объявлены четыре hooks — `on_startup`, `on_request`, `on_result` (в рамках вызова) и `on_entry` (формирует векторную коллекцию) — и таблица `QUERY_ALIASES` (замены терминов в запросе перед эмбеддингом). Полный контракт лежит в образе: `/app/plugin_api.py`, `/app/plugins/AGENTS.md`, `/app/plugins/example.py`. Проверить файл без данных и индекса:

```powershell
docker run --rm -v "E:/plugins/mcp_ssl/10-terms.py:/tmp/my_plugin.py" `
  comol/mcp_ssl_server:latest python launcher.py --dry-run /tmp/my_plugin.py
```

Правка `on_entry` делает сохранённую коллекцию устаревшей и вызывает переэмбеддирование выбранной базы БСП; call-scoped хуки и таблица ничего не пересобирают. Подробно: [Доработка MCP: система плагинов](/mcp-servery-1c/sistema-pluginov.md) и [справочник хуков SSLSearchServer](/mcp-servery-1c/sistema-pluginov/spravochnik-hukov.md#sslsearchserver).

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

| Переменная                         | Описание                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Пример                                                                         |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| `EMBEDDING_API_BASE`               | URL API сервера. Суффикс `/v1` добавляется автоматически                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `http://host.docker.internal:1234/v1`                                          |
| `EMBEDDING_API_BASE_NO_V1`         | Передавать базу API дословно, без автодобавления `/v1` (значения `1`, `true`, `yes`) — для шлюзов, отдающих OpenAI-совместимый API без суффикса `/v1`. С 10.10.2026                                                                                                                                                                                                                                                                                                                                                  | `1`                                                                            |
| `EMBEDDING_API_KEY`                | Ключ API                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `lm-studio`                                                                    |
| `EMBEDDING_MODEL`                  | Имя модели, с которым вызывается API эмбеддингов. У модели Qwen3-Embedding запрос идёт с инструкцией задачи (см. [Инструкция к запросу у Qwen3](https://docs.onerpa.ru/mcp-servery-1c/servery/ssl-search-server/pages/zZx7MZNnC5Ejse6V9TZC#инструкция-к-запросу-у-qwen3)); `EMBEDDING_INPUT_TYPE_ENABLED=false` выключает её вместе с остальным разделением запроса и документа                                                                                                                                      | `qwen/qwen3-embedding-8b`                                                      |
| `LOCAL_EMBEDDING_MODEL`            | Hugging Face repo id модели, которую загружает локальный (CPU) режим, когда API недоступен. Совместимый алиас — `OFFLINE_EMBEDDING_MODEL`. Если задана только `EMBEDDING_MODEL`, локальный режим использует её                                                                                                                                                                                                                                                                                                       | `intfloat/multilingual-e5-small`                                               |
| `EMBEDDING_ALLOW_OFFLINE_FALLBACK` | Разрешить вариантам `latest`/`arm64` переходить на `LOCAL_EMBEDDING_MODEL`, если API эмбеддингов недоступен на старте. `true` — разрешить, любое другое значение — запретить. При запрете старт ждёт API (пауза 5 с, удваивается до 60 с), а при 401/403/404 завершается с «No embedding backend available», как `light`. Даже при разрешённом переходе коллекция, построенная через API, не удаляется и не пересобирается: старт останавливается, коллекция остаётся нетронутой. На `light` не влияет. С 27.09.2026 | `false`, если задан `EMBEDDING_API_BASE` (или `OPENAI_API_BASE`); иначе `true` |
| `EMBEDDING_DIMENSIONS`             | Явное указание размерности эмбеддингов. Для моделей с переменной размерностью (Qwen3, text-embedding-3). Если не указано — определяется автоматически                                                                                                                                                                                                                                                                                                                                                                | *(авто)*                                                                       |
| `EMBEDDING_INPUT_TYPE_ENABLED`     | Передавать провайдеру параметр `input_type` (query/document), если он его принимает; `false` выключает его и инструкцию Qwen3. Текстовых префиксов сервер не добавляет                                                                                                                                                                                                                                                                                                                                               | `true`                                                                         |

Старые имена `OPENAI_API_BASE`, `OPENAI_API_KEY` и `OPENAI_MODEL` остаются совместимыми алиасами.

{% hint style="warning" %}
Для предсказуемого обновления явно закрепляйте и `EMBEDDING_MODEL`, и `LOCAL_EMBEDDING_MODEL`. Если задан `EMBEDDING_API_BASE`, сервер с 27.09.2026 при недоступном API по умолчанию не переходит на локальную модель, а ждёт API (5 с, удваиваясь до 60 с); при 401/403/404 старт завершается. Переход разрешает `EMBEDDING_ALLOW_OFFLINE_FALLBACK=true`, но и тогда коллекцию, построенную через API, он не пересоздаёт: при другой размерности или другом имени модели старт останавливается, не изменяя коллекцию, независимо от `FORCE_REINDEX_ON_DIMENSION_MISMATCH`. Чтобы намеренно перевести коллекцию на локальную модель, сделайте один старт с `RESET_DATABASE=true`. Если сохранённая коллекция построена другой моделью или API недоступен и сервер переходит на локальный fallback с другой размерностью, при `FORCE_REINDEX_ON_DIMENSION_MISMATCH=false` запуск останавливается, не изменяя коллекцию. Верните `EMBEDDING_MODEL` к модели из манифеста, либо осознанно перестройте индекс с `FORCE_REINDEX_ON_DIMENSION_MISMATCH=true`; безопасный side-by-side вариант — `MIGRATE_VECTOR_STORE=true`.

Смена модели **без** смены размерности проверкой размерности не ловится: 384 — ширина десятка разных энкодеров, и два из них размещают один и тот же текст в разных местах. Поэтому старт дополнительно сверяет имя модели, записанное в манифесте индекса, с моделью текущего процесса и при расхождении пересобирает коллекцию из корпуса — той же одной пересборкой, что и остальные причины устаревания. Манифест, не называющий модель вовсе, тоже считается неактуальным. Backend при этом не сравнивается: `latest` через API и `arm64` локально с одной моделью дают одни и те же векторы. Если же старт перешёл на локальную модель с другим именем поверх коллекции, построенной через API, коллекция не пересобирается — старт останавливается с ошибкой (с 27.09.2026).

Раздельные defaults и этот сценарий миграции относятся к текущим исходникам; опубликованный образ мог быть собран раньше.
{% endhint %}

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

| Хост               | Контейнер      | Назначение                 |
| ------------------ | -------------- | -------------------------- |
| `E:/bases/mcp_ssl` | `/app/zvec_db` | Векторная база данных zvec |

## Доступные версии БСП

Сервер поддерживает различные версии БСП. Укажите вашу версию в `SSL_VERSION`.

Примеры:

* `3.1.11`
* `3.1.9`
* `3.2.1`
* `2.4.6`

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

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

```powershell
docker run -d -p 8008:8008 `
  --name mcp_ssl_server `
  -e LICENSE_KEY=YOUR_LICENSE_KEY `
  -e SSL_VERSION=3.1.11 `
  comol/mcp_ssl_server:latest
```

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

```powershell
docker run -d -p 8008:8008 `
  --name mcp_ssl_server `
  -e LICENSE_KEY=YOUR_LICENSE_KEY `
  -e SSL_VERSION=3.1.11 `
  -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:/bases/mcp_ssl:/app/zvec_db" `
  comol/mcp_ssl_server:latest
```

## Обновление после исправления FTS-кодека

Исправление portable-сборки zvec меняет отпечаток полнотекстового индекса. После установки образа с исправлением сервер автоматически перестраивает старый индекс из выбранной базы БСП. Это обычная переиндексация SSL: она может повторно вызвать embedding-провайдер; до завершения `/ready` сообщает о неготовности. Устанавливать `RESET_DATABASE=true` для этого не требуется.

Нативный FTS старого профиля не используется. Замена одной библиотеки без перестроения не восстанавливает потерянные совпадения в старых FTS-блоках.

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

```json
{
  "mcpServers": {
    "1c-ssl-mcp": {
      "url": "http://localhost:8008/mcp",
      "connection_id": "1c_ssl_service_001"
    }
  }
}
```
