chrome-devtools-mcp-mux
chrome-devtools-mcp-mux
Используйте один экземпляр Chrome для множества MCP-клиентов. Каждый клиент — например, отдельная сессия Claude Code — получает свой собственный изолированный набор вкладок, при этом все они работают с одним и тем же браузером и профилем.
Какую проблему это решает
chrome-devtools-mcp предоставляет MCP-клиенту доступ к Chrome DevTools. Это отлично работает для одного клиента, но если подключаются два клиента одновременно (два окна Claude Code, Claude Code плюс Gemini CLI и т. д.), они мешают друг другу в работе с вкладками — list_pages показывает всё, select_page конфликтует, new_page открывается не в том окне.
cdmcp-mux располагается между клиентами и chrome-devtools-mcp и предоставляет каждому соединению свой изолированный набор вкладок, сохраняя при этом запущенным только один экземпляр Chrome.
Установка и настройка (однократно)
git clone <this-repo> chrome-devtools-mcp-mux
cd chrome-devtools-mcp-mux
npm install
npm run build
npm link # exposes `cdmcp-mux` on PATHЗатем в файле .mcp.json каждого MCP-клиента:
{
"mcpServers": {
"chrome": { "command": "cdmcp-mux" }
}
}Это всё. Первый подключившийся клиент автоматически запускает общий демон; последующие клиенты подключаются к тому же демону.
Как проверить работоспособность
Запустите два MCP-клиента с конфигурацией, указанной выше. В каждом из них попросите модель:
Открыть другой URL через
new_page.Выполнить
list_pages.
Каждый клиент должен видеть только свою страницу. На хосте выполните cdmcp-mux status, чтобы увидеть оба контекста рядом в демоне.
Для полноценной демонстрации со скриптами и записанным видео см. demo/.
Переменные окружения (опционально)
Переменная | Назначение |
| Бинарный файл Chromium (по умолчанию Puppeteer) |
| Переопределение директории профиля Chrome |
| Переопределение пути к unix-сокету для демона |
|
|
|
|
Отладка
Всё вне канала связи; mux никогда не предоставляет инструменты отладки MCP-клиентам.
Команда | Что делает |
| pid демона, состояние, контексты, страницы |
| потоковый вывод структурированного лога mux |
Лог находится по адресу ~/.local/state/cdmcp-mux/mux.log.
Как это работает
flowchart TB
subgraph clients["one process per MCP client"]
direction LR
C1["Claude Code #1"] -- "stdio (MCP)" --> S1["cdmcp-mux shim"]
C2["Claude Code #2"] -- "stdio (MCP)" --> S2["cdmcp-mux shim"]
end
subgraph shared["shared — auto-spawned on first connect"]
direction TB
D["mux daemon<br/><i>per-connection context table</i><br/>(socket fd → ctxId → owned pageIds)"]
U["chrome-devtools-mcp subprocess<br/><code>--experimentalPageIdRouting</code><br/><code>--userDataDir <fixed></code>"]
B["Chromium<br/><i>one instance, one profile</i>"]
D -- "stdio (MCP)<br/>rewrite + filter" --> U
U -- "CDP" --> B
end
S1 -- "unix socket" --> D
S2 -- "unix socket" --> D
classDef client fill:#e3f2fd,stroke:#1976d2
classDef shim fill:#fff3e0,stroke:#f57c00
classDef core fill:#f3e5f5,stroke:#7b1fa2
classDef browser fill:#e8f5e9,stroke:#388e3c
class C1,C2 client
class S1,S2 shim
class D,U core
class B browserКаждый MCP-клиент запускает свой собственный shim cdmcp-mux (так работает .mcp.json — один дочерний процесс на клиента). Shim представляет собой чистый байтовый канал между stdio клиента и unix-сокетом; первый подключившийся shim автоматически запускает общий демон, последующие подключаются к нему. Демон владеет одним подпроцессом chrome-devtools-mcp, управляющим одним Chromium с одним --userDataDir.
Каждое соединение через unix-сокет = один новый BrowserContext (изолированные куки, localStorage, WebSockets). Демон анонсирует те же схемы инструментов, что и обычный chrome-devtools-mcp — pageId и isolatedContext удаляются из того, что видит клиент, и повторно внедряются при каждом вызове tools/call из таблицы владения демона для каждого соединения. Атомарность обеспечивается за счет использования вышестоящего --experimentalPageIdRouting, поэтому одновременные вызовы из разных контекстов не могут конфликтовать. Когда клиент отключается, его вкладки закрываются, а контекст браузера уничтожается.
Заметки по разработке
Этот проект был полностью написан агентом Claude-Code за одну рабочую сессию, исходя из требований, возникавших в ходе живого общения. План тестирования разделен по уровням для обеспечения функциональной корректности (58 тестов, ~19 с, все пройдены), а мультиплексор был визуально продемонстрирован с помощью VNC-автоматизированного воспроизведения.
Соответствие PRD и тестов см. в DEMO.md. Полный лог агентской разработки — обнаружение требований, итерации архитектуры, уровни тестирования и три дубля видеодемонстрации — см. в demo/README.md.
Тестирование
# requires a Chromium binary; the smoke/e2e tests need it
CDMCP_MUX_CHROMIUM=/usr/bin/chromium npm testОжидается: 8 файлов, 58 тестов, все пройдены.
Релиз
CI запускается при каждом push и PR в ветку main с использованием Node 22 и 24, выполняя сборку, проверку типов и запуск полного набора из 58 тестов (включая smoke-тесты реального Chromium и бинарные e2e-тесты).
Публикация автоматизирована через .github/workflows/publish.yml, который запускается при создании релиза на GitHub:
Увеличить
versionвpackage.json, закоммитить, пометить тегомv<version>.gh release create v<version> --generate-notes.Воркфлоу выполняет сборку, тестирование и
npm publishс npm provenance (подписано через GitHub OIDC, у воркфлоу естьid-token: write).
NPM_TOKEN — единственный необходимый секрет репозитория. Пакет публикуется с publishConfig.provenance: true, поэтому флаг --provenance подразумевается. Как только этот репозиторий будет зарегистрирован как доверенный издатель на npmjs.com, секрет NPM_TOKEN можно будет полностью удалить.
Лицензия
Apache-2.0 — см. LICENSE. Такая же, как у вышестоящего chrome-devtools-mcp.
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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/ochen1/chrome-devtools-mcp-mux'
If you have feedback or need assistance with the MCP directory API, please join our Discord server