Using the request inspector
There is no web UI and no localhost:4040. ngstone port opens a full-screen terminal dashboard (built on Bubble Tea) that shows every request and response as it passes through your tunnel — nothing leaves your machine to render it.
Opening the inspector#
The inspector opens automatically whenever ngstone port runs with stdout attached to a terminal:
$ ngstone port 3000It is skipped automatically when stdout is not a terminal — piping output, running under CI, or backgrounding the process with & all fall back to plain log lines on stderr instead of taking over the screen. See Plain output instead below.
Layout#
The dashboard has four parts:
tabtoggles focus between the request list and the detail pane. Request history is kept in memory for the life of the process and survives tunnel reconnects, so a blip in your network connection doesn't clear what you've already captured.
The request list#
Each row shows a method, path, status, and duration. WebSocket upgrades show WSin the method column and, once connected, live byte counts in both directions instead of a duration — because a socket doesn't have a single duration while it's still open.
A WebSocket appears the moment it connects
101 upgrade completes, not when the socket eventually closes. A long-lived connection shows up right away instead of sitting invisible for its entire lifetime.Replayed requests are marked with ↺; a replay that is still in flight shows ~ instead.
Press / to filter the list by method, a status class (2xx, 4xx, etc.), or a path substring; enter commits the filter, esc cancels it.
Inspecting a request#
Moving the selection (↑/k, ↓/j) updates the detail pane with the full exchange: request and response headers, and both bodies. When the detail pane has focus, the same keys — plus pgup/pgdown — scroll it instead of moving the list selection.
Bodies and truncation#
Request and response bodies are captured up to a fixed cap. Beyond that, the entry is marked truncated rather than blocking the stream — capture observes, it never gates.
gzip and deflate response bodies are decoded for display, so a compressed JSON response renders as readable JSON rather than a hex dump — the raw bytes are kept underneath so replay can still send the original encoding. br and zstdaren't decoded (they aren't in the Go standard library) and render as binary. Binary bodies of any kind render as a hex preview.
Key bindings#
Plain output instead#
Pass --no-tui to skip the dashboard and log plain text to stderr instead — useful for scripts, or when you just want a scrolling log:
$ ngstone port 3000 --no-tui