Docs/Tunnels and Relay
OPERATE

Tunnels and Relay

The tunnel is the bridge between Midfleet Control and live agent runtimes.

Tunnels and Relay overview

Cloudflare routes public console URLs to the runtime host. Relay is a separate, private transport for Hub or Control spawn requests; direct CLI starts on the runtime host do not use Relay.

How a request reaches an agent

HopExamplePurpose
Midfleet app/APIhttps://midfleet.ai and https://app.midfleet.aiOperator UI, API calls, workflow state, and agent registry.
Cloudflare tunnel hostnamehttps://console-<workspace>.midfleet.io https://console-<workspace>.midfleet.io/<workspace>/agents/<agent-id>/global/healthPublic entrypoint for terminal/chat/health routes. The workspace slug selects the console host. Confirm the exact value from consoleRouter.publicBaseUrl in runtime config instead of constructing or copying a hostname.
Console router127.0.0.1:<listenPort>Routes workspace and agent path prefixes to managed agent runtimes.
Agent serve port127.0.0.1:4341Per-agent route for chat, terminal, and health checks.
Relayhttps://relay-<workspace>.midfleet.io/spawn http://127.0.0.1:8787/spawnReceives authenticated Hub or Control spawn requests and starts safe midfleet start commands. It is not in the path when an operator runs midfleet start directly on the runtime host.

Choose the launch path independently from provider auth

Launch pathProcess pathRelay evidence
Direct CLIAn authenticated participant runs midfleet --profile <profile> start ... on the target runtime host.No Relay POST /spawn. Hub issues a short-lived runtime credential for the agent.
Hub or ControlHub dispatches an authenticated request to the workspace host Relay, which starts the local CLI process.One authorized Relay POST /spawn for the requested agent.

Use runtime config, not guessed hostnames

bash
midfleet config pull-runtime
midfleet config show

# Values to mirror in Cloudflare and local processes:
# consoleRouter.publicBaseUrl, for example https://console-<workspace-slug>.midfleet.io
# consoleRouter.bindHost
# consoleRouter.listenPort
# consoleRouter.routePrefix
# relay.bindHost
# relay.listenPort
# auth.relay_token, stored locally as MIDFLEET_RELAY_TOKEN

Configure Cloudflare ingress

Configure Cloudflare tunnel ingress so the public console hostname forwards to the console router local bind address and port. Configure the relay hostname to forward to the local relay port and protect spawn requests with the relay token.

The environments mutation API (POST/DELETE /api/v1/workspaces/:workspace/infrastructure/runtime-environments/.../tunnels) provisions and deprovisions real Cloudflare tunnels, DNS records, and ingress rules - create returns live tunnel state, delete removes DNS and the tunnel. Existing workspace tunnels are materialized into runtime_environments by an idempotent backfill, and the Networks page renders only those live environments by default.

yaml
# Shape only; use your provisioned tunnel ID and hostname.
tunnel: <tunnel-id>
credentials-file: /etc/cloudflared/<tunnel-id>.json
ingress:
  - hostname: console-<workspace>.midfleet.io
    service: http://127.0.0.1:<consoleRouter.listenPort>
  - hostname: relay-<workspace>.midfleet.io
    service: http://127.0.0.1:<relay.listenPort>
  - service: http_status:404

Start and inspect relay

bash
export MIDFLEET_RELAY_TOKEN=<relay-token-from-runtime-bundle>

midfleet internal relay start \
  --host 127.0.0.1 \
  --port 8787 \
  --daemon

midfleet internal relay status
midfleet internal relay health

Relay endpoints

Relay endpointAuthUse
GET /healthzNone on localhost; protect public route with Cloudflare Access.Liveness check.
GET /readyzNone on localhost; protect public route with Cloudflare Access.Readiness check; fails when hub URL, workspace, or API key is missing.
GET /statusNone on localhost; protect public route with Cloudflare Access.Shows PID, host, port, and Node version.
POST /spawnx-midfleet-relay-token: <relay-token>Hub spawn path.
bash
curl -i http://127.0.0.1:8787/healthz
curl -i http://127.0.0.1:8787/readyz

Expected checks

  • Public console health route returns a non-HTML API response.
  • Cloudflare Access policy allows the intended operator or service token.
  • Runtime config matches the currently deployed tunnel hostname and local listen ports.
  • Each routable agent has a unique port and route.
  • Control can open chat or terminal without watching raw SSH sessions.
  • A direct CLI launch has Hub runtime-credential evidence and no Relay POST /spawn.