Debugging a request that crosses HTTP → WebSocket → raw TCP usually means juggling four or five tools: a REST client, a socket client, nc, a proxy, and a terminal. Every switch costs you context — headers here, frames there, logs somewhere else.
uvscope is my attempt to collapse that stack into one place — a Swiss Army knife for web debugging. It puts HTTP, WebSocket, TCP, UDP, TLS, SOAP/WSDL and managed reverse proxies behind a single Vue 3 control plane, backed by a C++ daemon that owns the event loop, the SQLite store, authentication and all outbound network traffic. The browser only renders state and sends commands.
Why another debugging tool?
Most tools stop at request/response. uvscope is built around the whole handshake:
- One workbench for every protocol — HTTP/1.1 and HTTP/2, WebSocket, raw TCP/UDP, X.509 and WSDL-driven SOAP, with the same history, telemetry and export model.
- A real gateway, not a mock — reverse proxies with routing rules, weighted upstreams, retries, health checks, circuit breaking and WebSocket pass-through, with live traffic in view.
- Long-lived services without a second stack — TCP/UDP listeners, SOCKS5 servers, reverse proxies and terminal PTYs run in child processes under one desired-state supervisor.
- Local-first — SQLite, server-side sessions, PBKDF2 password hashing, RBAC and a first-run admin flow. No telemetry, no cloud account, no external database.
- One network stack — every target connection is driven by libuvcpp 1.8.2, from socket to UI.
- A UI that keeps context — collapsible navigation, cached multi-tab workspaces, live telemetry and an offline command library built with Vue 3, Pinia and Vite.
What's inside
HTTP and APIs
| Capability | Status |
|---|---|
| HTTP/1.1 + HTTPS debugger with headers, body, timing and history | Stable |
| Body modes: raw, form-urlencoded, multipart with files | Stable |
| cURL / HAR / OpenAPI / Postman import and export | Stable |
Environments with {{variables}}, pre-request and post-response scripts |
Stable (browser-side) |
| HTTP/2 over TLS with ALPN, stream IDs, GOAWAY and frame summary | Stable |
| gzip / deflate / brotli decoding with a raw-body toggle | Stable |
| Streaming download with progress, cancel and Range resume | Stable |
| Response preview: sandboxed HTML, images, audio, video and PDF | Stable (scripts opt-in) |
| SOAP 1.1 + WSDL operation discovery | Stable |
| HTTP/3 and raw QUIC probes | Supported in QUIC-enabled builds |
Realtime and transports
| Capability | Status |
|---|---|
| WebSocket console: daemon-side backend sessions and browser-native mode | Stable |
| Backend WebSocket headers, subprotocols, frames, ping/pong, close codes | Stable |
| One-shot TCP and UDP probes (text / hex) | Stable |
| Persistent TCP sessions with repeated sends and event logs | Stable |
| TCP / UDP server listeners with sessions, datagrams and replies | Stable |
| SOCKS5 client and server (CONNECT / BIND / UDP ASSOCIATE) | Stable |
| Virtual terminal (Unix PTY / Windows ConPTY) with offline command library | Stable — off by default |
Gateway and long-lived services
| Capability | Status |
|---|---|
| Reverse proxy: exact / prefix / regex rules, redirects and rewrites | Stable |
| Header / method / host conditions, weighted upstreams, retries | Stable |
| Active upstream health checks, per-upstream circuit breaker, QPS/latency metrics | Stable |
| Proxy config hot reload with runtime config versions | Stable |
| WebSocket pass-through in the reverse proxy | Stable |
| Child-process isolation for proxies, listeners, SOCKS5 servers and terminals | Stable |
| Unified desired-state supervisor with restart, backoff and event log | Stable |
| Managed TLS certificates, local CA, CA-signed certs and in-place renewal | Stable |
Operations and security
| Capability | Status |
|---|---|
| SQLite persistence, first-run setup, local auth, RBAC (admin / operator / viewer) | Stable |
| Server-side sessions, active-session revocation, audit log | Stable |
| Backup download and staged restore | Stable |
| Module toggles, factory reset, update check, about/help | Stable |
| Chinese / English UI with browser-language detection and manual switch | Stable |
| Dark / light / follow-system theme | Stable |
| Linux tar/deb/rpm, Windows zip + installer, macOS tar.gz | Stable |
Quick start
Requirements
- C++17 compiler, CMake ≥ 3.20, Ninja
- Node.js 20+ and npm
- libuv, zlib, SQLite and OpenSSL development headers
- Linux, macOS, or Windows with MSYS2 MinGW-w64
On Debian/Ubuntu:
sudo apt install build-essential cmake ninja-build libuv1-dev zlib1g-dev \
libssl-dev libsqlite3-dev git curl
Build from source
git clone https://github.com/Antruly/uvscope.git
cd uvscope
./scripts/build.sh
./build/uvscope --port 8787 --open
build.sh clones the libuvcpp v1.8.2 release into .deps/, applies one minimal upstream patch shipped in patches/upstream/ (WebSocket handshake headers), builds the frontend, then builds uvscope and runs --self-check.
If you already have a libuvcpp 1.8.2 SDK:
npm --prefix web ci && npm --prefix web run build
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DUVCPP_ROOT=/path/to/libuvcpp
cmake --build build -j
./build/uvscope --self-check
Open http://127.0.0.1:8787. The first visit creates the administrator account. Runtime state lives in the data directory printed at startup (~/.local/share/uvscope on Linux by default; override with --data-dir).
CLI
uvscope [options]
--host <addr> Listen address (default 127.0.0.1)
--port <port> Listen port (default 8787, 0 picks a free port)
--data-dir <path> SQLite and runtime data
--web-root <path> Built frontend directory
--tls-cert <pem> Serve the workbench UI over HTTPS
--tls-key <pem> Private key paired with --tls-cert
--open Open the workbench in the default browser
--self-check Run offline smoke tests and exit
--version Print version and exit
Hidden child modes (--proxy-child, --listener-child, --socks5-child, --terminal-child, --ipc-child) are spawned by the daemon and are not meant to be invoked by hand.
Architecture
Vue 3 SPA (multi-tab, cached workspaces)
│ same-origin HTTP + WebSocket + cookies
▼
uvscope daemon (C++17 / libuvcpp)
├─ auth + RBAC + SQLite + audit + backup
├─ HTTP API and static asset server
├─ probes, debug sessions and terminal sessions
├─ desired-state supervisor
└─ optional child processes (isolated services)
├─ reverse proxy runtime
├─ TCP/UDP listener runtime
├─ SOCKS5 server runtime
└─ terminal PTY / ConPTY
│
└─ libuvcpp → libuv → sockets
The daemon is the only process that serves the UI and owns SQLite. In the default in-process mode it also owns every outbound socket; with isolation enabled, a service opens its own sockets inside its child process. The WebSocket view additionally offers a browser-native mode, because origin, mixed-content and certificate prompts are part of what is being debugged.
Isolation and supervision
Proxies, TCP/UDP listeners, SOCKS5 servers and virtual terminals accept isolated: true. The parent process keeps the API state, scrollback and ownership metadata; the service runs in a child process and talks to the parent over a length-prefixed JSON IPC channel.
All four service kinds are registered with one desired-state supervisor:
- a crashed child is restarted with exponential backoff (2–60 s) and a new PID;
- restart counts and events are visible in
/api/supervisorand/api/supervisor/events; - stopping a service clears its desired state, so the watchdog leaves it down;
- deleting a service unregisters it before teardown;
- a normal terminal
exitis not a crash — the child stays alive so scrollback and the exit code remain readable. A crashed terminal is respawned with a fresh shell, and attached WebSocket clients receive aresetframe before the new output.
Security model
- Default bind is
127.0.0.1. Do not expose uvscope to an untrusted network without an authenticating proxy. - Passwords are PBKDF2-HMAC-SHA256 (210,000 iterations); sessions are server-side and stored as SHA-256 token hashes. Cookies are
HttpOnly+SameSite=Lax. - Anyone who can authenticate can reach the host network, start listeners/proxies, and — when the terminal module is enabled — obtain a shell as the daemon user. Treat access as equivalent to code execution on that host.
- Isolated services run as the same OS user; isolation is a fault boundary, not a security sandbox.
- Use the TLS Inspector and “Allow insecure TLS” only against systems you control.
Platforms and downloads
Prebuilt v1.0.1 assets are on the Releases page, shipped with SHA256SUMS, a Sigstore keyless signature and a generated SPDX SBOM.
| Platform | Release | Notes |
|---|---|---|
| Linux x64 | tar.gz, deb, rpm | Primary CI and smoke matrix |
| Linux arm64 | tar.gz, deb, rpm | Release build and self-check |
| Windows x64 (MinGW) | zip, setup.exe | CI build, self-check and ConPTY smoke |
| macOS arm64 | tar.gz | CI build, self-check and HTTP/2 runtime check |
| HTTP/3 / QUIC | QUIC-enabled builds | Requires OpenSSL 3.6+; default assets keep QUIC off |
Verify a download with:
sha256sum -c SHA256SUMS
cosign verify-blob --bundle SHA256SUMS.sigstore.json \
--certificate-identity-regexp 'https://github.com/Antruly/uvscope/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
SHA256SUMS
Wrapping up
uvscope is MIT-licensed and the docs live at https://antruly.github.io/uvscope/ — including the HTTP API, architecture notes, event schema and roadmap.
If it saves you a debugging session, a star on GitHub helps other protocol wranglers find it.











Top comments (1)
The shared history and export model is an interesting part of this design. Can one export include an HTTP request and the WebSocket frames that followed it, or are those saved separately?