Собираем локального AI агента на LibreChat, Langflow и MCP
Представьте, что вам не нужно вручную копировать данные из таблиц в чат или пересказывать боту содержание своих документов. Вместо этого вы просто пишете: «Проверь отчеты в папке и выпиши главное». И агент сам открывает нужные файлы, анализирует их и выдает результат. Поделюсь подробной инструкцией по сборке подобного инструмента.

Николай Луняка
Системный аналитик из команды подписки Альфа Смарт
Всем привет! Сегодня мы соберем агентную AI систему, которая умеет вызывать инструменты, работать с файловой системой и выполнять сложные многошаговые сценарии, при этом работает локально.
Представьте, что вам не нужно вручную копировать данные из таблиц в чат или пересказывать боту содержание своих документов. Вместо этого вы просто пишете: «Проверь отчеты в папке и выпиши главное». И агент сам открывает нужные файлы, анализирует их и выдает результат. Поделюсь подробной инструкцией по сборке подобного инструмента.
Локальная агентная система состоит из трех основных компонентов:
- LibreChat — open-source UI для работы с LLM (провайдеры моделей + подключение MCP-серверов через librechat.yaml)
- Langflow — low-code платформа и визуальный редактор, flow как последовательность компонентов/шагов
- MCP-сервер — сервер, который публикует tools/ресурсы по стандартному транспорту (HTTP/SSE/stdio)
В инструкции мы будем последовательно подключать данные инструменты. В конце у нас будет UI + инструменты + централизованная логика, но, что примечательно, можно остановиться на любом этапе и использовать, например, только MCP filesystem и тогда агент сможет читать ваши файлы (но не более).
Важно: все примеры рассчитаны на локальный запуск в изолированной docker сети. Для публичного деплоя потребуется дополнительная настройка безопасности (TLS, reverse proxy и т.д.)
Этап №1. Подключаем LibreChat и локальную LLM
LibreChat — это open-source веб UI чат для работы с различными LLM в одном интерфейсе. Он умеет подключаться к OpenAI-совместимым API и поддерживает работу с агентами и протокол MCP (об этом позже).
На этом уровне мы запустим три контейнера:
- MongoDB — для хранения истории диалогов и настроек пользователей
- Ollama — для запуска локальных LLM
- LibreChat — веб UI чата, интерфейс.
Схематично взаимодействие контейнеров выглядит так:
Все контейнеры будут работать в изолированной Docker сети и общаться по внутренним именам (service names).
Шаг 1. Создаем структуру проекта:
Шаг 2. Создаём файл docker-compose.yml со следующим содержимым:
Шаг 3. Создаём librechat.yaml:
Важно: строка модели в default должна точно совпадать с тем, как она называется (см. шаг 6 (ollama list)). Если модель хранится как llama3.1:8b или llama3.1:latest, то именно так и надо указывать.
Если же повторяете статью позже и конфиг ругается на схему, то сверяйтесь с актуальной версией Librechat и при необходимости обновляйте ее до актуальной.
Шаг 4. Создайте .env с переменными окружения:
Шаг 5. Теперь запускаем все сервисы:
Если что-то пошло не так:
Если после старта app не поднимается, первым делом смотрите логи mongo, чаще всего проблема в том, что Mongo еще не прошел healthcheck.
Шаг 6. Ollama запущен, но в нем ещё нет моделей.
Можно выбрать другую модель из библиотеки Ollama или подключить другой OpenAI совместимый endpoint.
Скачаем Llama 3.1:
Как выбрать модель (в двух словах)?
Проверяем, что модель скачалась:
Вы должны увидеть
Шаг 7. Открываем LibreChat. Переходим в браузере http://localhost:3080/. При первом запуске увидим экран регистрации. Создаем аккаунт (данные хранятся локально в MongoDB).
Настройка чата:
- В верхнем меню выберите endpoint: Ollama
- В выпадающем списке моделей выберите llama3.1
- (Опционально) Нажмите на иконку настроек и настройте параметры: Temperature — креативность ответов, Max Tokens — максимальная длина ответов, System Prompt — промпт для модели.
Теперь можно общаться с локальной LLM через удобный интерфейс:
На этом уровне мы развернули базовую инфраструктуру для работы с локальными LLM. Этого достаточно, если вам нужен просто удобный локальный чат с сохранением истории. Далее добавим MCP filesystem сервер, и наша модель научится работать с файлами на диске.
Этап №2. Подключаем MCP Server в LibreChat
На этом шаге LibreChat подключается к MCP-серверу по streamable-http, получает список доступных tools, а дальше уже модель решает вызывать инструмент или отвечать текстом. Сам MCP-сервер при вызове инструмента читает файлы только из того, что вы смонтировали (в нашем примере /data). Общая схема будет выглядеть так:
Теперь у нашей модели есть tools (filesystem). За счет этого уже можно решать простые многошаговые задачи (прочитать несколько файлов, сравнить, составить отчет).
MCP (Model Context Protocol) — это новый открытый протокол, который описывает, как разным LLM подключаться к инструментам (файлам, базам данных, API) через единый стандарт.
Используя MCP-сервер больше нет необходимости настраивать отдельную интеграцию для каждой задачи. Хотите подключить файлы, почту или календарь? Просто возьмите готовый сервер из каталога (например, есть reference серверы в GitHub: modelcontextprotocol, а для поиска сторонних есть реестры вроде Smithery.ai). При этом вы сохраняете полный контроль, так как агент работает в изолированной среде и получает доступ только к тем папкам, которые вы ему открыли (в конфиге), не обращаясь к остальной системе.
Для работы с MCP нужен хост / клиент / сервер.
MCP Host — приложение, с которым общается пользователь, он принимает запрос, знает, какие MCP сервера доступны и в каких случаях их вызывать.
MCP Client — часть хоста, которая обеспечивает связь между хостом и сервером — по одному соединению на каждый сервер.
MCP Server — это отдельный сервис-прослойка, который умеет работать с внешней системой на ее языке (API, файлы и т.д.), и наружу отдает единый набор инструментов, доступный для хоста.
Для связи с MCP сервером существует два основных вида транспорта:
- stdio — локальный транспорт, где хост запускает MCP сервер как процесс и общается с ним через stdin / stdout.
- Streamable HTTP — удаленный транспорт. MCP сервер работает как отдельный сервис и отдает один HTTP endpoint (обычно /mcp) для GET / POST. При необходимости внутри этого транспорта можно стримить события через SSE.
Дальше покажу все на примере filesystem MCP server. Это готовый сервер, в котором есть набор инструментов для работы с файлами в папке (показать список, прочитать файл и т.д.). По умолчанию это stdio сервер и HTTP порта не поднимает.
Чтобы подключить такой stdio сервер по сети, нужен мост, который конвертирует stdio ↔ сетевой MCP транспорт (в статье показываю на примере Streamable HTTP). Для этого я использую supergateway. Он запускает filesystem сервер как дочерний stdio-процесс и публикует его наружу как Streamable HTTP сервер на /mcp.
Шаг 1. Обновляем docker-compose.yml.
Добавьте новый сервис mcp-filesystem в ваш docker-compose.yml:
Важно: всегда монтируйте только рабочую папку. По умолчанию используйте :ro. Разрешайте запись (:rw) только если это действительно необходимо и вы понимаете риски, так как агент сможет удалять и изменять файлы.
Шаг 2. Обновляем librechat.yaml.
Добавьте конфигурацию MCP в librechat.yaml:
Шаг 3. Подготовка тестовых данных — убедитесь, что в папке documents есть файлы для тестирования. Для примера можно создать два файла в формате .txt и наполнить их данными.
Шаг 4. Перезапускаем сервисы:
Проверяем, что MCP сервер запустился:
Если ошибка, то смотрим логи:
Шаг 5: Настройка в LibreChat:
- Откройте LibreChat: http://localhost:3080.
- Создайте новый чат или откройте существующий.
- Нажмите на иконку “Настройки MCP” в меню справа.
- Вы должны увидеть доступный MCP сервер: filesystem.
- Включите его, нажав на переключатель справа.
Шаг 6: Тестирование.
Теперь модель может вызывать инструменты для работы с файлами.
Пример некоторых команд:
Теперь добавим Langflow, чтобы у нас появились последовательные флоу с валидациями и кастомной логикой.
Этап №3. Подключаем Langflow к MCP Server
Langflow — это open-source платформа, где флоу собирается через визуальный интерфейс. В отличие от обычного чата с LLM, здесь можно зафиксировать порядок шагов. Каждый флоу можно запускать не только через UI, но и через REST API. Чтобы избежать галлюцинации при работе с данными существует возможность использовать свои Python-компоненты (например, для расчетов). Плюс в Langflow есть нативная поддержка MCP Tools.
Добавив Langflow, MCP по-прежнему будет отвечать за доступ к файлам, но расчеты и проверки уведем в Python-компоненты, поэтому агент будет работать стабильнее, точнее и можно работать с большим объемом данных (например, в работе с ролевой моделью). Плюсом, в данном процессе шаги не меняются от запуска к запуску и формат вывода проще держать под контролем, а ошибки можно отлавливать на этапе обработки данных.
Общая архитектура теперь будет выглядеть так:
Как агент работает с данными, я покажу на простом кейсе с двумя xlsx-файлами, которые содержат расходы за разные месяцы. В этом флоу будет четкая последовательность действий: найти нужные .xlsx в папке с помощью mcp-filesystem, прочитать их и посчитать суммы по категориям и создать таблицу — кодом в кастомном компоненте, а уже потом оформить итог в виде коротких выводов при помощи LLM.
Важно. На этом шаге увеличивается порог входа, да и флоу нужно собрать и поддерживать. Готового пользовательского UI тут нет (Playground скорее для тестов). Также весь созданный процесс можно встроить в свой сайт через REST API, но если нужен функционал как у чата (хранение истории, авторизация, пресеты и т.п.), то все это придется реализовывать дополнительно.
Перейдем к развертыванию.
Шаг 1. Обновляем docker-compose.yml.
Добавляем сервис langflow (остальные сервисы остаются без изменений):
Важно: в данном коде, в рамках локальной сборки, я использую автоматический вход без пароля LANGFLOW_AUTO_LOGIN: "True".
Шаг 2. Запускаем Langflow.
Шаг 3. Создаём Flow в Langflow.
Откройте браузер: http://localhost:7860
Если LANGFLOW_AUTO_LOGIN: "True", вы сразу попадете в интерфейс. Иначе создайте аккаунт.
В Langflow создаем новый Flow, нажав “New Flow” и добавляем компоненты:
- Chat Input
- Agent
- New Custom components (в самом низу)
- MCP Tools
- Chat Output
Шаг 4. Создаём Custom Component для флоу.
Нажимаем на «Code» и добавляем свой код компонента:
У меня кастомный компонент будет выполнять следующие функции:
- Принимает путь к нужному файлу формата xlsx.
- Проверяет наличие нужных колонок (Категория и Расход).
- Приводит данные из колонки «Расход» к числовому формату.
- Группирует строки по «Категория» и считает суммы по «Расход».
- Считает общий итог и количество строк.
- Формирует результат в виде таблицы.
После добавления кода — сохраняем и переводим его в режим «tool mode».
Важно: чтобы кастомные компоненты подгружались автоматически и сохранялись при перезапуске контейнеров, их необходимо сохранять в папке custom_components. Также надо создать файл __init__.py, чтобы директория превратилась в Python-пакет и Langflow смог корректно индексировать инструменты.
Шаг 5. Подключаем MCP filesystem в Langflow.
Добавьте MCP Server:
- Type: Streamable HTTP/SSE.
- Name: любое значение.
- URL: http://mcp-filesystem:8000/mcp.
Теперь сам компонент MCP Tools можно перевести в режим tool mode и отредактировать инструменты в настройках, если есть в этом необходимость.
Шаг 6. Настраиваем Agent (Ollama).
Внутри docker сети общаемся по service name ollama, не по localhost.
- Ollama API URL: http://ollama:11434.
- Model Name: выбрать из выпадающего списка llama3.1 (или то, что вы скачали).
- Temperature: 0.3.
- Agent Instructions: пишем промт, который четко фиксирует последовательность действий и вызовов tools.
В настройках самого компонента есть еще много полезных функций.
Шаг 7. Выставляем связи:
Chat Input → Agent (Input)
MCP Tools → Agent (Tools)
Custom component (Tools) → Agent (Tools)
Agent → Chat Output
Шаг 8. Тестирование в Playground.
Нажимаем на Playground и просим сделать отчет.
В финале подключим Langflow к LibreChat, чтобы совместить последовательную логику и готовый чат-интерфейс.
Этапе №4. Подключаем Langflow к LibreChat как MCP Server
Настроим Langflow в режиме MCP-сервера, чтобы добавить его как инструмент LibreChat (как это делали на шаге 2), а оркестратор (LibreChat или любая другая среда) вызывает его через MCP как одну из функций. Таким образом, мы сможем получить привычное окно чата от LibreChat и гарантированную точность выполнения шагов от Langflow.
Общая архитектурная схема:
Главный минус такой схемы — архитектурная избыточность.
Если LibreChat вызывает Langflow-tool, а внутри Langflow еще крутится LLM, получается «LLM над LLM». Ну и вдобавок два сервиса сложнее администрировать и дебажить. Для простых задач это слишком трудозатратно, но на сложных флоу схема работает хорошо. Поэтому пропишу примечание, что данный шаг опционален.
Шаг 1. Включаем MCP Server в Langflow.
- Открываем проект в Langflow — http://localhost:7860.
- В верхнем меню нажмите на вкладку MCP Server.
- Убеждаемся, что нужный flow добавлен в Flows/Tools (например, NEW_FLOW).
- В блоке справа выбираем транспорт.
В Langflow в JSON показывает пример с localhost, типа:
- Streamable: http://localhost:7860/api/v1/mcp/project/<id>/streamable.
- SSE: http://localhost:7860/api/v1/mcp/project/<id>/sse.
ВАЖНО: если LibreChat в Docker, то для него localhost — это сам контейнер LibreChat
Поэтому делаем замену:
- было: http://localhost:7860/...
- стало: http://langflow:7860/...
(где langflow — имя сервиса из docker-compose)
Шаг 2. Настраиваем аутентификацию (опционально).
Если Langflow доступен не только вам (или вы просто хотите нормальную защиту API), включите доступ по API ключу:
- Langflow → Settings → API Keys → Create.
- Langflow сгенерирует ключ вида: sk-langflow-abc123def456...
- Скопируйте ключ — он больше не будет показан!
- Вставьте его в .env как LANGFLOW_API_KEY.
Сохраняем ключ auth в .env (если вы оставили Auth: None (public), этот шаг можно пропустить)
Добавьте в файл .env:
Шаг 3. Обновляем docker-compose.yml.
Шаг 4. Обновляем librechat.yaml.
Шаг 5. Перезапускаем сервисы.
Шаг 6. Добавляем MCP сервер в LibreChat UI.
Открываем LibreChat: http://localhost:3080
- Настройки → MCP Servers → Add MCP server
- Заполняем поля:
- Имя: любое значение.
- URL адрес сервера MCP: вставляем наше скопированное значение.
- Transport: если URL заканчивается на /sse → выбираем SSE, если URL заканчивается на /streamable → выбираем Streamable HTTP.
- Auth: если в Langflow стоит Auth: None (public) — выбираем No Auth, если нажали AddAuth в Langflow — тогда уже API key/OAuth (по ситуации) из .env.
3. Проставляем галочку в чекбоксе, что доверяете приложению.
Если все настроено правильно, сервер появится в списке доступных MCP серверов.
Шаг 7. Тестирование.
Теперь в чате LibreChat:
- Выбираем модель (например, локальную llama 3.1).
- Выбираем MCP сервер (тот, что добавили).
- В настройках чата включите ранее добавленный MCP сервер (Langflow).
Если просто подключить флоу из предыдущего уровня «как есть», то появится проблема, как LLM над LLM. LibreChat отправит запрос своей модели, та вызовет инструмент Langflow, внутри которого другая модель начнет генерировать свой ответ. В итоге мы получаем избыточный расход токенов, лишние задержки и риск, что финальный ответ отобразится некорректно из-за двойной интерпретации.
Чтобы система работала корректно, нужно изменить подход к проектированию флоу в Langflow:
- Убираем компонент Agent из Langflow
- Оставляем в Langflow только логику: сбор данных через MCP, Python-скрипты для расчетов и форматирование.
- Роль оркестратора полностью отдаем модели в LibreChat.
В такой конфигурации Langflow превращается в чистый MCP-инструмент. Он возвращает сухие факты или готовую таблицу, а модель в LibreChat уже сама решает, как преподнести эти данные пользователю.
Масштабирование системы
Главная идея туториала — инструмент = MCP‑сервер. Хотите добавить новый источник данных — добавляете/пишете MCP‑сервер и подключаете его либо в LibreChat (если LibreChat оркестратор), либо в Langflow (если Langflow оркестратор).
На практике один и тот же стек можно использовать в трех режимах, здесь отличается не «логика», а подготовка окружения и безопасность.
1) Полностью локально. Подходит для личных документов и задач, где важна приватность: отчеты по Excel, поиск по локальной базе заметок/документов, сравнение файлов и версий, разбор логов/дампов, генерация сводок.
2) Закрытая/безопасная сеть (корпоративный контур, без интернета). Можно использовать с Jira/Confluence (если доступны внутри), отчеты по ролевым моделям/матрицам доступов, анализ инцидентов, обработка выгрузок, унификация ответов/шаблонов.
3) Онлайн/гибрид (часть источников снаружи). Подходит для AI ассистентов: почта/календарь, внешние API, задачи/трекеры, умные уведомления.
Но важно заранее донастроить безопасность: TLS/reverse proxy, аутентификацию, ограничение прав инструментов и хранение секретов, но это тема отдельной статьи.