{"name":"ru.layero/layero","slug":"layero","title":"Layero","description":"Deploy and operate sites on Layero — hosting with build servers in Russia: domains, env, Data API.","url":"https://mcp.market/server/layero","grade":"B","score":75,"certified":false,"status":"active","category":"devtools","tags":["devtools"],"transport":"remote","callable_via_gateway":true,"default_price_micros":0,"repository":"https://github.com/LayeroInfra/layero-agents","website":"https://docs.layero.ru/agents/","version":"2.2.0","remotes":[{"type":"streamable-http","url":"https://mcp.layero.ru/mcp","headers":[{"description":"Layero token for CI and headless clients, issued at https://app.layero.ru/settings/cli or with `npx layero@latest token create`. Optional: interactive clients sign in through OAuth.","isSecret":true,"placeholder":"Bearer layero_ci_...","name":"Authorization"}]}],"packages":[],"tools":[{"name":"cancel_deploy","description":"Остановить сборку, которая ещё идёт.\n\n    Живой адрес при этом не меняется — на нём остаётся прошлая версия.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"deploy":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"id сборки. Без него берётся самая свежая.","title":"Deploy"}},"required":["project"],"title":"cancel_deployArguments"}},{"name":"check_copy","description":"Механические ошибки русской типографики — с точным местом и заменой.\n\n    Это КОД, а не суждение модели: один и тот же текст даёт один и тот же\n    список находок. Ловится то, что глаз не видит, а читатель чувствует:\n    неразрывные пробелы, тире, прямые кавычки, точка вместо запятой в дробях,\n    пробелы у знаков препинания, двойные пробелы.\n\n    Каждая находка несёт готовую замену — подставляй её, а не переписывай\n    фрагмент по-своему.\n\n    ЧЕГО ЗДЕСЬ НЕТ. Инфостиль, длина фраз, канцелярит, признаки нейрослопа —\n    это суждение, и оно живёт в ресурсе `layero://editorial/ru`. Прочитай его,\n    если просят «сделать текст лучше», а не «исправить типографику».\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"text":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Текст для проверки. Либо это, либо `project` — что-то одно.","title":"Text"},"project":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Слаг проекта: проверить тексты ОПУБЛИКОВАННОЙ страницы. Удобно, когда правишь чужой сайт или свой после публикации.","title":"Project"},"path":{"default":"/","description":"Путь страницы, если проверяем проект. По умолчанию главная.","title":"Path","type":"string"}},"title":"check_copyArguments"}},{"name":"check_domain","description":"Check whether a connected domain has started working.\n\n    Runs the DNS check immediately instead of waiting for the background\n    re-check. If the records have not propagated yet, that is normal — say\n    so and suggest coming back later.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"domain":{"description":"Домен без схемы — ровно тот, что подключали.","title":"Domain","type":"string"}},"required":["project","domain"],"title":"check_domainArguments"}},{"name":"check_performance","description":"Measure a site's speed and say whether it got worse after a deploy.\n\n    The verdict comes FROM THE SCORE, not from timings: repeated runs of the\n    same deploy vary by at most one point, while LCP and TTFB on identical\n    code swing by 37-40%. A difference of 3 points or more is meaningful;\n    anything smaller is measurement noise, and calling that a regression is\n    inventing a problem.\n\n    A run takes tens of seconds. With `wait=true` the tool waits for you; do\n    not start a second measurement in parallel — it will occupy the queue\n    and add nothing.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"wait":{"default":true,"description":"Дождаться результата замера (десятки секунд) или вернуться сразу. `false` — когда пользователю нужен не результат, а сам факт запуска.","title":"Wait","type":"boolean"}},"required":["project"],"title":"check_performanceArguments"}},{"name":"connect_analytics","description":"Connect Yandex Metrika to a site.\n\n    IMPORTANT: authorisation happens IN A BROWSER, and neither you nor the\n    platform can do that step for the user. The tool returns a link — show\n    it and ask them to open it and grant access. Do not poll in a loop: the\n    person may walk away for an hour. Check later through this same tool\n    without the `branch` argument, or through `site_analytics`.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Ветка, трафик которой считать. По умолчанию — основная; указывай, только если пользователь просит считать превью-ветку.","title":"Branch"}},"required":["project"],"title":"connect_analyticsArguments"}},{"name":"connect_domain","description":"Connect a custom domain to a site.\n\n    IMPORTANT: between this call and a working domain stands A PERSON. You\n    get DNS records — show them to the user and explain they go in at their\n    domain registrar. Do not wait for readiness: DNS propagates in minutes\n    to an hour, the platform re-checks on its own, and you check later via\n    `check_domain`. Spinning here burns time and context for nothing.\n\n    The address can be passed as-is: the platform reduces\n    `https://shop.example.com/page` to `shop.example.com` itself.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"domain":{"description":"Домен без схемы и без слеша: `example.ru` или `www.example.ru`. Со схемой (`https://…`) платформа ответит отказом 422.","title":"Domain","type":"string"}},"required":["project","domain"],"title":"connect_domainArguments"}},{"name":"data_api_grant","description":"Кто может вызывать метод таблицы или функции: показывает SQL и применяет после согласия.\n\n    ОТКРЫВАЕТ ДАННЫЕ ИНТЕРНЕТУ. Сначала вызывай без apply: платформа вернёт\n    команды и предупреждения (например, «защита строк выключена — посетитель\n    получит все строки»). Покажи их человеку. С apply=true клиент с формами\n    спросит его сам; без форм — получи согласие в чате и передай confirmed=true\n    вместе с expected_sql из показа.\n\n    Неназванные методы таблицы сохраняют текущий уровень. Применяются ровно\n    показанные команды: если права успели измениться, платформа откажет —\n    покажи новые. Нужен токен со scope admin — и для показа тоже.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"object":{"description":"Таблица `схема.имя` или функция `схема.имя`, при перегрузке — `схема.имя(типы)`. Как в data_api_methods.","title":"Object","type":"string"},"get":{"anyOf":[{"enum":["closed","visitor","user","server"],"type":"string"},{"type":"null"}],"default":null,"description":"Чтение таблицы. closed — закрыто; visitor — любой посетитель сайта; user — вошедшие в приложение; server — только сервер с секретным ключом.","title":"Get"},"post":{"anyOf":[{"enum":["closed","visitor","user","server"],"type":"string"},{"type":"null"}],"default":null,"description":"Добавление строк в таблицу.","title":"Post"},"patch":{"anyOf":[{"enum":["closed","visitor","user","server"],"type":"string"},{"type":"null"}],"default":null,"description":"Изменение строк таблицы.","title":"Patch"},"delete":{"anyOf":[{"enum":["closed","visitor","user","server"],"type":"string"},{"type":"null"}],"default":null,"description":"Удаление строк таблицы.","title":"Delete"},"call":{"anyOf":[{"enum":["closed","visitor","user","server"],"type":"string"},{"type":"null"}],"default":null,"description":"Вызов функции. closed — закрыто; visitor — любой посетитель сайта; user — вошедшие в приложение; server — только сервер с секретным ключом.","title":"Call"},"apply":{"default":false,"description":"false (по умолчанию) — только показать команды. true — применить после согласия человека.","title":"Apply","type":"boolean"},"confirmed":{"default":false,"description":"true — человек уже согласился в чате, увидев, что поменяется. Клиенту с формами не нужен: он спросит сам. Без явного согласия человека не ставь.","title":"Confirmed","type":"boolean"},"expected_sql":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"default":null,"description":"Команды `sql` из ответа показа, которые видел человек. Обязательны с confirmed=true: применятся только они.","title":"Expected Sql"},"database":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"База: имя, слаг или id. Без него — единственная база организации с включённым Data API.","title":"Database"},"organization":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Организация (слаг). Без него — единственная или личная.","title":"Organization"}},"required":["object"],"title":"data_api_grantArguments"}},{"name":"data_api_keys","description":"Ключи Data API базы: список, выпуск, отзыв.\n\n    Значения ключа в списке нет никогда. Выпуск и отзыв — только с согласия\n    человека: клиент с формами спросит сам, без форм спроси в чате и передай\n    confirmed=true. Значение выпущенного ключа возвращается один раз: секретный\n    платформа не хранит. Отдай его человеку для сервера и не повторяй дальше.\n\n    Отзыв ломает всех, кто пользуется ключом, — и сайт, если ключ в его сборке\n    (`in_build`). Для выпуска и отзыва нужен токен со scope admin.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"action":{"default":"list","description":"`list` — ключи с префиксами, без значений; `issue` — выпустить ключ, значение вернётся ОДИН раз; `revoke` — отозвать ключ `key`.","enum":["list","issue","revoke"],"title":"Action","type":"string"},"kind":{"default":"public","description":"Для issue: public — для сайта (лежит в браузере), secret — только для сервера.","enum":["public","secret"],"title":"Kind","type":"string"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Для issue: подпись, по которой ключ узнают в списке.","title":"Label"},"expires_in_days":{"anyOf":[{"enum":[30,90,365],"type":"integer"},{"type":"null"}],"default":null,"description":"Для issue: срок в днях; без него ключ бессрочный.","title":"Expires In Days"},"key":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Для revoke: id или префикс ключа из списка.","title":"Key"},"confirmed":{"default":false,"description":"true — человек уже согласился в чате, увидев, что поменяется. Клиенту с формами не нужен: он спросит сам. Без явного согласия человека не ставь.","title":"Confirmed","type":"boolean"},"database":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"База: имя, слаг или id. Без него — единственная база организации с включённым Data API.","title":"Database"},"organization":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Организация (слаг). Без него — единственная или личная.","title":"Organization"}},"title":"data_api_keysArguments"}},{"name":"data_api_methods","description":"REST и RPC базы с уровнем доступа на каждый HTTP-метод.\n\n    Уровень — кто может вызвать метод: closed, visitor (любой посетитель), user\n    (вошедшие), server (только сервер). Читается из действующих прав ролей в\n    самой базе — так, как их увидит шлюз.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"database":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"База: имя, слаг или id. Без него — единственная база организации с включённым Data API.","title":"Database"},"organization":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Организация (слаг). Без него — единственная или личная.","title":"Organization"}},"title":"data_api_methodsArguments"}},{"name":"data_api_origins","description":"Сайты, которым можно звать базу из браузера: список, добавить, убрать.\n\n    Адреса подключённых проектов и их веток пускаются сами — их не добавляют.\n    Добавленный сайт данных не открывает: что можно читать и писать, решают\n    уровни доступа. Добавить и убрать — только с согласия человека; убранный\n    сайт получает отказ на все запросы. Для этого нужен токен со scope admin.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"action":{"default":"list","description":"`list` — адреса проектов базы и добавленные вручную; `add` — пустить сайт; `remove` — убрать сайт.","enum":["list","add","remove"],"title":"Action","type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Для add и remove: адрес сайта со схемой, `https://shop.example`.","title":"Url"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Для add: зачем сайт добавлен.","title":"Note"},"confirmed":{"default":false,"description":"true — человек уже согласился в чате, увидев, что поменяется. Клиенту с формами не нужен: он спросит сам. Без явного согласия человека не ставь.","title":"Confirmed","type":"boolean"},"database":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"База: имя, слаг или id. Без него — единственная база организации с включённым Data API.","title":"Database"},"organization":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Организация (слаг). Без него — единственная или личная.","title":"Organization"}},"title":"data_api_originsArguments"}},{"name":"data_api_probe","description":"Настоящий запрос к методу через шлюз — от имени посетителя, пользователя или сервера.\n\n    Ключ и токен подставляет платформа. Запись (POST, PATCH, DELETE, вызов\n    функции) откатывается: строки в базе не меняются, но откат не отменяет номера\n    последовательностей, вызовы из базы наружу, сессионные блокировки и суточную\n    квоту вызовов. Ответ настоящий: права, правила строк и отказы те же, что\n    увидит сайт. Нужен токен со scope admin.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"method":{"description":"HTTP-метод.","enum":["GET","POST","PATCH","DELETE"],"title":"Method","type":"string"},"path":{"description":"Путь от адреса базы: `/rest/v1/products`, `/rest/v1/rpc/order_create` или `/whoami` (только GET).","title":"Path","type":"string"},"role":{"default":"visitor","description":"От чьего имени: visitor — посетитель с публичным ключом, user — вошедший пользователь (нужен user_id), server — секретный ключ.","enum":["visitor","user","server"],"title":"Role","type":"string"},"query":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"default":null,"description":"Параметры запроса как у PostgREST: {\"select\": \"id,title\", \"price\": \"gt.100\"}.","title":"Query"},"body":{"anyOf":[{"additionalProperties":true,"type":"object"},{"items":{},"type":"array"},{"type":"null"}],"default":null,"description":"Тело для POST и PATCH.","title":"Body"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Для role=user: id пользователя приложения.","title":"User Id"},"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Схема таблицы: api, public или app. Без неё имя ищется по порядку api → public → app — указывай, когда одноимённые таблицы есть в нескольких схемах. Функциям и /whoami не нужна.","title":"Schema"},"database":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"База: имя, слаг или id. Без него — единственная база организации с включённым Data API.","title":"Database"},"organization":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Организация (слаг). Без него — единственная или личная.","title":"Organization"}},"required":["method","path"],"title":"data_api_probeArguments"}},{"name":"data_api_status","description":"Включён ли у базы Data API, его адрес, ключи и сайты, которым можно звать базу.\n\n    Ключи — только префиксы: значения платформа не отдаёт, секретные не хранит.\n    Включить API инструментом нельзя: после включения у базы появляется\n    публичный адрес, и это решение человека в панели.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"database":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"База: имя, слаг или id. Без него — единственная база организации с включённым Data API.","title":"Database"},"organization":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Организация (слаг). Без него — единственная или личная.","title":"Organization"}},"title":"data_api_statusArguments"}},{"name":"deploy_logs","description":"Сырые строки лога — когда разбора `diagnose_deploy` не хватило.\n\n    Начинай с `diagnose_deploy`: он уже вытащил причину и окрестности фатальной\n    строки. Сюда иди, когда нужно посмотреть глазами — например, причина\n    невнятная или интересует не отказ, а поведение приложения.\n\n    Возвращается ХВОСТ. Сколько отброшено — видно по `truncated`; не выдавай\n    хвост за весь лог.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"kind":{"default":"build","description":"`build` — что писала сборка. `runtime` — что пишет само приложение (только для проектов-приложений, не для статики).","enum":["build","runtime"],"title":"Kind","type":"string"},"deploy":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"id сборки. Без него берётся самая свежая.","title":"Deploy"},"tail":{"default":100,"description":"Сколько последних строк вернуть, не больше 200.","title":"Tail","type":"integer"}},"required":["project"],"title":"deploy_logsArguments"}},{"name":"diagnose_deploy","description":"Why a deploy failed — with the cause parsed out, not a raw log.\n\n    Without `deploy` the latest build is used; that is what reflects the\n    current state. To examine a specific older one, pass its id.\n\n    The response is not a log tail but the neighbourhood of the fatal line:\n    the platform has already picked out what matters. Read `verdict` and the\n    summary, fix the code, deploy again — you close this loop yourself,\n    without involving the person.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"deploy":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"id конкретной сборки. Без него берётся самая свежая — она и отражает текущее состояние проекта.","title":"Deploy"}},"required":["project"],"title":"diagnose_deployArguments"}},{"name":"env_vars","description":"Project environment variables: list names, set them, remove them.\n\n    VALUES ARE NEVER READ BACK — not by you, not by the platform in its\n    response. Only names and lengths are returned. This is a deliberate rule\n    rather than an implementation limit: anything that reaches your answer\n    settles into the conversation history, and a secret that lands there\n    cannot be taken back. If the user asks \"what is my key\", say plainly\n    that you cannot show it and offer to set a new one.\n\n    `set` does not require knowing the other variables — the platform keeps\n    them. `unset` removes only the named ones.\n\n    A change needs a new deploy: variables are picked up at build time, not\n    on the fly. Say so, or the user will think nothing happened.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"action":{"default":"list","description":"`list` — показать имена (значения не возвращаются никогда), `set` — задать переменные из `values`, `unset` — удалить переменные, перечисленные в `keys`.","enum":["list","set","unset"],"title":"Action","type":"string"},"values":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"default":null,"description":"Для `action=\"set\"`: пары имя → значение. Остальные переменные проекта сохранятся — присылать их заново не нужно.","title":"Values"},"keys":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"default":null,"description":"Для `action=\"unset\"`: имена переменных, которые убрать.","title":"Keys"}},"required":["project"],"title":"env_varsArguments"}},{"name":"import_repo","description":"Create a Layero project from a repository — path (a) without the\n    dashboard. From then on a push to the branch is a preview, a push to the\n    production branch is production.\n\n    After the link the tool finishes the setup wizard itself (detect →\n    settings → first build), exactly what the dashboard's \"Start deploy\"\n    button does; `setup` in the result says whether that happened. Until\n    2.1.1 the project stayed in `pending_setup` while the answer promised a\n    build that never started.\n\n    Two shapes, same as the CLI: GitHub goes through the App installation\n    (project and webhook in one call); other providers create the project\n    first and then connect the source — that step reports whether the\n    webhook could be registered. If the provider is not connected, the result\n    says `needs_connection` with the dashboard address: the person connects\n    the token there, never through the chat.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"provider":{"description":"Провайдер: github, gitverse, gitlab, gitflic или sourcecraft.","title":"Provider","type":"string"},"repo":{"description":"Путь репозитория у провайдера: `owner/repo`; у GitLab бывает вложенным (`group/sub/project`). Допустима форма `gitverse:owner/repo`.","title":"Repo","type":"string"},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Ветка прода. По умолчанию — ветка по умолчанию репозитория.","title":"Branch"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Имя проекта; из него выводится слаг и адрес. По умолчанию — имя репозитория.","title":"Name"},"organization":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Слаг организации. Без него — единственная организация аккаунта или личная; если их несколько и личной нет, инструмент перечислит слаги.","title":"Organization"},"deploy":{"default":true,"description":"Применить настройки из детекта и запустить первую сборку сразу — как кнопка «Начать деплой» в панели. `false` — оставить проект в мастере: сборок не будет, пока человек не завершит настройку в панели.","title":"Deploy","type":"boolean"}},"required":["provider","repo"],"title":"import_repoArguments"}},{"name":"list_deploys","description":"Последние сборки проекта: какая чем кончилась и какая сейчас живая.\n\n    Нужен, чтобы выбрать цель для `rollback` или `diagnose_deploy`. Для\n    вопроса «что с сайтом прямо сейчас» хватает `site_status` — он дешевле.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"limit":{"default":10,"description":"Сколько последних сборок вернуть. По умолчанию 10.","title":"Limit","type":"integer"}},"required":["project"],"title":"list_deploysArguments"}},{"name":"list_domains","description":"The project's own domains and their state.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"}},"required":["project"],"title":"list_domainsArguments"}},{"name":"list_environments","description":"The project's environments — one per branch (or the single `cli` one),\n    each with its address and the state of its latest build.\n\n    Answers «где превью моей ветки» and «что сейчас на проде». There is no\n    separate environments endpoint on the platform: branches and deploys are\n    read and joined here, the same way the CLI does.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"}},"required":["project"],"title":"list_environmentsArguments"}},{"name":"list_sources","description":"Which git providers Layero supports and which of them the organization\n    has connected (GitHub App installations and provider tokens).\n\n    Call before `import_repo` when you are not sure the provider is\n    connected. Connecting a provider token is done by the person in the\n    dashboard — never ask them to paste the token into the chat.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"organization":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Слаг организации. Без него — единственная организация аккаунта или личная; если их несколько и личной нет, инструмент перечислит слаги.","title":"Organization"}},"title":"list_sourcesArguments"}},{"name":"my_projects","description":"The user's sites on Layero.\n\n    Thirty most recent by default. The full list is rarely needed, while\n    flooding half your context with it is easy: an active user has dozens\n    of projects.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"limit":{"default":30,"description":"Сколько последних проектов вернуть. По умолчанию 30 — этого хватает почти всегда; поднимай, только если пользователь ищет старый сайт и в списке его нет.","title":"Limit","type":"integer"}},"title":"my_projectsArguments"}},{"name":"project_create","description":"Create an empty project with no repository — an address reserved for a\n    later `publish_site` or `npx layero@latest deploy`.\n\n    For a project FROM a repository use `import_repo` instead. Nothing is\n    built or served yet: the address answers only after the first publish.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"name":{"description":"Имя проекта; из него выводится слаг — часть адреса `<слаг>.layero.app`.","title":"Name","type":"string"},"organization":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Слаг организации. Без него — единственная организация аккаунта или личная; если их несколько и личной нет, инструмент перечислит слаги.","title":"Organization"}},"required":["name"],"title":"project_createArguments"}},{"name":"publish_landing","description":"DEPRECATED — use `publish_site`. Same behaviour, same arguments.\n\n    Kept for one release (removed in the next) so that configs and prompts\n    written before 17.09.2026 keep working; new instructions must call\n    `publish_site`.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"files":{"description":"То же, что у `publish_site`: файлы сайта с `index.html` в корне.","items":{"$ref":"#/$defs/FilePayload"},"title":"Files","type":"array"},"project_name":{"description":"То же, что у `publish_site`: слаг проекта.","title":"Project Name","type":"string"},"project":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"То же, что у `publish_site`: id существующего проекта.","title":"Project"}},"required":["files","project_name"],"$defs":{"FilePayload":{"properties":{"path":{"title":"Path","type":"string"},"content":{"title":"Content","type":"string"},"encoding":{"default":"text","description":"Use `base64` for binary files — images, fonts, favicons. Text files (html/css/js/svg) stay `text`. A binary sent as text is silently corrupted.","enum":["text","base64"],"title":"Encoding","type":"string"}},"required":["path","content"],"title":"FilePayload","type":"object"}},"title":"publish_landingArguments"}},{"name":"publish_site","description":"Publish a static site to Layero — from here, with no terminal.\n\n    Takes ANY ready static bundle, so it is the answer to \"deploy my site\" when\n    the project has no connected repository. Requirements — `index.html` at\n    the root, at most 200 files, 8 MB in total, 2 MB per file. Binary files\n    (images, fonts) must come with `encoding=\"base64\"`; sent as text they are\n    silently corrupted.\n\n    Do NOT use it for a project with a connected repository (`site_status`\n    shows one): the next git push would overwrite what you published.\n\n    Publishing without a Layero account is not possible from here — the\n    server requires sign-in. For that case there is the CLI:\n    `npx layero@latest deploy --claim` deploys first and lets the person\n    claim the site later. An empty project for a future publish is created\n    with `project_create`.\n\n    A project that still needs a build step (Vite, Next, Astro — anything\n    where the answer is `npm run build`) does NOT go here: publish its build\n    output, or tell the user to run `npx layero@latest deploy`, which builds\n    on our side.\n\n    Send the ACTUAL file contents: the server does not remember the bundle\n    between calls. If the user edited the text after generation, pass the\n    current versions, or what gets published is what used to be there.\n\n    Pass `project` (the id of an existing project) when republishing the\n    same site; without it the platform finds a project with that name or\n    creates a new one.\n\n    Returns as soon as the build finishes, or after ~40s with `status`\n    `building` and the `deploy_id` — the build keeps going on its own. Never\n    call this tool a second time to \"retry\" a build that is still running:\n    that starts a SECOND build. Follow `next_action`.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"files":{"description":"Файлы сайта целиком, с `index.html` в корне. Пути относительные (`assets/app.css`). Двоичные файлы — с `encoding=\"base64\"`. Не более 200 файлов, 8 МБ всего, 2 МБ на файл.","items":{"$ref":"#/$defs/FilePayload"},"title":"Files","type":"array"},"project_name":{"description":"Слаг проекта — строчные латинские буквы, цифры и дефис. Он станет частью адреса сайта. Если проект уже существует, передавай ещё и `project`, иначе платформа заведёт новый.","title":"Project Name","type":"string"},"project":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"id существующего проекта — для повторной публикации того же сайта. Без него платформа ищет проект по имени или создаёт новый.","title":"Project"}},"required":["files","project_name"],"$defs":{"FilePayload":{"properties":{"path":{"title":"Path","type":"string"},"content":{"title":"Content","type":"string"},"encoding":{"default":"text","description":"Use `base64` for binary files — images, fonts, favicons. Text files (html/css/js/svg) stay `text`. A binary sent as text is silently corrupted.","enum":["text","base64"],"title":"Encoding","type":"string"}},"required":["path","content"],"title":"FilePayload","type":"object"}},"title":"publish_siteArguments"}},{"name":"read_site","description":"Что на самом деле опубликовано: заголовки, тексты, формы, мета, ссылки.\n\n    Зови это ПЕРЕД тем, как что-то править на живом сайте, и ПОСЛЕ публикации,\n    чтобы убедиться, что приехало ожидаемое. Без этого правка идёт вслепую: то,\n    что лежит на диске у пользователя, и то, что отдаётся посетителю, —\n    разные вещи, и расходятся они молча.\n\n    Возвращается СТРУКТУРА, а не сырой HTML: страница с инлайн-стилями съела бы\n    половину твоего контекста, а нужны из неё заголовки, тексты, формы и мета.\n    Если нужен исходник целиком — он у пользователя на диске.\n\n    `served_fallback=true` означает, что по этому пути отдали содержимое\n    главной: страницы с таким адресом нет, а бакет ответил на отсутствующий\n    ключ своим `index.html` с кодом 200. Не принимай это за успех.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"path":{"default":"/","description":"Путь страницы от корня: `/`, `/about`, `/blog/post`. Не файл — для файлов инструмент откажет.","title":"Path","type":"string"}},"required":["project"],"title":"read_siteArguments"}},{"name":"refactor_site","description":"Одно названное преобразование разметки — с предсказуемым результатом.\n\n    Инструмент НИЧЕГО НЕ ПУБЛИКУЕТ. Он возвращает изменённый HTML; показать\n    его человеку, получить согласие и позвать `publish_site` — твоя работа.\n    Молча переписывать чужой сайт нельзя.\n\n    Преобразования идемпотентны: повторный вызов ничего не меняет и честно\n    отвечает `changed=false`. Пустой список изменений — не ошибка, а ответ\n    «применять было нечего».\n\n    ⚠️ ЧЕГО ЗДЕСЬ НЕТ И ПОЧЕМУ. Шрифты со сторонних хостов, перекодировка\n    картинок в webp и разбор инлайн-стилей сюда НЕ входят: для них нужны сами\n    файлы, которых у сервера нет, либо суждение о задуманном внешнем виде.\n    Эти проблемы называет `site_issues` — с адресом и объяснением; правит их\n    тот, у кого файлы на руках.\n\n    Выигрыш меряется `check_performance` ДО и ПОСЛЕ публикации. Если разница\n    меньше трёх баллов — это шум измерения, а не улучшение; так и скажи.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"html":{"description":"Содержимое `index.html` — то, что лежит у пользователя на диске. Прочитай файл сам и передай сюда.","title":"Html","type":"string"},"fix":{"description":"`meta` — заполнить lang и OG-разметку из того, что на странице уже написано. `lazy_images` — отложить загрузку картинок ниже первого экрана (первую не трогает: по ней меряется LCP).","enum":["meta","lazy_images"],"title":"Fix","type":"string"}},"required":["html","fix"],"title":"refactor_siteArguments"}},{"name":"retry_deploy","description":"Поставить упавшую сборку в очередь заново.\n\n    Разрешено ТОЛЬКО для сборок в состоянии `failed`. На идущей сборке\n    (`queued`, `building`) платформа откажет — это не ошибка, а защита от\n    второй параллельной сборки.\n\n    ⚠️ Повтор осмыслен, когда причина отказа была внешней (сеть, реестр,\n    таймаут). Если сборка упала на коде, повтор даст тот же результат: сначала\n    `diagnose_deploy`, потом правка, и только потом повтор.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"deploy":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"id сборки. Без него берётся самая свежая.","title":"Deploy"}},"required":["project"],"title":"retry_deployArguments"}},{"name":"rollback","description":"Вернуть на живой адрес предыдущую рабочую сборку.\n\n    МЕНЯЕТ ТО, ЧТО ВИДЯТ ПОСЕТИТЕЛИ, — спроси человека перед вызовом, если он\n    не попросил откат прямо. Действие обратимо (можно откатиться обратно), но\n    промежуток времени с чужой версией на адресе вернуть нельзя.\n\n    ⚠️ Для приложений (`ssr_next`, `streamlit`, `gradio`, `flask`) откат\n    работает не так, как для статики, и часто невозможен: у приложения нет\n    готового артефакта, который просто переключить. Если платформа откажет —\n    объясни это человеку прямо и предложи собрать заново, а не повторяй вызов.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"deploy":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"id сборки, на которую откатываем. Без него платформа берёт ближайшую пригодную из предыдущих.","title":"Deploy"}},"required":["project"],"title":"rollbackArguments"}},{"name":"search_docs","description":"Search docs.layero.ru — no token needed.\n\n    Use it before guessing how the platform works: build settings and\n    `layero.json`, environments and preview URLs, custom domains, env vars,\n    runtime apps, Data API, CLI flags and JSON events. Returns the page\n    title, a direct URL (with anchor) and a snippet; open the URL with your\n    own fetch tool when the snippet is not enough.\n\n    The index is the site's own search index, refreshed hourly.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"query":{"description":"Что ищем, словами: «переменные окружения», «layero.json node version», «rollback». Русский или английский — как в доках.","title":"Query","type":"string"},"limit":{"default":5,"description":"Сколько результатов вернуть, 1–20.","maximum":20,"minimum":1,"title":"Limit","type":"integer"}},"required":["query"],"title":"search_docsArguments"}},{"name":"site_analytics","description":"Site traffic: totals, direction and top sources.\n\n    The time series is collapsed into a direction and breakdowns are cut to\n    five: ninety chart points are useless in your context, and the\n    conclusion is yours to draw anyway.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"period":{"default":"7d","description":"Окно наблюдения: 7, 30 или 90 дней.","enum":["7d","30d","90d"],"title":"Period","type":"string"}},"required":["project"],"title":"site_analyticsArguments"}},{"name":"site_issues","description":"Конкретные проблемы страницы — каждая с адресом и что с ней делать.\n\n    Это НЕ балл. Балл отдаёт `check_performance`, и по нему нечего чинить:\n    «73 из 100» не говорит, что именно править. Здесь только то, у чего есть\n    адрес и понятное действие: закрытая индексация, ресурсы с зарубежных\n    хостов, растровые картинки без webp, отсутствующие мета и alt, формы без\n    получателя.\n\n    Находки отсортированы по важности. Не вываливай их списком — назови две-три\n    главные и спроси, чинить ли.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"},"path":{"default":"/","description":"Путь страницы от корня. По умолчанию главная.","title":"Path","type":"string"}},"required":["project"],"title":"site_issuesArguments"}},{"name":"site_screenshot","description":"Снимок последней собранной версии сайта — как он выглядит.\n\n    Дополняет `read_site` (что на странице) и `site_issues` (что с ней не так)\n    третьим вопросом: как это смотрится. Полезно перед правкой оформления и\n    после неё.\n\n    ⚠️ Снимок делается при СБОРКЕ, а не сейчас. Если ты только что что-то\n    опубликовал, свежий снимок появится не мгновенно — не выдавай прошлый за\n    результат своей правки.\n\n    Картинка стоит контекста заметно дороже текста. Не зови «на всякий случай»:\n    для «что не так с сайтом» есть `site_issues`, он дешевле и конкретнее.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"}},"required":["project"],"title":"site_screenshotArguments"}},{"name":"site_status","description":"How a site is doing: whether it is being served and how its build ended.\n\n    `project` is an id or a slug. One call instead of three (project,\n    deploys, live check of the address): an agent needs the conclusion, not\n    the raw material to assemble it from.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"project":{"description":"Проект: слаг (`my-site`) или id. Слаг — то, что видно в адресе сайта; если пользователь назвал сайт словами, возьми слаг из `my_projects`.","title":"Project","type":"string"}},"required":["project"],"title":"site_statusArguments"}},{"name":"whoami","description":"Who is connected to Layero and how many projects they have.\n\n    Call this first when you are unsure the token is configured: a clear\n    error here is cheaper than one halfway through a deploy.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{},"title":"whoamiArguments"}}],"scan":{"score":75,"grade":"B","scanned_at":"2026-09-18T04:51:31.950Z","report":{"scannerVersion":"0.1.2","scannedAt":"2026-09-18T04:51:31.877Z","components":{"code":{"score":-1,"max":25,"notes":["remote-only server, no package to scan"]},"reliability":{"score":12,"max":20,"notes":["remote reachable in 6197ms"]},"poisoning":{"score":15,"max":15,"notes":["34 tool descriptions checked"]},"auth":{"score":8,"max":15,"notes":["API key sent as a header"]},"maintenance":{"score":15,"max":15,"notes":["last push 0 days ago"]},"identity":{"score":6,"max":10,"notes":["namespace and repository owner differ","website matches verified namespace"]}},"findings":[],"inputs":{"probes":[{"url":"https://mcp.layero.ru/mcp","reachable":true,"authRequired":false,"latencyMs":6197,"serverInfo":{"name":"layero","version":"2.2.0"}}],"packages":[],"repo":{"found":true,"owner":"LayeroInfra","repo":"layero-agents","archived":false,"pushedAt":"2026-09-18T00:20:42Z","stars":0,"openIssues":0,"ownerType":"Organization","ownerCreatedAt":"2026-05-02T12:06:38Z","license":"MIT"}}}},"grade_history":[{"kind":"downgrade","fromGrade":"A","toGrade":"B","reason":"score 75","createdAt":"2026-09-18T04:51:39.192Z"}]}