Skip to main content
Glama

Local Browser Control MCP

A local MCP server with a shared Chrome and Firefox extension. It controls your existing tabs and sessions. No remote relay, account or browser debugging port is required.

Install

Requires Node.js 22 or later and Yarn.

yarn install
yarn build
yarn setup

yarn setup starts the local bridge and prints the MCP configuration for this checkout. The MCP server also starts the bridge automatically when a tool is used.

Load the extension:

  • Chrome: open chrome://extensions, enable Developer mode, select Load unpacked, then select build/chrome in this checkout.

  • Firefox: open about:debugging#/runtime/this-firefox, select Load Temporary Add-on, then select build/firefox/manifest.json. Firefox removes temporary extensions when it closes. A permanent release installation needs Mozilla signing.

Allow access to the sites you want to control. The extension popup shows Connected when the bridge is available. Its button disables or enables browser control for that profile.

After an update, run yarn build, reload the extension and reconnect the MCP client. Chrome now requires the debugger permission for trusted page input. Chrome can display a debugging banner while control is attached. No remote debugging port is needed.

New tabs open in a blue MCP Automation tab group in an existing normal window, without changing your selected tab by default. Named sessions reuse their group; new sessions prefer the focused normal window. A new window is created only when no normal, non-incognito window is available. Screenshots briefly select their target tab, then restore the previous selection unless you selected a different tab during capture. browser_focus intentionally brings the target forward.

A blue virtual cursor shows movement and pulses at each click. It stays visible between actions. The injected viewport overlay uses a closed shadow root to isolate its styles and the browser's popover top layer to appear above dialogs. It is click-through and never moves your physical cursor. Reduced-motion settings disable movement animation and replace expanding pulses with a fade. Navigation removes the overlay until the next action; iframe actions display it within the targeted frame.

Idle tab cleanup

Automation tabs close after four hours without use, checked every five minutes. Change the timeout in the extension popup; 0 disables cleanup. Agent actions, navigation and selecting an owned tab refresh the session deadline. A selected or audible tab in a group keeps that group active. Pinned tabs and tabs marked as handoffs or deliverables are protected.

Only tabs created by this extension, or child tabs opened from them, are eligible. Manually added tabs and tabs outside their automation group are left alone. Closing the last tab removes the group automatically. Pin or mark tabs containing work you need to keep: unmarked idle tabs, including forms, may close.

Ownership and deadlines survive background-worker restarts, but not a full browser restart or extension reload. Older groups without recorded per-tab ownership are never adopted for automatic closure.

Add the configuration printed by yarn setup to your MCP client. The transport is stdio. For this checkout:

{
    "mcpServers": {
        "browser-control": {
            "command": "/usr/bin/node",
            "args": ["/home/kieran/dev/browser-control-mcp/dist/server.js"]
        }
    }
}

Restart or reconnect the MCP client after adding the server. Call browser_list, then browser_tabs. Use the returned browser id if multiple profiles are connected. chrome or firefox also works when exactly one matching profile is connected.

Related MCP server: open-browser-control

Tools

Tools

Purpose

browser_list, browser_windows, browser_tabs, browser_frames

Find browser profiles, windows, tabs and frames

browser_open, browser_navigate, browser_close, browser_focus

Manage tabs

browser_back, browser_forward, browser_reload

Navigate history and reload

browser_snapshot

Read visible text and interactive element refs

browser_screenshot

Capture the visible viewport as a PNG

browser_click, browser_hover, browser_move

Interact with an element or move the virtual cursor

browser_fill, browser_type, browser_select, browser_press

Edit forms and send keys

browser_scroll, browser_wait

Scroll or wait for text/an element

browser_drag, browser_select_text, browser_paste

Drag, select a text range and paste text or HTML

browser_secondary, browser_mark

Expand/collapse controls, change numeric values and mark tab handoffs

browser_capabilities, browser_accessibility

Check input support and read Chrome's native accessibility tree

browser_api, browser_run, browser_reset

Read the JavaScript API, run persistent scripts and reset variables

Page tools use tabId. Targets use ref from a snapshot or a CSS selector that matches one element. Click also accepts viewport coordinates x and y. Use frameId for an iframe. Open shadow roots are included. Refs are scoped to a document and become stale after navigation.

Typical sequence:

browser_list {}
browser_tabs {"browser":"firefox"}
browser_snapshot {"browser":"firefox","tabId":3}
browser_fill {"browser":"firefox","tabId":3,"ref":"<ref from snapshot>","text":"Example"}
browser_click {"browser":"firefox","tabId":3,"selector":"button[type=submit]"}

Persistent browser scripts

Call browser_api for the reference. browser_run accepts JavaScript with top-level await. Variables remain available in the next call from the same MCP client:

let tab = await cua.createBrowserTab("chrome", "https://example.com", {
    sessionName: "Research",
});

In a later call:

await tab.getAXStateAndScreenshot();
await tab.markDeliverable();

State output contains numeric element indices. Use a current index with tab.click(index) or tab.setValue(index, text). Use nodeRepl.write(value) to return other values. Observations emit automatically unless emit:false is set. Each named session has its own tab group; groups can share a window with normal tabs. Handoff and deliverable marks protect tabs from idle cleanup; they do not send messages or publish tabs.

Scripts run in a separate local Node process, not a security sandbox. They have the MCP process's OS permissions. Await all browser actions. A script timeout resets its variables but does not undo or cancel browser actions already sent. browser_reset clears variables without closing tabs. See API compatibility for exact signatures and differences.

Connection and security

The bridge listens only on 127.0.0.1:18925. MCP clients use authenticated local HTTP requests. Extensions use an authenticated local WebSocket. A random pairing token is created in .local/config.json and copied into the generated extensions. Neither directory is tracked by Git. Do not publish generated extension folders or their ZIP files: they contain your local pairing secret.

The bridge rejects web page origins. Extension authentication has a five-second deadline. Heartbeats run every 15 seconds. A dropped connection fails pending requests and reconnects automatically. Browser actions are not automatically replayed: after a timeout or disconnect, inspect the page before retrying a write. Multiple MCP clients share one bridge. Actions are serialised within each browser profile.

The bridge runs independently of a single MCP client. This prevents one client closing from disconnecting other clients. For a foreground bridge with visible startup errors, use node dist/server.js --bridge. To use another port, stop the bridge, change port in .local/config.json, run yarn build, and reload both extensions.

Chrome uses Manifest V3 and a service worker. Firefox uses Manifest V2 and a persistent background script, with the same action code. This avoids Firefox's Manifest V3 screenshot permission issue. Minimum versions are Chrome 120 and Firefox 139.

Limits

This is an independent implementation with a browser-facing cua compatibility API. It does not implement OpenAI's private extension protocol or all of its runtime features.

  • Chrome supports trusted text insertion only, when the target tab is active in the focused window. Background automation uses DOM input. Explicit inputMode:"trusted" requests fail if the target is not in front; they never focus it automatically. inputMode:"dom" always requests synthetic input. Close DevTools for the target tab if they conflict with attachment.

  • Pointer actions and keyboard chords use DOM events in both browsers. Native Chrome pointer and key delivery did not pass validation, so trustedPointer and trustedKeyboard are false. Explicit trusted pointer/key requests return an error. Sites that require these trusted events are not supported.

  • Firefox and explicit iframe actions use synthetic DOM input. Sites can reject these events. Synthetic hover does not guarantee CSS :hover, and synthetic drag does not reproduce every browser drag behaviour. Neither backend moves your physical pointer.

  • HTML paste uses DOM editing in both browsers. Text and Markdown paste insert literal text, not rendered Markdown. Native clipboard contents are not changed.

  • Browser settings pages, extension stores and some built-in viewers block content scripts.

  • Screenshots cover the visible viewport and briefly activate the requested tab within its window before restoring the previous selection. They can briefly interrupt what you see. Explicitly targeting one of your normal tabs can still affect that tab.

  • It does not support file upload/download management, browser permission dialogs, native dialogs, closed shadow roots or browser-toolbar keyboard shortcuts. The JavaScript API controls page input, not the address bar.

  • Semantic snapshots approximate accessible names and hierarchy from the DOM; they are not complete native accessibility trees. Chrome's native tree is available separately through browser_accessibility. Firefox does not provide that tool.

  • Password input values are redacted in snapshots. Page text and screenshots can still contain sensitive data and are returned to the MCP client.

  • Browser navigation can finish before a single-page application has rendered its content. Use browser_wait for the required element or text.

  • The MCP process and browser must run on the same computer. A remote agent needs to launch this stdio server on the browser's computer, for example through SSH. Do not expose the loopback bridge publicly.

Development and tests

yarn check
yarn build
yarn test

Tests use temporary profiles and an isolated bridge on ports 19826 and 19827. They do not use your normal browser profile. Chromium must be installed for Playwright (yarn playwright install chromium). To also test installed Firefox, supply a Mozilla geckodriver executable:

GECKODRIVER=/path/to/geckodriver yarn test

The Firefox test uses port 19828 and /usr/bin/firefox. It installs the extension temporarily in a disposable Firefox profile. Both browsers run the same MCP tests for form controls, shadow roots, frames, screenshots, stale refs and connection recovery. The suite also checks that idle connections remain available beyond the Chrome worker inactivity window.

Implementation references: MCP SDK, Chrome WebSocket worker lifecycle, Firefox background scripts, Firefox extension connection policy.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    F
    maintenance
    Enables AI agents to directly control your real Chrome browser with full context including login sessions, cookies, and open tabs. It provides tools for page scanning, JavaScript execution, CDP control, screenshots, and physical mouse/keyboard input for authentic browser automation.
    20
    241
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI agents to control the user's Chrome or Firefox browser, leveraging existing sessions for tasks requiring authentication and user handoff.
    18
    48
    16
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables local AI agents to operate the user's existing browser session via a Manifest V3 extension and native messaging, supporting tabs, DOM snapshots, clicks, form input, JavaScript, screenshots, cookies, network capture, and Arc Spaces.
    71
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables AI agents to control a persistent Chromium browser or attach to an existing Chrome with sandboxed JavaScript and structured tools for web interaction and automation.
    16
    MIT

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/kierandrewett/browser-control-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server