Atlas / MCP servers / kubed-io / selenium-flow

selenium-flowBLOCK

mcp/kubed-io/selenium-flow

A selenium mcp and http workflow client.

Verdict
BLOCK
Grade
D
Trust score
69 /100
Exposed tools
15 15r · 0w · 0d
Transport
stdio · streamable-http
License
MIT
Stars
2
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

One browser, many calls. Drive a real Chrome or Firefox on Selenium Grid from an agent over MCP — or from anything else over plain HTTP. Same actions, same server, one browser that stays exactly where you left it. 🧭

[](https://github.com/kubed-io/selenium-flow/actions/workflows/test.yml) [](https://github.com/kubed-io/selenium-flow/actions/workflows/quality.yml) [](https://github.com/kubed-io/selenium-flow/actions/workflows/image.yml) [](https://github.com/kubed-io/selenium-flow/wiki) [](LICENSE) [](https://hub.docker.com/r/kubed/selenium-flow) [](https://gofastmcp.com/)

The whole idea, in one breath

Open a browser once. It stays alive — same page, same cookies, same scroll position — while an agent works a task one call at a time, or an n8n workflow steps node to node. Nothing relaunches, nothing logs in twice.

agent  ──── MCP  /mcp ─────▶  ┌───────────────┐        ┌───────────────┐
│ selenium-flow │ ─────▶ │ Selenium Grid │ ──▶ 🌐
workflow  ──── HTTP /browser ──▶ └───────────────┘        └───────────────┘
holds no browser          the browser
lives here

This server holds no browser. The browser lives on the Grid, and with WORKSPACE_STORE=redis the recor

Read from source at commit 768dcd40b726OBSERVED · 2026-10-12
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control.

claude-code
claude mcp add selenium-flow-ui -- npx -y selenium-flow-ui
claude-desktop
{
  "mcpServers": {
    "selenium-flow-ui": {
      "command": "npx",
      "args": [
        "-y",
        "selenium-flow-ui"
      ]
    }
  }
}
03

Exposed tools (15)

15 read · 0 write · 0 destructive.

ToolRiskDescription
adminreadThe token.
authreadThe bearer token every request needs.
dbreadRedis database number.
dirsreadDirectories of secrets. First match wins.
grafanareadLDAP sign-in for Grafana
loginreadSign in
passwordreadRedis password.
portreadPort to listen on.
public_base_urlreadWhere browsers reach this server, for links.
redisreadThe workspace store’s connection.
secretsreadWhere secrets are read from.
selenium-adminreadAdmin token for this server
serverreadWhere it listens, and where it lives.
the-internetreadPublic demo login
tokenreadBearer token for every request. Unset is open.
04

Trust audit

BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (1 observation(s))
Network
declared (1 observation(s))
Shell
declared (1 observation(s))
Dependencies
pinned
Secrets in source
found

Findings (24)

HIGHCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
kubed/selenium_flow/flows/library.py:59
return len(text.encode()) + ENTRY_BYTES, yaml.load(text, Loader=_LOADER)
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
tests/test_capture_masking.py:321
token = "Tk-bound-secret-token-0123456789"                   # 32: fits the text
LOWInventory / provenance · inv.hidden_file · CWE-1104
.gitmodules
.gitmodules
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.hadolint.yaml
.hadolint.yaml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
tests/test_site_data_restore.py:204
"const counts = [eval(local), eval(session)];\n"
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
tests/test_site_data_restore.py:205
"console.log(JSON.stringify({counts, local: eval(read), session: sessionStorage.getItem('t')}));\n",
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/test_coercion.py:99
("../../etc/passwd", "passwd"),
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/test_files_and_admin.py:135
assert "%2F" in links.file_path("abc", "../../etc/passwd")
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/test_flowapi.py:430
response = client.get("/flows", headers=named("../../etc"))
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/test_flows.py:62
"sneaky/../../etc",
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/test_flows.py:354
for attempt in ("../escape", "..", "a/../../b"):
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/fakes.py:108
self.url = f"http://127.0.0.1:{self.server.server_address[1]}"
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/integration/conftest.py:145
local = f"http://127.0.0.1:{port}"
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/jwks.py:54
self.issuer = f"http://127.0.0.1:{port}/realms/example"
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/test_shutdown.py:42
base = f"http://127.0.0.1:{port}"
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/test_shutdown.py:47
"GRID_URL": "http://127.0.0.1:9",
LOWObfuscation / stealth · obf.anti_debug · CWE-506, CWE-94
tests/test_capture_masking.py:448
sys.settrace(lambda *a: None)
LOWObfuscation / stealth · obf.anti_debug · CWE-506, CWE-94
tests/test_capture_masking.py:452
sys.settrace(before)
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
kubed/selenium_flow/core/actions.py:102
return len(base64.b64decode(value, validate=False))
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
kubed/selenium_flow/core/actions.py:1232
shot["raw"] = base64.b64decode(image)
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
kubed/selenium_flow/core/actions.py:1294
data = base64.b64decode(at.driver.print_page(options))
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
kubed/selenium_flow/core/browser.py:142
raw = base64.b64decode(b64[:64])
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
kubed/selenium_flow/core/browser.py:499
archive = base64.b64decode(response.json()["value"]["contents"])
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
README.md:68
| [`save_site_data`](https://github.com/kubed-io/selenium-flow/wiki/save_site_data) | `POST /browser/save-site-data` | Keep cookies and storage to restore 🍪 |
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine

Gates applied: no_behavioural_pass.

Audited 2026-10-12 · audit v0.4.1 · source sha 768dcd40b726full audit observations/trust-audit/mcp-server/kubed-io__selenium-flow.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-12768dcd40b726BLOCKD69first audit
06

Questions

What is the selenium-flow MCP server?

A selenium mcp and http workflow client.

What tools does selenium-flow expose?

15 in total: 15 read-only, 0 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is selenium-flow safe to connect to an agent?

No — not without reading the findings first. The audit graded it D (69/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on.

What credentials does selenium-flow need?

No credential environment variables were found in its source, so it appears to need none.

How does selenium-flow run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as selenium-flow-ui.

How current is this page?

The grade is for one exact copy of the source (768dcd40b726), read on 2026-10-12. The repository is watched and re-audited when it changes.

Advertisement