# Chromiumfish Mcp

> Secure, session-aware MCP server for ChromiumFish browser automation

- **Type:** MCP server
- **Install:** `agentstack add mcp-loworbitlab-chromiumfish-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [LowOrbitLab](https://agentstack.voostack.com/s/loworbitlab)
- **Installs:** 0
- **Category:** [Web & Browser](https://agentstack.voostack.com/c/web-and-browser)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [LowOrbitLab](https://github.com/LowOrbitLab)
- **Source:** https://github.com/LowOrbitLab/chromiumfish_mcp

## Install

```sh
agentstack add mcp-loworbitlab-chromiumfish-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# chromiumfish_mcp

`chromiumfish_mcp` is an independent Model Context Protocol (MCP) server for [ChromiumFish](https://github.com/arman-bd/chromiumfish). It lets Claude Code, Claude Desktop, Cursor, and other MCP clients drive a ChromiumFish browser through structured tools.

It uses the official ChromiumFish npm package and ships no Chromium source or binaries — on the first tool call that needs a page, the upstream SDK downloads and caches the matching browser build. See **[docs/USAGE.md](docs/USAGE.md)** for detailed tool usage.

## Requirements

- Node.js 20 or later.
- An OS and architecture supported by ChromiumFish.
- Network access for the initial browser download. If no prebuilt asset matches your platform, build ChromiumFish locally and point to it with `--chrome-path` or `CHROME_BIN`.

## Install

```bash
npm install --global github:LowOrbitLab/chromiumfish_mcp
chromiumfish_mcp --persona-seed alice
```

Or run without installing: `npx --yes github:LowOrbitLab/chromiumfish_mcp --persona-seed alice`.

## Configure

Add the server to your MCP client config:

```json
{
  "mcpServers": {
    "chromiumfish": {
      "command": "chromiumfish_mcp",
      "args": ["--persona-seed", "alice"]
    }
  }
}
```

To run from GitHub instead of a global install, set `"command": "npx"` and prepend `"--yes", "github:LowOrbitLab/chromiumfish_mcp"` to `args`. On Windows, use `npx.cmd` if your client cannot resolve `npx`.

## Tools

| Tool | Purpose |
|------|---------|
| `list_pages`, `open_page`, `select_page`, `close_page` | Manage pages by stable `pageId` |
| `navigate`, `navigate_back`, `navigate_forward`, `reload` | Navigate and use page history |
| `snapshot` | List visible interactive elements with `e1`/`e2` references |
| `get_text`, `take_screenshot` | Retrieve page or frame content; `take_screenshot` crops to one element with `target` |
| `click`, `hover`, `type_text`, `select_option`, `set_checked`, `press_key`, `scroll`, `wait_for` | Interact with the page |
| `drag` | Drag onto another element or by a pixel offset, with a human-like path |
| `handle_dialog` | Arm the answer for the next `alert`/`confirm`/`prompt`/`beforeunload` |
| `upload_file` | Attach local files to a file input — requires `--upload-dir` |
| `list_downloads` | Report what was downloaded and where it landed — requires `--download-dir` |
| `click_at` | Click absolute coordinates (for widgets `snapshot` cannot see) |
| `list_frames` | List frames/iframes with stable IDs |
| `find_challenge`, `solve_challenge` | Detect and clear interstitial / framed challenges; the result says whether one was observed, interacted with, and verified |
| `evaluate` | Run arbitrary JavaScript — requires `--allow-eval` |
| `run_task` | Native ChromiumFish agent — requires `--allow-native-agent` |

A JavaScript dialog is answered the instant it opens, because a page left waiting on one freezes and no later call could finish. Unarmed the answer is dismiss — which is what Playwright already did silently — so a click that only raised `confirm("Delete?")` did not delete, and the action result now says so under `dialogs`. Call `handle_dialog` to arm the next answer, then repeat the action. The four navigation tools also report the HTTP `status`, since a 404 or a 500 loads like any other page.

Every navigation and interaction tool reports the resulting `url`, `title`, `navigated`, and any `newPages`, so a client only needs a follow-up `snapshot` when the page actually changed; `returnSnapshot: true` returns the action result and a fresh snapshot in one call. An action that navigates waits for the new document before reporting, so those fields describe the page it arrived on; one whose navigation is still in flight after ten seconds reports `navigationPending: true` rather than describing the page being left as though nothing happened, and one whose navigation was cancelled outright — blocked by `--allowed-host`, an unresolvable host — reports `navigationFailed` with the browser's own reason instead of waiting out that bound for a page that is never coming. Reference numbers are never reused, so one held across a snapshot fails with an error instead of acting on a different element; `snapshot` also reports ARIA roles, so `role=button[name="Submit"]` works in any `target` field as a re-render-proof alternative. The server ships MCP `instructions` describing this workflow, reference lifetime, and the challenge sequence.

Snapshot references, frame-aware interaction, waiting, and the cross-origin challenge workflow are covered in **[docs/USAGE.md](docs/USAGE.md)**.

## Command-line options

```text
--persona-seed VALUE       Use a stable browser fingerprint persona
--chrome-path PATH         Use a local ChromiumFish executable
--browser-version VERSION  Select an upstream ChromiumFish build version (rejected with --chrome-path)
--headed                   Show the browser window
--window-size WIDTHxHEIGHT Set the browser window size
--timezone ZONE            Use an IANA time zone, auto, or system (default: auto)
--proxy URL                Route browser traffic through a proxy
--allowed-host HOST        Allow top-level navigation to a bare host and its subdomains; repeatable
--max-text-chars N         Set the hard limit for text and snapshot output
--upload-dir PATH          Allow upload_file to read this directory; repeatable
--download-dir PATH        Save downloads here; without it they are discarded
--allow-eval               Enable arbitrary JavaScript execution
--allow-native-agent       Enable the native ChromiumFish browser agent
```

Proxy credentials can be embedded in the proxy URL, but are then exposed in the client config. Never commit config files containing proxy passwords, cookies, or API keys.

## Security

- stdio only — do not expose the Chromium DevTools endpoint to the public internet.
- `evaluate` and the native agent are disabled by default; enable them only in trusted environments.
- `--allowed-host example.com` restricts top-level HTTP/HTTPS navigation (redirects, links, form posts, popups) to a host and its subdomains. Give it a bare host name: matching is on the host alone, so a scheme, path, port, leading dot, or wildcard is rejected at startup rather than quietly matching nothing. Third-party subframes and page assets remain reachable — it is a navigation guard, not a network egress filter. A blocked navigation is reported as `navigationFailed` with reason `net::ERR_BLOCKED_BY_CLIENT`, rather than as a click that appeared to do nothing. Enabling it also turns on request interception, which disables the browser's HTTP cache for the session: expect slower asset-heavy pages, and note that a browser re-fetching everything on a repeat visit is itself a signal to sites that profile behavior.
- `upload_file` sends host files to whatever origin the page posts to, so it is unregistered until `--upload-dir` names at least one directory, and every path must resolve inside one. Both the path and the roots are resolved through symlinks first, so a link planted inside a root cannot reach outside it. Scope the roots to the files a task actually needs — a page can influence which file the model picks.
- Downloads are written only when `--download-dir` names a directory; without it the transfer still runs (so the page's own flow is unchanged) but nothing is kept, and the action result says `discarded`. The file name comes from the remote server's `Content-Disposition`, so it is reduced to a bare base name and the resolved path is checked against the root before anything is written.
- A page can raise `confirm()` to guard a destructive action. Unarmed dialogs are dismissed, so that guard holds by default; `handle_dialog` with `accept: true` deliberately answers the next one. Keep human confirmation in front of it for anything irreversible.
- Clients can click and type with real side effects. Keep human confirmation for purchases, publishing, deletion, and permission changes.
- `solve_challenge` returns `ok: true` whenever the page is not blocked, including on pages that were never challenged. Read `challengeObserved`, `interactionPerformed`, and `clearanceVerified` before recording or reporting that a challenge was cleared — `ok` alone will overstate what happened.
- Each process runs an independent browser context; this is not a shared multi-tenant service.

## Development

```bash
npm ci
npm test
node dist/index.js --help
```

The suite uses an in-memory MCP transport to verify tool discovery, dangerous-tool opt-in, and results. It does not download or launch a browser.

## License

MIT. ChromiumFish code and trademarks belong to their respective contributors; see [NOTICE](NOTICE) for attribution. This is an independent wrapper, not an official ChromiumFish release.

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [LowOrbitLab](https://github.com/LowOrbitLab)
- **Source:** [LowOrbitLab/chromiumfish_mcp](https://github.com/LowOrbitLab/chromiumfish_mcp)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-loworbitlab-chromiumfish-mcp
- Seller: https://agentstack.voostack.com/s/loworbitlab
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
