Skip to main content

Overview

The connect reach command creates a local tunnel to services exposed by other agents in your workspace. Once connected, the remote service appears on your localhost as if it were running locally.
Quick Start: Use the shorthand connect <service-name> instead of connect reach <service-name> for faster commands.

Basic Usage

1

Find available services

If a service isn’t found, Private Connect lists available services:
connect reach unknown-service
Output:
[x] Service "unknown-service" not found

Available services:
  ● prod-db
  ● staging-api
  ● redis-cache
2

Connect to a service

connect reach prod-db
Output:
πŸ” Reaching "prod-db"...

  Service ID: svc_abc123
  Target: localhost:5432
  From: laptop (this agent)

  Running diagnostics...

  [ok] REACHABLE

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  DNS     [ok]  OK (192.168.1.50)        β”‚
  β”‚  TCP     [ok]  OK                        β”‚
  β”‚  Latency    45ms                         β”‚
  β”‚  From       laptop                       β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“‘ Creating local tunnel...
  [ok] Connected to hub
  [ok] Listening on localhost:5432

  [ok] Connected to prod-db

  Endpoints:
    TCP:   localhost:5432
    HTTP:  http://prod-db.localhost:3000
           (proxy auto-started on port 3000)
    psql:  psql -h localhost -p 5432

  Press Ctrl+C to disconnect
3

Use the service

The service is now accessible on localhost:
psql -h localhost -p 5432 -U postgres
Or use the HTTP proxy:
curl http://prod-db.localhost:3000

Port Selection

Private Connect uses stable port allocation to ensure consistent local ports:

Default Behavior (Stable Ports)

connect reach prod-db
Port selection priority:
  1. Saved mapping - If you’ve reached this service before, uses the same port
  2. Original port - If available, uses the service’s target port (e.g., 5432 for PostgreSQL)
  3. Hash-derived - Generates a stable port from the service name
Output:
[ok] Listening on localhost:5432
On subsequent connections:
[ok] Listening on localhost:5432
Port 5432 saved β€” will be reused next time.

Custom Port

Specify a custom local port with --port:
connect reach prod-db --port 5433
Output:
[ok] Listening on localhost:5433
If the specified port is in use, the command will fail:
[x] Port 5433 is in use
  Try without --port to use a stable auto-assigned port

Diagnostics

Private Connect runs comprehensive diagnostics before creating the tunnel:
connect reach api
Output:
[ok] REACHABLE

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  DNS     [ok]  OK (10.0.1.100)          β”‚
β”‚  TCP     [ok]  OK                        β”‚
β”‚  TLS     [ok]  OK                        β”‚
β”‚  HTTP    [ok]  200 OK                    β”‚
β”‚  Latency    32ms                         β”‚
β”‚  From       laptop                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Check-Only Mode

Run diagnostics without creating a tunnel:
connect reach api --check
This runs the health check and exits without creating a tunnel.

JSON Output

Get machine-readable diagnostics:
connect reach api --json
Output:
{
  "success": true,
  "service": {
    "id": "svc_abc123",
    "name": "api",
    "target": "localhost:8080"
  },
  "diagnostic": {
    "dnsStatus": "OK (10.0.1.100)",
    "tcpStatus": "OK",
    "tlsStatus": "OK",
    "httpStatus": "OK",
    "latencyMs": 32,
    "message": "OK",
    "perspective": "agent-to-service",
    "sourceLabel": "laptop"
  },
  "shareUrl": null
}

TLS Certificate Details

For HTTPS services, Private Connect shows detailed TLS information:
connect reach api
Output:
[ok] REACHABLE

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  DNS     [ok]  OK                        β”‚
β”‚  TCP     [ok]  OK                        β”‚
β”‚  TLS     [ok]  OK                        β”‚
β”‚  HTTP    [ok]  200 OK                    β”‚
β”‚  Latency    28ms                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”’ TLS Certificate
   Subject: api.internal.local
   Issuer: Let's Encrypt
   Expires: 89 days

Certificate Issues

If there are certificate problems:
[x] UNREACHABLE

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  DNS     [ok]  OK                        β”‚
β”‚  TCP     [ok]  OK                        β”‚
β”‚  TLS     [x]   FAIL                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”’ TLS Certificate
   Subject: api.internal.local
   Issuer: Self-Signed
   Expires: -5 days
   [!] Self-signed certificate
   [x] Certificate has expired

Local Proxy Integration

Private Connect automatically starts a local HTTP proxy for subdomain-based access:
connect reach my-api
Output:
Endpoints:
  TCP:   localhost:8080
  HTTP:  http://my-api.localhost:3000
         (proxy auto-started on port 3000)
  curl:  curl http://my-api.localhost:3000

Access via Subdomain

curl http://my-api.localhost:3000/health
No need to remember port numbers - just use the service name as a subdomain.

HTTPS Proxy

Start the proxy with HTTPS:
connect proxy start --https
Then reach services:
connect reach my-api
# β†’ https://my-api.localhost:3000
See the connect proxy command for complete proxy documentation.

Service-Specific Commands

Private Connect shows context-aware connection examples:
connect reach prod-db
Output:
Endpoints:
  TCP:   localhost:5432
  HTTP:  http://prod-db.localhost:3000
  psql:  psql -h localhost -p 5432

Direct URL Reach

Test connectivity to any URL without going through the hub:
connect reach https://api.example.com
Output:
πŸ” Reaching "https://api.example.com"...

  Target: api.example.com:443
  Protocol: HTTPS

  Running diagnostics...

  [ok] REACHABLE

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  DNS     [ok]  OK (93.184.216.34)       β”‚
  β”‚  TCP     [ok]  OK                        β”‚
  β”‚  TLS     [ok]  OK                        β”‚
  β”‚  HTTP    [ok]  200 OK                    β”‚
  β”‚  Latency    120ms                        β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  https://api.example.com is reachable.
This is useful for:
  • Testing external API connectivity
  • Debugging TLS/certificate issues
  • Checking firewall rules
  • Validating HTTP response codes
Direct URL reach runs diagnostics only - it doesn’t create a tunnel.

External Services

Services marked as β€œexternal” (no tunnel) are tested directly:
connect reach external-api
Output:
  Service ID: svc_xyz789
  Target: api.external.com:443
  Type: External (direct connection)

  Running diagnostics...

  [ok] REACHABLE

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  DNS     [ok]  OK (1.2.3.4)             β”‚
  β”‚  TCP     [ok]  OK                        β”‚
  β”‚  TLS     [ok]  OK                        β”‚
  β”‚  HTTP    [ok]  200 OK                    β”‚
  β”‚  Latency    85ms                         β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Command Options

OptionDescriptionExample
--port <port>Use a specific local port--port 5433
--timeout <ms>Connection timeout in milliseconds--timeout 30000
--checkRun diagnostics only (no tunnel)--check
--jsonOutput in JSON format--json
--hub <url>Hub URL (defaults to production)--hub https://api.privateconnect.co
--config <path>Path to config file--config ~/.connect/config.json

Connection Lifecycle

Private Connect maintains persistent connections with automatic reconnection:
connect reach prod-db
Initial connection:
[23:44:15] Connected to hub
[ok] Connected to prod-db
If the hub restarts:
[23:50:30] Server restarting, reconnecting...
[23:50:32] Reconnected to hub
   Re-establishing tunnel...
[ok] Tunnel established

πŸ“‘ Service "prod-db" is accessible through the hub
   Public URL: https://abc123.privateconnect.co

   Press Ctrl+C to stop exposing
On network interruption:
[23:55:00] Reconnecting... (transport close)
[23:55:02] Reconnecting... (attempt 2)
[23:55:05] Reconnected to hub
   Re-establishing tunnel...
Private Connect automatically handles reconnections. Your local applications can keep their connections open - the tunnel will seamlessly restore.

Error Handling

Service Not Found

connect reach nonexistent
Output:
[x] Service "nonexistent" not found

Available services:
  ● prod-db
  ● staging-api
  ● redis-cache

Port Already in Use

connect reach prod-db --port 5432
Output:
[x] Port 5432 is already in use
  Try a different port with --port <port>

Service Unreachable

connect reach broken-api
Output:
[x] UNREACHABLE

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  DNS     [ok]  OK                        β”‚
β”‚  TCP     [x]   FAIL                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

[!] TCP connection failed: ECONNREFUSED

  Check that your service is running on the target port

Cannot create tunnel - service is not reachable.

Not Authenticated

connect reach prod-db
Output:
[x] Agent not configured
  Run connect up --api-key <key> first.

Examples

# Connect to production database
connect reach prod-db

# Use with psql
psql -h localhost -p 5432 -U postgres

Next Steps

Expose Services

Make your services accessible to others

Local Proxy

Access services via subdomains (my-api.localhost)

Share & Collaborate

Share your environment with teammates

Project Dev Mode

Auto-connect services from pconnect.yml

Build docs developers (and LLMs) love