Opening Tunnels

Basic usage

# Expose a local port (positional shorthand)
nullbore open 3000
# ✓ https://a7f3bc.tunnel.nullbore.com → localhost:3000

# Or with explicit flag
nullbore open --port 3000

This creates a tunnel with a random slug and a 1-hour default TTL.

Named tunnels

On Dev and Pro plans, users with a claimed account subdomain can choose their tunnel URL:

nullbore open --port 3000 --name myapp
# ✓ https://myapp.pj.nullbore.com → localhost:3000

Named tunnels live under your account subdomain (*.yourname.nullbore.com). Without a claimed subdomain, tunnels get random slugs on *.tunnel.nullbore.com.

Names must be 2-63 characters, lowercase alphanumeric and hyphens only.

TTL (time to live)

Every tunnel has a TTL — the maximum time it stays open. When it expires, the tunnel closes and the client exits cleanly (no reconnect).

nullbore open 3000 --ttl 30m      # 30 minutes
nullbore open 3000 --ttl 4h       # 4 hours
nullbore open 3000 --ttl 0         # persistent (Dev plan max)

TTL limits depend on your plan:

PlanMax TTL
Free2 hours
DevPersistent
ProUnlimited (persistent)

Idle TTL mode

With --idle, the TTL becomes an inactivity timeout instead of a hard deadline. The tunnel stays alive as long as there's traffic, and only expires after the TTL period of silence.

# Stay alive while there's traffic, close after 30 min of silence
nullbore open 3000 --ttl 30m --idle

This is useful for:

  • Dev servers you want up while you're working
  • MCP servers that should be available while an agent session is active
  • Demo environments that clean themselves up

Basic auth

Protect your tunnel with HTTP basic auth. Visitors are challenged with a 401 before any request reaches your local service:

nullbore open 3000 --auth admin:s3cret
# ✓ https://a7f3bc.tunnel.nullbore.com → localhost:3000  [auth protected]

The Authorization header is stripped before forwarding — your local service never sees it. Auth also works in config.toml for daemon tunnels:

[[tunnels]]
port = 3000
auth = "admin:s3cret"

Multiple tunnels

Open several tunnels at once:

# With the -p flag (PORT:NAME format)
nullbore open -p 3000:api -p 8080:web -p 5432:db
# ✓ https://api.pj.nullbore.com → localhost:3000
# ✓ https://web.pj.nullbore.com → localhost:8080
# ✓ https://db.pj.nullbore.com  → localhost:5432

# Positional shorthand (random slugs)
nullbore open 3000 8080 5432
# ✓ https://a7f3bc.tunnel.nullbore.com → localhost:3000
# ✓ https://b2e91d.tunnel.nullbore.com → localhost:8080
# ✓ https://c4f7a0.tunnel.nullbore.com → localhost:5432

Named tunnels (the -p PORT:NAME form) require a Dev+ plan with a claimed account subdomain. Without one, names are silently ignored and you get random slugs.

Flags apply to all tunnels in the command:

nullbore open 3000 8080 --ttl 2h --auth demo:pass

Via the API

curl -X POST https://tunnel.nullbore.com/v1/tunnels \
  -H "Authorization: Bearer nbk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"local_port": 3000, "ttl": "30m", "name": "api", "auth_user": "admin", "auth_pass": "s3cret"}'

See API: Tunnels for full details.