3 октября 2026 г.
Как заставить Cursor понимать структуру регистров накопления 1С: MCP-сервер Графон на практике
Почему Cursor «не видит» регистр накопления
Cursor — текстовый агент. Он индексирует файлы и умеет искать по строкам, но не имеет семантической модели метаданных 1С. Для него РегистрНакопления.ТоварыНаСкладах — это просто набор XML-файлов:
Registers/ТоварыНаСкладах.xml— свойства регистра (вид: Остатки, периодичность, режим записи);Registers/ТоварыНаСкладах/Ext/ManagerModule.bsl— модуль менеджера;Ext/RecordSetModule.bsl,Ext/Form/...— модуль набора записей и формы;- десятки файлов движений в модулях документов и подписок.
Агент не понимает, что Количество — это Ресурс, а Склад — Измерение; что регистр имеет вид «Остатки», а значит доступна виртуальная таблица Остатки(); что запись движений возможна только внутри ОбработкаПроведения() при Движения.<Регистр>.Записывать = Истина. В итоге он:
- Придумывает несуществующие поля (
ОстатокКоличествовместоКоличествоОстаток). - Пытается «записать движение» через
РегистрыНакопления.ТоварыНаСкладах.СоздатьНаборЗаписей()в обход движений документа. - Теряет измерения в группировке запроса и генерирует невалидный BSL, который платформа отвергает на этапе компиляции.
- Скармливает вам «простыню» на 2000 строк из XML, сжигая 80–120k токенов на одну задачу.
Корень проблемы — не модель, а отсутствие контекста о структуре метаданных.
Что именно должен знать агент о регистре накопления
| Элемент структуры | Где лежит в конфигурации | Зачем агенту |
|---|---|---|
| Вид регистра (Остатки/Обороты) | ТоварыНаСкладах.xml | Определяет доступные виртуальные таблицы |
| Измерения | XML + RecordSetModule.bsl | Ключи группировки, обязательность заполнения |
| Ресурсы | XML | Поля для РегистраторОтразилДвижение и расчёта итогов |
| Реквизиты | XML | Контроль остатков, служебные признаки |
| Регистраторы | Граф движений по конфигурации | Кто и когда пишет движения |
| Виртуальные таблицы | Вычисляются платформой | .Остатки(), .Обороты(), .ОстаткиИОбороты() |
| Подписки и вызовы | Граф связей модулей | Регресс при изменении структуры |
Без графа зависимостей эту таблицу агенту взять неоткуда — он видит только текст.
Архитектура: Графон как семантический слой
Графон ([grafonbase.ru](https://grafonbase.ru)) — локальный инструмент и MCP-сервер. Он один раз индексирует выгрузку конфигурации в формате XML, строит граф:
- Узлы метаданных: справочники, документы, регистры, планы видов характеристик.
- Рёбра: движения регистраторов, подписки на события, вызовы процедур и функций, обращения к виртуальным таблицам в текстах запросов.
- Срезы: сигнатуры процедур/функций с параметрами и экспортностью.
Через MCP (Model Context Protocol) Cursor обращается к графу и получает точный срез — 10–30 файлов вместо 300 000 строк XML. Токенов тратится в 10 раз меньше, галлюцинации по полям практически исчезают.
Подключение Графона к Cursor за 4 шага
1. Индексация выгрузки
grafon index --src ./src --out .grafon/index.db
2. Конфиг MCP в проекте — .cursor/mcp.json:
{
"mcpServers": {
"grafon": {
"command": "grafon",
"args": ["mcp", "--index", ".grafon/index.db"],
"env": { "GRAFON_SRC": "./src" }
}
}
}
3. Рестарт Cursor и проверка: в панели MCP должны появиться инструменты metadata_search, register_structure, find_movements, call_graph, impact_analysis, query_fields.
4. Файл правил .cursor/rules/1c.mdc — он заставляет агента сначала спрашивать граф, а потом писать код:
Всегда перед генерацией BSL, работающего с регистром накопления,
вызывай grafon.register_structure и grafon.find_movements.
Никогда не угадывай имена измерений, ресурсов и полей виртуальных таблиц.
Для условий в виртуальных таблицах параметры передавай через &Параметр,
список полей выводи явно.
Практические MCP-запросы
Структура регистра:
{ "tool": "register_structure", "args": { "name": "РегистрНакопления.ТоварыНаСкладах" } }
Ответ: вид регистра, измерения с типами, ресурсы, реквизиты, доступные виртуальные таблицы и точные имена полей (КоличествоОстаток, КоличествоОборот, КоличествоРасход).
Кто пишет движения:
{ "tool": "find_movements", "args": { "register": "ТоварыНаСкладах", "includeSubscriptions": true } }
Ответ — список процедур ОбработкаПроведения документов и подписок с номерами строк. Агент больше не ищет регистраторов grep’ом по гигабайтам кода.
Оценка влияния изменения:
{ "tool": "impact_analysis", "args": { "object": "РегистрНакопления.ТоварыНаСкладах", "change": "add_dimension", "dimension": "Склад" } }
Ответ: какие формы, отчёты, запросы и движения затронуты.
Сценарий: добавить измерение «Склад»
Без Графона. Агент читает XML регистра, не находит измерение Склад, правит XML, затем «на глаз» добавляет поле в 14 документов и ломает три отчёта с группировкой по складу.
С Графоном. Последовательность запросов:
register_structure→ измерения:Номенклатура,Характеристика; ресурсы:Количество.find_movements→ 14 процедурОбработкаПроведения, три из них уже используютСкладиз шапки документа.impact_analysis→ отчёты и формы, где потребуется новое измерение.- Агент выдаёт точечные патчи — только по 17 затронутым файлам.
Итоговый код движения, который генерирует агент:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Движения.ТоварыНаСкладах.Записывать = Истина;
Для Каждого СтрокаТЧ Из Товары Цикл
Движение = Движения.ТоварыНаСкладах.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
Движение.Период = Дата;
Движение.Регистратор = Ссылка;
Движение.Номенклатура = СтрокаТЧ.Номенклатура;
Движение.Характеристика = СтрокаТЧ.Характеристика;
Движение.Склад = Склад; // новое измерение
Движение.Количество = СтрокаТЧ.Количество;
КонецЦикла;
КонецПроцедуры
И запрос к виртуальной таблице с корректными именами полей:
Запрос.Текст =
"ВЫБРАТЬ
| Остатки.Номенклатура,
| Остатки.Склад,
| Остатки.КоличествоОстаток КАК Количество
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК Остатки
|ГДЕ
| Остатки.КоличествоОстаток > 0";
Ключевая разница: имена КоличествоОстаток и параметры виртуальной таблицы взяты из графа, а не выдуманы.
Сравнение: без Графона vs с Графоном
| Метрика (задача «добавить измерение в регистр») | Без Графона | С Графоном |
|---|---|---|
| Прочитано контекста, токенов | 90 000 – 140 000 | 8 000 – 12 000 |
| Время ответа агента | 4–8 мин | 40–70 сек |
| Галлюцинации имён полей | 3–7 на задачу | 0–1 |
| Затронутые файлы найдены | частично (grep) | 100 % (граф движений) |
| Стоимость запроса (условно) | 1.0x | 0.1x |
| Правки «наугад» в чужих модулях | да | нет |
Типичные ошибки внедрения
- Индексировать только
src/, но неExt/— тогда в графе нет движений и модулей наборов записей. - Давать агенту весь XML регистра «на всякий случай» — контекст забивается, и MCP-вызовы теряют смысл.
- Не описывать правила в
.cursor/rules— модель по привычке пойдёт читать файлы напрямую. - Игнорировать
impact_analysisперед правкой структуры — получите тихий регресс в отчётах. - Забыть про подписки на события при поиске регистраторов — часть движений уйдёт мимо агента.
Чек-лист
- Выгрузка конфигурации в XML лежит в репозитории рядом с кодом.
grafon indexобновляется в CI или по pre-commit-хуку..cursor/mcp.jsonподключён, MCP-инструменты видны в Cursor..cursor/rules/1c.mdcзапрещает угадывать поля регистров.- Для задач по регистрам накопления обязательны вызовы
register_structureиfind_movements. - Перед изменением метаданных —
impact_analysisи обновление графа.
Регистр накопления — это не файл, а узел графа: измерения, ресурсы, регистраторы и виртуальные таблицы связаны рёбрами. Пока Cursor видит только текст, он будет гадать. Как только вы отдаёте ему граф через MCP, агент начинает работать как разработчик 1С, который читает конфигурацию, а не как автодополнение.