MCP для Juggler на Go
- суббота, 22 августа 2026 г. в 00:00:16

ИИ-агенты уже не просто отвечают на вопросы - они действуют. Они открывают страницы, читают разметку, кликают по кнопкам, заполняют формы и делают скриншоты. А самый быстрорастущий способ дать агенту руки - это Model Context Protocol (MCP), открытый стандарт, который превращает браузер в набор инструментов, вызываемых любым ИИ-клиентом.
Браузерная половина задачи в Go уже была решена. Пакет go-https://github.com/yvv4git/go-juggler принёс стек автоматизации Camoufox/Juggler в экосистему Go в виде чистого REST-клиента. Но оставался разрыв между "я могу управлять stealth-браузером из Go" и "мой ИИ-ассистент может управлять stealth-браузером". Подключение браузерного клиента к MCP-серверу означало написание клея: определения инструментов, JSON-schema для входных данных, обработка транспорта, настройка сессий. Каждая команда изобретала одну и ту же интеграцию заново.
Пакет https://github.com/yvv4git/go-juggler-mcp - это тот самый клей, написанный один раз и хорошо. Это MCP-сервер под лицензией MIT, который отдаёт весь интерфейс автоматизации Juggler - ARIA-снимки, стабильные ссылки на элементы, клики, ввод текста, выполнение JavaScript, анализ сети - как девятнадцать инструментов, которые может вызывать любой MCP-клиент. OpenCode, Claude Desktop, Cursor: все они говорят на одном протоколе, и этот сервер отвечает им тем же в сторону браузера Camoufox.
MCP (Model Context Protocol) - открытый протокол, представленный Anthropic в конце 2024 года, который стандартизирует взаимодействие ИИ-приложений с инструментами и источниками данных. Вместо того чтобы каждый агент встраивал собственный код вызова инструментов, сервер объявляет свои инструменты как JSON-схемы, а клиент вызывает их через хорошо определённый формат обмена:
запрос: { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "snapshot", "arguments": { "tab_id": "..." } } } ответ: { "jsonrpc": "2.0", "id": 1, "result": { "content": [...] } }
Один сервер может использовать любой совместимый клиент, а один клиент - общаться со множеством серверов. Транспорты тоже подключаются: локальные серверы работают через stdio, удалённые - через streamable HTTP.
Экосистема MCP - это место, где автоматизация браузера становится по-настоящему практичной для агентов. Модели не нужен собственный плагин под каждый клиент - нужен один сервер, который отдаёт open_tab, snapshot, click, type как обычные инструменты. Именно это и предоставляет go-juggler-mcp.
go-juggler-mcp - это Go-бинарник, который располагается между MCP-клиентом и браузером с поддержкой Juggler. Цепочка выглядит так:
ИИ-клиент (opencode, Claude Desktop, Cursor) │ MCP (stdio или streamable HTTP) ▼ go-juggler-mcp │ REST (JSON поверх HTTP) ▼ camofox-browser │ протокол Juggler ▼ Camoufox / Firefox (с патчами stealth)
Внизу - Camoufox, антидетект-браузер, который подменяет hardwareConcurrency, WebGL-рендереры, AudioContext, геометрию экрана и WebRTC на уровне C++ - до того, как JavaScript вообще увидит страницу. Бразуер https://github.com/daijro/camofox оборачивает этот движок в REST API, созданный для агентов: accessibility-снимки, стабильные ссылки на элементы, изоляция сессий. Пакет https://github.com/yvv4git/go-juggler предоставляет Go-клиент для этого API. go-juggler-mcp добавляет верхний слой: он регистрирует каждый метод go-juggler как MCP-инструмент, и весь стек становится доступен из промпта.
Сборка из исходников (Go 1.26+):
go build -o go-juggler-mcp .
Единственное обязательное условие - запущенный экземпляр Camoufox, доступный через camofox-browser:
docker run -d -p 9377:9377 --name camoufox camoufox
Затем запустите сервер:
./go-juggler-mcp serve
С транспортом по умолчанию (stdio) сервер ждёт MCP-клиента на stdin/stdout. Пропишите его в конфиге opencode:
{ "mcp": { "juggler": { "type": "local", "command": ["/path/to/go-juggler-mcp", "serve"] } } }
И теперь модель может сама ходить по сайтам. Слово juggler в промпте говорит opencode, к какому MCP-серверу обращаться:
opencode run -m "opencode/deepseek-v4-flash-free" \ "Open https://rutube.ru with juggler, snapshot the page, and summarize the main blocks, headings, navigation, and the first 10 clickable elements with their refs"
Один промпт - и агент открыл реальную вкладку, снял ARIA-снимок и рассуждает о живой странице: никаких селекторов, написанных вручную, никакого HTML в контексте.
Сейчас go-juggler-mcp предоставляет девятнадцать инструментов - отображение один-в-один на REST-клиент go-juggler:
health - проверить статус браузера (движок, соединение, память)
open_tab - открыть новую вкладку и перейти по URL
navigate - загрузить URL в существующей вкладке
snapshot - получить ARIA-дерево страницы (ссылки на элементы)
click - кликнуть по элементу по ref или CSS-селектору
type - заполнить поле ввода по ref или селектору
press - нажать клавишу клавиатуры (Enter, Tab, Escape и т. д.)
scroll - прокрутить страницу вверх/вниз на N пикселей
back - перейти назад по истории
forward - перейти вперёд по истории
refresh - перезагрузить текущую страницу
links - список всех ссылок на странице с пагинацией
screenshot - сделать скриншот, вернуть или сохранить на диск
evaluate - выполнить произвольный JavaScript в контексте страницы
network_requests - получить все загруженные ресурсы (навигация + подресурсы)
stats - получить состояние вкладки (URL, посещённые URL, refs)
list_tabs - список всех вкладок в сессии
close_tab - закрыть вкладку
close_session - уничтожить всю сессию со всеми вкладками
Три из них заслуживают более пристального внимания.
Инструмент screenshot - это место, где сервер добавляет реальную ценность, а не просто тупой HTTP-прокси. "Сырой" скриншот Camoufox - это PNG размером с вьюпорт; агенту с vision-моделью он нужен, а агенту без неё - компактный JPEG или вообще ничего.
По умолчанию инструмент возвращает изображение как base64 внутри результата MCP, которое vision-модель может прочитать напрямую:
Screenshot of tab 60bf9c8c-e6d9-4be0-ba09-738058215af6 (248732 bytes)
Передайте аргумент path - и сервер запишет файл на диск вместо этого: удобно, когда нужно сохранить артефакты или отдать их модели без vision. format (png/jpeg), quality (1-100, по умолчанию 85) и max_width (уменьшение) дают агенту контроль над размером ответа. Пайплайн изображений декодирует PNG, при необходимости уменьшает его масштабированием Catmull-Rom и перекодирует - всё в процессе, без внешних инструментов работы с картинками.
Протокол Juggler группирует вкладки в сессии. Ручное управление ключами сессий - ровно та бухгалтерия, которой агент не должен заниматься. Если запустить go-juggler-mcp без --session, он сгенерирует уникальный ключ (mcp-<нано-время>) при старте, и каждый инструмент будет использовать его по умолчанию:
./go-juggler-mcp serve --addr http://localhost:9377 --session demo
Каждый инструмент также принимает необязательный аргумент session, так что один сервер может обслуживать несколько изолированных сессий от разных агентов - полезно, когда несколько MCP-клиентов делят один сервер.
Локальным инструментам вроде opencode и Claude Desktop нужен stdio: сервер запускается как дочерний процесс и общается через stdin/stdout. Удалённым сценариям нужен streamable HTTP-транспорт, чтобы сервер мог работать на машине с браузером и быть доступным по сети:
./go-juggler-mcp serve --transport http --http-addr :8080
Тот же бинарник переключается между ними одним флагом - без пересборки и без отдельных пакетов. Удалённый режим прописывается в opencode как "type": "remote", указывающий на http://localhost:8080/mcp.
go-juggler-mcp пока молод - базовая поверхность инструментов появилась в первом же проходе - поэтому будем честны о том, что работает сегодня, а что нет.
Работает сегодня: все девятнадцать инструментов на обоих транспортах (stdio и streamable HTTP), генерация сессий без конфигурации, пайплайн скриншотов (возврат base64 или запись на диск, PNG/JPEG, качество и изменение размера), TOML-конфиг с переопределением флагами, корректное завершение по SIGINT/SIGTERM и набор мок-тестов обработчиков инструментов.
Ещё нет: MCP-ресурсов (сегодня сервер только про инструменты), шаблонов промптов и аутентификации на HTTP-транспорте - поэтому не стоит выставлять удалённый режим в недоверенную сеть. Список ресурсов, более богатые возможности сервера и аутентификация для HTTP-транспорта - естественные следующие шаги по мере развития проекта.
Для основной задачи - дать MCP-клиенту возможность управлять stealth-браузером Camoufox уже сегодня - go-juggler-mcp готов.
История "автоматизация браузера для агентов" долго была лоскутным одеялом из плагинов под каждый клиент и самописного клея. go-juggler-mcp стандартизирует всё это: один бинарник, один протокол и браузер со спуфингом отпечатков на уровне C++, вызываемый из любого MCP-клиента. Если вашим агентам нужны настоящие руки в настоящем вебе - это быстрый способ их дать.
Ссылки:
MCP сермер https://github.com/yvv4git/go-juggler-mcp
Пакет для работы с juggler из go https://github.com/yvv4git/go-juggler
Model Context Protocol https://modelcontextprotocol.io
Camoufox https://camoufox.com
Camofox-browser https://github.com/daijro/camofox
Моя версия браузера docker push yvv4docker/camoufox:tagname