Skip to content

Repository files navigation

ORCHORDS — BUILD DIFFERENT.

Orchords Web Pilot

Main verification Daily build CodeQL Dependency audit License: Apache-2.0

⭐ If you like Orchords Web Pilot or find it useful, please consider starring this repository. It helps more people discover the project.

Interested in sponsoring ORCHORDS? Sponsorships start at US$1,000. Depending on the sponsorship level, sponsors may receive public recognition, logo and website placement, sponsor updates and early previews, roadmap-feedback briefings, priority issue triage, and engineering or integration discussions. Sponsorship does not buy control of the roadmap or guarantee feature implementation. Contact crm@orchords.com.

Independent software studio founded in 2025.

A Model Context Protocol server that gives coding agents a real browser — navigate, observe, interact, and capture proof on any web page through one transport-agnostic surface.

Orchords Web Pilot is a Model Context Protocol server that exposes a Playwright-backed browser session as a set of agent-friendly tools. Point your agent at it and it can navigate, observe, interact, and capture proof on any web page — same model across local and hosted browsers, same surface across stdio and Streamable HTTP transports.

Start here

If you need… Start with
Install and first run Install
Wire it into a desktop agent stdio (default)
Run it as a hosted service Streamable HTTP
Use a remote browser grid Local or remote browser
Available tools and parameters Tools · Configuration
Security guidance Security · SECURITY.md
Contributing process Contributing

Capabilities

  • Real Chromium session — local via Playwright or remote via any WebSocket endpoint (Browserless, hosted Chrome, your own grid)
  • Small, well-typed tool surface — navigate, snapshot, click, type, screenshot, drag, press-key, hover, evaluate JS, capture console + network, fill forms, manage tabs
  • One transport for everything — stdio for desktop agents, Streamable HTTP for hosted and multi-user setups
  • Auto-detection — set BROWSER_WS_ENDPOINT to flip to a remote browser; everything else stays the same
  • Accessibility-first — every interaction accepts an element target from the agent's snapshot, not raw pixel coordinates

Install

npm install -g orchords-web-pilot

Or run it straight from a checkout:

git clone https://github.com/ORCHORDS/OrchordsBrowserPilot.git
cd OrchordsBrowserPilot
npm install
npm run build
npm start

Compatibility

  • Node.js: >=20.10.
  • Playwright: >=1.59.1 <2.0.0. Web Pilot uses the AI-mode accessibility snapshot APIs introduced in the Playwright 1.59 line; startup fails with an actionable error if package-manager overrides force an older or unsupported major version.
  • Browser binaries: Playwright browser revisions are coupled to the installed Playwright package. After changing Playwright versions, install the matching browser with npx playwright install chromium (or npx playwright install --with-deps chromium on a fresh Linux runner).
  • Verification policy: every main push exercises the declared minimum Playwright 1.59.1 with a real browser and also installs the packed npm artifact into a clean fixture. The scheduled Daily Build deliberately overrides the lockfile with the current stable playwright@latest to detect upstream compatibility drift before the supported range is changed.

Web Pilot does not claim support for arbitrary older Playwright installations just because npm can be forced to resolve them. The declared dependency range, runtime guard, package smoke test, and CI compatibility lanes are the support contract.

Usage

stdio (default — desktop agents)

Add to your MCP client config (Claude Desktop, ZCode, etc.):

{
  "mcpServers": {
    "orchords-web-pilot": {
      "command": "orchords-web-pilot",
      "env": {
        "PILOT_HEADLESS": "true"
      }
    }
  }
}

Streamable HTTP (hosted / shared)

PILOT_TRANSPORT=http \
PILOT_HTTP_HOST=0.0.0.0 \
PILOT_HTTP_PORT=8788 \
PILOT_HTTP_PATH=/mcp \
npm start

Then point your client at http://<host>:8788/mcp.

Local or remote browser

By default Web Pilot launches a local Chromium via Playwright. To use a remote browser (Browserless, hosted Chrome, your own grid), set:

export BROWSER_WS_ENDPOINT="wss://chrome.browserless.io?token=..."

The server auto-detects: if BROWSER_WS_ENDPOINT is set it connects to that; otherwise it spins up a local browser.

Tools

Tool What it does
browser_navigate Open a URL.
browser_snapshot Return an accessibility tree (preferred for agent planning).
browser_click Click by ref (from snapshot), selector, or coordinate.
browser_type Type into the focused element.
browser_fill Set an input value directly.
browser_press Press a key (Enter, Tab, Escape, arrow keys…).
browser_hover Hover an element.
browser_drag Drag from one element to another.
browser_select Choose an <option> in a <select>.
browser_screenshot Capture PNG (returns base64 or saves to disk).
browser_evaluate Run a JS expression in the page context.
browser_console Read console messages captured for this session.
browser_network List network requests captured for this session.
browser_wait Wait for text, selector, or a fixed duration.
browser_captcha_solve Plug into an external captcha-solving service.

Snapshot refs

browser_snapshot returns an accessibility tree in which every interactive node carries a ref token, e.g.:

- generic [active] [ref=e1]:
  - heading "Settings" [level=1] [ref=e2]
  - button "Save" [ref=e3]
  - textbox "Email" [ref=e4]

Pass the token back into any interaction tool: browser_click({ "ref": "e3" }). Refs are resolved to scoped Playwright locators (role + accessible name + occurrence index), so they work even when CSS selectors would be brittle.

Ref lifetime. Refs are valid from the moment browser_snapshot returns until the next navigation (or another snapshot replaces them). After a browser_navigate, all previous refs are invalidated. Using an invalidated ref returns a structured error (Ref 'eN' is no longer valid…) rather than clicking the wrong element — take a fresh browser_snapshot and retry.

Fallback. Every interaction tool also accepts a raw CSS selector (and browser_click accepts x/y coordinates). Prefer refs for agent flows; use selectors only when you already know the DOM.

Sessions. Each MCP session owns its own page, console buffer, and network buffer. On the HTTP transport, sessions are keyed by the Mcp-Session-Id header; on stdio there is a single session for the process lifetime. Console and network diagnostics never leak across sessions.

The captcha-solver tool is a hook: it reads PILOT_CAPTCHA_SOLVER_URL and PILOT_CAPTCHA_SOLVER_TOKEN and forwards the challenge. Wire in your own provider (2Captcha, AntiCaptcha, your own microservice) — the MVP does not ship a default to keep the licensing surface clean.

HTTP transport security

The HTTP endpoint is hardened by default (#43):

  • Origin validation — any request carrying an Origin header must match the allowlist (loopback variants by default) or it is rejected with 403. This blocks malicious websites from driving your local browser via fetch against localhost:8788, including sandboxed null origins.
  • Host validationHost must match the bound host or the allowlist, defeating DNS-rebinding attacks.
  • Public-bind refusal — binding to a non-loopback address (including 0.0.0.0) fails at startup unless PILOT_HTTP_ALLOW_PUBLIC_BIND=true is set. There is no authentication yet (#42); expose the server only through an authenticating reverse proxy.
  • Rate limiting — fixed-window per client IP (default 120/min) with 429 + Retry-After.
  • Body cap + timeouts — requests above the body cap get 413; each request has a hard timeout (504).
  • Security headersX-Content-Type-Options: nosniff, Cache-Control: no-store, X-Frame-Options: DENY.

Configuration

All config is via environment variables. See .env.example.

Variable Default Notes
PILOT_TRANSPORT stdio stdio or http.
PILOT_HTTP_HOST 127.0.0.1 HTTP transport only.
PILOT_HTTP_PORT 8788 HTTP transport only.
PILOT_HTTP_PATH /mcp HTTP transport only.
PILOT_HTTP_ALLOWED_ORIGINS loopback Comma-separated Origin allowlist.
PILOT_HTTP_ALLOWED_HOSTS bind host Comma-separated Host allowlist.
PILOT_HTTP_RATE_LIMIT 120 Requests/minute per client IP.
PILOT_HTTP_MAX_BODY_KB 1024 Max JSON body size.
PILOT_HTTP_REQUEST_TIMEOUT_SEC 60 Hard per-request timeout.
PILOT_HTTP_TRUST_PROXY false Honor X-Forwarded-For (trusted proxies only).
PILOT_HTTP_ALLOW_PUBLIC_BIND false Required to bind beyond loopback.
PILOT_HEADLESS true Set false to watch the agent work.
BROWSER_WS_ENDPOINT (unset) Set to use a remote browser.
PILOT_CAPTCHA_SOLVER_URL (unset) Captcha solver endpoint.
PILOT_CAPTCHA_SOLVER_TOKEN (unset) Captcha solver bearer token.

Development

npm install
npm run dev      # tsx watch
npm run lint
npm test

Security

Web Pilot is opt-in remote-capable. The HTTP transport binds to 127.0.0.1 by default; change to 0.0.0.0 only behind auth. Never expose it on the public internet without putting a reverse proxy + auth in front.

See SECURITY.md.

Documentation boundary

Product-specific engineering guidance lives in this repository. Company-wide public engineering, security, governance, and operational documentation is maintained in ORCHORDS/docs.

Contributing

Issues and PRs welcome. See CONTRIBUTING.md.

Brand

ORCHORDS — BUILD DIFFERENT.

License

Licensed under the Apache License 2.0.

About

Orchords Web Pilot — MCP server that lets coding agents drive a real browser.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages