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

# TemplatesSearchServer

Поиск по шаблонам кода 1С и проектная память.

## Назначение

TemplatesSearchServer предоставляет ИИ библиотеку готовых шаблонов и паттернов кода 1С, а также проектную память для хранения заметок и решений. Сервер содержит публичные шаблоны и позволяет добавлять собственные — как через веб-интерфейс, так и программно через MCP-инструменты.

## Возможности

ИИ получает инструменты для:

* Поиска типовых шаблонов кода (гибридный: векторный + полнотекстовый)
* Просмотра каталога всех шаблонов и получения конкретного шаблона по ID
* Добавления новых шаблонов прямо из чата
* Сохранения заметок, решений и наблюдений в проектную память
* Поиска по памяти с помощью семантического поиска

## Примеры использования

**Шаблоны кода:**

* "Как обойти результат запроса?"
* "Покажи шаблон обработки проведения документа"
* "Как правильно работать с транзакциями?"
* "Шаблон формы с динамическим списком"

**Проектная память:**

* "Запомни, что в этом проекте мы используем БСП 3.1"
* "Что мы решили по архитектуре обменов?"
* "Сохрани решение по обработке ошибок в HTTP-сервисах"

## Особенности

* Содержит публичные шаблоны с [fastcode.im](https://fastcode.im/Templates)
* **Веб-интерфейс**: чтение и поиск доступны на `http://localhost:8004/extend/`; создание, изменение и удаление требуют настроенной учётной записи, разрешения операции и CSRF-токена
* Добавление собственных шаблонов через веб-интерфейс или MCP
* **Проектная память** — ИИ может сохранять и извлекать заметки между сессиями
* Гибридный поиск: комбинация векторного (семантического) и полнотекстового

## Доступные инструменты MCP

ИИ получает следующие инструменты:

| Инструмент       | Описание                                                      |
| ---------------- | ------------------------------------------------------------- |
| `templatesearch` | Гибридный поиск шаблонов кода по описанию или ключевым словам |
| `list_templates` | Страничный список шаблонов (ID и описание, без кода)          |
| `get_template`   | Получение полного шаблона по ID (с исходным кодом)            |
| `add_template`   | Добавление нового шаблона с автоматической индексацией        |
| `remember`       | Сохранение заметки в проектную память                         |
| `recall`         | Семантический поиск по проектной памяти                       |
| `plugin_state`   | Состояние плагинов, hooks, ошибок и fingerprint индекса       |
| `plugin_reload`  | Атомарно перечитать каталог плагинов без перезапуска          |

{% hint style="info" %}
`add_template` и `plugin_reload` — изменяющие инструменты. По умолчанию они не регистрируются: их включает `MCP_ENABLE_WRITE_TOOLS` вместе с обязательным `MCP_OPERATOR_TOKEN` (токен передаётся в заголовке `Authorization`). `remember` пишет в проектную память и под этот гейт **не попадает**: он зарегистрирован всегда, не требует заголовка `Authorization` и не расходует лимиты изменяющих вызовов — ограничена только длина заметки. Плата за это: заметку запишет любой, кто дотянется до порта; публикуйте его на `127.0.0.1`. Про доработку сервера плагинами: [система плагинов](/mcp-servery-1c/sistema-pluginov.md).
{% endhint %}

{% hint style="warning" %}
Пагинация `list_templates`, проектная память, защищённые изменяющие инструменты и служебный plugin surface опубликованы в beta. Stable-теги сохраняют прежний контракт; сверяйтесь с `tools/list`. Вызов `plugin_reload` меняет активное поведение процесса и допустим только по явному поручению оператора.
{% endhint %}

***

### templatesearch

Выполняет гибридный поиск по библиотеке шаблонов кода 1С: комбинирует векторный (семантический) и полнотекстовый поиск. Запросы принимаются на русском языке.

| Параметр | Тип    | Обязательный | Описание                                                               |
| -------- | ------ | ------------ | ---------------------------------------------------------------------- |
| `query`  | string | да           | Поисковый запрос — описание нужной функциональности или ключевые слова |

**Возврат**: Отформатированная строка с найденными шаблонами (название, описание, код).

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

* Семантический маршрут получает нормализованный текст запроса, и его кандидаты отсекаются по `TEMPLATE_RELEVANCE_THRESHOLD` (максимальная cosine-distance) до объединения.
* Полнотекстовый маршрут получает исходный текст запроса, потому что индексируемые поля сохраняют точки и подчёркивания. Соседние термины объединяются по `FTS_DEFAULT_OPERATOR`.
* Результаты обоих маршрутов объединяются reciprocal rank fusion с константой `FUSION_RANK_CONSTANT`.
* Из одного шаблона в ответ попадает не более `GROUP_RESULT_CAP` документов; размер выборки кандидатов задаётся `GROUP_CANDIDATE_BUDGET` и ограничен размером коллекции.

**Границы ответа.** Каждый результат — карточка, которая начинается с `**ID:**` и потому всегда адресуема. Весь ответ вместе с примечаниями не превышает 64 KiB; внутри карточки идентификатор ограничен 256 байтами, описание — 1 KiB, код — 3 KiB. Текст режется по границе символа, поэтому один и тот же результат при том же бюджете каждый раз даёт одну и ту же карточку. Карточка, в которую шаблон не поместился целиком, называет число недостающих байт, указывает `get_template(template_id="…")` и содержит машиночитаемую метку `[templatesearch/truncated:<id>]`. Бюджеты подобраны так, чтобы полный ответ помещался целиком: карточки сокращаются, а не выбрасываются; если карточка всё же не вошла, ответ сообщает их число под меткой `[templatesearch/omitted:<count>]`. Полный исходный текст всегда доступен через `get_template`, на который эти границы не распространяются.

***

### list\_templates

Возвращает ограниченную страницу шаблонов — ID и описание. Исходный код не включается; для получения кода используйте `get_template`.

| Параметр | Тип | По умолчанию | Описание                                              |
| -------- | --- | ------------ | ----------------------------------------------------- |
| `limit`  | int | `50`         | Размер страницы, от 1 до 200                          |
| `offset` | int | `0`          | Сколько шаблонов пропустить; неотрицательное значение |

Описания этих границ доступны клиенту в схеме параметров через `tools/list`.

**Возврат**: JSON-объект `{templates, total, returned, limit, offset, next_offset, truncated}`. `next_offset` содержит начало следующей страницы или `null`. Общий ответ ограничен 64 KiB; если даже одна запись слишком велика, её описание явно сокращается и содержит `retrieve_with: "get_template"`.

**Пример ответа:**

```json
{
  "templates": [
    {"id": "1", "description": "Обход результата запроса с выборкой"},
    {"id": "2", "description": "Транзакция с обработкой ошибок"}
  ],
  "total": 120,
  "returned": 2,
  "limit": 2,
  "offset": 0,
  "next_offset": 2,
  "truncated": true
}
```

***

### get\_template

Возвращает полный шаблон по идентификатору, включая исходный код.

| Параметр      | Тип    | Обязательный | Описание                         |
| ------------- | ------ | ------------ | -------------------------------- |
| `template_id` | string | да           | Идентификатор шаблона (числовой) |

**Возврат**: JSON-объект `{id, description, code}`.

**Пример ответа:**

```json
{
  "id": "1",
  "description": "Обход результата запроса с выборкой",
  "code": "Выборка = Запрос.Выполнить().Выбрать();\nПока Выборка.Следующий() Цикл\n    // Обработка строки\nКонецЦикла;"
}
```

***

### add\_template

Добавляет новый шаблон в базу данных и автоматически индексирует его для поиска. Переиндексация или перезапуск не требуются — шаблон сразу доступен через `templatesearch`.

| Параметр      | Тип    | Обязательный | Описание                                         |
| ------------- | ------ | ------------ | ------------------------------------------------ |
| `description` | string | да           | Подробное описание шаблона (минимум 10 символов) |
| `code`        | string | да           | Исходный код на языке 1С (минимум 10 символов)   |

**Возврат**: JSON `{success, message, id}`.

**Пример ответа (успех):**

```json
{"success": true, "message": "Шаблон успешно добавлен (ID: 42)", "id": 42}
```

Если строка уже сохранена в SQLite, но индекс ещё не обновлён, ответ содержит `success: false`, `status: "index_pending"`, `stored: true`, `index_pending: true` и `id`. **Не повторяйте запрос:** повтор создаст дубль; фоновый outbox восстановит индекс.

**Валидация:**

* Описание и код должны содержать минимум 10 символов каждый
* При несоблюдении — `success: false` с описанием ошибки

***

### remember

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

| Параметр  | Тип    | Обязательный | Описание                                                          |
| --------- | ------ | ------------ | ----------------------------------------------------------------- |
| `content` | string | да           | Текст заметки — решение, наблюдение или факт (минимум 5 символов) |

**Возврат**: JSON `{success, message, id}`.

**Авторизация не требуется.** `remember` зарегистрирован при любой конфигурации, заголовок `Authorization` ему не нужен, и лимиты изменяющих вызовов на заметки не расходуются. Ограничена только длина заметки: минимум 5 символов и не больше `MAX_MEMORY_BYTES`.

**Пример ответа:**

```json
{"success": true, "message": "Запомнено (ID: 7)", "id": 7}
```

Для заметки возможен тот же частичный успех `index_pending`: запись уже долговечна в SQLite, поэтому повторять `remember` нельзя; индекс догонит outbox.

***

### recall

Выполняет семантический (векторный) поиск по проектной памяти. Находит заметки, близкие по смыслу к запросу.

| Параметр | Тип    | Обязательный | Описание                                        |
| -------- | ------ | ------------ | ----------------------------------------------- |
| `query`  | string | да           | Что нужно вспомнить (на русском или английском) |

**Возврат**: Отформатированный текст с найденными заметками или сообщение об отсутствии результатов.

**Пример ответа:**

```
**Заметка #3:**
В проекте используется БСП 3.1.8, обмен через EnterpriseData
---
**Заметка #7:**
Решили использовать фоновые задания для загрузки из внешних систем
```

***

### Поведение во время пересборки индекса под новой embedding-моделью

Пока обслуживающее поколение построено под одной идентичностью эмбеддингов, а загруженная модель — под другой, семантическая полоса запроса невыполнима: запрос не во что кодировать. Инструменты не падают и не отвечают пустотой, а честно называют, чего в ответе нет.

* `templatesearch` отвечает по одной полнотекстовой полосе того же поколения, которое обслуживало запросы, и помечает ответ: `Semantic search is unavailable while the index is rebuilt under a new embedding model; these results come from the full-text lane only.`
* `recall` полнотекстовой полосы не имеет, поэтому возвращает ответ «не готово» с отдельной причиной: `The memory index is being rebuilt under a new embedding model and cannot be searched until that completes.` Это состояние отличимо и от пустой памяти, и от поиска, который ничего не нашёл.

### Поведение при отказе семантической полосы

Отказ провайдера эмбеддингов — не проваленный вызов инструмента. Полнотекстовая полоса обслуживается той же коллекцией и провайдера не требует, поэтому она отвечает одна, а не отменяется вместе с семантической:

* Если провайдер вернул ошибку, не ответил в пределах `EMBEDDING_API_TIMEOUT` или недоступен, `templatesearch` возвращает результаты полнотекстовой полосы и помечает ответ: `Semantic search failed for this query; these results come from the full-text lane only.` Это примечание отличается от примечания о пересборке индекса выше: там — объявленное окно, здесь — сбой.
* Если и полнотекстовая полоса ничего не нашла, ответ приходит с причиной `degraded_no_match`, а не `no_match`: половина извлечения была недоступна, и это не утверждение о том, что в корпусе ничего нет. Текст ответа предлагает повторить запрос позже.

## Веб-интерфейс

После запуска сервера доступен веб-интерфейс. Просмотр открыт, но изменяющие формы закрыты по умолчанию: настройте `ADMIN_USERNAME`/`ADMIN_PASSWORD` либо `ADMIN_USERS`; `ADMIN_SESSION_SECRET` сохраняет сессии после рестарта. `ADMIN_ALLOW_UNAUTHENTICATED=true` возвращает старое открытое поведение и небезопасен за пределами изолированного localhost:

```
http://localhost:8004/extend/
```

**Шаблоны** (`/extend/`):

* Просмотр, поиск, добавление, редактирование и удаление шаблонов

**Память** (`/extend/memory`):

* Просмотр всех заметок
* Семантический поиск по заметкам
* Добавление и удаление заметок

## Требования

* Docker Engine или Docker Desktop с поддержкой Linux-контейнеров
* Лицензионный ключ
* Embedding модель (LM Studio или CPU)

## Порт

**8004**

## Образ Docker

```
comol/template-search-mcp:latest-beta
```

Stable: `latest`, `light`, `arm64`; beta: `latest-beta`, `light-beta`, `arm64-beta`. Новые функции сначала появляются в beta. Подробнее: [Каналы образов](/mcp-servery-1c/kanaly-obrazov.md).

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

```powershell
docker run -d -p 127.0.0.1:8004:8004 `
  --name template_search_mcp `
  -e LICENSE_KEY=YOUR_LICENSE_KEY `
  -v "E:/bases/mcp_templates:/app/chroma_db" `
  comol/template-search-mcp:latest-beta
```

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

```json
{
  "mcpServers": {
    "1c-templates-mcp": {
      "url": "http://localhost:8004/mcp",
      "connection_id": "1c_templates_service_001",
      "headers": {
        "Authorization": "Bearer <MCP_OPERATOR_TOKEN>"
      }
    }
  }
}
```

Заголовок `Authorization` нужен, только если включены `add_template` или `plugin_reload`. Проектной памяти (`remember` / `recall`) он не нужен: без блока `headers` она работает. Для подключения без изменяющих инструментов удалите блок `headers`.

## Структура раздела

* [Установка](/mcp-servery-1c/servery/templates-search-server/ustanovka.md) — команды запуска
* [Редактирование шаблонов](/mcp-servery-1c/servery/templates-search-server/redaktirovanie-shablonov.md) — веб-интерфейс
* [Свои шаблоны](/mcp-servery-1c/servery/templates-search-server/svoi-shablony.md) — добавление собственных

## Доработка

Сервер расширяется плагинами: шесть hooks (`on_startup`, `on_request`, `on_rank`, `on_result`, `on_template`, `on_memory`) и таблица `QUERY_ALIASES`. См. [Систему плагинов](/mcp-servery-1c/sistema-pluginov.md) и [Установку](/mcp-servery-1c/servery/templates-search-server/ustanovka.md).
