Chrome Browser Control
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| CHROME_BROWSER_CONTROL_HOST | No | Loopback host for the broker (default 127.0.0.1). | 127.0.0.1 |
| CHROME_BROWSER_CONTROL_PORT | No | WebSocket broker port (default 8765). | 8765 |
| CHROME_BROWSER_CONTROL_TOKEN | Yes | High-entropy pairing token shared by the broker, MCP adapter, and extension popup. | |
| CHROME_BROWSER_CONTROL_EXTENSION_ID | No | Optional. Pins the broker to one installed extension ID. | |
| CHROME_BROWSER_CONTROL_DISABLE_LOCAL_ENV | No | Optional. Set to '1' to skip loading .env.local. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| browser_statusA | Check whether the MCP adapter can reach the local broker and whether the Chrome extension answers ping. Read nextAction for onboarding coaching. When the extension answers, also read cdpEnabled and attachedTabs for the trusted-input tier. |
| name_sessionA | Set a human-readable browser-control session name for status, logs, and debugging. |
| list_tabsA | List tabs visible to the Chrome Browser Control extension in the current Chrome profile. |
| list_framesA | List current frame documents for an allowed target tab. Blocked or unsupported frames are redacted and cannot be targeted. |
| claim_tabA | Claim an allowed Chrome tab for this browser-control session. Advisory claims are default. Use exclusive=true with ttlMs for fail-fast tab leases across parallel agents. |
| release_tabA | Release a previously claimed tab by sessionTabId or tabId without closing the browser tab. |
| cdp_attachA | Attach trusted CDP input to a claimed tab. While attached, click, type, keypress, click_at, and matching perform_actions steps use trusted CDP input. Requires the popup enableCdp toggle, a claimed tab, and an allowed origin. The debugger permission is required in the manifest. Chrome shows a debugging banner on the tab. Repeating attach on the same tab refreshes the TTL without tearing down the socket. |
| cdp_detachB | Detach trusted CDP input from a claimed tab and return click/type/keypress to the content-script path. release_tab and finalize_tabs also detach, including kept finalize claims. |
| cdp_network_watchA | Enable the Network domain on an attached tab and keep an in-memory index of metadata rows only (requestId, url, method, status, mimeType, size, timestamp). No response body is read or stored. Restricted-category origins never enter the index. Requires cdp_attach. Optional patterns narrow which URLs are indexed. |
| cdp_network_requestsA | Return the in-memory network request index for an attached tab. Rows are metadata only. Response headers, Set-Cookie, and request post data are never included. |
| cdp_response_bodyA | Read one response body by requestId from an attached tab. Deny by default: the request origin must be in the popup body-capture allowlist, which does not accept *. Restricted-category origins are refused even when listed. Binary bodies (base64Encoded) are refused. Bodies over the size cap return an error, never a truncated body. Token-shaped JSON fields receive best-effort masking of obvious token-shaped fields, not a guarantee — treat any response body as if it contains credentials. Response headers, Set-Cookie, and Network.getRequestPostData are never exposed. Each successful read is recorded to an append-only metadata log; body content is never written there. |
| finalize_tabsA | Release browser-control ownership state for claimed tabs. This does not close user tabs; pass keep entries to preserve handoff/deliverable claims. Detaches CDP attachments on every claimed tab, including kept claims. |
| snapshotA | Return a simplified DOM snapshot for the current top document or an exact documentId from list_frames. Compact mode (default) returns textPreview only — not text. Full mode returns text. Compact defaults to main-landmark scope when present; a visible modal dialog (aria-modal=true or opened with showModal()) takes scope instead. Pass scope: "document" for legacy full-body text including the page behind a modal, ignoreRoles: ["dialog"] or ["alertdialog"] to hide both dialog and alertdialog, or mode: "full" for the unscoped legacy snapshot. Defaults truncate at 500 (compact) or 4000 (full) chars; pass textLimit (up to 100000) for long page content such as API docs. Response includes authoritative document identity and coordinate space. |
| visible_snapshotB | Return a viewport-aware snapshot with visible/intersecting elements, refs, labels, roles, bounds, and scroll metadata. Iframe bounds use frameViewport coordinates. |
| navigateA | Navigate the active tab or target tab to a URL. Default leaves focus alone (does not activate a background tab and does not deactivate the focused tab). Pass active: true only when the tab must become visible. |
| activate_tabA | Focus an allowed tab and its window without navigating. Waits until the document reports visibilityState visible or a short timeout elapses. Returns visibilityState and visible; reason is present only when visible is false. focused is not success. Use this when click/type fail with DOCUMENT_HIDDEN. Pass allowHidden=true only when visibilityState is hidden. If reason is host_permission_denied or document_unavailable, grant permission or reload; allowHidden will not help. Does not change the page URL. |
| clickA | Click an element by snapshot ref in the current top document or an exact documentId from list_frames. Fails with DOCUMENT_HIDDEN when the document is hidden unless allowHidden=true. |
| typeA | Type text into an element by snapshot ref. Password-like fields are blocked unless force=true. Fails with DOCUMENT_HIDDEN when the document is hidden unless allowHidden=true. |
| scrollA | Scroll the current top document or an exact documentId by pixel deltas. x/y are tabViewport coordinates for the top document and frameViewport coordinates for an iframe. Use textLimit on snapshot to capture more text; scroll only helps when the page lazy-loads content. |
| query_elementsB | Find elements by selector, role, text, and visibility without returning full page text. |
| extract_elementsB | Extract bounded structured data from elements selected by CSS selector. Safer alternative to raw JavaScript evaluation. |
| extract_feed_postsB | Extract structured feed/post records (author, text, times, live flags) from a scoped feed region without site-specific selectors. |
| screenshotA | Capture the visible tab viewport. This tool is tab-target only; iframe frameViewport bounds are not valid crop coordinates. Optionally crop to a top-document snapshot ref or tabViewport bounds. |
| keypressB | Dispatch common DOM keyboard events in the target page. Browser/OS shortcuts are not guaranteed under MV3. Fails with DOCUMENT_HIDDEN when the document is hidden unless allowHidden=true. |
| click_atA | Click at tabViewport coordinates in the top document or frameViewport coordinates in an exact iframe documentId. Fails with DOCUMENT_HIDDEN when the document is hidden unless allowHidden=true. |
| wait_forB | Wait for text, selector, URL substring, selector absence, scoped text, or bounded content stability in the target page. |
| page_statusC | Return lightweight page status, viewport/scroll state, and resource summary counts for an allowed target tab. |
| console_logsC | Return bounded console logs captured after the content script was injected in the target tab. |
| collect_scrollA | Scroll a bounded number of steps (hard ceiling when until is set), extract selected elements each step, optionally target a nested scroll container, and optionally stop early via until conditions. Results include stoppedReason. |
| perform_actionsA | Run up to 10 sequential page actions in one document target. An explicit batch-level documentId is revalidated before every step and after observation; steps cannot override it. Fail-fast on the first step error. Click, type, and keypress steps fail with DOCUMENT_HIDDEN on hidden documents unless that step sets allowHidden=true. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 30 tools
Several tools overlap significantly: snapshot, visible_snapshot, query_elements, extract_elements, and page_status all provide ways to inspect page content/state; click, click_at, and perform_actions (with click steps) overlap in interaction; browser_status and page_status both report status but with different focus. The descriptions are detailed but the high-level purposes blur together.
Tool names are predominantly verb_noun (e.g., list_tabs, navigate, click_at), but there is inconsistency in verb style: some use explicit verbs like 'browser_status' (noun-only), 'cdp_attach' (abbreviation), 'snapshot' (noun-only), and 'keypress' (verb-noun but single word). Also 'extract_feed_posts' is more domain-specific than the rest.
30 tools is on the high end for a browser control server. While the domain is complex, many tools feel like slight variations of each other (e.g., snapshot vs visible_snapshot), making the count feel bloated. The server could be consolidated to around 20 tools without losing functionality.
The tool set covers well the lifecycle of controlling a browser: claiming tabs, navigating, interacting, snapshotting, waiting, extracting, and CDP network inspection. Missing basic operations like page reload, back/forward, or download management are minor gaps that agents can work around.