Status page
Every mcppipe deployment exposes a single public health URL, GET /status.
It rolls the three core services — broker, api, and edge — into one answer so
you can tell whether the control plane is up from one request, without scraping
each service’s /healthz yourself.
It is built for external uptime monitors: poll it from Uptime Kuma, a
statuspage.io heartbeat, a load-balancer health check, or a curl in a cron
job.
The endpoint
Section titled “The endpoint”curl https://<your-zone>/status/status is served on the same host that serves your tunnels (the apex of your
zone, e.g. https://mcppipe.dev/status). It is public — no API key, no
OAuth, no IP allowlist — because a status page that needs a credential is
useless to a monitor.
The response shape depends on the Accept header:
Accept: text/html(a browser) → a minimal HTML page.- Anything else (
curl, monitors, your scripts) → JSON.
JSON response
Section titled “JSON response”curl -H 'Accept: application/json' https://<your-zone>/status{ "status": "ok", "components": [ { "name": "broker", "ok": true, "detail": "ok" }, { "name": "api", "ok": true, "detail": "ok" }, { "name": "edge", "ok": true, "detail": "ok" } ], "checked_at": "2026-06-07T12:34:56.789Z"}| Field | Type | Meaning |
|---|---|---|
status | string | "ok" when every probed component reported ok: true; "degraded" if any component is down. |
components | array | One entry per probed service, always in the order broker → api → edge. |
components[].name | string | "broker", "api", or "edge". |
components[].ok | bool | true if that service’s /healthz returned a 2xx. |
components[].detail | string | "ok" on success; otherwise the failure reason — "status 503" for a non-2xx reply, or the connection error message when the service is unreachable. |
checked_at | string | ISO-8601 / RFC 3339 UTC timestamp of when the roll-up was last refreshed (not necessarily this request — see caching). |
The edge component is always present. Because the /status handler runs on
the service that answers /status, its being able to answer at all is proof it
is alive, so its entry is reported ok without a separate probe.
HTTP status codes
Section titled “HTTP status codes”The HTTP status code mirrors the status field, so a monitor can flag the page
red without parsing the body:
| Condition | HTTP code |
|---|---|
All components ok | 200 OK |
| Any component down | 503 Service Unavailable |
A 503 still returns the full JSON (or HTML) body, so you can see which
component is degraded and why.
HTML response
Section titled “HTML response”Hitting /status in a browser (or with Accept: text/html) renders a small,
dependency-free HTML table: an overall verdict, the checked_at timestamp, and
one row per component with a green ok / red down pill. It is the same data
as the JSON, formatted for a human glance. There is no JavaScript, no styling
framework, and nothing to configure.
Caching
Section titled “Caching”Each roll-up is cached server-side for 10 seconds. Within that window every
request to /status returns the cached result; mcppipe only re-probes the
broker and api once the cache expires. This keeps a 1 RPS poller from
synthesising load on the upstreams — a thundering herd of monitors still
triggers at most one probe per 10s window.
Each upstream probe has a hard 2-second timeout, so a wedged broker or api
makes /status answer in roughly the same time as a healthy request rather
than hanging.
Wiring it into a monitor
Section titled “Wiring it into a monitor”/status is designed to drop straight into common uptime tools:
- Uptime Kuma / statuspage.io heartbeat / Pingdom — point an HTTP(S)
monitor at
https://<your-zone>/status. Treat200as up and503as down; no body parsing required. The literal"ok"/"degraded"strings are also there if you prefer keyword matching. - Load balancer / Kubernetes — you can use
/statusas a readiness signal, but for a per-instance liveness probe prefer each service’s own/healthz(edge, broker, and api each expose one)./statusreflects the health of the whole control plane, not just the instance answering it. - Logging the failure window — because
detailcarries the exact error string, archiving the JSON over time lets an operator scrub back to a transient failure ("status 503", a connection-refused message, etc.).
Example threshold check with curl:
# Exit non-zero (and print the body) whenever the roll-up is degraded.curl -fsS -H 'Accept: application/json' https://<your-zone>/status \ || echo "mcppipe control plane is degraded"What “degraded” actually probes
Section titled “What “degraded” actually probes”mcppipe probes the broker and api /healthz endpoints over plain HTTP
inside its deployment network, and always reports edge — the service that
answers /status is alive by definition. When every probed component returns a
2xx the roll-up reads ok; if any is down it reads degraded.
Metrics
Section titled “Metrics”Every probe outcome (counted on a cache miss) is exported on the Prometheus
endpoint as mcppipe_edge_status_check_total, labelled by
component (broker / api / edge) and ok (true / false). A Grafana
panel can split the probe rate by outcome to alert before a customer notices.
The refresh runs inside an edge.status_check span, so it also appears in
mcppipe’s trace backend.
Related
Section titled “Related”- Client compatibility — which clients can reach a tunnel.
- Reliability: reconnect & sessions — what happens to live sessions during a blip.