clutchcall CLI and its QUIC
data-plane engine. There is no typed Tunnel SDK class today.
A programmatic client (embed a tunnel in your own process) is Preview — see
Programmatic API (Preview) at the bottom. For
shipping work, use the CLI documented here.
Install
Sign in
0600). Sign out with
clutchcall logout.
Command surface
| Command | What it does |
|---|---|
clutchcall login | Sign in via device flow → session token |
clutchcall logout | Forget the saved session |
clutchcall status | Plan, devices (n/5), wallet balance, this-month egress |
clutchcall devices | List your devices |
clutchcall devices rm <id> | Remove a device, freeing a slot on the free plan |
clutchcall claim <name> | Reserve a subdomain → https://<name>.clutchcall.dev |
clutchcall http <port> [--name n] | Expose localhost:<port> at a public HTTPS URL |
clutchcall p2p share <pair-id> --port <p> | Share a local service direct to a peer (no relay) |
clutchcall p2p connect <pair-id> --listen <p> | Reach a peer’s shared service directly |
clutchcall topup <amount> | Add wallet balance |
clutchcall version | Print version |
http — expose a local service
localhost:<local-port>. Prints the public URL and runs until interrupted.
The local TCP port to expose (e.g.
3000).A label appended to your reserved subdomain: with handle
alice,
--name api → https://alice-api.clutchcall.dev. Requires a claimed handle.Override the slug explicitly (power users). The edge still enforces your
namespace from the session token, so a stale slug can’t escape it.
p2p — direct peer-to-peer
Two peers run with the same pair-id; they auto-discover via the control-plane
rendezvous and connect directly, with the edge brokering candidates but never
carrying bytes. Across NATs, set the <P>_STUN env var (where <P> is your CLI’s
uppercased brand prefix) to a reflector so each side can gather
its public candidate.
A shared secret both peers know; gates the direct tunnel and keys the rendezvous.
(share) The local service port to expose to the peer.
(connect) A local port to listen on; connections to it are piped to the peer’s
shared service.
(share)
tcp, udp, or http.STUN reflector
host:port for reflexive candidate gathering (or set <P>_STUN).Endpoint-independent (cone) NATs punch through directly. Symmetric NATs fall back
to the relayed path.
status & devices
devices and enforced by the session token’s device claim.
Config
CLI state lives at your user config dir, e.g.~/.config/clutchcall/config.json
(mode 0600). It stores only non-secret session state:
Environment variables
Env vars use your CLI’s brand prefix — shown below as<P> (the uppercased binary
name, e.g. clutchcall → its uppercase form).
| Var | Purpose | Default |
|---|---|---|
<P>_API | Control-plane base URL | https://api.clutchcall.dev |
<P>_POP | QUIC edge host:port (data plane) | <base>:4443 |
<P>_STUN | STUN reflector host:port for P2P | — |
<P>_TUNNEL_BIN | Path to the QUIC data-plane engine | next-to-binary / $PATH |
<P>_BASE_DOMAIN | Public base domain for printed URLs | clutchcall.dev |
Data-plane engine flags
clutchcall http execs the QUIC engine (clutchcall-engine) with
the resolved arguments. You rarely call it directly, but the surface is:
Remote desktop on the same transport
A remote-desktop client (a fork of an open-source remote-desktop project) runs its network transport over this same raw-QUIC relay instead of its own rendezvous/relay. Enable it by pointing the client’squic-relay-server option at
a host:port running the tunnel module:
- The controlled box registers its device id as a slug (
proto":"quick") and parks bidi work streams. - The controller dials the box by slug; the edge splices the two QUIC streams.
- The remote-desktop client’s own message framing and end-to-end encryption ride unchanged on top — the edge only secures the QUIC hop to the PoP and never sees cleartext.
Programmatic API (Preview)
- TypeScript (Preview)
- Python (Preview)
Related
- Tunnel overview — wire model & architecture
- Cookbook — task snippets
- Recipes — worked examples

