Opencode-chrome MCP server
2026년 10월 26일 커밋AI 클라이언트가 Chrome DevTools Protocol을 사용하여 Chrome 브라우저 세션을 제어하고, 웹사이트와 상호작용하며, 탭을 관리하고 스크린샷을 캡처할 수 있도록 합니다.
다른 이름 G10hdz/Opencode-chrome
- 스타
- 1
- Tools
- 5
- 다운로드, 30일
- —
- 최신 버전
- —
- 마지막 커밋
- 2026년 10월 26일
- 라이선스
- MIT
Opencode-chrome MCP란?
Opencode-chrome은(는) MCP server입니다. AI 클라이언트가 Chrome DevTools Protocol을 사용하여 Chrome 브라우저 세션을 제어하고, 웹사이트와 상호작용하며, 탭을 관리하고 스크린샷을 캡처할 수 있도록 합니다. 5개 도구를 제공합니다. 예: browser_status, list_tabs, list_frames.
프로젝트 README에서 생성된 요약
Opencode-chrome MCP server 정보
Opencode-chrome은 AI 클라이언트에서 현재 사용 중인 Chrome 브라우저 세션을 제어할 수 있게 해줍니다. AI 에이전트는 Chrome DevTools Protocol을 사용하여 사용자가 이미 로그인해 있는 대시보드나 스테이징 사이트를 포함하여, 웹사이트를 보이는 그대로 상호작용할 수 있습니다. 이 설정을 위해서는 npx를 통해 실행되는 로컬 브릿지, 버전 116 이상의 Chrome 또는 Chromium 브라우저, 그리고 두 요소를 연결할 MV3 확장 프로그램이 필요합니다.
보안을 위해 사용자는 고유 토큰을 사용하여 브릿지와 확장 프로그램을 페어링해야 합니다. 확장 프로그램 툴바를 통해 탭이 연결되면, AI는 URL 탐색, 요소 클릭, 텍스트 입력, 탭 관리와 같은 복잡한 작업을 수행할 수 있습니다. 또한 텍스트 트리를 위한 snapshot, PNG 캡처를 위한 screenshot, 요청 본문을 검사하기 위한 list_network와 같은 도구를 통해 가시성을 제공합니다. 실제 브라우저 세션을 구동하므로, 에이전트는 별도의 계정 자격 증명 없이도 기존의 인증 및 권한을 그대로 상속받습니다.
활용 사례
- 1읽지 않은 알림 모니터링AI가 특정 URL로 이동하여 계정의 최근 활동을 확인할 수 있습니다.
- 2웹사이트 시각적 상태 캡처에이전트에게 스테이징 환경으로 이동하여 페이지의 시각적 확인을 수행하도록 지시할 수 있습니다.
- 3복잡한 사이트 상호작용 자동화개발자는 선언적 레시피를 사용하여 특정 오리진에서 검색 및 데이터 추출과 같은 다단계 시퀀스를 실행할 수 있습니다.
- 4구조화된 페이지 데이터 추출에이전트가 특정 요소를 읽거나 페이지의 텍스트 트리를 생성하여 인터페이스를 이해할 수 있습니다.
프로젝트의 README를 바탕으로 작성되었습니다. 모든 활용 사례는 해당 내용의 인용문과 대조하여 확인합니다.
Opencode-chrome MCP 도구 5
README에서 감지됨browser_statuslist_tabslist_frameslist_storage_keyslist_console_messages
| browser_status | — | |
| list_tabs | — | |
| list_frames | — | |
| list_storage_keys | — | |
| list_console_messages | — |
자동 검사
2026년 11월 14일에 실행됨전체 보고서 →아직 인증되지 않았습니다. 서버는 80점 이상의 점수, 심각한 결함 없음, 그리고 검사에 충분한 데이터를 갖추어야 합니다. 검사 방식 · 점수를 높이기 위해 수정할 항목
- 소스 저장소 연결 및 접근 가능g10hdz/opencode-chrome is public and reachablegithub.com/g10hdz/opencode-chrome ↗통과
- 패키지가 이 저장소를 소스로 명시검사되지 않음
- 빌드 출처(Sigstore 증명)검사되지 않음
- 오픈 소스 라이선스 (OSI)MITspdx.org/licenses/MIT.html ↗통과
- 최근 1년 내 커밋 또는 릴리스Last commit or release 2026-10-26github.com/g10hdz/opencode-chrome ↗통과
- OpenSSF Scorecard검사되지 않음
- 패키지 이름이 인기 패키지와 유사하지 않음검사되지 않음
- 패키지 및 해당 종속성에 중요한 보안 권고 없음검사되지 않음
- 모델에 대한 숨겨진 지침 없음5 tool descriptions and the README read; no override phrases, credential paths or hidden characters통과
- 파괴적인 도구에 라벨 표시됨No tool named like delete, drop or exec통과
- 원격 엔드포인트가 MCP 핸드셰이크에 응답검사되지 않음
README
GitHub에서 보기opencode-chrome
opencode-chrome lets opencode use your real Chrome: the one already logged into Gmail, your dashboards, your staging site. Ask in the terminal, watch it happen in your browser. An unofficial, community-built bridge in the spirit of Claude in Chrome / Codex in Chrome.
Unofficial. Not affiliated with or endorsed by the opencode project. BYOK: your model keys stay in your opencode config. This bridge collects nothing and talks only to localhost.
What it looks like
you ▸ open github.com/notifications and tell me which repos have unread activity
you ▸ click the extension icon to attach that tab
opencode ▸ snapshot (reads the list as a text tree)
→ acme/api (2), acme/web (1), infra/deploy (5)
you ▸ go to the staging checkout and screenshot it
opencode ▸ navigate staging.example.com/checkout
screenshot → returns the PNG
It works because it drives your browser session, so anything you can see while logged in, the agent can see too.
How it works
A tiny local bridge (npx opencode-chrome, an MCP server plus a WebSocket on
127.0.0.1:19223) and an MV3 extension that connects to it and drives only the
tabs you attach from the toolbar, using the Chrome DevTools Protocol. An
attachment is limited to the tab's current origin. No backend, no accounts,
no analytics.
Requirements
- Node 20 or newer
- Google Chrome (or Chromium) 116 or newer
- opencode (or any MCP client that launches a local stdio server)
Install
1. Extension: download the repo (or the latest
release), open chrome://extensions, enable Developer
mode, "Load unpacked", select the extension/ folder. The toolbar badge
shows off until the token is configured and the bridge is running.
2. Bridge: add to your opencode config (opencode.json):
{
"mcp": {
"chrome": { "type": "local", "command": ["npx", "-y", "opencode-chrome"] }
}
}
3. Pair the token: the bridge generates a token at
~/.config/opencode-chrome/token (or prints it to stderr and copies it to
your clipboard at startup; set OPENCODE_CHROME_TOKEN to use your own).
Paste it into the extension's options page (right-click the toolbar icon →
Options); it shows a live connection status and reconnects the moment you
save. Connections without this token are refused, so other local processes
can't drive your browser.
4. Attach a tab: restart opencode, open the page you want to share, and
click the extension icon. Its badge shows on for attached tabs. Cross-origin
navigation detaches the tab by default; for legitimate flows (SSO redirects)
list the extra origins in ~/.config/opencode-chrome/policy.json:
{ "origin_allowlist": { "https://app.example.com": ["https://sso.example.com"] } }
The bridge pushes the allowlist to the extension on connect (env override:
OPENCODE_CHROME_POLICY). Entries apply per attached origin and are not
symmetric; with no file the policy is strict exact-origin.
The same command works from another local MCP client. How many sessions run at once is set in the extension options, under Sesiones. It stays at one unless you change it.
Site adapters
Declarative per-origin recipes live in ~/.config/opencode-chrome/adapters/
(env override: OPENCODE_CHROME_ADAPTERS). list_recipes enumerates them;
run_recipe(name, params?) executes one on an attached tab. The adapter's
origin must be inside the attachment's reach: exact match or allowlisted,
same rule as SSO redirects and OOPIF frames.
{
"name": "example",
"origin": "https://app.example.com",
"params": ["q"],
"steps": [
{ "navigate": "https://app.example.com/search?q={{q}}" },
{ "wait_for": "Results" },
{ "eval": "Array.from(document.querySelectorAll('.row')).map(r => ({title: r.innerText}))" },
{ "columns": ["title"] }
]
}
Steps: navigate, wait_for (+ optional timeout), init_script, eval,
columns. init_script registers JS on new documents for the duration of the
recipe only (auth/session setup), then it is removed.
{{key}} placeholders come from params; inside eval each placeholder is
substituted as a JSON-encoded literal (write search({{q}}), no quotes) so a
param value can never break out of the script's context. The eval JS lives
only in files you install: there is no free-form eval tool. See
examples/adapters/hackernews.json.
Chat (side panel)
An optional chat client lives in the Chrome side panel: you type, a model drives your attached tabs through the same tool surface. It works with no MCP client running. The key lives in the bridge, never in the extension:
// ~/.config/opencode-chrome/chat.json (chmod 600)
{ "provider": "anthropic", "api_key": "sk-...", "model": "claude-sonnet-4-5" }
provider is anthropic or openai (any OpenAI-compatible endpoint: set
base_url for OpenRouter, Ollama, Groq, etc.). Optional: effort
(off|low|medium|high → reasoning_effort / Anthropic thinking
budget), max_turns, max_minutes, max_tokens. Env override:
OPENCODE_CHROME_CHAT.
You can also configure it from the panel itself: the gear opens a form
with provider, key, optional base URL, a model picker (loaded from the
provider's /models, free models first), and an effort selector. The
key travels only over the authenticated socket and is written to
chat.json — it never lands in extension storage. The form also shows a
data-retention note for the endpoint (no training / conditional /
free-tier trains / local / unknown), worth a look before pasting
passenger or payment data.
Run opencode-chrome --serve for a chat-only bridge (no MCP stdio); the
normal MCP-spawned bridge serves chat too. Attaching a tab opens the
panel. Reads run directly; mutations pause on an approve/deny prompt in
the panel. Page content reaches the model only through tool results,
wrapped as untrusted data — same rules as an MCP client, the key and the
loop just move into your bridge.
Tools
| Tool | What it does |
|---|---|
browser_status |
bridge connection and attached tabs |
list_tabs |
attached tabs with id, title, url |
new_tab(url?, background?) |
open a tab (active unless background:true) |
close_tab(id) / activate_tab(id) |
tab management |
navigate(url?, action?, ignore_cache?, handle_before_unload?, tabId?) |
go to a URL or action back/forward/reload; waits for load; handle_before_unload auto-answers that dialog |
snapshot(tabId?) |
accessibility-style text tree with [ref] per interactive element; selector, interactive_only, in_viewport_only, max_chars, frame scope it; sensitive fields are redacted |
find(text?, role?, selector?, frame?) |
matching [ref] lines only |
read_text(selector?, max?, scroll?, frame?) |
element innerText, hydrates lazy sections |
list_frames |
frame tree with OOPIF session ids and allowlist status |
click(ref) / hover(ref) |
trusted CDP pointer actions |
drag(from, to) |
trusted drag between refs of the same frame |
type(ref, text) |
focus + type; trailing \n = Enter |
fill(ref, value) |
set value with native setter + input/change events |
select(ref, value) |
select option by label or value |
press_key(key) |
key or combo on the focused element: Enter, Tab, Escape, arrows, Control+A... |
form_schema(tabId?) |
form fields with ref, kind, label, autocomplete, required, sensitive; honeypots counted in hidden_count |
list_profile_keys(profile) / apply_mapping({ref: key}, profile) |
fill a whole form from chrome.storage.local.profiles.<profile>; values never cross the wire, missing keys land in unmapped_keys |
scroll(ref? or dx/dy) |
scroll element into view or page by deltas |
upload(ref, paths) |
set files on a file input via CDP |
list_network / get_network_body(id) |
captured requests and response bodies; filter, resource_types, offset/limit scope it, include_headers adds redacted headers, format:'har' or output_path exports HAR 1.2 |
list_storage_keys |
localStorage/sessionStorage key names only (values never leave the tab) |
list_console_messages |
console calls, uncaught exceptions and browser log entries; types/filter scope it |
list_dialogs / handle_dialog |
pending/recent JS dialogs; per-tab accept/dismiss policy |
screenshot(tabId?, annotate?) |
PNG (base64); annotate overlays [N] badges on snapshot refs |
resize_page(width, height, clear?, tabId?) |
viewport override via CDP; persists while attached |
emulate({network,cpu,geolocation,color_scheme,reduced_motion,user_agent,locale}, clear?) |
environment overrides per tab; clear:true resets |
| `wait_for(text | text[], timeout?)` |
wait_download(timeout_ms?) |
wait for a download; returns saved path, bytes, mime and sha256 |
list_recipes / run_recipe(name, params?) |
site adapters from ~/.config/opencode-chrome/adapters/ |
Notes
- Mutating tools (
navigate,click,hover,drag,type,fill,select,scroll,upload,apply_mapping,press_key) acceptinclude_snapshot:trueto return a fresh snapshot in the same response; its refs replace the previous ones. - Payload tools (
snapshot,find,read_text,screenshot,get_network_body) acceptoutput_pathto write the payload to a file on the bridge machine and return{path, bytes}instead of inline content. - While the agent acts, Chrome shows the "being debugged" banner. That is expected with CDP; the extension auto-detaches after 30s idle.
- Env vars for the bridge:
OPENCODE_CHROME_PORT(default 19223; the extension follows it via the port field on the options page),OPENCODE_CHROME_TIMEOUT_MS(default 30000),OPENCODE_CHROME_SESSION(optional name for that terminal, shown only when more than one session is connected). - Security: the WebSocket binds to 127.0.0.1 only, rejects non-extension
origins, and requires the shared bridge/extension token. The only data
stored persistently is that token, the optional port override, and the
session cap (in
chrome.storage.local, and in~/.config/opencode-chrome/config.jsononce the extension has connected). Attached tab origins live only inchrome.storage.session. Page content never leaves your machine through this bridge; it goes only to your model provider, exactly like any opencode prompt.
Troubleshooting
- Badge stays
off: the extension is not connected. Check that the bridge is running (opencode launchesnpx opencode-chrome; its stderr prints the token at startup) and that the token in the options page matches. The options page shows the connection status live. - A tool returns "Chrome extension not connected": same causes as above; the bridge is up but no extension has paired.
cannot listen,cannot attach, orno free port: something that is not this bridge holds the port, or every port in the session range is taken. With Sessions left at one, a second copy attaches to the bridge already running. If stderr says the bridge is an older process, restart that process. If it says there is no free port, close one session or raise the cap under Sesiones in the extension options.- Connection drops after sleep or a restart: the extension retries every three seconds while awake and uses a Chrome alarm to recover after suspension. A connection that receives no messages for 45 seconds is replaced. If a tool was interrupted, check the page before retrying; actions are not replayed.
- Testing a local fix:
npx opencode-chromeruns the published package. Change the MCPcommandto["node", "/absolute/path/to/opencode-chrome/src/index.js"], reload the extension inchrome://extensions, then restart opencode. debugger attachfails: a tab allows only one debugger client. Close DevTools on that tab (or detach other debuggers) and retry.
Development
npm install
npm test # bridge tests (node:test, no Chrome needed)
npm run pack # builds dist/opencode-chrome-<version>.zip for CWS upload
# real-Chrome smoke: launches Chrome, loads the extension, drives a fixture
# page end to end. Needs a Chrome binary; kept out of `npm test` for that reason.
node scripts/e2e-smoke.mjs # SMOKE_HEADLESS=1 for --headless=new
# Playwright e2e suite (e2e/): same real path with broader coverage: tabs,
# interactions, downloads, dialogs, network, guards. Also needs Chrome
# (OPENCODE_CHROME_BIN overrides the lookup).
npm run test:e2e
Icons live in extension/icons/, sized from the 1024px masters in assets/:
sips -z <size> <size> assets/logo-1024-transparent.png --out extension/icons/icon<size>.png.
Contributions welcome: see CONTRIBUTING.md. Working on the code with an AI agent? Start with AGENTS.md.
MIT license. See LICENSE.
opencode-chrome (español)
opencode-chrome deja que opencode use tu Chrome real: el que ya tiene la sesión iniciada en Gmail, tus dashboards, tu staging. Pídelo en la terminal y pasa en tu navegador. Puente comunitario no oficial, al estilo de Claude in Chrome / Codex in Chrome.
No oficial. Sin afiliación con el proyecto opencode. BYOK: tus keys viven en tu config de opencode. Este puente no recolecta nada y solo se comunica con localhost.
Cómo se ve
tú ▸ abrí github.com/notifications y decime qué repos tienen actividad sin leer
opencode ▸ navigate github.com/notifications
snapshot (lee la lista como árbol de texto)
→ acme/api (2), acme/web (1), infra/deploy (5)
tú ▸ andá al checkout de staging y sacale un screenshot
opencode ▸ navigate staging.example.com/checkout
screenshot → devuelve el PNG
Funciona porque maneja tu sesión del navegador: lo que ves con la sesión iniciada, el agente también lo ve.
Cómo funciona
Un puente local chico (npx opencode-chrome, servidor MCP más un WebSocket en
127.0.0.1:19223) y una extensión MV3 que se conecta a él y controla solo las
pestañas que adjuntas desde el ícono, mediante Chrome DevTools Protocol. Sin
backend, sin cuentas, sin analítica.
Requisitos
- Node 20 o superior
- Google Chrome (o Chromium) 116 o superior
- opencode (o cualquier cliente MCP que lance un servidor stdio local)
Instalación
- Extensión:
chrome://extensions→ modo desarrollador → "Cargar descomprimida" → carpetaextension/del repo. El badge muestraoffhasta configurar el token y correr el puente. - Puente: en tu
opencode.json:{ "mcp": { "chrome": { "type": "local", "command": ["npx", "-y", "opencode-chrome"] } } } - Token: el puente genera uno en
~/.config/opencode-chrome/token(o lo imprime por stderr y lo copia a tu portapapeles al arrancar;OPENCODE_CHROME_TOKENpara usar el tuyo). Pegalo en la página de opciones de la extensión (click derecho en el ícono → Opciones); muestra el estado de conexión y reconecta apenas guardás. Sin ese token, las conexiones se rechazan. - Reinicia opencode, abre la página, haz clic en el ícono de la extensión para adjuntar esa pestaña y luego pídele cosas.
El mismo comando sirve para otro cliente MCP local. Cuántas sesiones corren a la vez se define en las opciones de la extensión, en Sesiones. Queda en una hasta que lo cambies.
Chat opcional en el panel lateral: configurá
~/.config/opencode-chrome/chat.json (provider anthropic u openai,
api_key, model, effort opcional) o abrí el engranaje del panel y
llená el form: provider, key, URL base opcional, selector de modelo
(ordenado gratis primero) y effort. La key viaja solo por el socket
autenticado hasta chat.json; nunca queda en la extensión. El form
también muestra la política de retención del endpoint (no entrena /
condicional / gratis entrena / local / desconocida). Corré
opencode-chrome --serve o el puente MCP de siempre. Al adjuntar un
tab se abre el panel; las lecturas corren directo y cada mutación pide
aprobación ahí mismo.
Herramientas, notas de seguridad, solución de problemas y desarrollo: ver sección en inglés arriba (mismo contenido). Para contribuir: CONTRIBUTING.md; si trabajas con un agente de IA: AGENTS.md.
Opencode-chrome MCP 질문
Opencode-chrome MCP는 어떤 도구를 제공하나요?
5개 도구를 제공합니다. 예: browser_status, list_tabs, list_frames, list_storage_keys, list_console_messages.
Opencode-chrome 브릿지를 어떻게 설치하나요?
opencode.json 파일의 mcp 섹션에 'npx -y opencode-chrome' 명령어를 사용하여 opencode 설정에 추가할 수 있습니다.
확장 프로그램 배지가 'off' 상태로 유지되면 어떻게 하나요?
배지가 'off' 상태라면 확장 프로그램이 연결되지 않은 것입니다. 브릿지가 실행 중인지 확인하고, 옵션 페이지의 토큰이 브릿지에서 생성된 토큰과 일치하는지 확인해야 합니다.