mare-browser-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mare-browser-mcpgo to example.com and get the page title"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mare-browser-mcp
A lean, LLM-first browser automation MCP server. Gives Claude (or any MCP client) a real Chromium browser to navigate, interact with, and debug web apps — without the overhead of raw Playwright APIs.
Built with Playwright + MCP SDK. One server = one browser session = one LLM.
Free to use. If it saves you time, buy me a coffee ☕
Install (recommended)
Prerequisites: Node.js 18+, pnpm
git clone https://github.com/emadklenka/mare_browser_mcp
cd mare_browser_mcp
pnpm install
npx playwright install chromiumThis is the fastest way to run the server — starts instantly with no registry lookups.
Related MCP server: HumanBrowser
Alternative installs
Global install — no cloning, still fast:
pnpm add -g mare-browser-mcp
npx playwright install chromiumRegister with Claude Code
If you cloned the repo, the setup script does it for you:
pnpm run setupThat's it. The script detects the correct path automatically and registers the MCP with Claude Code. Restart Claude Code and the browser tools are ready.
Manual config — add to ~/.claude.json under mcpServers:
{
"mcpServers": {
"mare-browser": {
"command": "node",
"args": ["/absolute/path/to/mare_browser_mcp/src/index.js"],
"env": { "HEADLESS": "false" }
}
}
}If installed globally:
{
"mcpServers": {
"mare-browser": {
"command": "mare-browser-mcp",
"env": { "HEADLESS": "false" }
}
}
}Register with OpenCode
Add this to ~/.config/opencode/opencode.json (global) or opencode.json (project root):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"mare_browser_mcp": {
"type": "local",
"command": [
"node",
"/absolute/path/to/mare_browser_mcp/src/index.js"
]
}
}
}If installed globally:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"mare_browser_mcp": {
"type": "local",
"command": ["mare-browser-mcp"]
}
}
}Tools
browser_navigate(url, clear_logs?)
Navigate to a URL. Pass clear_logs: true when starting a new task to wipe stale console/network/dialog history.
browser_act(commands[])
Run a sequence of actions in one call. Supported actions:
action | required params | optional params | what it does |
|
|
| Click an element. Use |
|
| Hover over an element — triggers tooltips, dropdown menus, hover states | |
|
|
| Drag an element to another element ( |
|
| Click a link/button by its visible text | |
|
| Type into an input (clears first) | |
|
| Select a dropdown option | |
|
| Press a key (e.g. | |
|
|
| Wait until element appears |
|
| Scroll element into view | |
|
| Pause for N milliseconds | |
| — | Clear console log buffer |
browser_debug()
Start here when something goes wrong. Returns in one call:
Current URL and page title
Console logs (filterable by type:
error,warning,log,pageerror)Network requests with: method, URL, query params, request body, request headers (auth masked), status code, response body (JSON), and
duration_mstimingDialog history (alert/confirm/prompt — auto-accepted, text captured)
Filter with url_filter, method_filter, console_types, or last_n.
browser_query(selector, all?, fields?, visible_only?, limit?, count_only?)
Read the DOM without a screenshot. Query any element by CSS selector.
param | what it does |
| Return all matching elements (default: first only) |
| Pick fields: |
| Filter to visible elements only — recommended for broad selectors |
| Cap the number of results (e.g. |
| Just return the count — fast way to check "how many rows?" without fetching data |
browser_eval(code)
Escape hatch for anything the other tools don't cover:
Read computed styles:
getComputedStyle(el).backgroundColorAppend text to inputs without clearing
Type character-by-character for autocomplete
Drag-and-drop via manual DOM events
Call
fetch()to hit APIs directlyRead JS app state (
window.__store__, etc.)Check CSS visibility (
display,opacity,visibility)
browser_scroll(direction?, pixels?, selector?, container?)
Three modes:
Page scroll:
direction: "down", pixels: 500Scroll into view:
selector: ".my-element"Scroll within a container:
container: ".ag-body-viewport", direction: "down", pixels: 300— for scrollable divs, grid viewports, chat panels
browser_wait_for_network(url_pattern?, method?, timeout?)
Wait for a specific network response after triggering an action — smarter than guessing with wait.
browser_screenshot()
Returns a PNG screenshot. Use as a last resort — prefer browser_debug and browser_query first.
browser_upload(selector, files[])
Upload files to a file input element.
browser_restart(url?)
Kill the browser and start fresh. Clears all logs. Optionally navigate to a URL after restart.
browser_emulate_device(device, orientation?, custom?)
Switch the browser into a device profile for responsive QA. Emulation persists across navigations until you swap devices or call browser_restart.
Presets (natural portrait viewport):
iphone-15-pro-max(430×932),iphone-15-pro(393×852),iphone-15(393×852),iphone-se(375×667)galaxy-s24(360×800)ipad-pro-13(1024×1366),ipad-pro-11(834×1194),ipad-mini(768×1024)galaxy-tab-s9(800×1280)desktop-chrome(1280×800) — resets to desktopcustom— requirescustom.userAgent+custom.viewport.{width, height}
Swapping devices recreates the browser context, so cookies and localStorage are lost and auth'd pages may land on login. innerWidth: 980 on a mobile emulation viewing a page without <meta name="viewport"> is Chrome's legacy fallback, not a bug — pointer_coarse, hasTouch, and userAgent are the authoritative signals. browser_debug surfaces the active emulation under an emulation field.
Example workflow
1. browser_navigate("https://myapp.com", clear_logs: true)
2. browser_act([
{ action: "fill", selector: "#email", value: "user@example.com" },
{ action: "fill", selector: "#password", value: "secret" },
{ action: "click", selector: "button[type=submit]" }
])
3. browser_wait_for_network({ url_pattern: "/api/session", method: "POST" })
4. browser_debug({ console_types: ["error"] }) <- check for login errors
5. browser_query(".dashboard-title") <- confirm we're logged inHover + tooltip example
1. browser_act([{ action: "hover", selector: ".info-icon" }])
2. browser_query(".tooltip", { fields: ["text", "visible"] })Drag-and-drop example
// Reorder columns
browser_act([{ action: "drag", selector: ".col-name", target: ".col-age" }])
// Resize a column by 100px
browser_act([{ action: "drag", selector: ".resize-handle", offsetX: 100, offsetY: 0 }])Right-click context menu
1. browser_act([{ action: "click", selector: ".grid-row", button: "right" }])
2. browser_query(".context-menu-item", { all: true, fields: ["text"] })Scroll inside a container
browser_scroll({ container: ".ag-body-viewport", direction: "down", pixels: 500 })Count elements quickly
browser_query({ selector: ".ag-row", count_only: true })
// -> { selector: ".ag-row", count: 47 }Emulate a mobile device
1. browser_emulate_device({ device: "iphone-15-pro-max" })
2. browser_navigate({ url: "https://www.youtube.com" })
// redirects to m.youtube.com because of the iPhone UA
3. browser_screenshot() // mobile layout
4. browser_emulate_device({ device: "ipad-pro-13", orientation: "landscape" })
5. browser_emulate_device({ device: "desktop-chrome" }) // resetEnvironment
Variable | Default | Description |
|
| Run browser headless ( |
|
| Use your installed Chrome instead of Playwright's Chromium |
|
| Chrome profile name (when |
The browser launches lazily — it won't open until the first tool call.
License
MIT — free to use, modify, and distribute.
If this project helps you, buy me a coffee ☕
This server cannot be installed
Maintenance
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
- 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/emadklenka/mare_browser_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server