MCP-плагин для 1C:EDT — ИИ-ассистент получает полный доступ к коду конфигурации (26 инструментов)

12.02.26

Интеграция - Нейросети

Данная публикация описывает реализацию MCP-сервера (Model Context Protocol) для среды 1C:EDT. Инструмент предназначен для обеспечения прямого доступа внешних ИИ-ассистентов (Cursor, Claude Code, Windsurf и др.) к объектной модели конфигурации и результатам её индексации. В отличие от стандартных методов передачи кода в LLM, данное решение использует внутренние механизмы Eclipse и EDT (BM-индекс, AST-дерево) для предоставления точного контекста без избыточного потребления токенов.

 

Плагин для 1C:EDT 2025.2, который через протокол MCP (Model Context Protocol) даёт AI-ассистентам (Cursor, Claude Code, Windsurf и др.) полный доступ к метаданным и исходному коду конфигурации. 26 инструментов: от списка объектов метаданных до семантического анализа вызовов процедур через BM-индекс EDT.

ИИ видит всю конфигурацию так же, как её видит EDT — метаданные, модули, структуру процедур, перекрёстные ссылки. Это меняет качество работы ИИ-ассистента с кодом 1С принципиально.


Проблема

Если вы пробовали использовать AI-ассистенты (Cursor, Claude Code, GitHub Copilot) для разработки на 1С, то знаете главную проблему: ИИ не видит код конфигурации.

Конфигурация 1С — это не просто файлы на диске. Это:

  • Сотни объектов метаданных со сложной иерархией
  • Тысячи BSL-модулей (модули объектов, форм, менеджеров, команд)
  • Модули по 5 000–60 000 строк в типовых конфигурациях (УНФ, ERP, БП)
  • Перекрёстные ссылки между объектами и модулями через BM-индекс EDT

Без доступа ко всей этой информации ИИ-ассистент работает «вслепую» — даёт общие советы, галлюцинирует имена процедур, не понимает контекст вашей конфигурации.

Решение

MCP-плагин для EDT — встраивается в 1C:EDT и открывает AI-ассистенту доступ ко всей конфигурации через стандартный протокол MCP (Model Context Protocol).

MCP — это открытый протокол от Anthropic, который поддерживают Cursor, Claude Code, Windsurf, Continue и другие AI-инструменты. Плагин поднимает HTTP-сервер прямо внутри EDT, и AI-ассистент обращается к нему как к источнику данных.

Архитектура

AI-ассистент (Cursor / Claude Code / Windsurf)
        |
        | MCP (HTTP JSON-RPC 2.0, порт 8770)
        v
  EDT AI1C MCP Plugin (внутри 1C:EDT)
        |
        v
  BM Engine / Xtext / Eclipse Workspace
        |
        v
  Конфигурация 1С (метаданные + BSL-код)

 

Что умеет: 26 инструментов

Базовые инструменты метаданных (20 шт.)

Полный доступ к структуре конфигурации:

Инструмент Описание
list_metadata_objects Список всех объектов метаданных (справочники, документы, регистры…)
get_object_details Детальная информация об объекте (реквизиты, табличные части, формы)
get_config_properties Свойства конфигурации (имя, синоним, версия, поставщик)
find_object_references Все ссылки на объект метаданных (где используется) 
get_validation_errors Ошибки проекта из EDT (с фильтрацией по severity)
get_error_summary Сводка по ошибкам и предупреждениям
get_check_info Описание конкретной проверки EDT
get_code_completion Автодополнение кода в указанной позиции
get_platform_docs Документация по типам и методам платформы (Запрос, ТаблицаЗначений…)
list_bookmarks Закладки из рабочей области
get_object_tags Теги объектов метаданных
find_by_tags Поиск объектов по тегам
get_task_list Задачи из Task-листа
show_edt_version Версия EDT
list_applications Список приложений для запуска/отладки
sync_database Обновление базы данных
launch_debugger Запуск отладки
list_workspace_projects Список проектов в workspace (8 проектов УНФ + расширения)
rebuild_project Очистка и пересборка проекта
refresh_validation Перевалидация объектов

Инструменты анализа кода (6 шт.) 

Именно эти инструменты делают ИИ-ассистента по-настоящему полезным для разработки:

Инструмент Описание
read_module_source Чтение исходного кода BSL-модуля (целиком или диапазон строк)
get_module_structure Структура модуля: все процедуры/функции с сигнатурами, номерами строк, регионами, контекстом выполнения, флагами Экспорт
list_modules Список всех BSL-модулей объекта или всего проекта
search_in_code Полнотекстовый поиск по коду всей конфигурации с контекстом
read_method_source Извлечение конкретной процедуры/функции из модуля — вместо чтения 60 000 строк читаем только нужные 50
get_method_call_hierarchy Семантический поиск всех вызывающих процедуру/функцию через BM-индекс EDT. Не текстовый поиск, а реальный граф вызовов через AST

 


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

Сценарий 1: Анализ незнакомого модуля

Вы открыли типовую конфигурацию и нужно разобраться в модуле объекта документа:

Вы: Покажи структуру модуля объекта документа ЗаказНаПроизводство

ИИ вызывает get_module_structure и получает полный список всех процедур и функций с сигнатурами, регионами, контекстом выполнения и флагами Экспорт. Затем:

Вы: Прочитай процедуру ОбработкаЗаполнения

ИИ вызывает read_method_source — получает только эту процедуру (24 строки), а не весь модуль целиком.

Сценарий 2: Поиск по всей конфигурации

Вы: Найди все места где используется переменная ИспользоватьСерии

ИИ вызывает search_in_code — находит все вхождения во всех модулях конфигурации с контекстом (строки до и после).

Сценарий 3: Рефакторинг экспортной процедуры

Вы: Хочу переименовать функцию РассчитатьСебестоимость. Покажи кто её вызывает

ИИ вызывает get_method_call_hierarchy — через BM-индекс EDT находит все реальные вызовы (не текстовые совпадения, а именно вызовы через AST). Показывает список модулей и строк. Это тот же механизм, что используется в EDT при нажатии Ctrl+Shift+G.

Сценарий 4: Разработка нового функционала

Вы: Мне нужно добавить печатную форму в документ ЗаказКлиента. Покажи как устроены печатные формы в этой конфигурации

ИИ самостоятельно:

  1. Вызывает search_in_code — ищет “ПечатнаяФорма” и “Печать” по всем модулям
  2. Вызывает get_module_structure — анализирует найденные модули менеджеров
  3. Вызывает read_method_source — читает конкретные процедуры формирования печатных форм
  4. На основе реального кода конфигурации предлагает готовую реализацию


Практический пример: разработка обработки «Себестоимость номенклатуры»

Покажем реальный сценарий — как ИИ-ассистент с MCP-плагином помогает разработать внешнюю обработку для расчёта себестоимости единицы номенклатуры в конфигурации УНФ 3.0.

Постановка задачи

Вы: Мне нужна внешняя обработка, которая для выбранной номенклатуры покажет себестоимость единицы в разрезе складов. Используй типовые механизмы УНФ.

Шаг 1: ИИ ищет регистры себестоимости

ИИ вызывает list_metadata_objects с типом AccumulationRegister и анализирует результат (106 регистров). Находит ключевые:

  • РегистрНакопления.Запасы (синоним: «Запасы и затраты») — остатки в количественном и суммовом выражении
  • РегистрНакопления.Продажи — обороты продаж с ресурсом СебестоимостьОборот

Шаг 2: ИИ получает структуру регистра

ИИ вызывает get_object_details для AccumulationRegister.Запасы и видит:

  • Измерения: Организация, СтруктурнаяЕдиница, СчетУчета, Номенклатура, Характеристика, Партия, ЗаказПокупателя
  • Ресурсы: Количество, Сумма
  • Формула: Себестоимость единицы = СуммаОстаток / КоличествоОстаток

Шаг 3: ИИ изучает типовые запросы через search_in_code

ИИ вызывает search_in_code с текстом РегистрНакопления.Запасы.Остатки и находит реальные примеры запросов в типовом коде:

  • Catalogs/Номенклатура/Forms/ФормаСписка/Module.bsl — строка 17379
  • CommonModules/ИнтеграцияГИСМУНФ/Module.bsl — строка 4613

ИИ видит типовой паттерн:

РегистрНакопления.Запасы.Остатки(
    &МоментКонтроля,
    Номенклатура = &Номенклатура)

Шаг 4: ИИ получает документацию платформы через синтакс-помощник

Прежде чем писать код, ИИ запрашивает через get_platform_docs полную документацию по типам платформы, которые собирается использовать. Инструмент обращается к тому же источнику данных, что и встроенный синтакс-помощник EDT — IEObjectProvider.Registry. ИИ получает не просто названия, а полные сигнатуры с типами параметров и возвращаемых значений:

 

get_platform_docs("Запрос") — возвращает:

- Конструктор: Новый Запрос(ТекстЗапроса) — параметр ТекстЗапроса (Строка, необязательный)

- 5 методов: Выполнить() -РезультатЗапроса, УстановитьПараметр(Имя, Значение), ВыполнитьПакет() -Массив, НайтиПараметры() -ОписаниеПараметровЗапроса и др.

- 7 свойств: Текст (Строка, чтение/запись), Параметры (Структура, только чтение), МенеджерВременныхТаблиц и др.

 

get_platform_docs("РезультатЗапроса") — возвращает:

- Выбрать(ТипОбхода, Группировки) -ВыборкаИзРезультатаЗапроса

- Выгрузить() -ТаблицаЗначений или ДеревоЗначений

- Пустой() -Булево

 

get_platform_docs("ВыборкаИзРезультатаЗапроса") — возвращает:

- Следующий() -Булево, Количество() -Число, Сбросить() и ещё 8 методов

 

Теперь ИИ точно знает цепочку вызовов: Запрос.Выполнить() возвращает РезультатЗапроса, у которого Выбрать() возвращает ВыборкаИзРезультатаЗапроса, а обход идёт через Следующий(). Это не догадки из обучающих данных — это реальная документация из движка EDT.

 

Шаг 5: ИИ находит типовые методы в общих модулях

ИИ ищет стандартные методы для информирования пользователя. Вызывает search_in_code с текстом ОбщегоНазначенияКлиентСервер.СообщитьПользователю — находит сотни вызовов по всей конфигурации. Затем через read_method_source читает исходный код метода прямо из модуля ОбщегоНазначенияКлиентСервер (строка 3203 модуля из 4000+ строк):

// Найдено через MCP: read_method_source
// Модуль: CommonModules/ОбщегоНазначенияКлиентСервер, строка 3203
Процедура СообщитьПользователю(
    Знач ТекстСообщенияПользователю,
    Знач КлючДанных = Неопределено,
    Знач Поле = "",
    Знач ПутьКДанным = "",
    Отказ = Ложь) Экспорт

Аналогично находит СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку (строка 204) — для форматирования строк по шаблону "%1 пошел в %2".

Теперь ИИ знает точные сигнатуры типовых методов и может использовать их в коде правильно — не по памяти, а по реальному исходному коду конфигурации.

Шаг 6: ИИ генерирует готовый код

На основе реальной структуры регистра, типовых паттернов запросов и методов из общих модулей ИИ создаёт модуль формы обработки:

// =============================================================================
// Внешняя обработка: Себестоимость номенклатуры
// Модуль формы обработки
//
// Разработана с помощью ИИ-ассистента через MCP-плагин для EDT.
// ИИ анализировал реальный код конфигурации УНФ:
//   - Структуру регистра накопления "Запасы" (измерения, ресурсы)
//   - Структуру регистра накопления "Продажи" (себестоимость продаж)
//   - Запросы к регистрам в типовых модулях (формы справочников, общие модули)
//   - API платформы через синтакс-помощник (Запрос, РезультатЗапроса и др.)
//   - Методы общих модулей БСП (СообщитьПользователю, ПодставитьПараметрыВСтроку)
//     найдены через search_in_code + read_method_source
// =============================================================================

// Реквизиты формы:
//   Номенклатура     - СправочникСсылка.Номенклатура   - выбор номенклатуры
//   ДатаРасчета      - Дата                            - на какую дату считаем
//   Организация      - СправочникСсылка.Организации    - фильтр по организации
//   Склад            - СправочникСсылка.СтруктурныеЕдиницы - фильтр по складу
//
// Табличная часть "Результат":
//   Номенклатура     - СправочникСсылка.Номенклатура
//   Характеристика   - СправочникСсылка.ХарактеристикиНоменклатуры
//   Склад            - СправочникСсылка.СтруктурныеЕдиницы
//   КоличествоОстаток - Число(15,3)
//   СуммаОстаток     - Число(15,2)
//   СебестоимостьЕдиницы - Число(15,2)

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    ДатаРасчета = ТекущаяДатаСеанса();

КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

// Основная команда — расчёт себестоимости выбранной номенклатуры.
// Использует регистр накопления "Запасы" (Запасы и затраты) конфигурации УНФ.
// Себестоимость единицы = СуммаОстаток / КоличествоОстаток.
//
// Структура регистра "Запасы" (найдена через MCP-инструмент get_object_details):
//   Измерения: Организация, СтруктурнаяЕдиница, СчетУчета, Номенклатура,
//              Характеристика, Партия, ЗаказПокупателя
//   Ресурсы:   Количество, Сумма
//
&НаКлиенте
Процедура РассчитатьСебестоимость(Команда)

    Если НЕ ЗначениеЗаполнено(Номенклатура) Тогда
        ПоказатьПредупреждение(, "Выберите номенклатуру для расчёта");
        Возврат;
    КонецЕсли;

    РассчитатьСебестоимостьНаСервере();

КонецПроцедуры

&НаСервере
Процедура РассчитатьСебестоимостьНаСервере()

    Результат.Очистить();

    // Запрос к остаткам регистра "Запасы".
    // Паттерн запроса найден через MCP-инструмент search_in_code
    // в модулях: Catalogs/Номенклатура/Forms/ФормаСписка/Module.bsl,
    //            CommonModules/ИнтеграцияГИСМУНФ/Module.bsl

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |   ЗапасыОстатки.Номенклатура КАК Номенклатура,
    |   ЗапасыОстатки.Характеристика КАК Характеристика,
    |   ЗапасыОстатки.СтруктурнаяЕдиница КАК Склад,
    |   СУММА(ЗапасыОстатки.КоличествоОстаток) КАК КоличествоОстаток,
    |   СУММА(ЗапасыОстатки.СуммаОстаток) КАК СуммаОстаток,
    |   ВЫБОР
    |       КОГДА СУММА(ЗапасыОстатки.КоличествоОстаток) <> 0
    |           ТОГДА СУММА(ЗапасыОстатки.СуммаОстаток) / СУММА(ЗапасыОстатки.КоличествоОстаток)
    |       ИНАЧЕ 0
    |   КОНЕЦ КАК СебестоимостьЕдиницы
    |ИЗ
    |   РегистрНакопления.Запасы.Остатки(&ДатаРасчета, Номенклатура = &Номенклатура) КАК ЗапасыОстатки
    |
    |СГРУППИРОВАТЬ ПО
    |   ЗапасыОстатки.Номенклатура,
    |   ЗапасыОстатки.Характеристика,
    |   ЗапасыОстатки.СтруктурнаяЕдиница";

    // Добавляем условия фильтрации (организация, склад)
    ТекстУсловий = "";

    Если ЗначениеЗаполнено(Организация) Тогда
        ТекстУсловий = ТекстУсловий + " И Организация = &Организация";
        Запрос.УстановитьПараметр("Организация", Организация);
    КонецЕсли;

    Если ЗначениеЗаполнено(Склад) Тогда
        ТекстУсловий = ТекстУсловий + " И СтруктурнаяЕдиница = &Склад";
        Запрос.УстановитьПараметр("Склад", Склад);
    КонецЕсли;

    Если ЗначениеЗаполнено(ТекстУсловий) Тогда
        Запрос.Текст = СтрЗаменить(
            Запрос.Текст,
            "Номенклатура = &Номенклатура)",
            "Номенклатура = &Номенклатура" + ТекстУсловий + ")");
    КонецЕсли;

    Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
    Запрос.УстановитьПараметр("ДатаРасчета", ?(ЗначениеЗаполнено(ДатаРасчета),
        Новый Граница(ДатаРасчета, ВидГраницы.Включая), Неопределено));

    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();

    Пока Выборка.Следующий() Цикл
        НоваяСтрока = Результат.Добавить();
        НоваяСтрока.Номенклатура          = Выборка.Номенклатура;
        НоваяСтрока.Характеристика         = Выборка.Характеристика;
        НоваяСтрока.Склад                  = Выборка.Склад;
        НоваяСтрока.КоличествоОстаток      = Выборка.КоличествоОстаток;
        НоваяСтрока.СуммаОстаток           = Выборка.СуммаОстаток;
        НоваяСтрока.СебестоимостьЕдиницы   = Выборка.СебестоимостьЕдиницы;
    КонецЦикла;

    // Информирование пользователя о результатах расчёта.
    // Методы найдены через MCP-инструменты search_in_code и read_method_source
    // в общих модулях конфигурации:
    //   ОбщегоНазначенияКлиентСервер.СообщитьПользователю (строка 3203, модуль 4000+ строк)
    //   СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку (строка 204)

    Если Результат.Количество() = 0 Тогда
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
            СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                НСтр("ru = 'Нет остатков по номенклатуре ""%1"" на %2'"),
                Номенклатура,
                Формат(ДатаРасчета, "ДФ='дд.ММ.гггг'")));
    Иначе
        ИтогоКоличество = Результат.Итог("КоличествоОстаток");
        ИтогоСумма      = Результат.Итог("СуммаОстаток");
        СредняяСебестоимость = ?(ИтогоКоличество <> 0,
            ИтогоСумма / ИтогоКоличество, 0);

        ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
            НСтр("ru = '%1: остаток %2 шт. на сумму %3 руб., средняя себестоимость %4 руб.'"),
            Номенклатура,
            Формат(ИтогоКоличество, "ЧДЦ=3"),
            Формат(ИтогоСумма, "ЧДЦ=2"),
            Формат(СредняяСебестоимость, "ЧДЦ=2"));

        ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
    КонецЕсли;

КонецПроцедуры

#КонецОбласти

Что важно в этом примере

ИИ не галлюцинировал имена регистров и полей. Каждое имя взято из реальных метаданных конфигурации:

Что использовано Откуда ИИ это узнал MCP-инструмент
РегистрНакопления.Запасы Список объектов метаданных list_metadata_objects
КоличествоОстаток, СуммаОстаток Структура регистра get_object_details
Номенклатура, СтруктурнаяЕдиница Измерения регистра get_object_details
Паттерн .Остатки(&Дата, ...) Типовой код конфигурации search_in_code
Запрос.Выполнить().Выбрать() API платформы get_platform_docs
ОбщегоНазначенияКлиентСервер.СообщитьПользователю Общий модуль БСП (строка 3203 из 4000+) search_in_code + read_method_source
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку Общий модуль БСП (строка 204) search_in_code + read_method_source

Обратите внимание на последние две строки: ИИ не просто «знает» эти методы из обучающих данных — он нашёл их в реальном коде конфигурации через search_in_code, затем прочитал исходный код через read_method_source, увидел точные сигнатуры и примеры использования. Модуль ОбщегоНазначенияКлиентСервер содержит более 4000 строк кода, но ИИ извлёк нужный метод за доли секунды — без чтения всего модуля.

Без MCP-плагина ИИ мог бы предложить несуществующий регистр «РегистрНакопления.Себестоимость» или выдумать поле «ЦенаЗаЕдиницу», или использовать метод Сообщить() вместо типового ОбщегоНазначенияКлиентСервер.СообщитьПользователю(). С плагином — код написан на основе реальных данных и соответствует стандартам конфигурации.

 

Другие реальные кейсы

 

Вступайте в нашу телеграмм-группу Инфостарт

1C:EDT MCP Искусственный интеллект AI Cursor Claude Code Разработка 1С Автоматизация программирования Анализ кода BSL Eclipse LLM Инструменты разработчика Архитектура 1С BM-индекс AST Нейросети