Перейти к содержимому

Решения

Разработчикам

Ваш код ведёт настоящие профили: у каждого свой отпечаток, свои куки, своё хранилище и свой прокси. Локальный сервер на петле открывает профиль и отдаёт точку отладки, принадлежащую только ему, поэтому Puppeteer или Playwright подключаются как к обычному Chromium.
127.0.0.1:50325
Адрес локального API по умолчанию
26
Разных ходов у локального API
10
Инструментов у сервера MCP
8
Прав у ключа API
13
Событий для подписки

Код ведёт настоящий профиль

Сценарий, открывающий чистый Chromium, начинается с той машины, где он работает: её экран, её шрифты, её строка видеокарты, её часы.

Профиль ARMANOS несёт устройство с собой, на одном из пяти шаблонов, и значения подставляются внутри движка, а не рисуются поверх страницы.

Отдельный каталог данных разделяет куки и этого не умеет.

Как это решают сегодня

Обычные ответы это окно инкогнито, расширение подмены отпечатка или виртуальная машина на аккаунт.

Каждый останавливается в своём месте, а тот, что не останавливается нигде, стоит ноутбука памяти на личность.

Что нужноОкно инкогнитоРасширение подменыВиртуальная машинаПрофиль ARMANOS
Куки и хранилище врозь у каждого аккаунта––ДаДа
Отпечаток меняется ниже страничного JavaScript––ДаДа
Свой прокси, а не общий на машину–на весь браузерДаДа
Десять аккаунтов разом на ноутбуке––сколько хватит памятиДа
Код подключается ровно к одному из них––ДаДа
Открывается примерно за секундуДаДа–Да

Локальный API отвечает программам

Включите переключатель «Включить локальный API» в разделе «Для программистов» в левом столбце. Сервер слушает петлю и больше ничего, а до вашего включения он выключен.

При первом запуске программа кладёт рядом со своими данными токен доступа из 24 случайных байтов, читаемый только вашей учётной записью.

Петля сама по себе не граница: страницы, которые открывает человек, работают на этой же машине. Запрос с заголовком Origin, с чужим Host или с Sec-Fetch-Site не равным none получает 403.

Эта проверка идёт раньше хода состояния, который называет продукт и его точную версию.

ХодМетодЧто делает
/statusGETТокен не нужен. Готовность и версия программы.
/api/v1/profile/listGET, POSTВсе профили или страница по отбору и порядку: задача, группа, шаблон, прокси, заметка и состояние.
/api/v1/browser/listGETТе же профили, каждый со своим нынешним состоянием.
/api/v1/profile/quickPOSTЗаводит одноразовый профиль и открывает его; после закрытия он удаляется.
/api/v1/browser/startPOSTОткрывает профиль, возвращает его точку отладки.
/api/v1/browser/stopPOSTЗакрывает все окна профиля.
/api/v1/browser/activeGETНомера профилей, открытых прямо сейчас.
/api/v1/profile/createPOSTЗаводит профиль через проверку нормы; без presetId его заполняет заготовка по умолчанию, presetId none без неё.
/api/v1/profile/updatePOSTМеняет только присланные поля.
/api/v1/profile/deletePOSTПереносит профиль в корзину.
/api/v1/profile/codeGETТекущий код второго фактора этого профиля.
/api/v1/profile/unlockPOSTОткрывает закрытый паролем профиль на один запуск или до закрытия ARMANOS.
/api/v1/profile/lockPOSTСразу закрывает профиль с паролем снова.
/api/v1/profile/passwordPOSTСтавит или меняет пароль профиля.
/api/v1/profile/password/removePOSTСнимает пароль, если назван нынешний.
/api/v1/profile/cookiesGETКуки одного профиля, в JSON или в тексте Netscape.
/api/v1/profile/cookies/exportPOSTКуки до 100 профилей с ответом по каждому.
/api/v1/profile/cookies/importPOSTЗагружает куки в профиль, открытый или закрытый.
/api/v1/profile/exportPOSTНастройки прямо в ответе или полные архивы с сессией, до 100 профилей.
/api/v1/profile/importPOSTВозвращает профили из настроек или архивов с ответом по каждому.
/api/v1/proxy/listGETСохранённая библиотека прокси, без паролей.
/api/v1/preset/listGETЗаготовки этого компьютера, для presetId в profile/create.
/api/v1/flow/listGETЗдешние сценарии и число шагов у каждого.
/api/v1/flow/runPOSTЗапускает сценарий по названным профилям.
/api/v1/app/stateGETВошла ли программа и кем, движок, открытые профили и видеокарта.
/api/v1/app/loginPOSTВходит в аккаунт кодом из кабинета, почтой с паролем или ключом аккаунта.

У каждого профиля своя точка

Запуск идёт той же дорогой, что и кнопка в окне, а режим без окна просится на один прогон, не трогая галочку профиля «Запускать без окна (для автоматизации)».

На ARMANOS Browser в ответ приходит точка отладки, принадлежащая только этому профилю. Chromium берёт свободный порт на петле и записывает его в каталог профиля, а программа отдаёт вам этот адрес, если успела прочитать его за 4,5 секунды.

Открытый порт отладки обычно ставит navigator.webdriver в true, а это объявляет автоматизацию первой строкой большинства проверок. У вас значение остаётся ложным, и убедиться в этом можно на живой странице в самом движке.

На встроенном движке Electron порт отладки один на всю программу, поэтому ws приходит пустым.

  1. 1

    Включите локальный API

    Раздел «Для программистов» в левом столбце, переключатель «Включить локальный API». «Токен доступа» лежит на том же экране.

  2. 2

    Попросите профиль

    Запрос запуска с номером профиля и токеном.

  3. 3

    Возьмите адрес ws

    Порт и путь именно этого профиля и никакого другого, когда движок записал их за 4,5 секунды.

  4. 4

    Подключитесь и работайте

    Отпечаток, куки, расширения и прокси уже на месте.

Экран «Для программистов» в программе ARMANOS: переключатель «Включить локальный API» в положении «Запущен», «Адрес API» и «Токен доступа» с кнопками копирования, список ходов, справа сервер MCP.
Адрес API, токен доступа и настройка MCP на одном экране, с кнопками копирования.

Два вызова и одна оговорка

Попросите локальный API открыть профиль, возьмите из ответа адрес ws и отдайте его puppeteer.connect или Playwright через connect_over_cdp.

Оба клиента включают домены Runtime и Page при подключении, и Chromium ставит перехваты, которые страничный сценарий умеет заметить. Это свойство клиента, а не ARMANOS Browser.

Наш собственный исполнитель не включает домен Runtime. На время прогона он включает домен Page на вкладках прогона, чтобы ответить на alert или confirm страницы, и домен Network с первого шага ожидания запроса, а готовность опрашивается через document.readyState.

На экране «Сценарии» внутри программы девятнадцать видов шага, а повтор, ветвление и обход списка вкладываются до четырёх уровней. Переходы разрешены только по http, https и about:blank, и это проверяется при сохранении и при запуске.

Два клиента в хранилище

В хранилище лежат клиент на Node и клиент на Python, причём питоновский обходится одной стандартной библиотекой.

Они оборачивают серверный API и не добавляют своей логики, потому что клиент, знающий больше сервера, за месяц начинает врать.

В каждой ошибке лежат состояние HTTP и типовой код, поэтому обрыв связи и отвергнутый ключ различаются. Оба клиента проверяют подпись доставки и отвергают всё старше 300 секунд.

profiles.list() / profiles_list()
GET /profiles
profiles.search() / profiles_search()
POST /profiles/search
profiles.create() / profile_create()
POST /profiles
profiles.start() / profile_start()
POST /profiles/{id}/start
proxies.update() / proxy_update()
PATCH /proxies/{id}
logs.suspicion() / logs_suspicion()
GET /logs/suspicion
verifyWebhook() / verify_webhook()
HMAC-SHA256 по «время.тело»

Каждый путь, который зовут клиенты, сверяется с порождённым описанием, поэтому переименованный ход ломает сборку.

Десять инструментов по MCP

Сервер MCP это один файл на Node без зависимостей, и запускает его ваш клиент, а не программа. Он говорит по JSON-RPC 2.0 через stdin и stdout, а две переменные среды указывают ему на локальный API.

Инструментов десять, и каждый отображён на один ход, который у локального API есть на самом деле.

  • get_status

    Отвечает ли локальный API и версия программы.

  • list_profiles

    Все профили или страница по отбору, без заметок.

  • get_active_profiles

    Номера открытых прямо сейчас.

  • launch_profile

    Открывает профиль, отдаёт порт отладки.

  • stop_profile

    Закрывает все окна профиля.

  • create_profile

    Заводит профиль с группой и прокси.

  • update_profile

    Меняет только присланные поля, в том числе ручные значения отпечатка, вход сайта и ключ 2FA, без заметок в ответе.

  • delete_profile

    Переносит профиль в корзину.

  • get_one_time_code

    Текущий код второго фактора.

  • list_proxies

    Библиотека прокси, без паролей.

Ключи API и их права

Ключ это дверь в учётную запись без пароля, поэтому тайную часть показывают один раз, а сервер держит только её свёртку и десять первых знаков.

Права проверяются на каждом ходе, и по умолчанию закрыто всё. Ход, не объявивший права, ключу недоступен вовсе, а открытых ключам ходов сегодня 18.

Ключи живут на платных тарифах, и тариф читается при каждом запросе. Подписки идут в обратную сторону, и заводит их только человек, вошедший с паролем.

ПравоЧто можно ключом с этим правом
profiles:readСмотреть профили с задачей, группой и шаблоном и искать среди них.
profiles:writeЗаводить, править и удалять профили.
browser:runЗанимать и отпускать профиль, записывать открытия и закрытия.
proxies:readСмотреть библиотеку прокси. Пароли лежат за ходом, куда ключу дороги нет.
proxies:writeДобавлять, править и удалять прокси в библиотеке.
flows:readСмотреть библиотеку сценариев. Менять её может менеджер.
logs:readЧитать журналы, входы и правила подозрительного.
app:signinВходить в программу ARMANOS на сервере устройством, которое занимает место. По умолчанию не выдаётся.

Тринадцать событий на ваш сервер

Тринадцать событий покрывают жизнь профиля, общую библиотеку прокси, ключи, команду и тариф.

В каждой доставке лежат событие, время и подпись по времени, точке и ровно тому телу, которое вы получили. Поля, похожие на код, ключ, тайну, пароль или свёртку, наружу не уходят.

Отправка устроена осторожно: десять секунд на попытку, три попытки, без перенаправлений, повтор только на 5xx и 429. Пятнадцать отказов подряд выключают подписку с записанной причиной.

Пределы и описание сервера

Один предел накрывает весь серверный API: 300 запросов за 60 секунд, а вход и работа с паролем стянуты до тридцати в минуту.

Предела по тарифу нет. Тариф решает, сколько у вас профилей, машин и мест, а не с какой скоростью вам звонить.

Описание сервера собрано из тех же ходов, что и отвечают на запросы, поэтому пообещать несуществующий ход оно не может. Права у каждого хода в нём те же, что сервер и требует.

Все ходы сервера
300 запросов / 60 секунд
Вход и работа с паролем
30 в минуту, два хода по 10 и 3
Письма в поддержку
8 за 10 минут
Локальный API на машине
без предела, тело до миллиона знаков, у загрузки куки, одноразового профиля и ввоза профилей до 16 МБ
Размер ответа MCP
5 МБ, дальше понятный отказ
Ключей API на запись
20 действующих
Подписок на события
10 на запись
Сценариев на одной машине
200, до 500 шагов в списке

Каждое число здесь снято с кода, который его и применяет, а файлы названы ниже.

Чего это не делает

  • Облака, которое откроет браузер за вас, нет. Профили работают на вашей машине, через программу. Серверный API заводит, правит, отдаёт и занимает профили, но не запускает ни одного.
  • Ключи API это платная возможность. На тарифе Free сервер откажется его выписать, а ключ с кончившимся тарифом получит 402, а не молчание.
  • Оба клиента имеют версию 0.2.0 и лежат в хранилище. Ни один пока не выложен в npm или PyPI, поэтому сегодня файл копируется к вам в проект.
  • Мы не можем помешать внешнему Puppeteer или Playwright включить домены Runtime и Page при подключении. Если площадка, с которой вы работаете, это ищет, собирайте последовательность внутри программы.
  • Пределов по тарифу нет. Один предел в 300 запросов в минуту действует на всех, поэтому темп большого хозяйства ваша забота.
  • Ключ не заводит подписки, не меняет библиотеку сценариев и не читает пароль прокси: эти ходы не объявляют права. Их проходит вход человека или программы, а программа, вошедшая ключом с правом app:signin, подписок, ключей, команды и оплаты не трогает.

Как проверить

За каждым утверждением выше стоит файл, который можно открыть, а за большинством ещё и стенд, исполняющий настоящий код.

Локальный API отвечает программам и отказывает страницам
apps/desktop/src/lib/local-api.js · apps/desktop/test/local-api-gate.js
Открытый порт отладки не ставит navigator.webdriver
apps/desktop/src/lib/forkEngine.js · apps/desktop/test/webdriver-flag.js, который на машине с установленным ARMANOS Browser поднимает настоящий движок и читает значение с настоящей страницы
Наш исполнитель не включает домен Runtime
apps/desktop/src/lib/cdp.js · apps/desktop/test/области-отладки.js
Сервер MCP это один файл без зависимостей, и путь к нему переживает перезапуск
apps/desktop/src/mcp/armanos-mcp-server.js · apps/desktop/test/путь-mcp-переживает-перезапуск.js
Ключи хранятся свёрткой, ограничены правами и не выдаются на бесплатном тарифе
apps/server/src/api-keys/api-keys.service.ts · apps/server/src/auth/api-key.guard.ts · apps/server/test/ключ-хранится-отпечатком.js · apps/server/test/ключи-платные.js
Описание сходится с работающим сервером, и оба клиента ходят по нему
packages/sdk-js/index.js · packages/sdk-python/armanos.py · apps/server/src/openapi/openapi.ts · apps/server/test/sdk-and-openapi.js
Доставки подписаны, повторяются и видны, когда не дошли
apps/server/src/webhooks/webhook-dispatch.service.ts · apps/server/test/webhooks.js
Пределы на этой странице те же, что применяет код
apps/server/src/app.module.ts · apps/desktop/src/lib/local-api.js · apps/desktop/src/lib/rpa.js
Поиск профилей на сервере видит только то, что открыто по правам, и оба клиента передают его доводы
apps/server/test/api-список-профилей.js
Программа, вошедшая ключом с правом app:signin, не выпускает ключей, не трогает подписки, команду и оплату и не читает журналы аккаунта; решение о таком входе записано у всех ходов сервера
apps/server/src/auth/вход-ключом-перепись.ts · apps/server/test/вход-ключом-устройства.js · apps/server/test/вход-ключом-перепись.js

Вопросы

Как передавать токен?
Как параметр token в адресе, как заголовок x-api-token или как Authorization: Bearer. Новый токен после «Обновить токен» действует сразу, перезапуск не нужен.
Чем отличаются отказы по ключу?
401 у ключа неверного или закрытого, 402 у настоящего ключа с кончившимся тарифом, 403 у настоящего ключа без нужного права.
Какой машиной представляется клиент?
Как sdk@имя-машины, пока вы не сказали иначе. Занятость профиля и счёт машин на тарифе одинаково требуют, чтобы машины отличались.
Почему запуск через MCP бывает долгим?
Инструмент ждёт до девяноста секунд, потому что движок открывает порт отладки в своём темпе, а более короткое ожидание отвечает раньше, чем поднимется окно.
Может ли страница позвать локальный API?
Нет. Запрос с заголовком Origin или с чужим Host получает 403, и домен, перенаправленный на петлю, это ровно то, ради чего проверка и стоит.
Живёт ли точка отладки после закрытия?
Нет. Она существует, только пока профиль открыт, а следующий запуск отдаст новую.

Начните собирать уже сегодня

Программа бесплатна на двух профилях, а локальный API входит в любой тариф, включая этот.