MCP-сервер для 1С своими руками: HTTP-сервис + LangGraph

Как написать MCP-сервер для 1С: протокол и рабочий код
Видео: Как написать MCP-сервер для 1С: протокол и рабочий код

Всем привет, с вами Низамов Илья. Протокол MCP (Model Context Protocol) Anthropic анонсировала в ноябре 2024 года, и за полтора года он из нишевой идеи превратился в отраслевой стандарт. Поддержку встроили в ChatGPT, Claude, Cursor, Gemini, GitHub Copilot и VS Code, а публичных MCP-серверов в мире уже больше десяти тысяч. 

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

Для 1С здесь открывается вполне конкретная возможность. Можно поднять MCP-сервер прямо на HTTP-сервисах платформы, и тогда ИИ-агент (Claude Desktop, Cursor, Codex или ваш собственный агент на Python) сможет обращаться к живой базе. 

Читать остатки, проверять статусы заказов, поднимать данные по контрагентам. В этой статье мы соберём минимальный, но полностью рабочий пример. MCP-сервер на 1С и клиента на Python с LangGraph. Оба куска кода можно запустить и потрогать руками уже сегодня.

Что вы узнаете

  • Чем MCP отличается от обычного REST API и почему это протокол, а не библиотека
  • Из каких трёх методов состоит любой MCP-сервер и как выглядят их запросы и ответы
  • Как написать минимальный MCP-сервер на HTTP-сервисе 1С своими руками
  • Как собрать клиента на Python с LangGraph, который сам вызывает инструменты сервера
  • Где проходит граница между демо-примером и боевым сервером с бизнес-данными

Что такое MCP-сервер для 1С: расшифровка и суть простыми словами

MCP расшифровывается как Model Context Protocol, дословно «протокол контекста модели». Это открытый стандарт, по которому языковая модель получает доступ к внешним системам: не к их исходникам и не к дампу базы, а к набору именованных инструментов, каждый из которых умеет что-то посчитать или отдать. Аббревиатуру читают по буквам, эм-си-пи.

Слово «сервер» здесь сбивает с толку 1С-разработчика, поэтому уточню сразу: MCP-сервер это не железо и не сервер приложений 1С. Это программа, которая говорит на этом протоколе. В нашем случае обычный HTTP-сервис в расширении конфигурации: принимает JSON-RPC запросы, на tools/list отдаёт список своих инструментов со схемой аргументов, на tools/call выполняет нужный и возвращает результат. MCP-клиент это ИИ-приложение с другой стороны провода: Claude Desktop, Cursor, ChatGPT или ваш собственный агент на Python.

Ближайший знакомый аналог из мира 1С это публикация OData или самописного REST-сервиса, и разница между ними принципиальна. OData отдаёт таблицы, и клиент должен заранее знать, что с ними делать. MCP отдаёт инструменты с описанием на человеческом языке, поэтому модель сама решает, какой из них вызвать под конкретный вопрос пользователя. Написали один раз, работают все MCP-совместимые клиенты.

Чтобы стало предметно, представим сценарий. Менеджер спрашивает у ИИ-ассистента: "сколько на складе позиции с артикулом А-100 и есть ли по ней неоплаченные заказы". Ассистент сам решает, что для ответа нужно дёрнуть два инструмента вашей базы: остатки по номенклатуре и список заказов по товару. Он их вызывает, получает цифры прямо из 1С и формулирует ответ. Никто не писал под этот вопрос отдельную функцию. Ассистент собрал ответ из инструментов, о которых ему известно. Вот это ради чего пишут MCP, дать описание инструментов и реализовать их.

Первое, что стоит уложить в голове: MCP это не библиотека и не SDK, а именно протокол. Технически это обмен сообщениями по правилам JSON-RPC 2.0 поверх HTTP, либо поверх stdio, если клиент и сервер живут на одной машине. Сервер обязан реализовать всего три метода: initialize для рукопожатия, tools/list для перечня доступных инструментов и tools/call для их вызова.

Почему просто не написать REST API на 1С? Разница в одном слове, самоописание. Обычный REST API знаете только вы, клиент должен заранее знать адреса, параметры и форматы. MCP-сервер сам рассказывает о себе. Клиент отправляет tools/list и получает JSON-Schema каждого инструмента. Имя, описание, какие аргументы принимает. Не надо изобретать велосипед при каждой интеграции, потому что любой MCP-совместимый клиент уже знает этот протокол и умеет читать этот формат.

А как реализовать в 1С? Платформа давно умеет публиковать HTTP-сервисы. MCP-сервер для 1С это, по сути, обычный HTTP-сервис, который вместо своего самодельного формата говорит на диалекте MCP JSON-RPC. Никакой отдельной инфраструктуры под это поднимать не надо.

Протокол MCP в трёх методах

Прежде чем писать код на стороне 1С, посмотрим на формат сообщений. Он одинаков для любого MCP-сервера в мире, так что это знание переносимо. Начнём с запроса списка инструментов и ответа на него:

// Запрос tools/list
{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}
// Ответ
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "get_server_time",
        "description": "Возвращает текущую дату и время сервера 1С",
        "inputSchema": {"type": "object", "properties": {}, "required": []}
      }
    ]
  }
}

Вызов конкретного инструмента устроен так же просто. В params передаётся имя инструмента и словарь аргументов. Важная деталь, о которую спотыкаются новички: результат всегда обёрнут в массив content, даже если это одна строка текста.

// Запрос tools/call
{"jsonrpc": "2.0", "id": 2, "method": "tools/call",
 "params": {"name": "get_server_time", "arguments": {}}}
// Ответ: содержимое всегда внутри content[]
{"jsonrpc": "2.0", "id": 2,
 "result": {"content": [{"type": "text", "text": "2026-07-09 14:32:10"}]}}

Остаётся метод initialize. Это рукопожатие: клиент присылает версию протокола, которую поддерживает, а сервер отвечает своим serverInfo (структура вида {name, version}) и списком возможностей capabilities (для нашего случая это {"tools": {}}). Здесь прячется реальная тонкость, на которой легко застрять. Версий протокола уже несколько, и сервер обычно поддерживает список: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05. Если клиент прислал версию, которую сервер знает, соглашаемся на неё; если не прислал вовсе, разумно откатиться на стабильную, например 2025-03-26.

И ещё одна ловушка первого запуска. После initialize клиент шлёт уведомление notifications/initialized, на которое отвечать телом не нужно: правильный ответ это пустой HTTP 202. Многие ждут в ответ JSON, получают пустой 202 и решают, что сервер сломался, хотя всё в порядке. Ошибки, кстати, тоже имеют строгий вид: {"jsonrpc": "2.0", "id": ..., "error": {"code": -32600, "message": "..."}}.

Пишем MCP-сервер на 1С: минимальный рабочий пример

Теперь самое интересное. Соберём сервер на HTTP-сервисе 1С. Разберём по шагам.

Шаг 1. HTTP-сервис. Создаём HTTP-сервис MCPServer с корневым URL mcp и одним шаблоном URL /*. Привязываем к нему три обработчика: POST на основной метод (сюда прилетают все JSON-RPC запросы), GET на health-check и OPTIONS на preflight CORS, чтобы браузерные клиенты не упирались в политику источников.

Шаг 2. Диспетчер методов. Внутри POST-обработчика читаем JSON и раскидываем запрос по методу. Вся суть MCP-сервера умещается в одну функцию:

Функция ОбработатьMCPЗапрос(ЗапросJSON) Экспорт
	Метод = ЗапросJSON["method"];
	Если Метод = "initialize" Тогда
		Возврат ОбработатьИнициализацию(ЗапросJSON["params"]);
	ИначеЕсли Метод = "tools/list" Тогда
		Возврат ОбработатьСписокИнструментов();
	ИначеЕсли Метод = "tools/call" Тогда
		Возврат ОбработатьВызовИнструмента(ЗапросJSON["params"]);
	Иначе
		ВызватьИсключение "Метод не найден: " + Метод;
	КонецЕсли;
КонецФункции

Шаг 3. Регистрация инструментов. tools/list просто собирает массив описаний. Каждый инструмент это отдельный общий модуль, который умеет отдать своё описание и выполнить работу. Для примера возьмём два безобидных инструмента: get_server_time и echo.

Функция ОбработатьСписокИнструментов() Экспорт
	СписокИнструментов = Новый Массив;
	СписокИнструментов.Добавить(МодульИнструментВремя.get_server_time());
	СписокИнструментов.Добавить(МодульИнструментЭхо.echo());
	Результат = Новый Структура;
	Результат.Вставить("tools", СписокИнструментов);
	Возврат Результат;
КонецФункции

Шаг 4. Один инструмент целиком. Вот полный модуль инструмента get_server_time. Одна функция описывает инструмент для tools/list, вторая делает саму работу и вызывается из tools/call. Пятнадцать строк, и это рабочий инструмент.

Функция get_server_time() Экспорт
	Схема = Новый Структура("type, properties, required", "object", Новый Структура, Новый Массив);
	Инструмент = Новый Структура;
	Инструмент.Вставить("name", "get_server_time");
	Инструмент.Вставить("description", "Возвращает текущую дату и время сервера 1С");
	Инструмент.Вставить("inputSchema", Схема);
	Возврат Инструмент;
КонецФункции
Функция ПолучитьВремя(Аргументы) Экспорт
	Возврат Строка(ТекущаяДата());
КонецФункции

Шаг 5. Обёртка результата. Значение, которое вернул инструмент, оборачиваем в тот самый массив content из раздела про протокол. Один маленький хелпер вида НовыйТекстовыйРезультат(Текст) собирает структуру {"content": [{"type": "text", "text": Текст}]}, и его переиспользуют все инструменты.

На этом демо-версия честно заканчивается, и здесь стоит остановиться на важной границе. Как только инструмент должен работать со справочниками и документами (реальные остатки, заказы клиентов, контрагенты), появляется совсем другой уровень задач: права доступа роли, под которой выполняется HTTP-сервис, обработка пустых выборок и ошибок запроса, проектирование inputSchema под конкретную конфигурацию, чтобы ИИ понимал, какие аргументы и в каком виде передавать. Это ровно та инженерия, которую мы разбираем в блоке «MCP сервер в 1С» курса «ИИ для 1С»: там сервер подключается к настоящим бизнес-объектам базы, а не к учебным заглушкам.

Пишем MCP-клиента на Python с LangGraph

Сервер готов отдавать инструменты, теперь нужен клиент, который их вызовет. Писать разбор JSON-RPC руками не придётся: за нас это делает библиотека langchain-mcp-adapters. Она подключается к серверу и превращает каждый MCP-инструмент в обычный инструмент LangChain, с которым уже умеет работать агент.

from langchain_mcp_adapters.client import MultiServerMCPClient
async def get_mcp_tools(server_url: str):
    client = MultiServerMCPClient({
        "ones": {"transport": "streamable_http", "url": server_url},
    })
    return await client.get_tools()

Дальше собираем агента на LangGraph. Идея графа простая: узел agent вызывает языковую модель с привязанными инструментами; если модель в ответе попросила вызвать инструмент, управление уходит в узел tools, который реально дёргает MCP-сервер; результат возвращается обратно в agent, и цикл повторяется, пока модель не ответит без обращения к инструментам.

from langgraph.graph import StateGraph, START
from langgraph.prebuilt import ToolNode, tools_condition
from langgraph.checkpoint.memory import InMemorySaver
llm_with_tools = llm.bind_tools(tools)
def call_model(state):
    response = llm_with_tools.invoke(state["messages"])
    return {"messages": [response]}
builder = StateGraph(State)
builder.add_node("agent", call_model)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "agent")
builder.add_conditional_edges("agent", tools_condition)
builder.add_edge("tools", "agent")
graph = builder.compile(checkpointer=InMemorySaver())

Ключевой момент: сам код агента ни разу не говорит на JSON-RPC. Он оперирует привычными инструментами LangChain, а всю чёрную работу по формату MCP берёт на себя адаптер. Это и есть выгода протокола: клиент и сервер писались независимо, но понимают друг друга.

В работе это выглядит так. Вы задаёте агенту вопрос на естественном языке, например «какой сейчас остаток по складу и покажи время сервера». Модель в узле agent понимает, что своими знаниями тут не обойтись, и просит вызвать инструмент get_server_time, а следом инструмент по остаткам. Узел tools отправляет на MCP-сервер 1С запросы tools/call, получает ответы в формате content, кладёт их обратно в переписку, и на следующем проходе модель уже формулирует человекочитаемый ответ. Весь этот цикл LangGraph крутит сам, вам остаётся описать инструменты на стороне 1С и привязать их к модели.

И ещё одна практичная деталь. В качестве модели не обязательно брать облачный API. Если вместо ChatOpenAI на облако направить base_url на локальный vLLM или Ollama, тот же агент будет работать полностью на вашем железе, без утечки данных 1С наружу. Как выбрать локальную модель под задачу разработчика, разбираем в отдельной статье про нейросети для программиста 1С.

MCP это не только для 1С

Стоит держать в голове масштаб происходящего. Тот же самый протокол, который реализует ваш сервер на 1С, уже понимают серверы для GitHub, Slack, Google Drive, PostgreSQL, Figma и сотен других систем. Написав MCP-сервер для своей базы 1С, вы получаете интерфейс, который без единой доработки на их стороне понимают все крупные ИИ-ассистенты: и чат-клиенты, и редакторы кода. Это принципиально иная ситуация, чем самописный REST, который знаете только вы и ваша команда.

Что дальше

Минимальный сервер и клиент вы теперь можете собрать сами. Логичный следующий шаг это разобраться, как устроен сам ИИ-агент, который эти инструменты вызывает: как проектировать граф, состояние и цикл рассуждения. Об этом подробно в статье «ИИ-агент для 1С на LangGraph». А про то, что MCP это лишь один из двух способов дать агенту контекст, читайте в материале про context engineering. А как таким сервером пользуется агент-кодер поверх выгрузки конфигурации — в статье Claude Code для 1С. Где MCP стоит среди остальных ИИ-инструментов 1С, показывает обзор «ИИ для 1С в 2026», а во что это превращается в повседневной разработке — в статье про вайбкодинг в 1С.

Если же нужен не учебный, а боевой MCP-сервер, который читает реальные остатки, заказы и контрагентов из вашей базы, вся эта инженерия целиком разобрана в блоке «MCP сервер в 1С» курса «ИИ для 1С»: от прав доступа до проектирования инструментов под конкретную конфигурацию.

Как MCP-контекст работает в связке с агентом-кодером на боевой задаче, показано в записи вебинара «Вайбкодинг в 1С: MCP, скиллы и доработка тиражного решения в Claude Code» — там видно, где заканчивается MCP и начинаются скиллы, правила репозитория и гейты проверки.

Как тот же MCP-сервер работает в связке с голосом — на бесплатном вебинаре 20 августа «ИИ-агент для 1С на MCP: вопрос голосом, ответ из базы»: агент берёт остатки и заказы через MCP и отвечает вслух, на локальной модели, без выгрузок в облако.

Частые вопросы