# Tunnel — Cookbook

> Short copy-pasteable tunnel tasks: expose localhost, reserve a subdomain, tunnel SSH/Postgres, P2P links, share webhooks, and remote desktop.

Task-oriented snippets for the `clutchcall` CLI. Each does one thing.

> **NOTE:**
> Env vars below use `<P>` for your CLI's brand prefix — the uppercased binary name.

## Expose a local web app at a public URL

The headline move — one command, a public HTTPS URL, no inbound port.

```sh
clutchcall login
clutchcall http 3000      # → https://happy-otter.clutchcall.dev
```

## Reserve a stable subdomain

Claim a handle once; every `http` run reuses it instead of a random slug.

```sh
clutchcall claim alice    # reserves https://alice.clutchcall.dev
clutchcall http 3000      # → https://alice.clutchcall.dev
```

## Run multiple named tunnels off one handle

Use `--name` to suffix the reserved handle, so each service gets its own URL.

```sh
clutchcall http 3000 --name web    # → https://alice-web.clutchcall.dev
clutchcall http 8080 --name api    # → https://alice-api.clutchcall.dev
```

## Receive a webhook on your laptop

Point the provider's webhook at your public URL; deliveries reach `localhost`
without a deployed server.

```sh
clutchcall http 4000      # set the webhook URL to the printed https URL
```

> **TIP:**
> Streaming and chunked responses (SSE, long-poll) pass through unchanged — each
> public connection is its own QUIC stream, so one slow request never blocks others.

## Tunnel a raw-TCP service (SSH, Postgres)

The raw-TCP type maps a remote endpoint to a local port with no HTTP parsing —
ideal for SSH or a database. Use the P2P direct form for a private link, or the
public form for an internet-reachable port.

```sh
# Direct, private link between two of your machines:
home$   clutchcall p2p share db --port 5432
laptop$ clutchcall p2p connect db --listen 5432
laptop$ psql -h localhost -p 5432    # rides the QUIC tunnel
```

## Point a remote shell at a box behind NAT

Same P2P flow for SSH — the box only dials out, no inbound rule needed.

```sh
box$    clutchcall p2p share shell --port 22
client$ clutchcall p2p connect shell --listen 8022
client$ ssh -p 8022 localhost
```

## Connect two boxes on the same LAN

On one subnet, discovery is automatic and the edge stays out of the path entirely.

```sh
A$ clutchcall p2p share lanlink --port 3000
B$ clutchcall p2p connect lanlink --listen 3000
# Bytes flow A ⇄ B directly over the LAN — stop the edge and it still works.
```

## Punch through NATs with STUN

Across networks, set a STUN reflector so each side gathers its public candidate
before punching.

```sh
export <P>_STUN=stun.clutchcall.dev:3478
A$ clutchcall p2p share wan --port 8000
B$ clutchcall p2p connect wan --listen 8000
```

> **NOTE:**
> Cone NATs punch directly; symmetric NATs fall back to the relayed path
> automatically.

## Pick a region / specific edge PoP

Override the edge the data plane dials, e.g. to test a region or a self-hosted PoP.

```sh
export <P>_POP=edge-sg.clutchcall.dev:4443
clutchcall http 3000
```

## Point at a self-hosted control plane

Run against your own control plane by overriding the API base.

```sh
export <P>_API=https://api.internal.example.com
clutchcall login
```

## Check usage, devices, and egress

See your plan, device slots, wallet balance, and this-month egress.

```sh
clutchcall status
```

## Free a device slot

The free plan caps at 5 devices; remove an old one to make room.

```sh
clutchcall devices            # find the id
clutchcall devices rm dev-1a2b3c…
```

## Use a custom engine binary

If the QUIC data-plane engine isn't next to the CLI, point at it explicitly.

```sh
export <P>_TUNNEL_BIN=/opt/clutchcall/clutchcall-engine
clutchcall http 3000
```

## Enable remote desktop over the QUIC relay

Configure a remote-desktop client (open-source remote-desktop fork) to use this
relay for transport instead of its own rendezvous/relay.

```text
# In the remote-desktop client settings, set:
quic-relay-server = relay.clutchcall.dev:4443
```

The controlled box registers its device id as a slug and parks streams; the
controller dials it by slug. The client's own end-to-end encryption is unchanged.

## Run as a long-lived background tunnel

`http` runs in the foreground until interrupted; use your process manager to keep
it up across reboots.

```sh
# systemd user unit, supervisord, or simply:
nohup clutchcall http 3000 --name api >/var/log/tunnel.log 2>&1 &
```

## Related

- [SDK & CLI](/modalities/tunnel/sdk-methods) — full command surface
- [Recipes](/modalities/tunnel/recipes) — end-to-end worked examples
