Skip to main content
Glama
vKongv

Chrome Browser Control

by vKongv

Управление браузером Chrome

Версия npm Node.js Лицензия: MIT

Управление локальным профилем Chrome для MCP-хостов через stdio.

Этот проект предоставляет MCP-инструменты для управления браузером через расширение Chrome Manifest V3, подключённое к брокеру WebSocket с обратной связью (loopback). Настройте ваш MCP-хост на запуск адаптера stdio с тем же токеном пары, который вы вводите в расширении.

Репозиторий: https://github.com/vkongv/chrome-browser-control

Предварительные требования

  • Node.js 18+

  • Google Chrome

Related MCP server: Tabrix

Установка и настройка

Рекомендуемый путь: установите CLI, затем выполните настройку.

npm install -g chrome-browser-control
# or, without a global install:
npx -y chrome-browser-control setup

CLI устанавливается как cbctl (предпочтительное краткое имя) и также как chrome-browser-control.

cbctl setup
cbctl start
cbctl doctor

Команда setup создаёт ~/.chrome-browser-control/config.env (токен пары + порт), копирует распакованное расширение в ~/.chrome-browser-control/extension и выводит фрагменты конфигурации для MCP-хоста. Не добавляйте этот каталог в систему контроля версий.

Навык агента (отдельно от npm)

Навык агента времени выполнения в skills/chrome-browser-control/ не входит в состав npm-пакета. После установки CLI получите навык из этого репозитория (или из skills.sh), если ваш хост агента использует навыки.

Команды CLI (cbctl или chrome-browser-control):

Команда

Назначение

cbctl setup

Создать конфигурацию пользователя и установить копию расширения

cbctl start

Запустить общий брокер loopback

cbctl stop

Остановить брокер

cbctl status

Показать состояние брокера / конфигурации

cbctl doctor

Проверка локальной установки

cbctl mcp

Адаптер MCP через stdio (по умолчанию только подключение)

cbctl mcp-config

Вывести фрагменты MCP для конкретного хоста

cbctl broker

Запустить брокер в фоновом режиме (для разработки)

Из git-копии (для разработчиков):

git clone https://github.com/vkongv/chrome-browser-control.git
cd chrome-browser-control
npm install
npm run build
node dist/cli/main.js setup

Команды npm run broker / npm run mcp из репозитория остаются доступными для разработки с исходниками TypeScript (с опциональным .env.local в репозитории).

Переменные окружения

  • CHROME_BROWSER_CONTROL_TOKEN — Обязательно. Токен пары с высокой энтропией, общий для брокера, MCP-адаптера и всплывающего окна расширения.

  • CHROME_BROWSER_CONTROL_PORT — Порт WebSocket-брокера (по умолчанию 8765).

  • CHROME_BROWSER_CONTROL_HOST — Loopback-адрес для брокера (по умолчанию 127.0.0.1).

  • CHROME_BROWSER_CONTROL_EXTENSION_ID — Опционально. Привязывает брокера к одному установленному ID расширения.

  • CHROME_BROWSER_CONTROL_AUTOLOAD — Опционально. Установите в 1, чтобы mcp мог запустить брокера, если он недоступен (восстановление). Для обычного использования предпочтительнее cbctl start.

  • CHROME_BROWSER_CONTROL_DISABLE_LOCAL_ENV — Опционально. Установите в 1, чтобы пропустить загрузку .env.local из репозитория.

Конфигурация пользователя хранится в ~/.chrome-browser-control/ и загружается до любого .env.local из репозитория. Переменные окружения процесса имеют приоритет.

По умолчанию MCP только подключается: cbctl mcp соединяется с уже работающим брокером. Сначала запустите брокера командой cbctl start. Для восстановления используйте cbctl mcp --autoload или CHROME_BROWSER_CONTROL_AUTOLOAD=1.

Загрузка расширения

  1. Откройте Chrome с тем профилем, которым вы хотите управлять через MCP-инструменты.

  2. Перейдите на chrome://extensions.

  3. Включите режим разработчика.

  4. Нажмите «Загрузить распакованное расширение».

  5. Выберите ~/.chrome-browser-control/extension (путь выводится командой setup). Разработчики, работающие с исходниками, могут загрузить extension/ из репозитория.

  6. Откройте всплывающее окно расширения Chrome Browser Control.

  7. Оставьте адрес моста как ws://127.0.0.1:8765, если вы не изменили локальный порт.

  8. Вставьте сгенерированный токен пары.

  9. Добавьте разрешённые источники, например https://example.com, http://localhost:3000 или * для всех обычных страниц http:// и https://.

  10. Нажмите «Сохранить и переподключиться».

Расширение может запросить разрешение на доступ к хосту для указанных источников. Отказ от этого запроса отключает действия на страницах для этих источников.

Использование * удобно для локальной разработки, но открывает все обычные веб-страницы в текущем профиле Chrome для MCP-инструментов. Предпочитайте явные источники, если вам нужно всего несколько сайтов. Режим «все» также запрашивает необязательное разрешение <all_urls> для хоста, чтобы Chrome позволял делать скриншоты видимой области через chrome.tabs.captureVisibleTab; фоновый скрипт по-прежнему блокирует не-http(s) URL и запрещённые источники перед захватом.

Конфигурация MCP-хоста

Вставьте фрагмент из cbctl setup (или mcp-config) в Cursor, Claude Desktop, Codex или другой MCP-хост с stdio. Чтобы позже снова вывести конфигурацию для конкретного хоста:

cbctl mcp-config --host cursor
cbctl mcp-config --host claude
cbctl mcp-config --host codex
cbctl mcp-config --host yaml

Ключ MCP-сервера — chrome_browser_control. Команда адаптера — устанавливаемый CLI (cbctl предпочтительно) с args: ["mcp"] — не tsx против server/index.ts.

Пример в стиле YAML:

mcp_servers:
  chrome_browser_control:
    command: "cbctl"
    args: ["mcp"]
    env:
      CHROME_BROWSER_CONTROL_TOKEN: "<generated-token>"
      CHROME_BROWSER_CONTROL_PORT: "8765"
    timeout: 60
    connect_timeout: 30

Пример в стиле JSON:

{
  "mcpServers": {
    "chrome_browser_control": {
      "command": "cbctl",
      "args": ["mcp"],
      "env": {
        "CHROME_BROWSER_CONTROL_TOKEN": "<generated-token>",
        "CHROME_BROWSER_CONTROL_PORT": "8765"
      }
    }
  }
}

Если CLI отсутствует в PATH, используйте резервный вариант через NPX, который выводит setup: npx с args: ["-y", "chrome-browser-control", "mcp"].

Если ваш MCP-хост использует файл конфигурации, храните его в тайне и за пределами репозитория.

Проверка

  1. Запустите брокера: cbctl start

  2. Запустите проверку установки: cbctl doctor

  3. Подтвердите из вашего MCP-хоста, вызвав инструмент browser_status. Когда всё готово, extension.status и ping.status должны отражать активное соединение через мост, а extension.allowedOrigins — настроенную область видимости.

Инструменты

  • browser_status: проверяет, может ли MCP-адаптер достичь брокера и отвечает ли расширение Chrome на ping. Когда всё готово, extension.status и ping.status отражают активное соединение через мост (а не устаревшее отключённое значение по умолчанию), extension.allowedOrigins показывает настроенную область видимости (включая * (all http/https web origins) при включённом режиме «все»), extension.session — имя сессии и заявленные вкладки, а protocolVersion / features подтверждают код загруженного распакованного расширения. Версия протокола 6 включает маркер возможности document-targeting.

  • name_session: задаёт удобочитаемое имя сессии для статуса/отладки.

  • list_tabs: перечисляет вкладки, чей источник URL разрешён во всплывающем окне расширения. Если все открытые вкладки отфильтрованы, возвращает { tabs: [], detail, hiddenTabCount, allowedOrigins? } вместо пустого []. Режим «все» явно помечается в allowedOrigins.

  • list_frames: перечисляет текущие документы фреймов для разрешённой вкладки, используя реестр фреймов Chrome. Работоспособные активные HTTP(S) документы содержат documentId; заблокированные политикой, с запрещённым доступом к хосту, неподдерживаемые, фреймы с fenced и неактивные строки сохраняют только иерархию/статус и скрывают URL и идентификатор документа.

  • claim_tab: закрепляет разрешённую вкладку за текущей сессией управления браузером и возвращает sessionTabId. Закрепление — это состояние маршрутизации, а не эксклюзивная блокировка браузера.

  • release_tab: освобождает закрепление по sessionTabId или tabId без закрытия вкладки.

  • finalize_tabs: освобождает состояние закрепления для сессии без закрытия вкладок. Передайте keep, чтобы сохранить закрепления для передачи/доставки.

  • snapshot: возвращает упрощённый DOM-снимок для разрешённого документа. По умолчанию это компактный автоматизированный снимок, содержащий краткие доступные элементы, текстовый превью (500 символов), количество пропущенных элементов и сводки по областям. Передайте mode: "full" для подробных метаданных элементов и поля text (по умолчанию 4000 символов). Передайте mode: "visible" для элементов с учётом области просмотра/пересечения, с границами и метаданными прокрутки. Передайте textLimit (до 100000), если нужно больше текста страницы — проверьте textBytesOmitted, чтобы узнать, было ли содержимое усечено.

  • visible_snapshot: удобный инструмент для snapshot({ mode: "visible" }).

  • navigate: переходит на активную вкладку или указанную tabId по разрешённому URL, затем ожидает завершения загрузки вкладки, когда это возможно. По умолчанию фокус не меняется (фоновые вкладки остаются в фоне; активная вкладка не деактивируется). Передайте active: true, только если вкладка должна стать видимой. Если загрузка истекает по времени, результат включает pending: true и warning. Поддерживает наблюдения after после ожидания загрузки.

  • click: кликает по элементу по ссылке из снимка на разрешённой вкладке. Поддерживает наблюдения after.

  • type: вводит текст в элемент по ссылке из снимка на разрешённой вкладке. Поля, похожие на пароль, блокируются, если не указано force=true. Поддерживает наблюдения after.

  • scroll: прокручивает разрешённую вкладку на deltaX и deltaY. Опциональные координаты x/y области просмотра прокручивают прокручиваемый элемент под этой точкой, если он найден. Прокрутка не разбивает на страницы текст снимка — снимки используют полный document.body.innerText. Увеличивайте textLimit в snapshot вместо сшивания прокруткой, если только страница не загружает контент лениво. Поддерживает наблюдения after.

  • query_elements: возвращает ограниченные ссылки/роли/метки/границы для элементов, отфильтрованных по CSS-селектору, роли, тексту и видимости.

  • extract_elements: извлекает ограниченные текстовые/HTML/ссылочные/временные данные по CSS-селектору. Извлечение HTML скрывает значения атрибутов паролей/OTP/скрытых токенов и помечает конфиденциальные элементы, не раскрывая секретные значения. Это предпочтительная альтернатива прямому выполнению JavaScript.

  • screenshot: захватывает видимую область просмотра разрешённой вкладки в виде data URL. Опциональные ref или bounds (+ padding) обрезают после захвата; пустые обрезки завершаются ошибкой до captureVisibleTab. Необрезанные ответы опускают поля обрезки. Захват в MV3 работает только с областью просмотра; неактивные целевые вкладки могут быть активированы перед захватом. Chrome требует <all_urls> или activeTab для captureVisibleTab; это расширение запрашивает необязательный <all_urls> только в режиме «все» (*), поэтому скриншоты в режиме «все» требуют предоставления этого разрешения во всплывающем окне.

  • keypress: отправляет на страницу стандартные события клавиатуры DOM. Сочетания клавиш на уровне браузера/ОС не гарантируются в MV3. Поддерживает наблюдения after.

  • click_at: отправляет события мыши по координатам области просмотра. Поддерживает наблюдения after.

  • wait_for: ожидает условия по ограниченному селектору/тексту/подстроке URL и возвращает доказательства совпадения/тайм-аута.

  • page_status: возвращает заголовок, URL, состояние готовности/видимости, состояние области просмотра/прокрутки и количество ресурсов по типу инициатора. Не раскрывает заголовки запросов или тела ответов.

  • console_logs: возвращает ограниченные журналы консоли, собранные после внедрения скрипта содержимого. Не видит более старую историю консоли страницы.

  • collect_scroll: прокручивает ограниченное количество шагов (жёсткий лимит при заданном until), извлекает выбранные элементы на каждом шаге, опционально нацеливается на вложенный контейнер прокрутки через scroll, применяет агрегированный лимит элементов (maxItems, по умолчанию 100) и опционально удаляет дубликаты по тексту или href для ленивых лент. Опциональные until.noNewItemsForSteps / until.stopBeforeDatetime (ISO-8601; требует includeTimes) устанавливают stoppedReason. Результаты включают количество пропущенных/усечённых элементов. Поддерживает наблюдения after.

  • perform_actions: выполняет до 10 последовательных действий на странице (click, type, scroll, keypress) за один цикл обмена с брокером. Остановка при первой ошибке; терминальные наблюдения after выполняются только при успешном выполнении всех шагов. Координатные клики остаются в одноинструментном click_at. Шаги не могут содержать after, tabId или sessionTabId.

Нацеливание на документы фреймов

Инструменты для работы с DOM/контентом принимают опциональный documentId, возвращаемый list_frames. Если его опустить, сохраняется существующее поведение и каждая операция нацеливается на текущий верхний документ. Если указать его, выбирается именно этот документ: если iframe переходит, исчезает, перемещается на другую вкладку, становится неподдерживаемым или теряет доступ, операция завершается ошибкой, а не переходит на верхний фрейм или замену с тем же frameId.

Каждый результат содержимого несет подтвержденные атрибуты documentId, frameId, isTopFrame и coordinateSpace. Координаты верхнего фрейма используют tabViewport; границы visible_snapshot iframe, click_at и прокрутка координат используют frameViewport. Локальные границы iframe нельзя передавать в обрезку скриншота, поскольку screenshot остается инструментом, работающим только с областью просмотра вкладки. navigate, screenshot и list_frames принимают только цели вкладок; perform_actions.documentId применяется ко всему пакету и не может быть переопределен отдельным шагом.

Ошибки документов сохраняют один из следующих префиксов, в том числе внутри ошибок пакетных шагов и сбоев after: DOCUMENT_STALE:, DOCUMENT_POLICY_DENIED:, DOCUMENT_HOST_PERMISSION_DENIED: или DOCUMENT_UNSUPPORTED:. V1 поддерживает только активные HTTP(S) документы внешнего/вложенного фрейма. Он намеренно исключает about:blank, about:srcdoc, blob:, data:, фреймы с резервным источником, навигацию в iframe и преобразование координат скриншота из iframe во вкладку.

Действуй, затем Наблюдай

Инструменты действий navigate, click, type, scroll, keypress, click_at, collect_scroll и perform_actions принимают необязательный объект after. Расширение удаляет after перед отправкой базового действия в скрипт содержимого, а затем выполняет запрошенные наблюдения в следующем фиксированном порядке: waitFor, snapshot, pageStatus. Ответом является результат базового действия плюс объект after с результатами наблюдений.

Для perform_actions параметр after применяется только ко всему пакету: отдельные шаги не могут включать after, а терминальные наблюдения пропускаются при сбое любого шага. Частичные сбои пакета возвращают структурированные результаты шагов с failedIndex и completedCount, сохраняя успех на уровне моста, чтобы агенты могли проверить полезную нагрузку.

{
  "ref": "h12",
  "after": {
    "waitFor": { "selector": ".results", "timeoutMs": 5000 },
    "snapshot": { "mode": "visible", "limit": 40 },
    "pageStatus": true
  }
}

after.waitFor должен включать как минимум один из элементов text, selector или urlIncludes; timeoutMs является необязательным и ограничен значением 20000, чтобы вся цепочка «действие-затем-наблюдение» оставалась в пределах тайм-аута запроса брокера по умолчанию. after.snapshot может быть true для параметров снимка по умолчанию или объектом с mode, textLimit и/или limit. Недопустимые запросы after отклоняются до выполнения базового действия.

Если базовое действие выполнено успешно, но наблюдение after завершилось сбоем, ответ все равно включает результат базового действия и устанавливает after в { "ok": false, "error": "..." }.

Режимы снимков и ссылки

Компактные снимки по умолчанию предназначены для уменьшения использования контекста модели при сохранении автоматизации браузера. Компактный снимок выглядит так:

{
  "title": "Example Domain",
  "url": "https://example.com/",
  "mode": "compact",
  "elements": [{ "ref": "h1", "role": "link", "label": "Learn more" }],
  "omittedElements": 0,
  "textPreview": "Example Domain ...",
  "textBytesOmitted": 0,
  "regions": []
}

Используйте полный режим только тогда, когда вам нужны устаревшие подробные метаданные элементов:

{ "mode": "full", "tabId": 123 }

Используйте видимый режим для работы с границами области просмотра, виртуализированными страницами и планированием координат кликов:

{ "mode": "visible", "sessionTabId": "tab-1" }

Для чтения длинного содержимого страницы (например, документации API) увеличьте textLimit вместо использования скриптов брокера или обходных путей CDP:

{ "mode": "full", "textLimit": 100000, "tabId": 123 }

Компактный режим также поддерживает textLimit; текст тела возвращается в textPreview (в компактном режиме поля text нет). Когда textBytesOmitted больше нуля, увеличьте textLimit или прокрутите страницу и сделайте снимок снова, только если контент загружается лениво ниже сгиба.

Ссылки — это идентификаторы в памяти для каждого документа (h...), назначаемые на основе идентичности элемента, а не порядка вывода. Они остаются стабильными при вставке/переупорядочивании DOM в одном документе, а click / type разрешаются через хранилище ссылок скрипта содержимого. Ссылки могут конфликтовать между документами фреймов, поэтому сохраняйте documentId результата и передавайте его с последующими действиями в iframe. Переход на другую страницу загружает новый документ, поэтому ожидается, что старые ссылки будут чисто ошибаться; делайте новый снимок после навигации или серьезных изменений страницы. Хранилище ссылок удаляет отключенные, просроченные и превышающие лимит записи, а также удаляет устаревшие атрибуты data-cbc-ref, чтобы исключить случайное повторное использование удаленных ссылок.

Сессии вкладок

Отдавайте предпочтение claim_tab перед многошаговой работой в браузере:

{ "tabId": 123 }

Возвращенный sessionTabId можно передать в snapshot, navigate, click, type, scroll, query_elements, extract_elements, screenshot, wait_for и связанные инструменты страницы. Если у сессии есть текущая заявка, действия на странице без явного tabId или sessionTabId направляются на эту заявку. Если заявки нет, остается резервный вариант активной вкладки.

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

Проверки разработки

npm test
npm run build
cbctl doctor
# or: node dist/cli/main.js doctor
npm run benchmark:compact-snapshots
npm audit

npm run benchmark:snapshots является псевдонимом для того же теста сравнения компактного и полного режимов. Тест выводит количество байт в компактном режиме, количество байт в полном режиме и процент сокращения; компактный режим должен быть как минимум на 50% меньше на плотном тестовом наборе.

После редактирования файлов в extension/ перезагрузите распакованное расширение на chrome://extensions перед запуском сквозных проверок браузера. После изменений адаптера/сервера пересоберите и перезапустите хост MCP. Устаревший фоновый сервис-воркер или каталог инструментов может продолжать обслуживать старое поведение; browser_status должен сообщать adapter.registeredToolCount: 24, версию протокола расширения 6 и маркер функции document-targeting, когда обе стороны актуальны.

Ограничения

  • Это прототип с общим локальным токеном, а не многофакторная аутентификация.

  • Вызовы инструментов браузера сериализуются глобально на брокере.

  • Скрипты содержимого используют снимки DOM, а не полное дерево специальных возможностей Chrome.

  • Ссылки — это дескрипторы в памяти в рамках документа. Запустите snapshot снова после навигации, перезагрузок, серьезных изменений DOM или ошибок устаревших ссылок.

  • Видимые скриншоты ограничены областью просмотра. Захват неактивной вкладки может активировать ее, поскольку Chrome MV3 захватывает видимую вкладку в окне.

  • Захват скриншота Chrome требует <all_urls> или activeTab. Этот проект запрашивает опциональный <all_urls> в качестве разрешения хоста только для скриншотов по шаблону. Если screenshot сообщает об отсутствии этого разрешения, перезагрузите расширение после обновления манифеста, откройте всплывающее окно, сохраните настройки и предоставьте запрос.

  • keypress и click_at используют события DOM, а не диспетчеризацию ввода CDP. Они полезны для обработчиков страниц, но могут не запускать привилегированные сочетания клавиш браузера или каждый специфичный для фреймворка путь ввода.

  • Журналы консоли захватываются только после внедрения скрипта содержимого и ограничены.

  • Сводки ресурсов — это счетчики из API Performance; заголовки запросов, тела ответов, куки, хранилище, история, закладки и загрузки намеренно не раскрываются.

  • Инструменты истории браузера, закладок, загрузок и куки намеренно не раскрываются.

Безопасность

  • Токен по умолчанию не принимается. Установите CHROME_BROWSER_CONTROL_TOKEN в высокоэнтропийное URL-безопасное значение как для брокера, так и для адаптера MCP, затем вставьте то же значение во всплывающее окно расширения.

  • Брокер привязывается только к хостам обратной петли: 127.0.0.1, localhost или ::1.

  • Расширение подключается только к ws://127.0.0.1, ws://localhost или ws://[::1] с необязательным портом.

  • Доступ к страницам ограничен разрешенными источниками, настроенными во всплывающем окне. Используйте явные записи, такие как https://example.com, или введите *, чтобы разрешить все обычные веб-страницы http:// и https://. Вкладки и действия на страницах вне настроенной области действия блокируются.

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

  • Поля, похожие на пароли и одноразовые коды, определяются по типу ввода, автозаполнению, именам, ID, меткам и плейсхолдерам. type блокирует их, если не установлено force=true.

  • Опциональный CHROME_BROWSER_CONTROL_EXTENSION_ID привязывает брокера к одному установленному ID расширения.

  • Резервный вариант CDP не поддерживается адаптером MCP, поскольку он обходит связку расширения.

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

Публикация для мейнтейнера

Первые публичные npm-релизы выполняются вручную. Мейнтейнеры следуют docs/publish-checklist.md. Не добавляйте автоматическую публикацию при пуше или долгоживущие npm-токены в CI для пути релиза по умолчанию.

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
2wRelease cycle
3Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to control the Google Chrome browser through a Node.js WebSocket bridge and a dedicated browser extension. It provides tools for capturing screenshots, executing JavaScript, managing tabs, and extracting page content via the MCP protocol.
    2
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables browser automation over MCP using a real Chrome browser with existing profile, supporting real tabs, downloads, cookies, and RPA workflows.
    71
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Drive your real, signed-in Chrome browser from any MCP client, enabling browser automation such as navigation, clicking, typing, and screenshots through standard MCP tools.
    1

View all related MCP servers

Related MCP Connectors

  • Hosted real Google Chrome MCP with per-user persistent state. Navigate, click, type, screenshot.

  • Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.

  • Live browser debugging for AI assistants — DOM, console, network via MCP.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vKongv/chrome-browser-control'

If you have feedback or need assistance with the MCP directory API, please join our Discord server