РелизКод / SDK · В работуHabr AI→ оригинал

Пять MCP-компонентов для MODX проверили на сбоях: агент рапортует об успехе при половине правок

Разработчик веб-студии выбирал MCP-компонент для MODX, но полез в исходники и обнаружил: setTVValue() нигде не проверяется, поэтому при сбое записи агент получает «успех» при наполовину сохранённых данных. Он прогнал 25 проверок на пяти проектах и сравнил права, повторные запросы и защиту от чужих правок.

AI-обработка оригинала Habr AI; редакция Hamidun News
Пять MCP-компонентов для MODX проверили на сбоях: агент рапортует об успехе при половине правок
Источник: Habr AI. Коллаж: Hamidun News.
Слушать статью
Паспорт материала и цифры
ПараметрДанные
ПервоисточникHabr AI ↗
Главный редактор
Праваагент действует от пользователя или от админ-аккаунта
Устаревшие данныепроверка старого значения необязательна
Частичная записьоткат есть только в одном из компонентов

Обычная задача: выбрать MCP-компонент, чтобы отдать AI-агенту рутину на сайтах. Но разработчик одной веб-студии, работающей с MODX 2 и 3, заглянул в код и увидел цикл, который обновляет дополнительные поля страницы и не проверяет результат setTVValue(). Первое поле записалось, второе нет, а обработчик отчитался об успехе. Агент поверит этому ответу и скажет пользователю, что всё готово.

Из этого выросло небольшое исследование. Автор отобрал пять проектов: karamble/modxmcp, dampilov94/mcp-component, rumata-estor/modx3-mcp, modxcms/modAI и ShevArtV/mxBoard. Он зафиксировал исходники 26 октября 2026 года и провёл 25 проверок на PHP 8.3.6. Использовались настоящие классы компонентов, но вместо живого MODX и базы данных стояли тестовые объекты. Часть тестов специально воспроизводила ошибки, так что PASS не всегда означает, что компонент ведёт себя правильно.

Чьими правами действует агент

Представьте контент-менеджера, которому разрешены только новости. Если дать ему AI-помощника, какие права получит сам помощник? В исходниках нашлись две схемы. В karamble проверяются и разрешение на операцию, и доступ к конкретному ресурсу. В issue №11 даже была реальная ошибка: ограниченный пользователь получал через MCP данные, которых не видел в админке. Её исправили в версии 1.2.0.

У dampilov94 и rumata-estor можно ограничить группы команд, но выполняются они через служебного пользователя с админскими правами. Для задач администратора это нормально. Для личных помощников сотрудников со своими ограничениями уже нет.

Устаревшие данные и потерянные ответы

Цена на странице 1000 рублей, агент её прочитал, а сотрудник тем временем поставил 1100. Агент записывает 1200, и правка человека исчезает. В коде dampilov94 старое значение не сравнивается. В rumata-estor есть проверка ожидаемого значения со статусом STALE_STATE, и в тесте она сохранила человеческую правку. Но проверка необязательна: если клиент не передал предусловие, запись пройдёт. К тому же проверка и запись идут раздельно, атомарного сравнения на уровне базы нет.

С повторами другая история. Если сервер создал страницу, а ответ потерялся, агент может повторить команду и получить дубль. RequestStore у dampilov94 хранит состояние по идентификатору запроса. Параллельный дубль получает 409, завершённый запрос возвращает сохранённый ответ, а при смене аргументов под тем же идентификатором запрос отклоняется. Но с новым идентификатором команда выполнится заново.

Файловая блокировка в rumata-estor заставила второй процесс ждать 350 мс. Однако третий процесс, не знавший о ней, спокойно изменил файл. Так же поведёт себя обычная админка MODX. Идентификатор запроса, блокировка и проверка ожидаемого значения решают разные задачи и друг друга не заменяют.

Частичная запись и приёмка

rumata-estor оборачивает запись TV в транзакцию: если setTVValue() вернул false, вызывается rollback. В тесте значения вернулись к исходным. У modAI результат обновления кеша не проверяется, и в тесте инструмент сообщил об успехе при false. У karamble после изменения идёт повторное чтение ресурса. mxBoard отделяет выполнение задачи от приёмки: закрыть чужую задачу исполнитель не смог.

Что с этим делать

Ограничения честные: настоящий MODX с MySQL и языковой моделью автор пока не запускал, а rollback проверен только на заглушке. Тем не менее вывод применим к любой CMS и любому приложению, где агенту разрешили менять рабочие данные. Перед запуском решите, от чьего имени он работает. Требуйте от клиента передавать идентификатор запроса и ожидаемое значение. Проверяйте результат каждой записи, а не только последнего вызова. И не принимайте «успех» от агента за подтверждение того, что на сайте всё сохранилось.

Сюжет

Вопросы и ответы по материалу

Что известно по теме: чьими правами действует агент?

Представьте контент-менеджера, которому разрешены только новости. Если дать ему AI-помощника, какие права получит сам помощник? В исходниках нашлись две схемы. В karamble проверяются и разрешение на операцию, и доступ к конкретному ресурсу. В issue №11 даже была реальная ошибка: ограниченный пользователь получал через MCP данные, которых не видел в админке. Её исправили в версии 1.2.0. У dampilov94 и rumata-estor можно ограничить группы команд, но выполняются они через служебного пользователя с админскими правами.

Что известно по теме: устаревшие данные и потерянные ответы?

Цена на странице 1000 рублей, агент её прочитал, а сотрудник тем временем поставил 1100. Агент записывает 1200, и правка человека исчезает. В коде dampilov94 старое значение не сравнивается. В rumata-estor есть проверка ожидаемого значения со статусом STALE_STATE, и в тесте она сохранила человеческую правку. Но проверка необязательна: если клиент не передал предусловие, запись пройдёт. К тому же проверка и запись идут раздельно, атомарного сравнения на уровне базы нет. С повторами другая история.

Что известно по теме: частичная запись и приёмка?

rumata-estor оборачивает запись TV в транзакцию: если setTVValue() вернул false, вызывается rollback. В тесте значения вернулись к исходным. У modAI результат обновления кеша не проверяется, и в тесте инструмент сообщил об успехе при false. У karamble после изменения идёт повторное чтение ресурса. mxBoard отделяет выполнение задачи от приёмки: закрыть чужую задачу исполнитель не смог.

ЖХ
Жемал Хамидун — CPO Alpina Digital, продакт-менеджер AlpinaGPT. Делает AI-продукты с 2019 года. Hamidun News — pet project, который вырос в production-агрегатор с 6000+ читателей.
✦ Практика · Hamidun Academy

Соберите рабочего ИИ-агента или сервис своими руками без ручного кода

В Академии Жемала Хамидуна (academy.hamidun.com) открыт бесплатный 72-часовой тест-драйв: интерактивные скетч-уроки по Claude Code и Cursor, живой Tech Radar и готовые шаблоны агентов.

Открыть 72ч бесплатный доступ →Интенсив по Вайб-кодингу
Что вы думаете?
Загружаем комментарии…