arena-bridge
Облачный ИИ-агент получает управление вашим компьютером — и только с вашего разрешения.
npm i -g arena-bridge → arena-bridge setup → вставьте готовый промпт в чат с агентом
Что это
Облачный агент (Arena.ai Agent Mode, Claude, Cursor, любой MCP-клиент) работает в песочнице
с выходом в интернет, но не имеет доступа к вашему компьютеру. arena-bridge — это маленький
HTTP-сервис на вашей машине: он слушает только localhost, выставляется наружу туннелем
(cloudflared / ngrok / Tailscale) и отдаёт агенту инструменты, которые вы ему разрешили:
- файлы и шелл — прочитать, найти, изменить, запустить;
- Chrome — свой браузер агента (headless или с окном) или ваш настоящий Chrome на порту 9222;
- macOS-десктоп — скриншоты, мышь, клавиатура, приложения (через Peekaboo);
- процессы — фоновые дев-серверы с чтением вывода.
Всё, что меняет состояние, проходит через гейт подтверждений, а каждое действие пишется в журнал.
Без вашего arena-bridge approve агент ничего не сделает. Наблюдать за машиной можно без
подтверждений, а работать «без вопросов» — внутри окна доверия, которое вы открываете сами.
Быстрый старт
# 1. установить
npm i -g arena-bridge
# 2. один раз: создать конфиг, проверить машину, поднять API + туннель
arena-bridge setup --root ~/projects --root ~/Documents
# 3. скопировать блок «Paste this into the agent chat» и вставить его в чат с агентом
setup печатает готовый промпт и публичный URL. Дальше — просто говорите агенту задачу.
Туннель под присмотром: если cloudflared/ngrok упадёт, мост поднимет его заново и сам
напечатает новый публичный адрес. Постоянный адрес вместо случайного — arena-bridge tunnel --bin ngrok --domain <зарезервированный домен>.
Нужен туннель? Поставьте cloudflared (brew install cloudflared или бинарник в /usr/local/bin).
Можно и через ngrok — arena-bridge tunnel --bin ngrok; с сохранённым токеном и зарезервированным
доменом публичный адрес остаётся постоянным, и промпт агенту не нужно копировать заново:
arena-bridge tunnel --bin ngrok --authtoken <token> --domain <name>.ngrok-free.dev.
В фоне, чтобы не открывать терминал
Мост можно поднять как службу macOS — он стартует вместе с системой, переживает закрытие терминала и поднимается заново после сбоя:
arena-bridge service install # облако, случайный адрес
arena-bridge service install --bin ngrok --domain mymac.ngrok-free.app # постоянный адрес
arena-bridge service status # состояние и текущий URL
arena-bridge url # текущий публичный адрес
arena-bridge service uninstall
arena-bridge service install # launchd: стартует вместе с системой, URL всегда живой
arena-bridge url # текущий публичный URL
Python
pipx install arena-bridge # или: pip install arena-bridge
arena-bridge setup --root ~/projects
Что агент умеет
| Группа | Инструменты | Что это |
|---|---|---|
| Файлы | list_dir read_file write_file edit_file delete_path search_files file_get file_put |
работа с файлами в разрешённых папках |
| Журнал | audit_log audit_artifact |
что делалось, какие снимки и деревья Accessibility сохранены |
| Шелл | bash sysinfo |
команды и сведения о машине |
| Процессы | start_process read_process_output write_process kill_process |
фоновые дев-серверы |
| Chrome | chrome_launch chrome_profiles chrome_attach chrome_open chrome_navigate chrome_snapshot chrome_click chrome_type chrome_press chrome_screenshot chrome_evaluate chrome_tabs chrome_stop |
браузер через CDP |
| Десктоп | mac_see mac_element mac_click mac_set mac_type mac_key mac_scroll mac_move mac_drag mac_menu mac_menu_click mac_wait mac_spaces mac_space_switch mac_apps mac_windows mac_app_launch mac_app_focus mac_app_quit mac_permissions |
macOS через Peekaboo |
| Telegram | notify_user telegram_inbox telegram_status |
сообщения вам и ваши ответы |
Полный каталог с JSON-схемами: GET /tools или arena-bridge tools.
Как выбрать инструмент
| Агент хочет | Инструмент |
|---|---|
| прочитать страницу | chrome_snapshot ({"mode":"ax"} — роли и имена, {"mode":"text"}, {"mode":"html"}) |
| кликнуть на странице | chrome_click (CSS-селектор или видимый текст) |
| работать в вашем залогиненном Chrome | chrome_attach (порт 9222) и те же chrome_* |
| посмотреть на экран или нативное приложение | mac_see (скриншот + id элементов) |
| найти контрол по названию, без скриншота | mac_element (через Accessibility API: имя, роль, значение) |
| заполнить поле, не печатая и не забирая фокус | mac_set (значение пишется напрямую в элемент) |
| открыть пункт меню | mac_menu (список) → mac_menu_click (по названию) |
| дождаться, пока контрол появится | mac_wait |
| кликнуть в нативном приложении | mac_click (id элемента, видимый текст или координаты) |
| напечатать | mac_type, затем mac_key для Enter/Tab/cmd+s |
| посмотреть файлы | list_dir (только верхний уровень; глубже — {"recursive":true}) |
| написать вам или спросить | notify_user (Telegram), ответ читать через telegram_inbox |
Управление Chrome
Свой минимальный CDP-клиент внутри пакета: ни puppeteer, ни playwright не нужны.
// браузер агента: свой профиль, без ваших cookie
{"tool": "chrome_launch", "args": {"headless": true, "url": "https://example.com"}}
// прочитать структуру страницы
{"tool": "chrome_snapshot", "args": {"mode": "ax"}}
// кликнуть и ввести
{"tool": "chrome_click", "args": {"text": "Sign in"}}
{"tool": "chrome_type", "args": {"selector": "input[name=q]", "text": "hello", "submit": true}}
// скриншот
{"tool": "chrome_screenshot", "args": {"path": "shot.png"}}
headless: true— без окна (по умолчанию),headless: false— видимое окно;- профиль отдельный (
~/.arena-bridge/chrome-profile-*), в ваши сессии агент не попадает; - действия в браузере агента подтверждения не требуют — это его песочница.
Ваш настоящий Chrome (с вашими логинами) — через chrome_attach:
open -na "Google Chrome" --args --remote-debugging-port=9222 --user-data-dir="$HOME/.chrome-debug"
{"tool": "chrome_attach", "args": {"port": 9222}}
Любое действие в присоединённом браузере требует локального подтверждения. Инструментов чтения cookies и localStorage нет.
Управление macOS-десктопом
Через Peekaboo (это же использует и MCP-режим Peekaboo):
{"tool": "mac_see", "args": {"app": "Safari", "mode": "window"}} // скриншот + id элементов
{"tool": "mac_element", "args": {"name": "Save"}} // найти кнопку по названию
{"tool": "mac_click", "args": {"on": "B3"}} // клик по id из mac_see
{"tool": "mac_set", "args": {"on": "B2", "value": "hello"}} // вписать значение напрямую
{"tool": "mac_type", "args": {"text": "hello", "submit": true}}
{"tool": "mac_key", "args": {"key": "cmd+s"}}
{"tool": "mac_menu_click", "args": {"app": "Safari", "item": "Save"}} // пункт меню по названию
{"tool": "mac_wait", "args": {"name": "Saved", "timeout": 20}} // дождаться результата
{"tool": "mac_apps", "args": {}} // что запущено
{"tool": "mac_permissions", "args": {}} // чего не хватает в macOS
Установить Peekaboo: brew install peekaboo (или бинарник в /usr/local/bin/peekaboo).
Проверено с Peekaboo 4.9 (4.3 тоже работает, но синтаксис команд обновлён под 4.9).
macOS спросит разрешения Screen Recording и Accessibility для терминала, из которого
запущен мост — без них скриншоты и клики не работают; mac_permissions покажет, что не так.
Что даёт доступ Accessibility
macOS отдаёт приложениям два разных слоя: картинку экрана и Accessibility API — дерево элементов интерфейса с названиями, ролями и значениями. Второй слой полезен агенту сильнее:
| по картинке | через Accessibility API | |
|---|---|---|
| как найти кнопку «Сохранить» | угадать координаты | mac_element {"name":"Сохранить"} → точный элемент |
| как нажать | клик по координате, может промахнуться | mac_click {"on":"<id>"} — по самому элементу |
| как вписать текст | свайп, фокус, клавиатура | mac_set {"on":"<id>","value":"..."} — без фокуса и без клавиш |
| как открыть «Файл → Экспорт» | перемещать курсор по меню | mac_menu_click {"item":"Экспорт"} — по названию |
| как убедиться, что получилось | смотреть скриншот | mac_wait {"name":"Готово"} — ждать появления |
| как заполнить поле | свайп + клавиатура + фокус | mac_set {"on":"<id>","value":"..."} — значение пишется в элемент |
| чужой ввод и фокус | мешает вам | действия уходят в фоновое окно |
Практический вывод: с выданным Accessibility агент работает заметно точнее и тише. Разрешение
даётся один раз в Системные настройки → Конфиденциальность и безопасность → Универсальный
доступ (для терминала, из которого запущен мост). mac_permissions показывает текущее
состояние разрешений.
Журнал работы с артефактами
Каждый вызов записывается: аргументы, результат, время выполнения. Рядом с журналом хранятся доказательства — снимки экрана, деревья Accessibility, деревья меню, список рабочих столов.
arena-bridge audit # последние вызовы
arena-bridge audit artifacts # сохранённые файлы (скриншоты, деревья)
arena-bridge audit <id> # одна запись целиком
arena-bridge audit prune # удалить старые артефакты (по умолчанию старше 14 дней)
arena-bridge audit dir # где всё это лежит
Агенту доступно то же самое: audit_log (вызовы) и audit_artifact (сам артефакт — PNG в base64
или дерево Accessibility в JSON), а также GET /audit и GET /audit/artifact?entry=<id>&file=<name>.
Полезно, чтобы оглянуться назад: что было на экране и что находилось в интерфейсе.
Связь с Telegram
Агент может писать вам в Telegram и читать ваши ответы — даже если вы сейчас не в чате с ним.
# один раз: привязать бота (токен от @BotFather и ваш chat id)
arena-bridge telegram setup --token 123456:AA... --chat-id 190771108
# проверить связь
arena-bridge telegram test
# посмотреть, что вам писали
arena-bridge telegram inbox
Что это даёт:
notify_user— агент пишет вам: «сделал», «нужно ваше решение», «вот результат». С{"wait_for_reply": true}вызов ждёт вашего ответа прямо в Telegram.telegram_inbox— агент читает то, что вы написали боту: ответы, правки, поручения.telegram_status— бот, список чатов, число непрочитанных сообщений.- Подтверждения из Telegram. Когда агенту нужно ваше «да», мост сам пишет вам:
/approve <id>— разрешить,/deny <id>— отказать. Из терминала тоже можно:arena-bridge approve <id>.
Как это устроено и что защищено:
- токен бота лежит только в
~/.arena-bridge/config.json(права0600); агент этот файл прочитать не может — он в списке защищённых путей; - писать можно только в те чаты, что перечислены в
--chat-id(по умолчанию — ваш); - не больше 20 сообщений в минуту, одно сообщение — до 4000 символов;
- входящие сообщения мост слушает сам (служба launchd — автоматически), входящие лежат
в
~/.arena-bridge/telegram/.
Одно уточнение: для бота api_id/api_hash не нужны — они пригодятся только для режима
«личного аккаунта» (MTProto), который пока не включён.
Доверенное окно: работать без подтверждений
arena-bridge trust --for 2h # всё, на 2 часа
arena-bridge trust --for 30m --tools bash # только команды
arena-bridge trust --for 1h --paths ~/projects/my-app # только эта папка
arena-bridge trust --status
arena-bridge trust --off
- окно снимает требование подтверждения, но не снимает политику путей: за пределами
rootsи в защищённых каталогах по-прежнемуPROTECTED; --pathsограничивает доверие конкретными папками;bashпод такое ограничение не попадает — чтобы доверять командам, укажите--tools bashявно;- окно живёт локально (
~/.arena-bridge/trust.json), агент открыть его не может; - после истечения срока подтверждения возвращаются сами, а все действия остаются в журнале.
Отдельные браузерные «кабинеты» агента
Агенту можно выдать несколько независимых профилей браузера — например «рабочий», «клиентский», «тестовый». В каждом свои входы, и они переживают перезапуск моста.
arena-bridge browser open work # открыть Chrome с профилем «work»
# вы логинитесь в нужные сайты и закрываете окно — входы сохраняются
arena-bridge browser list # какие профили есть
arena-bridge browser close work # закрыть окно этого профиля
Агент открывает тот же профиль через chrome_launch {"profile":"work"} — уже с вашими входами.
Каталог профилей агент тоже видит: chrome_profiles.
Ваш собственный Chrome (на порту 9222, с вашими сессиями) доступен отдельно — через
chrome_attach; любые действия в нём требуют подтверждения.
Как это не мешает вам
| Что беспокоит | Как решается |
|---|---|
| окно агента занимает экран | по умолчанию агент работает в фоне; видимое окно можно сделать маленьким и в углу: chrome_launch {"headless":false,"width":900,"height":700,"x":-920,"y":40} |
| агент перехватывает фокус и курсор | действия в нативных приложениях идут «в фон» — в нужное окно, без переключения на вас; курсор двигается только по вашей явной просьбе |
| окно агента на вашем рабочем столе | macOS умеет несколько рабочих столов: агент переключается на отдельный стол через mac_space_switch, вы остаётесь на своём |
| нужен отдельный «второй монитор» | в macOS виртуальный монитор штатно не создаётся; сторонние утилиты (BetterDisplay, DisplayLink) умеют — тогда окно агента всегда там, где вы не работаете |
| нужен полностью независимый курсор и стол | только отдельная виртуальная машина; на 16 ГБ и Intel 2019 года она заметно тормозит и съедает 30–60 ГБ — как правило, не нужно |
Рекомендация для ноутбука с 16 ГБ и Intel 2019: отдельные профили браузера + фоновый режим + при необходимости второй рабочий стол macOS. Полноценная виртуальная машина того не стоит.
Безопасность
| Токен | Кто знает | Что позволяет |
|---|---|---|
token |
агент | вызывать инструменты по HTTP/MCP |
deviceToken |
только устройство | подключаться к хабу |
localToken |
только вы | подтверждать запросы и открывать окно доверия |
- Агент не может одобрить сам себя:
POST /approvals/:idтребует локальный токен. - Пути ограничены: всё вне
roots—PROTECTED. Защищённый список по умолчанию включает~/.ssh,~/.aws,~/.arena-bridge,~/.npmrc, профили браузеров, ключи. - Подтверждения:
bash, запись, удаление, управление вашим Chrome и десктопом ждутarena-bridge approve <id>. ОтветAPPROVAL_PENDINGсодержитapproval_id— покажите его пользователю и повторите вызов один раз. - Журнал:
~/.arena-bridge/audit.log(JSONL) — кто, что и когда вызвал. - Транспорт: сервер слушает
127.0.0.1, наружу — только туннель с HTTPS.
arena-bridge rotate # новый агентский токен (действует мгновенно)
arena-bridge rotate --device # новый девайсный токен
arena-bridge audit -n 50 # что происходило
Команды
| Команда | Что делает |
|---|---|
setup |
конфиг + проверка машины + API + туннель + готовый промпт |
init |
создать ~/.arena-bridge/config.json с токенами (--root повторяемый) |
start |
локальный API-сервер |
tunnel |
API + облачный туннель, печатает промпт |
hub / connect |
режим «хаб»: VPS принимает подключения многих машин |
prompt |
готовый промпт для чата с агентом |
tools |
каталог инструментов в JSON |
trust |
окно доверия (--for, --tools, --paths, --off, --status) |
approvals / approve <id> |
ожидающие подтверждения и ответ на них (--deny) |
audit [-n N] |
журнал действий |
doctor |
проверка установки, токенов, путей, Peekaboo, Chrome |
url |
текущий публичный URL |
version |
установленная и последняя версии |
update |
обновить пакет с npm (--check — только проверить) |
service |
macOS-фоновый сервис: install / uninstall / status |
browser |
профили браузера агента: list / open <name> / close <name> |
rotate |
сменить агентский или девайсный токен |
telegram |
связь с Telegram: setup / test / status / inbox / poll |
API и MCP
GET /health liveness (без авторизации)
GET /tools каталог инструментов с JSON-схемами
GET /prompt этот промпт для агента
GET /approvals ожидающие подтверждения
GET /audit журнал работы с артефактами
GET /audit/artifact сохранённый артефакт (entry=, file=)
POST /call {"tool":"bash","args":{...}}
POST /exec {"command":"...","cwd":"...","timeout_sec":120}
GET|PUT|DELETE /files?path=/abs/path
POST /approvals/:id {"decision":"approve"|"deny"} — только по локальному токену
POST /mcp MCP Streamable HTTP (protocolVersion 2025-06-18)
curl -sS -X POST "https://<ваш-url>/call" \
-H "Authorization: Bearer $ARENA_BRIDGE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"tool":"sysinfo","args":{}}'
Разработка
npm install # зависимостей нет — только dev-тесты
npm test # 52 теста Node: direct, approval, trust, MCP, hub, туннель, Chrome, десктоп
npm run test:python # 44 теста Python: то же самое
Тесты не требуют ни Chrome, ни Peekaboo: используются фейковые CDP- и Peekaboo-серверы
(test/fake-cdp.mjs, test/fake-peekaboo.sh).
src/ Node-реализация (zero dependencies)
ws.mjs минимальный WebSocket-клиент
cdp.mjs клиент Chrome DevTools Protocol
browser.mjs 13 инструментов chrome_*
mac.mjs 20 инструментов mac_* (Peekaboo, Accessibility API)
trust.mjs окно доверия
policy.mjs проверка путей (roots / protected)
engine.mjs каталог, гейт подтверждений, аудит
direct.mjs HTTP-сервер
hub.mjs хаб для нескольких машин
cli.mjs команды
arena_bridge/ тот же функционал на Python (stdlib only)
Частые проблемы
| Симптом | Что делать |
|---|---|
port 8787 is already in use |
остановите старый экземпляр (Ctrl+C) или arena-bridge start --port 8788 |
| туннель не поднимается | cloudflared по умолчанию использует QUIC и может быть заблокирован — arena-bridge tunnel --protocol http2 (это поведение по умолчанию) |
| агент не видит файлы | проверьте arena-bridge doctor и roots в ~/.arena-bridge/config.json; вне roots всё равно PROTECTED |
APPROVAL_PENDING |
покажите пользователю arena-bridge approve <id> или откройте arena-bridge trust --for 1h |
| скриншоты не работают | mac_permissions — выдайте терминалу Screen Recording и Accessibility |
peekaboo_not_found |
поставьте Peekaboo или укажите путь: arena-bridge init + peekabooPath в конфиге |
Лицензия
MIT
Metadata
Release files for arena-bridge 0.7.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| arena_bridge-0.7.2.tar.gz | 83.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| arena_bridge-0.7.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 156.0 kB
Release files / arena_bridge-0.7.2.tar.gz
| Download URL | arena_bridge-0.7.2.tar.gz |
|---|---|
| Size | 83.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c8b5eef0ed1cbb93ad2d952a9365cefbe1d5dbe829a41a50750aa74572ebb207
|
|
BLAKE2b-256 checksum How to use checksums |
97b587fced7b0fd9e8a2721f5e60fb0a2aaa6cab1ad551696b6aa709de4b11c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / arena_bridge-0.7.2-py3-none-any.whl
| Download URL | arena_bridge-0.7.2-py3-none-any.whl |
|---|---|
| Size | 72.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
854a6a4d575b2e595d437fe93d933c85e8ac9df1f5e6493db8b9fbddb395b2e4
|
|
BLAKE2b-256 checksum How to use checksums |
91d0553e7804e3b5f63fb2b2bbfc85fd1eecd4d78095b867776cf8926eeb2ef4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|