Sign inSign up

kubed/selenium-mcp

By kubed

•Updated 23 days ago

Image
0

124

kubed/selenium-mcp repository overview

⁠Selenium MCP

An MCP server that drives a real browser on Selenium Grid⁠, and serves the same actions as plain HTTP endpoints.

The browser is persistent. A session stays alive between calls and keeps its page, cookies and scroll position, so an agent can work through a multi-step task instead of starting a fresh browser for every action.

⁠Two surfaces, one implementation

SurfaceForPath
MCP over Streamable HTTPagents and MCP clients/mcp
JSON over HTTPanything else — n8n HTTP nodes, curl, scripts/browser/*

Both call the same functions in actions.py, so they cannot drift. A capability added once appears on both.

⁠Actions

ToolEndpointDoes
open_sessionPOST /browser/openStart a session; returns the session_id everything else needs
navigatePOST /browser/navigateGo to a URL
clickPOST /browser/clickClick the element at an XPath
writePOST /browser/writeType into a field, optionally pressing Enter
press_keyPOST /browser/press-keyPress a named key — Tab, Escape, arrows
extractPOST /browser/extractRead an element's text and HTML
execute_scriptPOST /browser/scriptRun JavaScript and return its result
screenshotPOST /browser/screenshotCapture the viewport, one element, or the full page
close_sessionPOST /browser/closeQuit the session and free its Grid slot

GET /health reports Grid readiness and the live session count. It needs no credentials, so a kubelet can probe it.

⁠Sessions

open_session returns a session_id; every other call takes it. Nothing is stored in this process — the browser lives on the Grid — which is why the server can restart, scale to zero, or run behind several replicas without losing a browser.

Always close_session, including on failure paths. Sessions are limited and an abandoned one holds a slot until the Grid times it out.

⁠Navigation

click, write, press_key, extract, screenshot and execute_script all take an optional url. It is not an assertion — if the browser is somewhere else it navigates there first, so a caller can jump straight to a page instead of clicking a path to it. URLs compare with the fragment and any trailing slash ignored; query strings count.

⁠Screenshots

Three modes: pass xpath for one element, full_page for the whole scrollable page, or neither for the viewport. Over MCP the result is an image content block a vision model can actually see; over HTTP it is base64 plus real pixel dimensions and byte size.

Everything uses plain W3C WebDriver, so it works on any browser the Grid runs. Chrome has no W3C full-page command, so full_page grows the window to the document height.

⁠Configuration

Every flag has an environment fallback.

EnvFlagDefaultNotes
GRID_URL--grid-urlthe in-cluster Grid ServiceSelenium Grid hub
MCP_AUTH_TOKEN--auth-tokenunsetBearer token required on /mcp and /browser/*. Unset disables auth
ROUTE_PREFIX--route-prefix/browserPath prefix for the HTTP endpoints
TRANSPORT--transporthttphttp or stdio
HOST / PORT--host / --port0.0.0.0 / 8000
LOG_LEVEL--log-levelINFO
⁠Auth

Setting MCP_AUTH_TOKEN turns on auth for both surfaces at once. Clients send it the normal way:

Authorization: Bearer <token>

The HTTP endpoints also accept the bare token as the Authorization value, for clients that cannot express a scheme. /health is always open.

In the cluster the token is generated by External Secrets — no value is authored anywhere. See apps/selenium/components/mcp in the cluster repo.

⁠Running it

docker compose up --build

That starts the server and a standalone Grid for it to drive, with auth off:

curl localhost:8000/health
curl -X POST localhost:8000/browser/open -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com","width":1280,"height":800}'

Point an MCP client at http://localhost:8000/mcp. The Grid's noVNC view is on localhost:7900 if you want to watch the browser work.

⁠Development

pip install -e ".[test]"
ruff check kubed
pytest

The tests wire a server against an unroutable Grid address and drive both surfaces through the real ASGI app, so they need no browser and no network.

⁠References

Tag summary

Content type

Image

Digest

sha256:5d79cffd0…

Size

87.2 MB

Last updated

23 days ago

docker pull kubed/selenium-mcp