Давайте будем честны: сегодня способы дать ИИ-агенту поработать в браузере выглядят так.

Playwright или Selenium: браузер, который агент запускает сам, со свежим профилем. Ни одной сессии, и на первом же шаге — стена логина, 2FA или капча. Настроить remote-debugging и подключиться к живому Chrome: работает, но требует запуска с флагом и убивает нормальную сессию. MCP-браузерные серверы: JSON-конфиги, совместимость клиента, и часто всё равно скриншоты.

Вендорские решения тоже появились — и все решают задачу внутри своей экосистемы. Расширение Anthropic водит вашим Chrome только из Claude: подписка, логин в claude.ai, сессия гоняется через облако, модель одна — Claude. Расширение OpenAI управляется десктоп-приложением, и в Codex CLI браузер по документации самого OpenAI недоступен. Встроенный браузер VS Code Copilot — отдельная среда со своим профилем, не ваш повседневный Chrome. Десктоп-агенты с computer use работают в своей песочнице со своими логинами. Каждый отвечает на вопрос «как дать моему агенту браузер», и никто — на вопрос «как дать агенту мой браузер».

При этом у каждого из нас уже есть идеально настроенный, залогиненный во всё браузер. Свой. И агент до него не дотягивается — по одной причине: никто не провёл нейтральный мост между расширением и терминалом.

Я этот мост провёл. Проект называется chrome-bridge: крошечное расширение для Chrome плюс CLI на Node без единой npm-зависимости. Агент получает ваш настоящий браузер — открытые вкладки, залогиненные сессии, SSO. Open source, MIT.

Как это устроено

Архитектура укладывается в одну строку: расширение (один читаемый background.js) — WebSocket — локальный Node-сервер — CLI. Никакого облака и никаких аккаунтов: код и данные не покидают машину.

Клиент у CLI — обычный shell, поэтому работает любой агент, который умеет запускать команды: Claude Code, Cursor, Codex, GLM, Kimi, Qwen, DeepSeek, локальные модели. MCP не нужен, SDK не нужен, версия модели не важна.

node cli.mjs snap habr.com          # страница как accessibility-дерево
node cli.mjs click habr.com @e14    # клик по элементу из дерева
node cli.mjs fill habr.com @e12 "chrome extension"
node cli.mjs shot habr.com out.png --max 800   # когда всё-таки нужны пиксели

Дерево выглядит так — весь текст страницы со ссылками на элементы:

table "Hacker News new | past | comments | ask | show | jobs | submit" @e1
  link "Hacker News" @e5
  link "new" @e6
  link "submit" @e12
  link "login" @e13

Ссылки @eN — это и есть главная экономия. Замер на живой странице: дерево целиком — 2,4 КБ, скриншот той же страницы шириной 1000px — 16 КБ. На порядок меньше контекста на каждый шаг, и агент не «угадывает координаты по картинке», а кликает по ссылке из дерева. Ссылки переживают повторные снимки и истекают только при навигации — после перехода агент делает новый snap.

События, доверие и вердикты

Синтетические события не имеют флага isTrusted, и часть приложений их честно игнорирует. Для этого есть режим --trusted: клик идёт через DevTools Input с isTrusted=true. Плата очевидна: команды через CDP (net, shot, --trusted) монтируют отладчик, и страница это видит. Никакого «стелса» в проекте специально нет — это инструмент для своих аккаунтов на своей машине, и в README это написано прямым текстом.

Вторая обязательная часть инженерии — вердикты. После действия агент получает не тишину, а диагноз: succeeded, needs_human (стена логина — зовём человека), blocked (rate limit) или uncertain (событие ушло, ничего не изменилось — проверь иначе). На Excalidraw это выглядело честно: клик в канвас вернул uncertain, скриншот подтвердил, что ничего не произошло, а --trusted с двойным кликом прошёл и создал текстовый элемент, который потом появился прямо в дереве.

Память команд и реплей

Сервер держит кольцевой журнал: каждая команда попадает в него в момент выполнения со статусом ok/fail. history --batch out экспортирует журнал как реплейбельный скрипт: упавшая строка закомментирована с текстом ошибки, секретные значения (fill/type/paste) вырезаны. Полуупавший батч можно дописать с места падения — с одной честной оговоркой: реплей не идемпотентен, уже сделанный клик сделается ещё раз, хвост скрипта допиливается руками.

Ограничения

  • Сервер слушает 127.0.0.1 и не отвечает запросам со страниц, но любой локальный процесс может им воспользоваться. Инструмент — для машины, которой вы доверяете.

  • Canvas-приложения деревом почти не видны; там агент чаще работает скриншотами.

  • CDP-команды детектируются антибот-системами; «стелс»-стек в проект сознательно не включён.

  • Расширение просит <all_urls> и debugger — это цена функциональности. Код при этом читается целиком: один background.js и манифест, без сборки.

Итог

chrome-bridge — это попытка решить одну конкретную проблему: агент весь день сидит в терминале рядом с моим залогиненным браузером и не может в него зайти. Теперь может: дерево вместо скриншотов, клики по ссылкам вместо координат, фиолетовая плашка с историей каждого действия и кнопка ⏏, которая одним нажатием возвращает мне контроль.

GitHub: https://github.com/siropkin/chrome-bridge Chrome Web Store: https://chromewebstore.google.com/detail/chrome-bridge/kmhjlnokjigmnimgjjmiahlinjbcebkg

Если инструмент пригодится — расскажите в комментариях, что вы им автоматизируете. Issue и рецепты принимаются.