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
| Hop | Example | Purpose |
|---|---|---|
| Midfleet app/API | https://midfleet.ai and https://app.midfleet.ai | Operator UI, API calls, workflow state, and agent registry. |
| Cloudflare tunnel hostname | https://console-<workspace>.midfleet.io
https://console-<workspace>.midfleet.io/<workspace>/agents/<agent-id>/global/health | Public 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 router | 127.0.0.1:<listenPort> | Routes workspace and agent path prefixes to managed agent runtimes. |
| Agent serve port | 127.0.0.1:4341 | Per-agent route for chat, terminal, and health checks. |
| Relay | https://relay-<workspace>.midfleet.io/spawn
http://127.0.0.1:8787/spawn | Receives 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 path | Process path | Relay evidence |
|---|---|---|
| Direct CLI | An 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 Control | Hub 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
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_TOKENConfigure 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.
# 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:404Start and inspect relay
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 healthRelay endpoints
| Relay endpoint | Auth | Use |
|---|---|---|
GET /healthz | None on localhost; protect public route with Cloudflare Access. | Liveness check. |
GET /readyz | None on localhost; protect public route with Cloudflare Access. | Readiness check; fails when hub URL, workspace, or API key is missing. |
GET /status | None on localhost; protect public route with Cloudflare Access. | Shows PID, host, port, and Node version. |
POST /spawn | x-midfleet-relay-token: <relay-token> | Hub spawn path. |
curl -i http://127.0.0.1:8787/healthz
curl -i http://127.0.0.1:8787/readyzExpected 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.