selenit-mcp
Provides browser automation and control for Google Chrome via CDP/Selenium, enabling navigation, interactive element snapshots, clicking, typing, form selection, alert handling, scrolling, iframe interaction, file uploads, hover actions, key presses, resizing, network monitoring, explicit waits, screenshots, JavaScript evaluation, history, and tab management.
Click on "Deploy 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., "@selenit-mcpopen example.com and list the clickable elements as e1/e2 refs"
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.
selenit-mcp
Browser automation built for small local models.
Selenium-powered MCP server · compact e1-style snapshots · loop protection · deterministic replay · attaches to your own Chrome.
Most browser MCP servers are designed for large cloud models: rich accessibility trees, verbose
output, plenty of tokens to spare. selenit-mcp goes the other way. It emits compact,
reference-based page dumps (e1, e2, …), guards against the failure modes small models
actually hit, and attaches to a real Chrome over CDP — so a 4B model running locally can
navigate, fill forms, and complete multi-step tasks without drowning in context.
🇹🇷 Turkish documentation (detailed engineering log): TURKCE.md
Contents
Related MCP server: Fast Browser MCP
Head-to-head benchmark against Playwright MCP
Same model, same machine, same task, same scoring rule, both tools with their own native tool
surface. Task: open the site, search for a term, report the first result heading as
title | url. A run passes only if a claimed heading's words actually exist in the live page
text — invented headings are counted as failures, not successes.
Run 2026-10-30 · google/gemma-4-e4b (LM Studio, temperature 0, thinking off, max_tokens 1200, 16-step budget, 1 run per site, tool-output cap 2,000 chars/call)
Tool | Tasks passed | Median steps | Median time | Median tool-output chars | Median tokens (prompt + completion) | Tokens / step |
selenit-mcp | 2/5 | 3.0 | 67.7 s | 6,000 | 15,542 + 1,034 = 16,576 | 5,225 |
Playwright MCP | 0/5 | 3.0 | 100.4 s | 751 | 16,363 + 1,871 = 18,234 | 5,896 |
Site | Selenit | Playwright MCP | What happened |
Wikipedia (EN) | PASS 4 steps, 72 s | FAIL 16 steps, 391 s | Playwright targeted |
npm (EN) | PASS 3 steps, 54 s | FAIL 3 steps, 76 s | Playwright waited for a search field that the SPA injects; gave up and reported it could not proceed. |
GitHub (EN) | FAIL 3 steps, 61 s — hallucinated | FAIL 11 steps, 302 s | Selenit claimed "Repository search results · GitHub" — that page text did not exist. Caught by the scorer, not hidden. |
Hürriyet (TR) | FAIL 10 steps, 495 s | FAIL 3 steps, 100 s | Selenit burned the whole step budget returning an empty answer. |
Trendyol (TR) | FAIL 3 steps, 68 s — hallucinated | FAIL 2 steps, 41 s | Selenit claimed an "Arama Sonuçları - Trendyol" heading that was not on the page. |
What this run actually shows. Selenit completed 2 of 5 tasks where Playwright MCP completed 0 — the gap is real and it is largest exactly where small models break down: when a tool call errors, Playwright's surface lets the model retry the same target until the step budget is gone (16 steps, 391 s on Wikipedia), while Selenit's loop guard turns the third identical call into a directive and the model stops. But 2/5 is not a good result. Four of the five real-site tasks are unsolved by at least one side, two Selenit "answers" were fabricated titles (correctly scored as failures), and the Turkish sites — which need SPA-ready search fields and bot-wall handling — failed on both sides. Total tokens are within 10% of each other, so this run does not support a "Selenit uses fewer tokens" claim either.
The honest reading: on a 4B model, a tool surface that guards against loops buys task completion, but
it does not yet make live-site search reliable. Treat 2/5 vs 0/5 as a direction, not a verdict, and
re-run with KOSUM=3 before quoting it anywhere.
Compare with the earlier 5-site run on a large model (deepseek-v4.1-flash, bench/kiyas-deepseek-adil.json):
5/5 vs 1/5, median 4.8 vs 9.2 steps. Same direction, much stronger signal — the tool-surface
effect matters more for weaker models, but a stronger model can still complete the task through a
worse surface.
Read this honestly. These are small-N runs on live websites the author does not control:
site markup changes, rate limits and bot walls move the numbers, and a single run is noisy. Use
KOSUM=3 for medians you intend to quote. The benchmark does not claim Selenium beats
Playwright in general — it claims that a tool surface designed for small models changes task
success rate and token burn.
Token accounting: both sides use LM Studio's usage.prompt_tokens / usage.completion_tokens,
summed over every step of a task. The per-call tool output fed back to the model is capped at
2,000 characters on both sides, so neither side is penalised by a harness limit the other does
not have.
Reported in this Medium article.
Quick start
One command — checks/installs Ruby, the gem and Chrome, then registers the MCP server:
curl -fsSL https://raw.githubusercontent.com/livdemirci/selenit-mcp/main/install.sh | bashIf Ruby 3.2+ is already present (or you prefer npm only):
npx -y selenit-mcp setup lmstudio --install # ruby+gem+Chrome check/install + config
npx -y selenit-mcp doctor # report ruby/gem/Chrome/config/portnpm only — Ruby sources ship inside the package:
gem install selenium-webdriver # requirement (not bundled)
npx selenit-mcp # stdio MCP server — prints a "ready" lineMCP client config: "command": "npx", "args": ["-y", "selenit-mcp"]. Set SELENIT_RUBY in env
to pin a specific Ruby.
From source:
git clone https://github.com/livdemirci/selenit-mcp.git
cd selenit-mcp
gem install selenium-webdriver
ruby bin/selenit-mcpRequirements: Ruby 3.2+, Google Chrome, and the selenium-webdriver gem. macOS and Linux are
tested; Windows is not — see ROADMAP.md.
Client configuration
Claude Desktop / any MCP client (claude_desktop_config.json):
{
"mcpServers": {
"selenit-browser": {
"command": "npx",
"args": ["-y", "selenit-mcp"],
"env": { "BROWSER_MCP_PORT": "19419", "BROWSER_MCP_MAX_ELEMENTS": "20" }
}
}
}LM Studio — let the package write the entry itself (it resolves the absolute Ruby path, the package path, and backs up your existing config):
npx -y selenit-mcp setup lmstudio # default port 19419
npx -y selenit-mcp setup lmstudio --port 19418 --max-elements 20
npx -y selenit-mcp setup print # JSON only, paste it yourselfThen restart LM Studio (or toggle Integrations). Manual equivalent — an absolute Ruby path
and cwd are required because a GUI-launched LM Studio may not have rbenv shims on PATH:
{
"mcpServers": {
"selenit-browser": {
"command": "/Users/you/.rbenv/versions/3.4.8/bin/ruby",
"args": ["/path/to/selenit-mcp/server.rb"],
"cwd": "/path/to/selenit-mcp",
"env": { "BROWSER_MCP_PORT": "19419", "BROWSER_MCP_MAX_ELEMENTS": "40" }
}
}
}Two Chrome modes
Managed (isolated) | Existing (your session) | |
How | Agent launches Chrome with | Chrome must already run with |
Pro | Never touches your tabs/cookies | Reuses your logged-in session |
When | Automation, testing, assistant chat | Continuing work in a portal you are signed into |
BROWSER_MODE=managed|existing|auto (default auto: attach if the port is open, otherwise launch).
Port separation
Two MCP servers attaching to the same CDP port fight over the same Chrome — give each its own port.
Consumer | Port | Profile |
Your assistant / coding agent |
|
|
LM Studio plugin |
|
|
Benchmark / replay |
|
|
selenit / your own Chrome |
| your own profile |
Warning: port 19218 is the one selenit uses. If you do not want an agent driving your own browser, use a separate port (recommended: 19419). A normally started Chrome cannot be attached to later; remote debugging is mandatory.
Why small models need a different tool surface
Design choice | Problem it solves for small models |
Compact dumps (~1–4 KB, max 40 elements) | Gemma E4B has a small context; raw HTML or full a11y trees blow it up |
| No CSS selectors to invent; fewer hallucinated locators |
Loop guard (same call 3× → warning, not execution) | Stops the classic scroll/read/snapshot death spiral |
Modal focus, overlay priority, row/card context |
|
Explicit waits + actionable errors | "ref is renewed every snapshot", "element is covered", "alert is open" |
Auto-recovery from JS alerts, stale elements, covered elements | The run continues instead of collapsing mid-task |
Measured on Gemma E4B (google/gemma-4-e4b, 20 tools, max_tokens 800): 17/17 tasks passed,
1–7 steps and 22–78 s per task, ~13 min total. Thinking is off by default
(BENCH_THINKING=0; set 1 to enable): the per-step cost dropped ~2.3×, and the real-site
Trendyol cart task passed in 13 steps (~439 s);
that discovery replays deterministically in ~30 s with no model at all.
How it works
Chrome is launched with
--remote-debugging-port=<port>and stays open (detached).Every later tool call attaches to the existing Chrome via CDP (
debugger_address) — no new browser per call.The page dump marks only visible/interactive elements with
data-tw-refand produces short text.Session, window, and cookies persist across calls.
Tools (23)
Tool | Description |
| Go to a URL, return a compact dump (waits out bot-check interstitials) |
| List interactive elements ( |
| Compact DOM read: header (URL/title/modal/alert ~400 chars) or element list via |
| Click by |
| Find an element by text, return a clickable ref (long pages) |
| Read visible page text (summary/translation) |
| Type into a field ( |
| Choose an option from a dropdown (native |
| Read/dismiss a JS alert ( |
| Scroll the page (down/up/top/bottom) |
| Enter an iframe / return to the main frame |
| Provide a local path to a file input |
| Hover an element (menus) |
| enter, tab, escape, arrowdown, … |
| Set the window size (consistent rendering) |
| WebDriver BiDi network monitor: requests/responses/console ( |
| Explicit wait: text, selector, URL, disappearance, element count, or download ( |
| Save a PNG, return the path |
| Run JS in the page (result truncated) |
| back / forward / reload |
| list / switch / close |
| Connection status |
| Close the session |
Safety nets
Loop warning: the same tool+arguments arriving a third time is not executed when the result and page state (URL + text hash) are unchanged; legitimate repetition (
+four times, paging) is allowed, and read-only tools (snapshot,dom,read,find,wait_for,status,screenshot,evaluate) are exempt. The response carries the page title/URL plus a directive telling the model what to do instead (stop and answer, stop scrolling, try another element) rather than the old generic "try browser_snapshot" — which, on abrowser_snapshotloop, told the model to repeat the very call that was looping. Measured on n11: the old wording let Gemma repeatbrowser_snapshot6× for 128 s and never answer; with the directive it stopped and answered correctly in 3 steps.Bot-check interstitials: if
navigatelands on a "Just a moment / Bir dakika lütfen / Checking your browser" screen, it waits up toBROWSER_MCP_CHALLENGE_WAIT(default 20 s) for the content to appear and only then returns the dump; otherwise it explains what to do.Hidden duplicates: when a CSS selector matches several nodes, the first visible one is used (menus often contain hidden copies of the same link).
Actionable errors: "refs are renewed every snapshot", "element is covered", "alert is open"; a wrong tag on
browser_selectsaysthis element is not a <select> but a <button>, and an invalid CSS selector returns an example-based hint.Alert hygiene:
navigatedismisses an open JS alert;snapshot/readreport it.Shadow DOM: the dump walks open shadow roots; ref resolution is done in JS (Selenium CSS search does not cross shadow boundaries).
Modal focus: while
role=dialog/aria-modalis open, only modal content is listed. Modals that carry no role (e.g.class*="modal|dialog|popup"covering the screen centre) are detected too.Overlay priority: content of
position:fixed+ high-z-index layers (cookie bars, notices) is listed first so the model can dismiss it.Row/card context: buttons inside table rows are shown as
Edit | 10 · Ada Lovelace · London; repeatedAdd to cartbuttons asAdd to cart | CEPFİT Boostar … · 57.97 TL. Card detection does not rely on class names alone: the nearest ancestor that shows a price-like string (1.234,56 TL,$19.99, …) and has at most 4 controls is used.Control priority: sort/filter controls (
aria-haspopup,role=combobox, text/class containingsort|filtre|filter) are listed before product cards, so a 40-item dump still contains "Sort by".Custom dropdowns:
browser_selectalso handles comboboxes that are not<select>(role=combobox,b-select,dropdown): it opens the widget, matches the option text and clicks it; on a miss it lists the visible options.Controlled inputs:
browser_typefalls back to the native value setter +input/changeevents when a React/Vue field swallows keystrokes; number fields are blurred to commit.Explicit waits: click/type/select/iframe/download use
Selenium::WebDriver::Wait(visibility, clickability, URL, text, file state). No fixedsleep; implicit wait is0. Timeouts return a message stating what was expected.Lazy load: if
browser_findfails, the page is scrolled, DOM/text growth is awaited, and the search repeats (maxBROWSER_MCP_LAZY_SCROLLS, default 8).Downloads:
browser_wait_for(type: "download", text: "report.pdf")reads Chrome'sdownloads-managershadow root, waits forIN_PROGRESSto finish, and returns the file path.After-click wait: URL changes are polled briefly with explicit waits; if a new tab opened, the correct 0-based index is suggested and a
TABSline is added while multiple tabs exist.Dump priority (form → sort/filter → primary action → overlay → card → rest): the element budget is spent on the controls whose absence is fatal, not on DOM order.
Form fields (
input,textarea,select) come first. Measured on n11.com: a content-dense home page has 485 interactive elements; card-first ordering filled all 40 slots with product cards and the header search box never appeared in the dump at all.Sort/filter controls (
aria-haspopup,role=combobox, text/class containingsort|filtre|filter) come next. Measured on Boyner: the 20k-product category page pushed "Önerilen Sıralama" past the 40-item budget, so the model could never sort.Primary action buttons (
Sepete Ekle/Add to cart/Buy now/Save/Submit, plusadd-to-cart/primaryclass hints) come second. Measured on an n11 product page: recommendation carousels consumed every slot and the page's own cart button (BUTTON.add-to-cart-btn) was missing; after the fix it ise2.
Settle after navigate:
document.bodyexisting does not mean the SPA finished rendering, sonavigatepolls the interactive-element count until two consecutive samples agree (ceiling ~0.9 s). Measured on n11: without it the navigate dump omitted the search box while a snapshot one second later included it — the model only ever sees the first dump.JS-driven submit escalation:
submit: trueclimbs a ladder and stops when the URL changes —Enter, 2) closest formrequestSubmit()or nearest submit-like control clicked via JS (works on<i>icons and overlay-covered nodes where Selenium click refuses), 3) URL scheme: try/arama?q=,/search?q=,/?s=,/search?s=and accept the first that both changes the URL and yields a populated body (≥10 interactive elements, so a soft-404 page of chrome is rejected). Measured on n11.com: no<form>, no button, no suggestion list, and both Seleniumsend_keys(:enter)and a hand-dispatched nativeKeyboardEventwere swallowed; only/arama?q=bluetooth+kulaklikproduced results (42 product links).
Search affordances that are not
<input>: some sites open search as an overlay, so no visible<input>exists until you click a text-less icon button. Measured on Trendyol: the control isbutton[data-testid="suggestion-placeholder"](aria-label "Open search"); clicking it injects the real<input>.birincil_eylemtherefore treatsdata-testid/aria-label/classmatchingsearch|suggestion-placeholder|search-iconas primary even with no text, otherwise the button is ranked behind product cards and never enters the dump. After the fix it ise1:e1 button Ürün, kategori veya marka ara.browser_dommodal flag matchessnapshot.js: the DOM summary used to reportmodal: !!document.querySelector("[class*=modal i],[class*=dialog i],[role=dialog]")— presence only, no visibility or geometry. Measured on Trendyol: a hiddenmodal-classed node mademodal: truewhile the real candidate was a 474×40 px cookie link that does not cover the screen centre, so the model was told a modal was open and chose the wrong strategy. Both code paths now require: visible (rect > 0, notdisplay:none/visibility:hidden/opacity:0), coverselementFromPoint(centre), and contains ≥1 visible interactive child.Overlay-gated inputs (
pointer-events: none): some sites render the search field withpointer-events: noneand put a plainDIVon top of it; clicking that DIV unhides the real field. Measured on Hepsiburada: input rect 418×52,display: inline-block,opacity: 1, yetpointerEvents: noneandelementFromPoint(centre)returnedDIV.initialComponent-…, so Seleniumsend_keysraisedElementNotInteractableError. Fixed bytype_click_ac(click the covering node, then re-resolve the ref — the click rewrites the DOM, so the old element handle goes stale) plusjs_yaz(native prototypevaluesetter +input/changeevents, required by React/Vue-controlled fields). After the overlay opens, a realEnterworks and is preferred over URL guessing.browser_readprefers the main content over the page chrome:body.innerTextstarts with the header/nav, so themaxcharacter budget was consumed by menu links before any result appeared. Measured on Hepsiburada:browser_readreturned only "Siparişlerim / Kampanyalar / Hepsiburada Premium…" — zero product names — while[class*="productList"]held an 8 509-character real listing.readnow tries[class*=productList],[class*=product-list],[class*=searchResult],main,[role=main],#contentfirst and uses the container text when it exceeds 200 chars. After the fix the same call starts withPensan Büro Mavi Tükenmez Kalem….browser_readappends a DURUM (status) line: result/item count plus remaining scroll distance, so the model does not have to scroll to discover what it already has. Measured on n11: Gemma scrolled 3× (third blocked by the loop guard) before reading the price that was already in thebrowser_typeoutput — the status line makes that information explicit.URL-scheme fallback must validate the destination, not just the URL:
submit_via_urlaccepted any candidate that changed the URL and had ≥10 interactive elements. Measured on Hepsiburada:/arama?q=kilimis a 404 page with 21 category links, and/?s=kilimrenders the home page with 124 product links — both passed the old check. Now each candidate is rejected whenhata_sayfasi?matches (title or first 400 chars of body:404,bulunamadı,sayfamız yok,not found) and unlessarama_terimi_sayfada?finds a token of the query in the first 3 000 chars of body text. The working schemes found so far:/arama?q=(n11),/sr?q=(Trendyol),/ara?q=(Hepsiburada — note the single r),/search?q=(GitHub),wiki/(Wikipedia).
browser_wait_for types
| Waits for | Fields |
| Text in the page body |
|
| A CSS selector to become visible |
|
| A URL fragment |
|
| A selector to disappear |
|
| At least N visible elements |
|
|
| — |
| Chrome download state + file |
|
Explore → freeze → replay
So the LLM does not pay on every run, a successful exploration becomes deterministic:
benchmark.rbsaves the steps and a durable CSS selector per element intoscenarios/<task>.json(shadow::host||innerfor shadow DOM).replay.rbreplays the same steps without a model and applies the same check.export_rspec.rbconverts the scenario into a Selenium + RSpec spec with Page Objects and shared explicit waits (try_for), runnable in CI.
ruby replay.rb filter # model-free replay
ruby export_rspec.rb filter # generates spec/generated/filter_spec.rb
BROWSER_MCP_PORT=19419 rspec spec/generated/filter_spec.rbAll 18 scenarios replay model-free in ~60 s total; the 17 generated specs pass in ~6.7 s.
Policy and audit
BROWSER_MCP_ALLOWED_HOSTS="example.com,portal.company.com" # empty = all
BROWSER_MCP_REQUIRE_APPROVAL=true # require confirmation for risky actions
BROWSER_MCP_ALLOW_DATA=true # allow data: URLs (default true)With BROWSER_MCP_REQUIRE_APPROVAL=true, buttons labelled delete/pay/send do not run without
confirm=true; the model has to ask you first.
Every tool call is appended to artifacts/audit-YYYYMMDD.jsonl (passwords/tokens masked, long
text truncated). See SECURITY.md for the threat model.
Configuration
Variable | Default | Description |
|
| CDP port (19419 recommended) |
|
|
|
|
| Managed profile directory |
|
| Max elements per dump (20–40 for Gemma) |
|
| Headless managed browser |
|
| Default explicit wait timeout (s) |
|
| Max wait for a bot-check interstitial to clear (s; |
|
| Lazy-load scroll attempts for |
|
| Managed download directory |
|
| Screenshot directory |
|
| Audit log directory |
|
| Attach upper bound; restarts an isolated Chrome on hang |
|
| Reject a missing selector this fast when the page is loaded |
|
| Post-action toast harvest window ( |
Reproducing the benchmark
# 1) local scenario pages + unit checks (no model needed)
python3 testapp/server.py 8765 &
ruby smoke_test.rb # 38/38 checks
# 2) head-to-head against Playwright MCP (needs LM Studio's OpenAI-compatible server on :1234
# and Node/npx for @playwright/mcp)
KOSUM=1 ruby kiyas.rb # 5 live sites, ~20 min
KOSUM=3 SITE_FILTER=wikipedia ruby kiyas.rb
BENCH_MODEL=minicpm5-2b ruby kiyas.rbkiyas.rb writes bench/kiyas-<model>-<timestamp>.json (every step's trace, the page text used for
scoring, and token counts) plus a paste-ready .md summary. Failures are preserved in the JSON — the
suite never silently drops a bad run.
benchmark.rb runs the task set against LM Studio without the comparison side:
ruby benchmark.rb # all tasks
ruby benchmark.rb deep select # selected tasks
BENCH_MODEL=google/gemma-4-e4b BENCH_MAX_STEPS=10 ruby benchmark.rb
BENCH_THINKING=0 BENCH_MAX_TOKENS=1600 ruby benchmark.rb sepetHard scenarios in testapp/: login, filter, frame, shadow, upload, newtab, dynamic,
download.
Measured results (Gemma E4B, 17 local tasks)
Task | Steps | Time | Task | Steps | Time |
link | 2 | 28s | login | 4 | 43s |
form | 3 | 52s | filter | 5 | 69s |
wiki | 4 | 46s | frame | 7 | 76s |
hn | 1 | 22s | shadow | 4 | 54s |
deep | 3 | 30s | upload | 4 | 64s |
read | 2 | 36s | newtab | 5 | 68s |
select | 2 | 25s | dynamic | 5 | 78s |
alert | 3 | 32s | stale | 3 | 35s |
download | 3 | 34s | — | — | — |
Real-site task sepet (Trendyol: search → sort by lowest price → add to cart → verify price in the
cart): 1/1 passed with Gemma E4B, thinking off, 13 steps (~439 s); replay without a model ~30 s.
Honest comparison with Playwright MCP
Where this server wins
Topic | This server | Playwright MCP |
Attaching to an existing browser | CDP attach to your open Chrome | Manages its own browser instance |
Small-model (4B) efficiency | 40-element ref list, ~4 KB cap, row/card context, modal focus | Large a11y tree, more tokens |
Audit / safety |
| Policies live in the client |
Loop protection | Same call 3× → warning, never locks up | None |
Discovery → regression |
| None (needs a model/scenario each run) |
Shadow DOM / iframes | Dumps + refs + | |
Waiting / downloads | Condition-based explicit waits, lazy-load sweep, download state | Strong auto-waiting; no explicit download-completion wait |
Network observation |
| Richer interception (mocking/aborting) |
Where Playwright MCP wins
Trace viewer, video/screenshot artifacts; request mocking (BiDi
browser_monitoronly observes).Multiple browsers (Firefox/WebKit), mature auto-waiting, less discipline needed with large cloud models.
Bigger ecosystem and maintenance continuity.
Summary: for general-purpose cloud models with rich artifacts, Playwright MCP is stronger. For small local models + an existing session + auditing + deterministic regression, this server fits better.
Tips for Gemma E4B
Ask for one step at a time:
browser_navigate→browser_snapshot→browser_click.Prefer
ref(e3); give a CSS selector only when necessary.On long pages use
browser_findorbrowser_read; never ask for full HTML.Keep
BROWSER_MCP_MAX_ELEMENTSbetween 20 and 40.Short system prompt:
You are an agent doing browser automation. Call one tool per step.
Use browser_snapshot to understand the page and select elements by refs like e1, e2.
Never request long HTML or full page text; answer briefly.Contributing
Issues and PRs welcome — see CONTRIBUTING.md. Especially useful right now: benchmark runs on models we have not measured yet (Qwen 3.5 4B/9B, LFM 1.7B, Hermes), Windows install reports, and real-site failure traces with the JSON attached.
License
MIT — see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Control a real browser from AI agents: navigate, click, type, screenshot, read the page.
Stealth web automation for AI agents. Login, signup, navigate, screenshot.
Stealth web automation for AI agents. Login, signup, navigate, screenshot.
Headless browser primitives for AI agents when sites need real JS rendering.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides 66 tools for browser automation using Selenium WebDriver, enabling AI agents to navigate, interact, capture screenshots, assert conditions, manage cookies, handle tabs, execute HTTP requests, record sessions, and more.10 npm1MIT
- AlicenseBqualityAmaintenanceEnables AI agents and developers to automate real Chrome/Chromium browsers through the Chrome DevTools Protocol, with token-efficient snapshots, multi-action batching, shadow DOM traversal, system-page control, extension management, and network/WebSocket inspection.811MIT
- FlicenseNot gradedqualityNot gradedmaintenanceEnables AI agents to browse and interact with web pages through a persistent headless Chromium session, serving compact structured orientations, targeted element queries, and full detail only when explicitly requested. It supports navigation, observation, form filling, monitoring, and session management while cutting token overhead by up to ~140x versus raw accessibility-tree dumps.4 npm-
- FlicenseNot gradedqualityAmaintenanceEnables AI agents to browse and interact with websites through a persistent headless Chromium session, returning compact structured page representations instead of full accessibility-tree dumps. Agents can navigate, query specific elements and forms, click, type, manage tabs and cookies, and monitor console or network activity while paying a fraction of the tokens.4 npm-