Skip to main content

A server-side browser proxy that lets clients operate websites without direct remote connections.

Project description

Website Agent Server

English | 中文

Website Agent Server is a Python server-side browser proxy. The client never loads the target website directly. It connects only to this server, receives rendered browser frames, and sends mouse, keyboard, input method, clipboard, wheel, file upload, and navigation events back to the server.

How It Works

  • FastAPI serves the local control UI, HTTP API, and WebSocket endpoint.
  • Playwright launches Chromium on the server.
  • The target website runs inside the server-side browser context.
  • The client receives binary WebSocket image frames: JPEG screenshots by default, or PNG frames when --screenshot-quality 100 is used.
  • User actions are replayed into Chromium by the server.
  • IME text, paste, copy, cut, downloads, file chooser actions, cookie management, and ordinary media element audio are brokered through local server endpoints.

Because the remote page is never embedded as HTML in the client, page scripts, link clicks, images, XHR/fetch calls, WebSocket connections, and form submissions are performed by the server-side browser.

Setup

Create or reuse the repository-root virtual environment:

python -m venv venv
venv\Scripts\python.exe -m pip install -r requirements.txt
venv\Scripts\python.exe -m playwright install chromium

Run

venv\Scripts\python.exe -m website_agent_server

Open http://127.0.0.1:8000, enter a website URL, and operate the remote site through the rendered viewport. By default the server listens on all interfaces, so LAN clients can also connect with the server machine's LAN IP.

If a target URL is entered without an http:// or https:// prefix, the server first probes HTTPS. It uses HTTPS when the TLS service is available, otherwise it falls back to HTTP. The same rule applies to --lock-url and /lock_url/... paths.

You can lock only one client by putting the target URL in the server URL path:

http://127.0.0.1:8000/lock_url/https/example.com/path

That client opens the target immediately and hides the browser option controls. Other clients that open / keep the normal URL picker. Query strings and fragments are preserved, for example /lock_url/https/example.com/path?x=1#section.

Command-Line Configuration

venv\Scripts\python.exe -m website_agent_server --port 8080 --headed

Require a PIN before clients can use the proxy:

venv\Scripts\python.exe -m website_agent_server --pin 123456
Option Default Description
--host 0.0.0.0 Server bind host. Use 127.0.0.1 to restrict access to this machine.
--port 8000 Server port.
--headed disabled Run Chromium with a visible browser window.
--ignore-https-errors disabled Ignore remote TLS certificate errors.
--allow-private-hosts disabled Allow navigation and resource requests to private, local, or reserved networks.
--session-ttl-seconds 600 Disconnected client session and client browser context lifetime. A client can reconnect to its cached browser session during this window.
--navigation-timeout-ms 30000 Navigation timeout.
--frame-interval-seconds 0.18 Screenshot streaming interval.
--screenshot-quality 95 Frame quality from 1 to 100. Values below 100 use JPEG; 100 uses PNG.
--media-frame-interval-seconds 0.35 Screenshot streaming interval while remote media is playing.
--media-screenshot-quality 80 JPEG quality while remote media is playing. Ignored when --screenshot-quality 100 enables PNG.
--min-viewport-width 320 Minimum remote viewport width.
--min-viewport-height 240 Minimum remote viewport height.
--max-viewport-width 1920 Maximum remote viewport width.
--max-viewport-height 1600 Maximum remote viewport height.
--data-dir .agent-data Runtime downloads and temporary uploads directory.
--pin disabled Require this PIN before clients can access the proxy UI, API, or WebSocket.
--lock-url disabled Open this URL automatically and hide/disable browser option controls such as Back, Forward, Cookie, Quit, and address navigation. PIN authentication still applies when configured.

Private and local network targets are blocked by default to reduce SSRF risk. Use --allow-private-hosts only when you trust the users who can access the proxy.

Because LAN access is enabled by default, prefer using a PIN:

venv\Scripts\python.exe -m website_agent_server --pin 123456

If the proxy itself also needs to open LAN or localhost target URLs, enable private hosts explicitly:

venv\Scripts\python.exe -m website_agent_server --allow-private-hosts --pin 123456

Each client receives exactly one server-side Playwright BrowserContext, keyed only by its local session-uuid cookie. Contexts are never shared by IP address, target host, port, URL path, or device class. If the same client opens another target URL before its UUID expires, the old page is closed and the same context is reused, including storage partitions, service workers, permissions, and other browser context state.

Mobile clients use a mobile Playwright browser profile with a narrow viewport, touch support, a mobile Chromium user agent, and mobile Client Hints so upstream responsive sites can select their mobile layout.

The local session-uuid cookie only identifies the Website Agent client, not the remote site. If the local page refreshes or the WebSocket drops, the server uses that cookie to reconnect the same client to its existing browser session. Disconnected browser sessions and idle client contexts are removed after --session-ttl-seconds, which is 10 minutes by default. When a UUID is removed, its BrowserContext, browsing history, cookies, localStorage, IndexedDB, download files, upload files, and in-memory session records are removed together.

Uvicorn's WebSocket ping keepalive is disabled because mobile browsers may suspend sockets while loading, switching apps, or sleeping. The client reconnect path and session TTL handle those drops without printing keepalive tracebacks.

Audio from ordinary server-side <audio> and <video> elements is captured in the page with captureStream() or a WebAudio fallback and forwarded over a dedicated WebSocket as WebM/Opus chunks, separate from screenshot frames. The server-side page is not relied on for audible playback. When remote media is playing, screenshot streaming automatically uses --media-frame-interval-seconds and --media-screenshot-quality to reduce CPU and network pressure. This does not cover DRM media, WebRTC calls, pure WebAudio graphs, browser UI sounds, or system-level mixed audio.

Limitations

This project proxies interaction by streaming rendered browser frames, not by rewriting HTML. That keeps remote network access on the server, but it also means the client sees a bitmap viewport rather than native DOM nodes. Browser extension APIs, local client certificates, DRM-protected media, and some system dialogs are outside the current scope.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

website_agent_server-0.1.0.tar.gz (36.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

website_agent_server-0.1.0-py3-none-any.whl (37.2 kB view details)

Uploaded Python 3

File details

Details for the file website_agent_server-0.1.0.tar.gz.

File metadata

  • Download URL: website_agent_server-0.1.0.tar.gz
  • Upload date:
  • Size: 36.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.11.15 Windows/10

File hashes

Hashes for website_agent_server-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3661c69a335e679fe27dc3e03e5d73351654dc0a2af1865c1064d32932bd71d7
MD5 cfe6d985ab09c56bf72623078e7e59d3
BLAKE2b-256 d2d76d4b9d008caaf27be704edb69095eaf5f5f3bfd62ad8a03fc30e67d072a9

See more details on using hashes here.

File details

Details for the file website_agent_server-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for website_agent_server-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d7ac48c335ec2848106d6ae409ab01e65c9854f4dad7448fa43ba3b811f52f8d
MD5 7107a750fdcc4d220799fad0414caee4
BLAKE2b-256 40f10050a1565a492c6106a2618ba8dfa716ae127986e083640644628695596a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page