# Public Production Ports

TrapOS public production services use the `4242-4244` TCP range. Keep local developer defaults separate from these public ports so tests and local tools can run without binding production-facing addresses.

| Port | Service | Notes |
|---|---|---|
| `4242` | opencode server HTTP API | Production/public port for `opencode serve`. Local/dev examples may still use opencode's default `4096`. |
| `4243` | Reserved | Formerly the ComputerCraft bridge WebSocket (removed with `tools/mcp-bridge`). Free for a future service. |
| `4244` | Reserved | Free public production port reserved for a future service. Do not assign it casually in local tooling. |
| `4444` | trapos-server gateway | Fastify service (`tools/trapos-server`) exposing the `trapos-cloud-gateway` WebSocket at `/gateway`. Sits **outside** the `4242-4244` range on purpose (4244 stays reserved). Default `TRAPOS_SERVER_PORT`; serve with `just serve`. |

## Local Vs Production

- Local/dev opencode: `http://127.0.0.1:4096`.
- Public/production opencode: `http://<public-host>:4242`.

Production services exposed on public ports should use the normal deployment controls for the host: authentication where supported, firewall rules, and TLS or a reverse proxy when crossing untrusted networks.

## Securing the gateway (port 4444)

The gateway authenticates each connection with a shared secret (`TRAPOS_SERVER_PASSWORD`) sent in the WebSocket `hello` frame. The server itself speaks **plain `ws://`** — it does not terminate TLS. Therefore:

- **Always front port 4444 with TLS (`wss://`)** — a TLS-terminating reverse proxy (nginx/Caddy/Traefik) or a tunnel/VPN. Exposing `ws://` directly to the internet sends the secret in cleartext and lets an MITM defeat authentication entirely.
- Keep `TRAPOS_SERVER_PASSWORD` a high-entropy random value. `just install` generates `openssl rand -hex 32` (256-bit); do not replace it with a weak/guessable string (the gateway has no brute-force rate limiting of its own — rely on the secret's entropy and the fronting proxy).
- The MCP endpoint (`exec-lua` / `write-file`, default `127.0.0.1:4445`) is **unauthenticated** and must stay loopback-bound. The server refuses to start if `MCP_HOST` is non-loopback unless `MCP_ALLOW_PUBLIC=1` is set — only do that behind your own authenticated proxy.
