Privacy-preserving desktop status monitor. Captures your screen periodically, blurs sensitive regions, and streams processed frames to a web dashboard via WebSocket. All processing is local — raw screenshots never leave your machine.
- Periodic screen capture (configurable interval)
- Gaussian blur on configurable rectangular regions
- Real-time WebSocket push to web dashboard
- Online/Away status detection
- Dark-themed status dashboard
backend/ Python server
server.py WebSocket server + capture loop
capture.py Screen capture (mss)
blur.py Gaussian blur
config.yaml Backend configuration
start.bat Quick start (Windows)
tests/
frontend/ Static HTML5 dashboard
index.html Dashboard page
config.js Frontend configuration
app.js WebSocket client + canvas rendering
style.css Dark theme styles
start.bat Quick serve (Windows)
functions/ Cloudflare Pages Functions
_middleware.js Inject WS_URL etc. from env vars
# 1. Install dependencies
pip install -r backend/requirements.txt
# 2. Edit backend/config.yaml — set blur regions for your screen layout
# 3. Start the backend
python backend/server.py
# 4. Serve the frontend (separate terminal)
python -m http.server 8080 -d frontend
# 5. Open http://localhost:8080Or use the .bat scripts on Windows:
backend/start.bat # starts the capture server
frontend/start.bat # serves the dashboard on :8080
capture_interval: 5 # seconds between captures
port: 8765 # WebSocket server port
jpeg_quality: 70 # 1–100
blur_regions:
- name: "except-taskbar"
x: 0
y: 0
width: 1860
height: 1080
radius: 25Each blur region requires: name, x, y, width, height, radius (Gaussian blur radius; 20–30 recommended).
Key configuration, resolved by priority (later overrides earlier):
| Priority | Source | Example |
|---|---|---|
| 1 | Defaults in config.js |
wsUrl: 'ws://localhost:8765' |
| 2 | Server-injected window.SCREENSTALK_CONFIG |
env vars at deploy time |
| 3 | URL query parameters | ?ws=192.168.1.5:8765 |
Supported keys: wsUrl, captureInterval, maxReconnectDelay.
To inject configuration, set window.SCREENSTALK_CONFIG before config.js loads — via an inline <script>, an nginx SSI template, a CI/CD sed replacement, or Cloudflare Pages Functions (see below).
The frontend includes a Cloudflare Pages Functions middleware (frontend/functions/_middleware.js) that automatically injects window.SCREENSTALK_CONFIG into every HTML response from environment variables.
Setup:
-
Deploy the
frontend/directory to Cloudflare Pages (connect the Git repo or use Direct Upload). -
In the Cloudflare Pages dashboard → Settings → Environment variables, add:
| Variable | Description | Example |
|---|---|---|
WS_URL |
WebSocket server address | wss://my-server.example.com:8765 |
CAPTURE_INTERVAL |
Expected capture interval in seconds (optional) | 10 |
MAX_RECONNECT_DELAY |
Max reconnect delay in ms (optional) | 30000 |
- Redeploy (or the next push triggers it automatically).
HTTPS / WSS requirement: Cloudflare Pages serves over HTTPS. Browsers block
ws://connections from HTTPS origins. Your WebSocket backend must usewss://(TLS). Use Cloudflare Tunnel (cloudflared) or a reverse proxy with TLS to expose your backend securely.
⚠️ WS_URLis required: WithoutWS_URLset, the CF Pages middleware will not inject any WebSocket URL — the frontend falls back to its defaultws://localhost:8765, which will only work on the machine running the backend. Set this env var before deploying.
- Server:
ws://<host>:<port> - Server → Client: binary — raw JPEG bytes (no framing)
- Client auto-reconnects with exponential backoff (1s → 30s max)
- Server binds to
0.0.0.0(all interfaces) — use a reverse proxy for remote access
- All processing is local — screenshots are captured, processed, and discarded on your machine
- No raw screenshots leave your machine — only blurred JPEG frames over WebSocket
- Blur is irreversible — Gaussian blur ensures text is illegible
- No cloud dependency — the entire stack runs locally
- Memory: typically < 200 MB
- CPU: < 5% during capture
- Frame size: 100–300 KB per JPEG (quality 70)
Multi-monitor? MVP supports primary monitor only. Multi-monitor planned.
Remote control? No. ScreenStalk is strictly read-only — no mouse/keyboard control.
Blur region partially off-screen? Regions auto-clamp to screen bounds — no crashes.
Custom WebSocket endpoint? Append ?ws=host:port to the dashboard URL, or inject via window.SCREENSTALK_CONFIG.
MIT