Chrome Bridge
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| CHROME_BRIDGE_CAPS | No | Comma-separated list of tool groups to load (e.g., core,audits,visual,network,storage,dom,files,all) | core |
| CHROME_BRIDGE_HOST | No | Bind address for the server | 127.0.0.1 |
| CHROME_BRIDGE_PORT | No | WebSocket port for the Chrome Bridge server | 8765 |
| CHROME_BRIDGE_TOKEN | No | Shared secret for extension and relay authentication |
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 |
|---|---|
| get_statusA | Check bridge status: extension connection, server mode (primary/relay), port, version |
| get_tabsA | List every open tab with id, url, title and active flag. Read-only. Use it to find a tab_id when the implicit target (last navigated tab, else the active one) is not the tab you mean. include_windows adds the windows themselves with their position, size, state and type — what you need before moving or tiling anything, and the only way to tell which monitor a window is on. |
| navigateA | Navigate a Chrome tab to a URL. Returns a preview of interactive elements with refs usable in click/type_text/hover. |
| screenshotA | Screenshot of the visible viewport only (PNG), at the current scroll position. Read-only. Activates the tab in the background without stealing window focus, then restores the previous tab. Downscaled to ≤1568px, so fine print may not survive. |
| execute_jsA | Run JavaScript in the page (MAIN world). Requires the extension's "Allow user scripts" toggle; errors explain setup if disabled. |
| clickA | Click an element, by CSS selector or by a ref (n1, n2…) from get_interactives or navigate. Fires a real pointer sequence, so it can submit, open a dialog or navigate away — use wait_after to let that settle. Not idempotent, and a click that triggers a native confirm() blocks the bridge: install handle_dialogs first. |
| type_textA | Put text into an input, textarea or contenteditable, by CSS selector or by a ref from get_interactives. Replaces the whole value rather than appending, and assigns through the native setter so React and Vue controlled inputs register the change, then fires input and change. mode=keys instead emits keydown/input/keyup per character, which is what autocomplete and masked fields need — slower, so reach for it only when mode=set leaves the field empty or the dropdown never opens. |
| read_pageA | Read the page as text (default), markdown, raw HTML, or accessibility tree. Read-only. markdown keeps headings, links and tables at a fraction of the HTML cost, and is usually the right middle ground. Expensive on large pages: HTML on a big table costs tens of thousands of tokens for data you then filter anyway — prefer extract_table or extract for tabular and repeated content, and get_interactives to find click targets. |
| get_page_infoA | Get page metadata: meta tags, scripts, stylesheets, links, and forms |
| get_storageA | Read localStorage, sessionStorage or cookies of the current origin (type=all for every one). Read-only. Cookies come with domain, path, expiry and the httpOnly/secure flags, so this also answers whether a session cookie is present — write them back with set_storage, or snapshot a logged-in state with session_fixture. |
| get_performanceA | Navigation timing, paint metrics, JS heap size and per-resource load times, as measured since the current document loaded. Read-only, no reload triggered — numbers are only meaningful once loading has settled, so on a page still fetching wait for network idle first. Covers how fast the document arrived, not the layout-shift and interaction metrics that accumulate afterwards. |
| query_domA | Query DOM elements by CSS selector, returning structure, attributes, bounding rect, and computed styles. |
| modify_domA | Change an element in the live DOM: setAttribute, removeAttribute, addClass, removeClass, setStyle, setTextContent. Nothing is persisted — the next reload restores the page as the server sends it. For styling many elements at once inject_css is one call instead of N. |
| inject_cssA | Inject a CSS rule into the page. Stays until the next navigation or reload, and re-injecting the same id replaces it rather than stacking. Affects only what is rendered — the stylesheet of the site is untouched. |
| read_consoleA | Read console messages captured since page load, incl. uncaught errors and unhandled rejections. |
| monitor_networkA | Monitor network requests. source=page: XHR/fetch hook (installed on first call); source=browser: all requests incl. static assets. format=har exports HAR 1.2. |
| create_tabA | Open a new tab, optionally at a URL, and make it the implicit target of later commands in this session. Each call creates another tab: reuse a tab_id or navigate() to move an existing one instead of piling up tabs. |
| wait_forA | Block until a condition holds: element (selector in the DOM), function (JS expression turns truthy; needs the "Allow user scripts" toggle), navigation (mode=spa for client-side route changes), network_idle. Polls until timeout — 10s for element and function, 15s for navigation and network_idle — then returns |
| scrollA | Scroll. action=to: once to element/coordinates; action=until: repeatedly until element visible, network idle, or no new content (infinite scroll). |
| set_storageA | Write, delete or clear a localStorage/sessionStorage key, or a cookie with its path, domain and expiry. action=clear wipes every entry of that type for the origin and cannot be undone — on a site the user is logged into, clearing cookies logs them out. Read the current values first with get_storage. |
| fill_formA | Batch fill form fields with React-compatible events. Handles input, select, checkbox, radio, and textarea. |
| viewport_resizeA | Resize the Chrome window to a preset (mobile 375x812, tablet 768x1024, desktop 1440x900) or to explicit dimensions. The rendered viewport ends up smaller than what you ask for, by the height of the browser chrome — measure it with execute_js if the exact number matters. width and height each override the corresponding half of the preset, so preset plus width gives a custom width at the preset height. A maximized window on ChromeOS ignores the request. |
| element_screenshotA | Screenshot cropped to one element (PNG), scrolled into view first. Read-only. The cheapest image in the set, because it carries only the box you asked for: a component, a chart, a table cell. |
| full_page_screenshotA | Full-page capture by scrolling: stitched segments of ~2 viewports (≤1568px, top→bottom), or one image per viewport with stitch=false. Read-only, but expensive: each segment costs ~2.7k image tokens, so only the first max_segments are returned and the rest need segment_offset. On a long page, reading the text you actually need is cheaper by an order of magnitude — prefer read_page, extract or find_text unless the layout itself is the question. |
| highlight_elementsA | Outline every element matching a selector with a coloured overlay, to see on a screenshot what a selector actually caught. Each call clears the overlays left by the previous one instead of stacking them, and remove=true clears without adding. The overlays are injected DOM nodes: a reload or a navigation drops them, and they sit above the page without altering its layout or its own styles. |
| accessibility_auditA | A11y audit: missing alt, empty links, heading hierarchy, ARIA, contrast (approximate), form labels. |
| check_linksA | Check page links for broken URLs, verified server-side (no CORS limits, real HTTP status). |
| measure_spacingA | Measure the gap, overlap and distance in CSS pixels between two elements, with their margins and paddings. Read-only. Values come from the current layout, so zoom and viewport size change them: set_zoom(1) and a fixed viewport_resize make results comparable across runs. |
| watch_domA | Watch DOM mutations (MutationObserver). First call installs the watcher; later calls read accumulated mutations. |
| emulate_mediaA | Make the page believe it runs in a different environment, until reset or reload: prefers-color-scheme, prefers-reduced-motion, print mode (matchMedia override + CSS) and navigator.userAgent/platform. user_agent only changes what page JS reads — the request header is a separate thing, set it with network_rules(action=modify_header, header="User-Agent"). Pair with viewport_resize to emulate a device. |
| hoverA | Hover over an element (mouseenter/mouseover), by CSS selector or ref. |
| press_keyA | Send a key to the focused element (or to selector, focusing it first) as a real keydown/keypress/keyup sequence, so framework handlers fire. For typing a value use type_text; this is for Enter, Tab, Escape, arrows and shortcuts. Not idempotent: two calls send the key twice. |
| get_framesA | List frames (main + iframes) with frameId, parent, URL — for the frame_id parameter of DOM tools. |
| tab_actionA | Tab lifecycle: close, activate (focus), reload (optional cache bypass), back, forward. close discards the tab and anything unsaved in it, and cannot be undone — it may be a tab the user is working in. reload and navigation drop injected CSS, emulations and page hooks. duplicate works where create_tab is forbidden (chrome-untrusted://, verified on a ChromeOS Terminal tab) and lands in the source tab's own window, app windows included — the only way to open a new Terminal session inside the Terminal window. discard replaces the tab id: the result carries the new one, saved ids go stale. |
| upload_fileA | Set a file on input[type=file] from the server filesystem via DataTransfer (max 10MB). |
| dismiss_overlaysA | Dismiss cookie banners/modal overlays: OneTrust, Cookiebot, Usercentrics, then generic heuristic. Idempotent. |
| handle_dialogsA | Auto-accept/dismiss future JS dialogs (alert/confirm/prompt), logging them. reset restores native dialogs and returns the log. |
| find_textA | Find text on the page: parent selector, context, visibility, position per match. Attaches nearby interactive elements (with refs for click/type_text/hover) for the first visible match. |
| network_rulesA | Network interception, browser-wide, survives reloads until cleared: block requests, redirect URLs, set/remove request headers, or stub responses with a synthetic body (served by a local helper; from HTTPS pages the stub host must be trustworthy). |
| screenshot_diffA | Visual regression: save a named baseline (viewport or element), compare later — returns changed-pixel % and red-highlighted diff image. Baselines are in-memory (lost on service worker restart). |
| web_vitalsA | Core Web Vitals accumulated since the current document loaded: CLS, LCP, FCP, TTFB, long tasks and an INP approximation. Read-only. Needs the page instrumentation active from before load, so it reports whether it was hooked instead of silently returning zeros — navigate() installs it. Covers user-perceived stability and responsiveness after load, not the load timings themselves. |
| list_event_listenersA | List addEventListener registrations since page load: counts by type + recent entries. |
| monitor_websocketA | Monitor WebSocket connections/messages (500-char previews). Hook installs on first call; earlier connections are missed. |
| seo_auditA | SEO audit: title/description lengths, canonical, robots, h1 count, Open Graph, Twitter card, JSON-LD validity, hreflang, lang, viewport, favicon |
| extract_tableA | Read a real as JSON: thead cells become keys, each row an object. Read-only. Only for tabular markup — |
| unused_cssA | List CSS selectors matching nothing in the current DOM (approximate; cross-origin sheets unreadable). |
| drag_and_dropA | Drag an element onto another. html5 = DragEvent+DataTransfer; pointer = pointer/mouse events (sortable libraries). |
| clipboardB | Read or write the system clipboard (text). Activates the tab first. |
| set_geolocationA | Override navigator.geolocation with fixed coordinates (page-level patch). reset restores native. |
| manage_downloadsB | List downloads, start one, or wait for the newest to finish. Files land in the browser Downloads folder, not on the server. action=download reports the download's real state rather than just an id: with Chrome set to ask where to save each file, saveAs:false is overridden and it comes back as waiting_for_user — every byte fetched, no destination chosen, and nothing will move until someone picks one. |
| save_pageA | Save the full page (DOM, styles, images) as an MHTML archive file on the server filesystem. |
| http_requestA | HTTP request sent from the browser, so it carries the session cookies of the logged-in user: fetches URLs a plain server-side request would get a login page for (invoices, authenticated JSON, CSV exports). Text bodies are returned inline (capped by max_length); with save_to the bytes are written to that path instead, which is how you read a PDF — Chrome renders PDFs in a viewer no content script can reach, so read_page returns nothing on a PDF tab. |
| move_tabA | Move an existing tab into another window (chrome.tabs.move). Nothing is created or closed: the tab keeps its id, history and page state, and this works even on chrome-untrusted:// tabs where creating one is forbidden — verified on a ChromeOS Terminal tab. The destination must be a normal window: moving out of an app or popup window is fine, moving into one is refused with "Tabs can only be moved to and from normal windows". So a ChromeOS Terminal session can be pulled out to its own window (new_window, then position it with viewport_resize) but cannot be merged back into the Terminal window — the closest look is window_type popup: no tab strip, no omnibox, visually a terminal window. An extension cannot create app windows: normal and popup are all Chrome offers. |
| tile_windowsA | Tile Chrome windows over one monitor, splitting its usable area into equal parts that leave no gap. Only Chrome windows: an extension cannot touch other applications. The monitor is chosen by pointing at a window already on it, since the work area is read from a page there — so at least one target window needs a scriptable tab (a chrome:// or chrome-untrusted:// tab cannot provide it). Maximized windows are restored first, because a maximized window accepts bounds and ignores them. |
| window_layoutA | Save the current window arrangement under a name, restore one, list or delete saved ones. save overwrites a same-named layout without asking. Window ids do not survive a browser restart, so restore recognises windows by the overlap of their tab URLs (same type required) and repositions the best match — windows it cannot recognise are reported, not guessed. Needs extension >= 1.14.0 for window geometry. |
| set_zoomA | Get or set tab zoom (0.25–5). No factor = read current; reset restores default. |
| http_authA | Set/clear credentials for HTTP Basic/Digest auth dialogs (browser-wide, in-memory only). |
| security_headersA | Audit security headers (CSP, HSTS, XCTO, clickjacking, Referrer/Permissions-Policy, version leaks). Captured from real navigations — reload if unavailable. |
| session_fixtureA | Snapshot localStorage, sessionStorage and cookies of the current origin into a named fixture on the server, restore one, or list what has been saved. A logged-in state is the usual reason. save overwrites a fixture of the same name without asking; restore writes entries on top of what is already there rather than clearing first, and refuses outright when the tab sits on a different origin than the one recorded — cookies would otherwise attach to the wrong site. name is required except for list. |
| get_interactivesA | List actionable elements (buttons, links, inputs, [role], [onclick]) with ready-to-use CSS selector, label, position, flags. Prefer this over dumping HTML to discover selectors. |
| extractA | Read repeated non-tabular structures — product cards, list items, search results — as one record per item: item_selector matches the repeating block, fields map output names to selectors relative to it. Read-only, deterministic, parsed server-side from the main-document HTML. |
| assertA | Assert a page condition, polling until timeout: element exists/visible (optionally with count or containing text), text on page, tab url/title. Patterns: substring, or "/…/" for regex. Recorded flows replay it as a test. |
| session_recordA | Record the commands of this session as a replayable jsonl file (replay with the CLI: chrome-bridge replay --file ). tab_id is stripped — replays target the tab they navigate. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/frsorrentino/chrome-bridge'
If you have feedback or need assistance with the MCP directory API, please join our Discord server