Руководство Melbis Shop: оглавление
Как MCP-сервер попадает в магазин, что агенту в нём разрешено и чем
подписан каждый запрос. Сами инструменты входа описаны на своих
страницах: session_init, session_connect, session_rules_accept.
Магазин. Приложение-агент, открытое на папке
магазина, запускает сервер, закреплённый за этим магазином: программа
кладёт в папку конфигурацию с
--store <папка магазина>. Такой сервер работает
только со своим магазином, что бы ни было открыто в программе:
переключение магазина в программе открытую сессию не прерывает, и в двух
окнах можно вести два магазина. Новой сессии пароль даёт программа,
открытая на этом магазине, или сохранённые настройки, а токены лицензии
программа кладёт, только пока открыта на нём, — см. ниже. Сервер без
--store — конфигурация с закладки «AI-помощник» окна
«Подключение» для приложения, открытого не на папке магазина, — входит в
магазин, который последним открыт в программе, и следует за ней: пока в
программе открыт другой магазин, его инструменты отказывают с
STORE_SWITCHED. Закрепление за папкой, которой нет в списке
магазинов программы, сессию не открывает вовсе.
Логин и пароль. Если программа запущена на этом
магазине, пару отдаёт она — это пользователь, под которым вошёл человек
за программой. Если нет — логин берётся из Shop.ini в папке
магазина, а пароль из реестра Windows, где программа хранит его
зашифрованным при включённой галочке «хранить пароли». Третьего пути
нет: пароль через переписку не передаётся и агенту не виден.
В магазин пароль не уходит. Сервер один раз вычисляет из него ключ — из логина, домена магазина и пароля — и подписывает им каждый запрос: строку из логина, времени и команды. Магазин хранит только открытую половину ключа и проверяет подпись; время подписи годится ±10 минут.
Под кем работает агент. Агент работает под пользователем человека и его правами. Всё, что агент делает, магазин подписывает именем этого пользователя: автор задачи, автор версии файла, владелец заметки, тот, кто держит таблицу. Исключение — AI-диспетчер: у него свой пользователь, его запускает Диспетчер программы по событиям магазина, и за клавиатурой никого нет (см. «AI-диспетчер»). Его сессия может прийти с принципалом — другим пользователем магазина, которого назвало событие и от чьего имени диспетчер действует. Команду AI-инструмента, которой диспетчеру не выдано, а принципалу выдано, сервер выполняет правами принципала и подписывает его именем; агент принципала не выбирает (см. «Поручения с правами пользователя»).
За каждым MCP-инструментом стоит команда движка — AGENT_
и имя инструмента заглавными буквами: engine_php_save →
AGENT_ENGINE_PHP_SAVE; tool_pool вызывает
команду tool_run и выдаётся её правом. Команды выдаются
правами ветки «AI-помощник» в правах пользователя. Подписи на
оригинальном языке могут отличаться.
| Ветка | Право | Ключ права | Инструменты |
|---|---|---|---|
| Память | Получить перечень | AGENT_MEMORY_LIST |
memory_list |
| Загрузить | AGENT_MEMORY_LOAD |
memory_load |
|
| Сохранить | AGENT_MEMORY_SAVE |
memory_save |
|
| Удалить | AGENT_MEMORY_REMOVE |
memory_remove |
|
| Репозиторий | Получить перечень | AGENT_REPO_LIST |
repo_list |
| Чтение данных | AGENT_REPO_READ |
repo_read |
|
| Изменение данных | AGENT_REPO_WRITE |
repo_write |
|
| Инструменты | Получить список | AGENT_TOOL_LIST |
tool_list |
| Выполнить | AGENT_TOOL_RUN |
tool_run, tool_pool |
|
| Прямой доступ → Файлы магазина | Загрузить | AGENT_ENGINE_FILES_LOAD |
engine_files_load |
| Добавить | AGENT_ENGINE_FILES_ADD |
engine_files_add |
|
| Удалить | AGENT_ENGINE_FILES_REMOVE |
engine_files_remove |
|
| Прямой доступ → База данных | Получить структуру данных | AGENT_ENGINE_DB_TABLES |
engine_db_tables |
| Чтение данных | AGENT_ENGINE_DB_SELECT |
engine_db_select |
|
| Изменение данных | AGENT_ENGINE_DB_EXECUTE |
engine_db_execute |
|
| Получить список блокировок | AGENT_ENGINE_DB_LOCKS |
engine_db_locks |
|
| Снять блокировку таблиц | AGENT_ENGINE_DB_UNLOCKS |
engine_db_unlocks |
|
| Прямой доступ → Разработка | Чтение данных | AGENT_ENGINE_DEV_READ |
engine_map_tree, engine_map_units,
engine_search, engine_history_list,
engine_history_content, engine_php_load,
engine_html_load, engine_static_load,
engine_image_load, engine_whole_load |
| Изменение данных | AGENT_ENGINE_DEV_WRITE |
все add, save, rename и
remove модулей, шаблонов, статики, картинок и их папок, а
также групп шаблонов |
|
| Получить конфигурацию | AGENT_ENGINE_DEV_CONFIG |
engine_dev_config |
|
| Выполнить очистку кэша | AGENT_ENGINE_DEV_CACHE_CLEAR |
engine_dev_cache_clear |
|
| Экспорт | AI-инструменты | AGENT_TOOL_EXPORT |
tool_export |
| Магазин | AGENT_SHOP_DOWNLOAD |
shop_download |
Без прав работают session_init,
session_connect, session_rules_accept,
session_clear, shop_page,
shop_module и shop_agent. Одно исключение
внутри них: shop_page и shop_module с
debug=true читают код отладчика из конфигурации и поэтому
требуют права «Получить конфигурацию».
Без прав работают и remote_exec,
remote_load, remote_save: в движок они не
обращаются, а к серверу их пускает окно «Сервер» программы, пока
владелец держит его открытым с паролем root и флажком доступа — «Сервер».
Работу с файлами проекта ветка «Разработка» делит только на чтение и изменение, и это не упрощение: пользователь, которому можно сохранить модуль, уже может сделать с магазином всё, что умеет сам магазин. Поэтому «Изменение данных» включает «Чтение данных»: сохранение начинается с загрузки файла.
Права принадлежат пользователю. Агент входит под пользователем человека, поэтому с одним человеком он умеет больше, чем с другим, в одном и том же магазине.
Когда проверяются. Список прав приходит при входе, и на вызов невыданного инструмента сервер отказывает сам, не обращаясь к магазину, — и называет недостающее право путём в дереве прав:
ACCESS_DENIED: this user may not run AGENT_ENGINE_PHP_SAVE.
The owner grants it in the program, to the user you signed in as
- in the user rights, <путь на языке магазина>.
The session has to be opened again afterwards.
После выдачи права сессию открывают заново: список посреди работы не
меняется. Если право сняли посреди сессии, вызов проходит сервер и
отказывает уже магазин — голым ACCESS_DENIED, без пути. Это
значит, что права пользователя изменились; после переподключения отказ
придёт с путём.
Каждый запрос подписан суточным токеном. Токены получает программа,
пока работает, и кладёт их в папку магазина, в
tokens\<логин>-<дата>.lic. MCP-сервер их только
читает и сам лицензию не запрашивает.
Лицензия выдаётся на пару «домен + логин», поэтому токен у пользователя и его агента общий: помощнику отдельная лицензия не нужна. У AI-диспетчера свой логин, и лицензия у него своя.
Нет файла на сегодня — на лицензионном магазине сессия не откроется:
session_connect отвечает LICENCE_NONE и
называет папку, где искал. Лечится это одним способом: открыть магазин в
программе, затем session_init и
session_connect заново. Движок отказывает токену своими
кодами — LICENCE_ERROR, LICENCE_DOMAIN,
LICENCE_DATE (см. «Ответы и
отказы»). Токен сервер ищет заново при каждом запросе, поэтому смена
суток посреди сессии её не закрывает: пока программа не записала файл на
новый день, каждая команда получает отказ LICENCE_NONE, а
потом снова работает.
Пока в корне магазина лежит admin.here, движок не
проверяет ни лицензию, ни логин с паролем, и любой вошедший становится
администратором. Сервер распознаёт это сам, и ответ
session_connect требует от агента первым делом предупредить
человека. Как выйти из демо-режима — «Инсталляция».