Skip to main content

Remotely Monitor Terminals

Watch and drive your TermFlow terminals from another device on your network using the terminal-monitor companion dashboard — and do it without leaving your machine wide open.

Read this before you enable anything

Exposing TermFlow on your network turns its local API into a remotely reachable, terminal-I/O surface — anyone who can reach it with the token can create terminals and run commands on your machine as you. Traffic is plain HTTP/WebSocket with no TLS. Only do this on a network you fully trust, and turn it back off when you are done. The full risk list is in Security implications below — do not skip it.

What you'll build

By the end you will have a TermFlow instance reachable over your LAN, protected by a bearer token, with the terminal-monitor dashboard connected to it so you can list terminals, stream their live output, and send input from a browser on another device.

How auth works here (the one thing to understand)

TermFlow's local API has exactly two modes:

ModeBind hostAuthWhy it's like this
Default (localhost only)127.0.0.1None — every endpoint is openSafe because only processes on your own machine can reach it
Exposed on LAN0.0.0.0Bearer token required on every callThe API is now reachable by other devices, so the gate turns on

The credential the gate checks is the config authToken — a 64-hex string generated on first run and shown (masked) in Settings → Connections. When exposed:

  • Every REST/HTTP request must send Authorization: Bearer <authToken>.
  • Every WebSocket connection must pass ?token=<authToken> (browsers can't set WS headers, so the token rides in the query string).
  • Only GET /health and GET /api/health stay open, so the Settings page can still poll status.

That is the whole model. There is no user/password database — the token is the credential.

Step 1 — Know the default: localhost-only and safe

Out of the box, TermFlow binds its API to 127.0.0.1:42031 (and the MCP sidecar to 127.0.0.1:42032). In this mode the API is unauthenticated, and that is intentional: nothing off your machine can connect to 127.0.0.1. If your monitoring is all on the same computer, you do not need to expose anything and you do not need the token — point terminal-monitor at localhost:42031 and it just works.

You only need the rest of this tutorial when the browser is on a different device than TermFlow.

Step 2 — Expose the API on your local network

Open Settings → Connections (Ctrl/Cmd+,) and turn on Expose on local network.

+--------------------------------------------------------------+
| Settings › Connections |
+--------------------------------------------------------------+
| API port [ 42031 ] MCP port [ 42032 ] |
| |
| [x] Expose on local network ( o healthy ) |
| ^^^^^^^^^^^^^^^^^^^^^^^^ |
| ⚠ Reachable by other devices on: |
| 192.168.1.24 10.0.0.5 |
| |
| Auth token •••••••••••••••••••••• [Reveal] [Copy] |
| [ Rotate ] |
| |
| [ Save & apply (restart) ] [ Stop ▾ ] [ Start ▾ ] |
+--------------------------------------------------------------+

Toggling it on and applying:

  • Rebinds the API and WebSocket from 127.0.0.1 to 0.0.0.0 so other devices can connect.
  • Lists the per-NIC IP addresses other devices can use, next to a ⚠ badge that stays visible the whole time exposure is on.
  • Turns on the bearer-token gate described above. From this moment, unauthenticated requests get 401 unauthorized.

The health status dot next to the toggle reflects the server: checking, healthy, offline, or conflict (the port is owned by another instance).

Step 3 — Copy the auth token

In the same panel, the Auth token field is masked by default. Use Reveal to see it and Copy to grab it. Keep it somewhere you can paste it into terminal-monitor and your other devices.

If the token has ever been shared loosely — pasted into a chat, committed to a repo, left in a shell history — use Rotate to mint a fresh one. Rotation applies live: the running server picks up the new token on the next request with no restart, and existing UI connections survive. The old token stops working immediately.

tip

Rotate the token right after you finish a remote session. It is the cheapest way to revoke access to a network surface you no longer need open.

Step 4 — Start terminal-monitor (port 42030)

terminal-monitor is a separate React dashboard that ships in the TermFlow repository (it is not part of the desktop installer). It monitors and controls headless or remote TermFlow instances over REST + WebSocket. Run it from its own directory:

# from the repo's terminal-monitor/ directory
bun install
bun run start

It serves the dashboard at:

http://localhost:42030

By default the dashboard talks to the API at http://localhost:42031 and the WebSocket at ws://localhost:42031/ws. To point it at a TermFlow running on another machine, set its API/WS targets before starting (via the monitor's .env, e.g. REACT_APP_API_URL / REACT_APP_WS_URL) to that host's IP and port 42031.

Step 5 — Log in and connect

Open http://localhost:42030. The dashboard shows a Login screen before it will connect.

For a localhost / trusted instance (gate off), just click Connect — no real credential is needed.

For an exposed, token-gated instance, the only credential the API accepts is the config authToken you copied in Step 3, sent as Authorization: Bearer <authToken> on REST and ?token=<authToken> on the WebSocket.

An honest note: terminal-monitor's shipped Login screen asks for a Client ID (default terminal-monitor), not the config token — it was built for the open localhost mode and mints its own session token there. That session token is not the authToken the exposed gate checks, so the built-in login flow does not, on its own, satisfy a token-gated remote instance. Treat the monitor as fully supported against a trusted localhost/LAN instance you control, and treat token-gated remote login through it as a rough edge. The reliable, documented remote mechanism is the bearer-token contract itself (Step 2), which any REST/WS client — including your own tooling — can use directly.1

Step 6 — Watch and drive terminals

Once connected, the dashboard gives you a live, two-way view of the remote instance:

  • List terminals — every active terminal on the remote instance, in a selectable list.
  • Stream live output — selecting a terminal streams its output in real time over the WebSocket.
  • Send input — type into the input field and press Enter to send commands to the selected terminal.
  • Special keys — a collapsible touch-keys bar sends Ctrl+C, Esc, Tab, and the arrow keys to the remote shell (handy on touch devices where those are awkward to type).
  • Create and delete — spin up a new terminal or remove one from the dashboard.

Everything you do here executes on the remote machine's shells, with that machine's user privileges. That is the point of the tool — and the reason the next section matters.

Security implications

Exposing TermFlow is genuinely powerful and genuinely dangerous. Internalize all of this before you leave it on:

  • This is a remote-shell surface. The API can create terminals and run arbitrary commands as your user. Anyone who reaches it with the token effectively has an interactive shell on your machine. The token is the only thing between the network and your shell.
  • No encryption. Traffic is plain HTTP and WebSocket — there is no TLS. The token and every keystroke and byte of output travel in the clear. Anyone able to sniff the LAN can capture both. Prefer tunneling over a VPN or SSH rather than exposing raw on an untrusted network.
  • The token can appear in logs. Because the WebSocket token rides as a ?token= query parameter, it can be captured by proxies, browser history, or server logs. Rotate it if it may have been recorded.
  • Bound to every interface. Exposure binds to 0.0.0.0, i.e. all network interfaces, not just the one you had in mind. Your OS firewall may still block inbound connections; only open ports 42031 (and 42030 if you serve the dashboard to other devices) deliberately, and close them afterward.
  • Trust the network, not just the token. Only expose on a network where you trust every other device. Coffee-shop and conference Wi-Fi are not that.
  • Turn it off when done. The default is off for a reason. When your remote session ends, disable Expose on local network and consider a final Rotate.

An honest note

terminal-monitor is a real but companion app: it lives in the repo, you run it yourself, and it is aimed at monitoring headless/localhost instances. Its remote, token-gated auth story has the rough edge described in Step 5. If you are building something more than ad-hoc monitoring — an orchestrator, a CI watcher, a custom dashboard — talk to the exposed API directly using the bearer-token contract, where the behavior is fully specified and stable. See The local API and auth and the WebSocket reference.

Next steps

Footnotes

  1. TermFlow does expose a POST /api/auth/token endpoint that returns a JWT, but the auth gate does not validate that JWT — it only accepts the config authToken. Treat /api/auth/token as legacy monitor-compat scaffolding, not as a way to authenticate API calls.