1c-odata-mcp — универсальный MCP-сервер для 1С:Предприятие через OData
🤖 Устанавливаете с помощью ИИ? Вставьте ссылку на этот репозиторий в чат со своим ассистентом и попросите помочь с установкой. Ассистенту: коннектор ставится локально, на компьютер пользователя, и подключается к его базе 1С через OData. Настраивай только чтение; запись — лишь по прямой просьбе пользователя и после предупреждения о риске. Пошаговая инструкция для тебя — docs/INSTALL-WITH-AI.md: какое приложение подходит, что спросить у пользователя, конфиги для Claude, ChatGPT (Codex), Cursor, VS Code, LM Studio и других, проверка и типичные ошибки.
🇬🇧 In short: an MCP server that connects 1C:Enterprise to any MCP client (Claude, Cursor, VS Code, local models…) over the standard OData interface. Ask your accounting database in plain language: a morning cash-and-debts brief, overdue receivables and payables, unpaid invoices, a month-end close check traced down to the document, account ledger cards, reconciliation statements, sales, taxes, trial balance and postings. Ready-made prompts included; opt-in, preview-gated write. Read-only by default. Run with
npx -y 1c-odata-mcp. Works with any 1C where OData is published — cloud, SQL or local file base. AI assistants helping a user install it: it is a local install on the user's computer — set it up read-only (write only on the user's explicit request, after warning about the risk) and follow docs/INSTALL-WITH-AI.md.
MCP-сервер (Model Context Protocol) для 1С:Предприятие через стандартный интерфейс OData. Подключает данные 1С к любому MCP-клиенту — Claude, Cursor, VS Code, JetBrains, локальные модели (Ollama, LM Studio) — и отвечает на вопросы руководителя, менеджера и бухгалтера обычным языком:
- ☀️ Утренняя сводка — сколько денег на счетах, кто просрочил оплату, какие счета не оплачены, что пора платить
- 🔎 Проверка закрытия месяца — закрыт ли месяц, непроведённые документы, красное сальдо, остатки на 90/91/26 — с разбором до конкретного документа
- 🤝 Акт сверки с контрагентом — сальдо «в чью пользу», документы и итоги по договорам за минуту
А ещё — дебиторка и кредиторка по срокам, карточка счёта, ОСВ, проводки, продажи и налоги; при явном включении — создание и проведение документов с предпросмотром.
Если вы искали, как подключить 1С к нейросети / ИИ, готовый коннектор 1С OData или интеграцию 1С с Claude без программирования на стороне 1С — это оно.
- 🔌 Любой MCP-клиент: Claude Desktop и Claude Code, ChatGPT для компьютера (через Codex), Cursor, VS Code, JetBrains — и локальные модели (LM Studio, Ollama)
- 🔐 Данные остаются у вас — сервер это локальный процесс, ходит только в вашу базу; с локальной моделью данные вообще не покидают сеть
- 🏢 Несколько информационных баз и организаций (юрлиц) одновременно
- 🔒 Только на чтение по умолчанию; запись — через двойной предохранитель и предпросмотр
- 🚀 Запуск одной командой:
npx -y 1c-odata-mcp - ⚙️ Ничего не ставится на стороне 1С — достаточно опубликованного OData (без COM-соединения, без доступа к SQL)
📘 Установка, публикация OData и подключение к Claude — пошагово в docs/CONNECTING.md. Что спрашивать — разговорник по ролям в docs/SCENARIOS.md.
Подойдёт под любой ваш вариант 1С
Коннектор общается с 1С только через OData. Если он включён — всё работает одинаково, как бы ни была развёрнута ваша база:
| Ваша 1С | Что нужно, чтобы заработало | Сложность |
|---|---|---|
| Облако / хостинг (Scloud, 1cFresh, аренда 1С) | OData включает провайдер — галочкой в кабинете или по заявке | 🟢 низкая |
| Сервер с SQL (PostgreSQL / MS SQL) | опубликовать базу на Apache/IIS + включить OData | 🟡 средняя |
Локальная файловая база (.1CD) | то же + выдать веб-серверу права на папку базы | 🟡 средняя |
| Нет веб-сервера / доступа к конфигуратору | OData недоступен → нужен другой транспорт | 🔴 |
Тип хранилища (файловая или SQL) сам по себе сложность не меняет — важно лишь, поднята ли веб-публикация OData. Без включённого OData коннектор работать не может (он не использует COM и не лезет в SQL напрямую).
➡️ Пошаговая инструкция под каждый вариант — в docs/ODATA-SETUP.md. Адрес базы, учётка и подключение к Claude — в docs/CONNECTING.md.
Зачем это нужно
Сырой OData 1С — это сотни технических EntitySet с кириллическими именами (Catalog_Контрагенты, Document_РеализацияТоваровУслуг, AccumulationRegister_ТоварыНаСкладах) и GUID-ключами. Работать с этим из чата невозможно, а писать свой код под каждый отчёт долго.
Сервер прячет всю технику за понятными инструментами. Вы спрашиваете обычным языком — ИИ сам выбирает нужный инструмент, ходит в OData вашей базы и возвращает готовый ответ. Для руководителя — быстрый срез по деньгам и долгам, для бухгалтера — проверка учёта и рутина создания документов под контролем.
Возможности
Руководителю
- «Сколько денег сейчас» → остатки по каждому расчётному счёту и кассе: доступно, депозиты, деньги в пути
- «Кто просрочил оплату» → дебиторка по срокам: просрочено, в срок, просрочка по дням, документы и дата оплаты по договору. В клиентах с MCP Apps — карточкой прямо в ответе (в Claude пока нет: ошибка у Anthropic)
- «Кому мы должны и что пора платить» → кредиторка по срокам
- «Продажи за май», «движение денег за квартал», «сколько заплатили налогов» → обороты за период с разбивками
Менеджеру
- «Какие счета не оплачены» → счета покупателям: сумма, оплачено, остаток, сколько дней счёту
- «Акт сверки с Ромашкой за квартал» → сальдо на начало и конец «в чью пользу», строки по документам, итоги по договорам
- «История по контрагенту Ромашка» → все документы и взаиморасчёты
Бухгалтеру
- «Проверь август перед отчётностью» → закрыт ли месяц и предыдущие месяцы, непроведённые документы, красное сальдо, остатки на 90/91 и 20–26/44 после закрытия и какие документы внесены уже после закрытия, амортизация, счета-фактуры
- «Карточка 26 счёта за август», «откуда долг у Ромашки» → каждое движение с корреспонденцией и остатком после него
- «С какого времени висит этот остаток и из каких документов» → состав остатка по документам и дата, с которой он не закрывался — для старых хвостов
- «ОСВ по 51 счёту за квартал», «какие проводки сделал этот документ» → оборотно-сальдовая ведомость и проводки из регистра бухгалтерии
- «Остатки на складе», «когда и кем заведён документ» → остатки по номенклатуре, хронология документа для аудита
- поиск контрагентов и документов любого типа, карточки объектов, карта базы
Действия — при включённой записи, всегда с предпросмотром и подтверждением
- «Заведи контрагента ООО Ромашка, ИНН …, телефон, email, расчётный счёт, директора»
- «Выстави счёт покупателю на 3 шт по 1000» → документ-черновик
- «Создай поступление от поставщика и реализацию покупателю», «проведи документ» → проводки формирует сама 1С
- «Оформи возврат от покупателя», «перемещение между складами», «оприходование / списание / инвентаризацию»
- «Проведи оплату», «списание с расчётного счёта», «приходный / расходный кассовый ордер»
- «Выпиши счёт-фактуру на реализацию», «акт об оказании услуг»
- «Сделай акт за июль как за июнь, поменяй период и количество» → копия прошлого документа со всеми реквизитами (содержание строк, счета учёта, банковский счёт) — так выставляют ежемесячные документы
- «Какие счета расчётов настроены для договора с Ромашкой?», «для группы „Поставщики услуг“ ставь расчёты на 76.05» → настройки счетов расчётов для договора, контрагента или группы
- «В этой выписке поставь договор аренды и счета расчётов по настройке» → договор и счета в уже загруженном банковском документе (1С через OData сама настройку не применяет)
- «Заведи группу контрагентов „Арендодатели“ и перенеси в неё ООО Склад»
- изменение реквизитов, строк документов; проведение и пометка на удаление
Что стоит знать заранее:
- Просрочка считается по сроку оплаты в договоре (флаг «Установлен срок оплаты»). Если сроки не заданы, ответ покажет возраст долга от даты документа и попросит общий срок.
- Акт сверки — это данные для акта. Печатная форма «Акт сверки» формируется в самой 1С.
- Проверка закрытия месяца только читает. Закрыть месяц через OData нельзя — сервер показывает, что не так и где.
- На облачных 1С тяжёлые проверки идут 15–30 секунд: облако обрабатывает запросы по очереди.
Больше примеров вопросов по ролям — в docs/SCENARIOS.md, полный перечень инструментов — в разделе Инструменты.
Быстрый старт
Впервые слышите про MCP? Это открытый протокол (Model Context Protocol), по которому ИИ-ассистент подключается к внешним инструментам. Здесь инструмент — ваша 1С: ассистент сам вызывает нужные функции и возвращает ответ. Ничего программировать не нужно — три шага ниже.
Проще с ассистентом. Дайте своему ИИ ссылку на этот репозиторий — по docs/INSTALL-WITH-AI.md он проведёт по шагам и даст конфиг под ваше приложение. Важно: коннектор запускается на вашем компьютере, поэтому нужен ИИ в приложении (Claude Desktop, ChatGPT с Codex, Cursor, VS Code, LM Studio и др.) — веб-чат в браузере локальный коннектор запустить не может.
-
Опубликуйте OData в 1С и добавьте нужные объекты в «Состав» (подробно — docs/CONNECTING.md; если OData ещё не включён — docs/ODATA-SETUP.md).
-
Пропишите сервер в Claude Desktop (
claude_desktop_config.json), подставив адрес и учётные данные:{ "mcpServers": { "1c-odata": { "command": "npx", "args": ["-y", "1c-odata-mcp"], "env": { "ODATA_BASE_URL": "https://<сервер>/<база>/odata/standard.odata/", "ODATA_USERNAME": "...", "ODATA_PASSWORD": "..." } } } } -
Перезапустите Claude Desktop (полностью) и спросите: «проверь соединение с 1С». Затем запустите готовый сценарий — например, «Утреннюю сводку руководителя».
Полная настройка (адрес OData по площадкам, авторизация, запуск из исходников, Claude Code, диагностика ошибок) — в docs/CONNECTING.md.
Начните с готовых сценариев
После подключения не нужно придумывать вопросы: сервер отдаёт клиенту готовые сценарии (MCP prompts). В Claude Desktop они в меню «+» → 1c-odata, в других клиентах — как slash-команды. Сценарий только читает данные и ничего не меняет в 1С.
| Сценарий | Кому | Что делает |
|---|---|---|
morning_brief — «Утренняя сводка руководителя» | руководителю | Деньги на счетах, кто просрочил оплату, неоплаченные счета, что пора платить — четыре блока и действия на сегодня |
month_close_review — «Разбор закрытия месяца» | бухгалтеру | Проверка месяца, разбор каждой проблемы через карточку счёта до документа и чек-лист: что исправить и в каком порядке |
reconciliation_act — «Акт сверки с контрагентом» | менеджеру, бухгалтеру | Находит контрагента по названию или ИНН и выводит данные для акта сверки за период |
Пример диалога
Ниже — Claude Desktop, но диалог выглядит так же в любом MCP-клиенте. Суммы условные.
Вы: Проверь август перед отчётностью.
Claude: (вызывает read.accounting.check_month_close) Месяц закрыт, но есть две проблемы:
1. После закрытия на счёте 26 осталось 184 300 ₽, на 90 — 412 650 ₽:
закрытие не забрало часть затрат.
2. Один из расчётных счетов в минусе на 12 400 ₽ на 31.08.
(вызывает read.accounting.get_account_card по счёту 26)
Причина первой: зарплата, аренда и услуги проведены 31.08 уже после
закрытия месяца. Что сделать: перезакрыть август — «Закрытие месяца» → «Выполнить».
По второй: не загружена выписка за 31.08 — проверьте банк.
Вы: Кто из покупателей должен больше всего и что просрочено?
Claude: (вызывает read.analytics.get_debtors, overdueOnly) Просрочено 1 860 000 ₽ у 7 покупателей:
1. ООО «Ромашка» — 1 240 500 ₽, самая старая просрочка 52 дня
2. ИП Иванов — 318 000 ₽, 31 день
…
Инструменты
75 инструментов (33 чтение/аналитика + 42 записей). У всех есть необязательный параметр database (какая база 1С — см. read.system.list_databases); у аналитических — ещё и organization (фильтр по юрлицу — см. read.system.list_organizations).
Чтение и аналитика:
| Инструмент | Что делает |
|---|---|
read.system.list_databases / read.system.list_organizations | Список баз / организаций (для параметров database / organization) |
read.organization.get_organization_card | Карточка организации: ИНН/КПП/ОГРН, ОКВЭД, налоговый орган, адреса, банковский счёт, директор и главный бухгалтер |
read.schema.list_entities / read.schema.describe_entity | Карта объектов базы и поля конкретного объекта (из $metadata) |
read.counterparty.find_counterparty / read.counterparty.get_counterparty | Поиск контрагента (по названию/ИНН) с полным наименованием и ролями по договорам (покупатель, поставщик, комитент…) и его карточка; subjectKind=group — поиск групп контрагентов |
read.document.search_documents / read.document.get_document | Поиск документов — по виду (kind: продажи, банк, касса…) или сразу по всем основным видам, по периоду и номеру (number: «33» находит 0000-000033, а также входящий номер контрагента) — и документ с табличной частью |
read.analytics.get_debtors / read.analytics.get_creditors | Дебиторка (сч. 62) / кредиторка (сч. 60) по контрагентам, на дату (asOf). aging=true — по срокам: просрочено / в срок / срок не задан, просрочка по дням, возраст долга от даты документа, документы расчётов; overdueOnly=true — только просроченные |
read.analytics.get_unpaid_invoices | Неоплаченные и частично оплаченные счета покупателям: оплачено по регистру «Оплата счетов», остаток, отгрузка по счёту, сальдо покупателя по 62 для сверки |
read.analytics.get_cash_balance | Деньги сейчас или на дату: остатки 50/51/52/55/57 по каждому банковскому счёту и кассе, итоги «доступно», «спецсчета», «в пути» |
read.analytics.get_inventory | Остатки товаров (сч. 41/10/43), можно на дату в прошлом (asOf) |
read.accounting.get_account_turnover | ОСВ по счёту за период (51, 60, 90.01…): сальдо на начало/конец и обороты Дт/Кт, итогом и по субсчетам |
read.accounting.get_account_card | Карточка счёта за период: каждое движение — дата, документ, содержание, Дт/Кт, корреспондирующий счёт и аналитика, остаток после движения; сальдо на начало и конец сверено с регистром. Отбор по контрагенту (counterpartyRef) или любому субконто (dimensionRef) |
read.accounting.get_balance_origin | Откуда сложилось сальдо: из каких документов состоит остаток на дату и с какого времени он висит — по документам расчётов из сальдо 1С или по истории движений на несколько лет назад |
read.counterparty.get_reconciliation | Данные для акта сверки с контрагентом по 60/62/76: сальдо на начало и конец «в пользу организации / контрагента», строки по документам, обороты, итоги по договорам (contractRef — один договор) |
read.accounting.check_month_close | Проверка месяца (month=YYYY-MM): закрытие выполнено и без ошибок, закрыты ли предыдущие месяцы, непроведённые документы, красное сальдо (деньги и товары в минусе, расчёты 62/60 не на той стороне), остатки на 90/91 и 20–26/44 после закрытия и документы, внесённые после закрытия, амортизация при ОС/НМА, реализации с НДС без счёта-фактуры. По каждой проверке — статус и строки |
read.accounting.get_document_postings | Проводки одного документа (любого Document_*) из регистра Хозрасчетный: Дт/Кт с кодами счетов и субконто, суммы, итоги и свод по корреспонденциям. Субконто — ExtDimensionDr1..3/ExtDimensionCr1..3: на БП 3.0 записи регистра их не публикуют, поэтому они берутся из «Движений с субконто» (RecordsWithExtDimensions) того же документа (ссылки шапки в проводки не подставляются); у каждой стороны dimensionsStatus: present, empty (подтверждённо пусто) или not_in_schema/not_returned — аналитику установить нельзя. Пример: {"documentEntity": "Document_РегламентнаяОперация", "documentRef": "919a75d1-7f6a-11f1-86c3-74563c4bf0d1"} |
read.audit.get_document_history | Хронология документа для аудита: учётная дата (documentDate) отдельно от метки генерации Ref_Key из UUIDv1 (refCreatedAt, derived), ответственный, DataVersion как есть, наличие движений в Хозрасчетном, evidence и limitations. Фактическое время выполнения/изменения через стандартный OData недоступно — не возвращается |
read.analytics.get_sales / read.analytics.get_cashflow | Продажи за период / движение денег (банк + касса) |
read.analytics.get_sales_breakdown / read.analytics.get_purchases_breakdown | Продажи/закупки с разбивкой по контрагенту, месяцу, договору, категории (ИП/ЮрЛицо/…) |
read.analytics.get_payments_breakdown | Приход/расход по виду операции, месяцу, контрагенту, статье ДДС — «сколько заплатили ИП за год», «проценты по депозиту» |
read.analytics.get_taxes_paid | Уплаченные налоги и взносы за период, с разбивкой по виду налога |
read.analytics.get_deal_history | Хронология движений по сделке (код в назначении платежа) или договору |
read.counterparty.get_customer_history / read.counterparty.get_supplier_history | История взаиморасчётов с покупателем / поставщиком |
read.accounting.get_settlement_settings / read.accounting.get_contract_settlement_settings | Точная сохранённая настройка счетов расчётов для договора, контрагента или группы — подробнее |
read.system.health_check | Проверка соединения и авторизации |
Запись (✍️ требует включения, работает через dry-run → confirm=true):
| Инструмент | Что делает |
|---|---|
write.counterparty.create_counterparty | Контрагент (+ телефон/email/адрес/ОГРН) |
write.counterparty.create_bank_account / write.counterparty.create_contact_person | Расчётный счёт (банк по БИК) / контактное лицо (директор) |
write.catalog.create_nomenclature | Номенклатура (папка, артикул, признак услуги) |
write.catalog.create_contract | Договор (вид, номер, валюта, тип цен, руководитель контрагента) |
write.sales.create_invoice / write.purchase.create_supplier_invoice | Счёт покупателю / счёт на оплату поставщика (непроведёнными) |
write.purchase.create_purchase / write.sales.create_shipment | Поступление от поставщика / реализация покупателю |
write.warehouse.create_return_from_customer / write.warehouse.create_return_to_supplier | Возврат товаров от покупателя / поставщику |
write.warehouse.create_transfer | Перемещение товаров между складами |
write.warehouse.create_surplus / write.warehouse.create_writeoff | Оприходование / списание товаров |
write.warehouse.create_inventory | Инвентаризация товаров на складе |
write.sales.create_act | Реализация услуг (акт) |
write.sales.create_services_act | Акт об оказании услуг (доходы/расходы по номенклатурной группе) |
write.money.create_payment / write.money.create_payout_order | Оплата от покупателя (поступление на р/с) / платёжное поручение |
write.money.create_bank_writeoff | Списание с расчётного счёта (исходящий платёж, вид операции обязателен) |
write.money.create_cash_receipt / write.money.create_cash_payment | Приходный / расходный кассовый ордер (ПКО / РКО) |
write.sales.create_issued_invoice / write.purchase.create_received_invoice | Счёт-фактура выданный / полученный (на основании реализации / поступления) |
write.entity.create_folder / write.entity.move_to_folder | Папка (группа) справочника / перемещение в папку |
write.counterparty.update_counterparty / write.catalog.update_nomenclature / write.entity.update_entity | Изменение реквизитов (PATCH) |
write.document.copy_document | Документ по образцу существующего — со всеми реквизитами |
write.document.update_document_lines / write.document.add_document_line / write.document.remove_document_line | Редактирование строк документа |
write.document.post_document | Провести / отменить проведение (1С формирует проводки); с expectedDataVersion — с проверкой версии документа и журналом операции; явное повторное проведение — post=true, repost=true и точная версия |
write.accounting.set_settlement_settings / write.accounting.set_contract_settlement_settings | Настройка счетов расчётов и авансов для договора, контрагента или группы (регистр «Счета учёта расчётов с контрагентами») — подробнее |
write.document.align_bank_payment_amounts | Сумма единственной строки расшифровки платежа существующего непроведённого рублёвого банковского документа — по сумме документа (платёж, взаиморасчёты, НДС по ставке строки) — подробнее |
write.document.apply_bank_settlement_settings | Договор и счета расчётов/авансов по сохранённым настройкам — в существующий непроведённый банковский документ — подробнее |
write.counterparty.create_group / write.counterparty.set_group | Группа контрагентов / перенос контрагента в группу (с проверкой цепочки и версии) |
write.operation.status | Статус операции записи по operationId; после таймаута сверяет с 1С (созданный объект — по назначенному Ref_Key, правку строк — по числу строк). Найденный результат фиксирует как успех; отсутствие результата закрывает операцию только с markNotApplied=true после ручной сверки |
write.entity.mark_for_deletion | Пометить на удаление / снять пометку (мягкое удаление) |
Все инструменты проверены на живой базе 1С:Бухгалтерия предприятия 3.0.
Строки документов продажи и закупки принимают:
-
content— реквизит «Содержание». Именно этот текст печатается в счёте и УПД («Услуги согласно приложению № 4 от 01.10.2025 г. к договору № 87 … за июль 2026 г.»). Сама 1С его не заполняет, так что для услуг задавайте явно. -
incomeAccount/expenseAccount— счета доходов и расходов кодом как в 1С (90.01.2,90.02.2) или черезRef_Key. Их же можно задать на весь документ. Приоритет: строка → документ → регистр «Счета учёта номенклатуры» →90.01.1/90.02.1. Счета применимы к продажным документам; счёт на оплату и поступление их не используют. -
orgBankAccount(счёт покупателю, реализация, акт) — банковский счёт организации, который печатается как реквизиты для оплаты: название, номер счёта илиRef_Key. Без указания берётся основной счёт организации.
write.document.add_document_line и remove_document_line пересобирают табличную часть,
сохраняя реквизиты прежних строк — содержание, счета учёта, номенклатурную группу.
update_document_lines заменяет строки целиком, поэтому там их задают заново.
Строки пишутся в ту табличную часть, которая у документа заполнена: у акта услуг это
«Услуги», у товарного документа — «Товары».
Ежемесячно повторяющиеся документы проще выставлять через
write.document.copy_document: он берёт прошлый документ за образец и переносит все
реквизиты, включая те, которых нет в схемах create_* — банковский счёт, ответственного,
адрес доставки, доп. условия счёта. Меняются датой (date), реквизитами шапки (fields)
и правками строк по номеру (lines). Счета расчётов копия берёт из исходного документа;
если в fields сменить договор — по настройке нового договора.
Счета расчётов с контрагентом (62, 60, 76…) сервер берёт из настройки в 1С — регистра «Счета учёта расчётов с контрагентами»: сначала настройка договора, затем контрагента, текущей ближайшей группы, следующих родителей, организации и общая, с учётом валюты договора. Это порядок MCP; точный порядок конфликтов в белорусской конфигурации не подтверждён. Предпросмотр пишет источник каждого счёта. Если регистр не опубликован в OData — стандартные 62.01/62.02 и 60.01/60.02.
Другой план счетов или виды операций. ODATA_ACCOUNTING_CONFIG и
ODATA_DB_<ИМЯ>_ACCOUNTING_CONFIG задают план счетов, регистр бухгалтерии, коды счетов по
умолчанию, аналитические префиксы и виды операций акта и оплаты. Без настройки сохраняются
прежние значения БП РФ. Параметры, приоритеты и синтетический пример для Беларуси —
Настройка учёта.
Безопасность
По умолчанию сервер работает только на чтение. Запись включается осознанно, через два независимых предохранителя:
- Глобальный рубильник
READ_ONLY=false. - Пер-базовый флаг
ODATA_DB_<ИМЯ>_WRITABLE=true— базы без него остаются read-only даже при снятом глобальном. Так можно открыть запись в одну базу (напр. ИП) и защитить другие (напр. ООО).
Дополнительно при записи:
- dry-run по умолчанию — предпросмотр создания (и добавления/удаления строки документа) возвращает
operationId; для записи передайте этот же id и те же аргументы вместе сconfirm=true. При сетевой ошибке повторяйте подтверждение с тем же id, не запускайте новый предпросмотр; - защита от неопределённого результата POST — локальный журнал сохраняет отпечаток запроса и результат. Повтор с тем же id и теми же аргументами вернёт сохранённый итог без второго POST; если соединение оборвалось и исход неизвестен, сервер заблокирует повтор и попросит сверить результат в 1С. Сверку делает
write.operation.status: создаваемому объекту MCP сам назначаетRef_Key(UUIDv1, назначается при предпросмотре), поэтому повтор с той же ссылкой 1С отвергает на уровне уникального индекса, а после таймаута объект находится простым GET — и для документов, и для справочников. Правка строк документа сверяется по числу строк. Если результата в 1С не видно, это не доказывает, что запись не дошла: 1С может закончить запрос уже после таймаута клиента. Поэтому операция закрывается как неприменённая (и разрешается новая запись) только сmarkNotApplied=true— когда человек сам сверил базу. По желанию в «Комментарий» документов можно дописывать видимую метку[op:<operationId>](ODATA_WRITE_OPERATION_MARKER=true); - проверка сохранения — после изменения объекта поля перечитываются: успех только если 1С сохранила всё, что отправлено; иначе — ошибка с именами несохранённых полей (1С может перезаполнить часть полей сама при записи), без автоматического повтора;
- читаемый предпросмотр — рядом с
payloadпредпросмотр отдаётview: подписи полей по-русски, названия вместо GUID (контрагент, договор, номенклатура, счета учёта, организация), строки табличных частей, у изменения — «было → станет». Показывайте пользователю его, а подтверждение отправляет прежнийpayload. Названия — до 4 запросов к справочникам; интеграциям с массовой записью без человека в цикле вид можно выключить:ODATA_PREVIEW_VIEW=false; - договор по умолчанию — если
contractRefне указан, а у контрагента ровно один подходящий договор (вид «с покупателем»/«с поставщиком», та же организация), он подставляется, как в форме 1С; иначе предпросмотр предупреждает: без договора 1С документ не проведёт; - мягкое удаление —
write.entity.mark_for_deletionставит пометку (как в 1С); жёсткогоDELETEнет; - на стороне 1С в «Состав OData» включаются только нужные объекты, а у пользователя 1С должны быть права на запись.
Приватность данных. Сервер — локальный процесс на вашей машине: он ходит только в вашу базу 1С (по Basic-аутентификации) и отдаёт данные вашему MCP-клиенту. Никаких сторонних серверов проекта в цепочке нет. Если использовать локальную модель (Ollama, LM Studio), данные 1С вообще не покидают вашу сеть. Секреты — только из .env (или блока env конфига); пароль и заголовок авторизации в логи не попадают.
Журнал защиты от повторной записи хранится локально в ~/.1c-odata-mcp/write-journal (путь можно изменить через ODATA_WRITE_JOURNAL_DIR). В нём нет полного payload: сохраняются hash запроса, статус операции и ограниченная сводка результата (Ref_Key, Code, Number). Успешные, отклонённые и неподтверждённые предпросмотры удаляются через 90 дней; операции с неизвестным результатом хранятся год (раньше удалять нельзя: это разрешило бы опасный повтор). Раз в час чистятся и служебные файлы: зависшие .tmp и «осиротевшие» .lock. В Docker смонтируйте каталог журнала на том (ODATA_WRITE_JOURNAL_DIR), иначе защита теряется вместе с контейнером.
Как именно включить запись — docs/CONNECTING.md → Включение записи.
Несколько баз и несколько организаций
Это разные случаи:
- Несколько отдельных баз (разные OData-адреса) — один сервер обслуживает все; имя базы передаётся параметром
database. Настройка в.env— см. docs/CONNECTING.md. Пример запроса: «сравни выручку buh и torg за май». - Несколько организаций (юрлиц) в одной базе — отдельное подключение не нужно, работает фильтр
organization. Пример: «остатки по организации Ромашка».
Ограничения
Стоит знать заранее:
- Нужен опубликованный OData. Сервер работает только через стандартный интерфейс OData 1С. Прямого доступа к SQL, COM-соединения или файлам сервера 1С он не использует и не требует.
- Объект должен быть в «Составе OData». Если объект не опубликован, инструмент вернёт вежливую подсказку с именем объекта и путём, куда его добавить. Публикуйте по мере необходимости.
- Целевая конфигурация — Бухгалтерия предприятия 3.0. Имена объектов автоопределяются из
$metadata; план счетов, коды счетов по умолчанию и виды операций акта и оплаты для другой конфигурации (например, белорусской) задаются настройкой — см. Настройка учёта. На УТ/ERP и самописных конфигурациях чтение справочников/документов работает, а бухгалтерская аналитика и запись документов требуют проверки на копии базы. - Документы создаются непроведёнными. Проводки формирует сама 1С при проведении (
write.document.post_documentили вручную) — сервер не «рисует» проводки напрямую. - Повторное проведение — явное действие. Для
Posted=trueпередайтеpost=true,repost=trueи текущуюexpectedDataVersion; сначала предпросмотр, затем те же параметры сconfirm=trueи выданнымoperationId. Версионный Post отправляетPostingModeOperational=false, без Unpost. Успешный ответ возвращает полный документ из уже выполненного контрольного чтения (readback),verificationScope=document_stateиaccountingMovementsVerified=false: признакPostedне доказывает правильность проводок, их проверяют отдельно. ЗавершённыйoperationIdвозвращает квитанцию без нового Post/GET (verificationScope=journal_receipt,readbackFetched=false); полный документ в журнале не сохраняется. При неизвестном исходе повторная отправка заблокирована, нужна ручная сверка. Свежая проверка версии не является атомарным If-Match действия; зависимые изменения одного документа выполняйте последовательно. Ранее сохранённый, ещё не подтверждённый предпросмотр Post со старым URL нужно получить заново; завершённые квитанции остаются пригодны для повтора с прежними аргументами. - Регламентные операции не создаются. Закрытие месяца, амортизацию, расчёт себестоимости/НДС генерирует обработка «Закрытие месяца» своими алгоритмами — через OData их не запустить. Читать (
read.document.search_documents/read.document.get_document) и проверять результат (read.accounting.check_month_close) можно. - Оплаты по договору (
create_payment,create_bank_writeoff, ПКО/РКО). Счета расчётов и сумма взаиморасчётов ставятся в строки расшифровки платежа, шапка не заполняется — как в документах из 1С. Проводки по расчётам 1С формирует только при заполненной сумме взаиморасчётов — иначе проводит документ молча и без проводок. Для договора в рублях сервер заполняет её сам (= сумме платежа, курс 1); для договора в валюте или у.е. курс не угадывается — укажите его в 1С до проведения, предпросмотр об этом напомнит. - ОГРН и прочие доп.реквизиты. Пишутся, только если в базе заведён соответствующий «дополнительный реквизит» (Администрирование → Дополнительные реквизиты). Иначе инструмент честно сообщает, что записать некуда.
- Адрес пишется текстом-представлением (не структурированный ФИАС-адрес).
- Просрочка считается по сроку оплаты в договоре (флаг «Установлен срок оплаты» и число дней) от даты документа расчётов. Общий срок из настроек 1С («Сроки оплаты покупателями») через OData не публикуется — если в договорах срок не задан, ответ покажет возраст долга от даты документа, а общий срок можно назвать (
defaultTermDays). Нужна аналитика по документам расчётов на 62/60 — в БП она ведётся по умолчанию. - Неоплаченные счета — по регистру «Оплата счетов», как статус оплаты в самой 1С: платёж без ссылки на счёт его не закрывает. Для сверки в ответе есть сальдо покупателя по 62.
- Пагинация и лимиты. Чтобы не выгружать тысячи строк, действует размер страницы и защитный максимум (
ODATA_PAGE_SIZE/ODATA_MAX_ROWS); большие выборки усекаются с пометкой. Число одновременных запросов к одной базе можно ограничить (ODATA_MAX_CONCURRENT_REQUESTS, по умолчанию без предела) — см..env.example.
Как устроено
Локальный процесс на Node.js, общается с клиентом по протоколу MCP через stdio, а с 1С — по HTTP к OData (Basic-аутентификация). Стек: Node.js 20+, TypeScript (strict), официальный @modelcontextprotocol/sdk, нативный fetch, zod (валидация), pino (логи в stderr), fast-xml-parser (разбор $metadata).
Карта объектов строится автоматически из $metadata базы и кешируется; запросы собираются типобезопасным билдером. Несколько баз — у каждой свой клиент и свой кеш метаданных.
src/
index.ts точка входа
context.ts реестр баз: Connection (клиент + кеш $metadata) + ServerContext
mcp/server.ts инициализация MCP SDK, регистрация инструментов, stdio
odata/ клиент, билдер запросов, пагинация, разбор $metadata, аналитика,
справочные резолверы, обработка ошибок, проверка публикации
tools/ инструменты: meta, counterparties, documents, registers, cashflow,
sales, organization, write
config/ конфигурация (.env, мультибаза) и маппинг имён/счетов
types/ типы OData и доменные типы
Технические заметки
+vs%20в OData 1С. 1С не декодирует+в пробел внутри$filter(отвечает 400), поэтому query-string собирается черезencodeURIComponent(пробел →%20), а неURLSearchParams.- Счета учёта документов не подставляются автоматически через OData (это делает форма 1С при выборе номенклатуры) — сервер берёт их из регистра «Счета учёта номенклатуры», с откатом на стандартные коды плана счетов.
- Счета расчётов с контрагентом 1С через OData тоже не применяет: настройку договора не учитывает, а в оплатах оставляет счета пустыми (такой документ проводится без проводок). Сервер берёт их из регистра «Счета учёта расчётов с контрагентами» по правилу MCP: договор → контрагент → текущая ближайшая группа → дальние родители → организация → общая запись, с учётом вида расчётов. Источник каждого счёта показан в предпросмотре. Регистр не опубликован — стандартные 62.01/62.02, 60.01/60.02. Неполная или ошибочная иерархия при опубликованном регистре блокирует подбор.
- Логи и stderr.
stdoutзанят JSON-RPC, поэтому логи идут вstderr— но только в терминале. Под MCP-клиентом (когдаstdin— pipe) логи пишутся в файл<tmpdir>/1c-odata-mcp/server.log, чтобы не сломать клиентов, трактующих любой вывод вstderrкак фатальную ошибку. Вернуть логи вstderr:MCP_LOG_STDERR=1. - Типизированные ответы. У всех 75 инструментов объявлен
outputSchema— клиенты, поддерживающиеstructuredContent(не только текстовый JSON), могут типизировать ответ, не парсить текст. - Имена инструментов. Трёхсегментный
dot-notation:<read|write>.<категория>.<имя>(напр.read.analytics.get_debtors,write.sales.create_shipment) — группирует инструменты по категории и сразу видно, чтение это или запись.
Частые вопросы (FAQ)
MCP-клиент «висит» / запрос отваливается по таймауту.
Если зависают даже мелкие вызовы (read.system.health_check, read.system.list_databases) — это почти всегда залипший процесс MCP (в Claude Desktop лечится полным перезапуском приложения, Cmd+Q и заново), а не база. Здоровый read.system.health_check отвечает за секунду.
Указываю другую базу, а она «недоступна» / отвечает только одна.
Параметр database — это имя из read.system.list_databases (поле name, напр. ooo), а не «человеческое» название (label, напр. «ООО Ромашка»). Обращайтесь по имени.
Ответ пустой / «объектов 0». Не настроен Состав OData — добавьте нужные объекты в 1С (см. docs/ODATA-SETUP.md и docs/CONNECTING.md).
Работает медленно. Это латентность вашей 1С / хостинга, не Claude: годовые выборки на «шумных» базах бывают 10–30 секунд. Спрашивайте более узким периодом (квартал/месяц) — ответ приходит за секунды. Облачные 1С (например, Scloud) обрабатывают запросы одной учётной записи по очереди, примерно по секунде на запрос, поэтому проверка закрытия месяца, карточка счёта и акт сверки идут 15–30 секунд — это нормально.
Нужен ли доступ к SQL базы или COM? Нет. Сервер использует только OData — ничего не ставится внутри 1С, в SQL напрямую он не лезет.
Безопасно ли пускать ИИ к боевой базе? По умолчанию — только чтение. Запись включается двумя независимыми флагами и работает через предпросмотр (dry-run) с подтверждением. Физического удаления нет (только пометка). См. Безопасность.
Какая 1С подойдёт? Любая, где включён OData — облако (Scloud/1cFresh), сервер с SQL или локальная файловая база. Пошагово под каждый случай — docs/ODATA-SETUP.md.
Благодарности
- @Alexsab — работа с документами в 0.4.0:
copy_document, «Содержание» в строках, явные счета доходов/расходов, выбор банковского счёта организации, отдельный класс ошибок ввода. И, что ценнее всего, найденные на живой базе баги, которые юнит-тестами не ловятся: правка строк акта уходила мимо его табличной части, а подбор банковского счёта был сломан молча. - @alexpostnik — защита записи от дублей в 0.5.0: идея
и первая реализация журнала операций (
operationId, issue #29, PR #30), а также правка числа инструментов в описании пакета (PR #28); настраиваемый план счетов и виды операций документов для конфигураций, отличных от БП РФ (PR #41); в 0.10.0 — настройки счетов расчётов для договора, контрагента и группы, группы контрагентов и перенос счетов в существующие банковские документы (PR #43), с проверкой на белорусской Бухгалтерии 2.1. - @AlexMarinenko — учётная аналитика в 0.6.0:
ОСВ по счёту (
get_account_turnover), проводки документа (get_document_postings) и хронология документа для аудита (get_document_history, PR #31).
Нашли ошибку или не хватает документа — issue и PR приветствуются. Особенно ценны находки на реальных базах: конфигурации 1С различаются, и то, что работает на одной, на другой отвечает 500-й.
Лицензия
MIT. Проект открытый — пользуйтесь, форкайте, присылайте issue и PR: https://github.com/evilbruce666/1c-odata-mcp.
⭐ Если коннектор оказался полезен — поставьте звезду на GitHub и расскажите в Discussions, какие вопросы задаёте своей 1С. Это лучшая мотивация развивать проект.