Local web inspector
mcppipe up --inspect starts a small local web inspector — a loopback
HTTP server, off by default — that shows the live MCP JSON-RPC traffic flowing
through your tunnel and lets you replay a captured call against your local
upstream. Think ngrok’s :4040 request inspector or the official MCP Inspector
:6274, but built into the CLI and MCP-protocol-aware: it parses every
tools/call by tool name, with per-call latency, HTTP status, and JSON-RPC error
codes.
It is the only place you can honestly inspect a zero-knowledge tunnel: in that mode the cloud never sees your payloads, so the inspection has to live client-side — in the CLI, where the bytes are still in the clear.
Turn it on
Section titled “Turn it on”# Default: 127.0.0.1:4040 (falls back to a free port if 4040 is taken)mcppipe up --upstream http://localhost:3000/mcp --inspect
# Pick your own address/portmcppipe up --upstream http://localhost:3000/mcp --inspect-addr 127.0.0.1:7000At startup the CLI prints the URL with a one-time token:
◆ inspector http://127.0.0.1:4040/?token=af1a4814b1ac4dbb961bef0ea640474fOpen it in your browser. The CLI never opens the browser for you and never binds anything but loopback by default.
| Flag / env | Effect |
|---|---|
--inspect | Bind the inspector on 127.0.0.1:4040 (free-port fallback). Tabs: Traffic + Overview (read-only). |
--inspect-addr <HOST:PORT> (env MCPPIPE_INSPECT_ADDR) | Override the bind address. Implies --inspect. |
--inspect-admin (env MCPPIPE_INSPECT_ADMIN) | Also enable the Config tab: edit/apply/save your upstreams live. Implies --inspect. Off by default. |
MCPPIPE_INSPECT_TOKEN | Use a fixed token instead of a fresh random one (stable, bookmarkable URL). |
MCPPIPE_INSPECT_ALLOW_HOST | Extra host:port values to trust in the Origin/Host check (comma-separated). Needed only when you bind a non-loopback address. |
What you see
Section titled “What you see”- A live list of requests — method or tool name, HTTP status, latency — that updates in real time as your agent works (server-sent events).
- A detail view with the request and response JSON-RPC bodies, pretty-printed, plus the headers.
- For
tools/call, the tool name and any JSON-RPC error code (-32xxx) are surfaced directly.
Capture is in-memory and bounded (a ring buffer of recent requests, with a per-body size cap that flags truncation). Nothing is written to disk — close the CLI and the history is gone.
Overview
Section titled “Overview”The Overview tab is a read-only “what am I running right now” panel — handy
because mcppipe up prints the URL once and then goes quiet. It shows the
public URL and subdomain, the connection state, the transport, the session id,
uptime and reconnect count, and your upstreams with per-upstream health
(available / recovering / failed for an aggregator). If you run an
aggregator it also shows the multiplex counters (fan-out, calls per tool). It
refreshes automatically and costs nothing — the data is updated on events, never
on the request path.
Admin: edit your upstreams live (--inspect-admin)
Section titled “Admin: edit your upstreams live (--inspect-admin)”Add --inspect-admin and the inspector grows a Config tab where you can
toggle, add, remove, and edit the local MCP servers behind the tunnel — then
Apply without restarting:
mcppipe up --upstream http://localhost:3000/mcp --inspect-admin- Apply = reconnect. Applying validates your edits, then reconnects the tunnel on the same URL/subdomain (a sub-second blip) with the new layout. Because it’s a fresh session, even switching a single upstream to a two-upstream aggregator — or changing transport — just works. An invalid edit is rejected before anything changes (no disruption).
- Save to TOML. Optionally write the enabled upstreams to a TOML file in the
format
--upstreams-fileunderstands, so your nextmcppipe up --upstreams-file <path>starts with the same layout. The write is atomic and confined to your working directory or home directory. - stdio is exec. Adding or editing a
stdioupstream runs that command on your machine — but only when you Apply, and the UI asks you to confirm, showing the exact command first.
The Config tab and the mutation endpoints exist only under --inspect-admin.
Without the flag they aren’t even registered (the server answers 404), so a plain
--inspect stays 100% read-only.
There is no host restriction on the upstream you point at — aiming an upstream
at localhost or an internal address is the whole point of a local dev tool. (The
tunnel’s own forward path keeps its SSRF protection; this is about your machine’s
upstreams, which you control.)
Replay
Section titled “Replay”Pick any captured call and hit Replay. The inspector re-injects it against
your local upstream only — it never re-sends anything to the public edge. You
can edit the request body first (edit-and-replay): change a tools/call’s
arguments and see the new response side by side. Great for iterating on a tool
without driving your agent through the whole flow again.
Security
Section titled “Security”The inspector is a developer tool bound to loopback, with defence in depth:
- Token — every
/api/*call requires the one-time token from the printed URL (compared in constant time). The page itself loads tokenless (it carries no data); its JavaScript reads the token from the URL. - Origin/Host allowlist — requests whose
Host(orOrigin, when a browser sends one) isn’t loopback are refused, blocking DNS-rebinding attacks. Add other hosts withMCPPIPE_INSPECT_ALLOW_HOSTif you deliberately bind off-loopback.
Because it is opt-in and bound to 127.0.0.1, the inspector adds no open port
to a normal mcppipe up.
- The inspector is separate from
--metrics-addr(Prometheus scrape) — different port, different purpose. Run both if you want. - It runs the same on Windows, macOS, Linux, and headless/CI — it’s a plain HTTP server, not a terminal UI.
- It does not change what the cloud sees: a zero-knowledge tunnel stays zero-knowledge. The inspector is purely local.