Ports
A port is the TCP number a service listens on. Adopted projects declare theirs in project.json services[].
What you see
The Dashboard lists declared services: name, port, up or down, open URL, Kill when live. Extra sockets that are not declared hide behind Show N observed. Overlapping declared ports get an amber row.
The This Mac dashboard (rail pill → View dashboard, or command palette → View this Mac) is the live control board: only rail projects that currently have a listening port or a running process. Each card lists that project's ports and process-manager rows, with Kill, Stop, and Stop all. Unattributed sockets hide behind Show N other sockets. Idle processes stay on the project Processes tab.
Live data comes from a 1s scan (lsof / ss) on the liveStatus topic. Conflicts publish on portConflicts.
Conflicts
Two adopted projects can declare the same number. Adopt writes the ports the repo actually uses and does not remap. The dashboard shows that the two cannot run at the same time.
Resolve port conflicts on the amber note opens a short draft prompt for you to review. It tells the agent to ask the engine for free ports through the port_suggest MCP tool and apply them across this project. Free ports come from the device registry, from 4200 up, skipping anything already claimed, listening, or declared by another project. The other project is untouched.
port.fixConflicts does the same without the draft step:
noc ports fix -p <projectId>
To see the numbers without changing anything, run noc ports suggest -p <projectId> (add --all for every service), or call port_suggest from any MCP client.
Rotate
Moves every declared service onto free registry ports, even when nothing currently overlaps. Rewrites the usual config files (.env, Vite/Next/Svelte configs, compose, .nocturnal/project.json). Does not commit.
noc ports rotate -p <projectId>
From the app: command palette → Rotate this project onto free ports. MCP: port_rotate with { "projectId": "…" }. Same via POST /cmd { "type": "port.rotate", "payload": { "projectId": "…" } }.
Kill
A live declared row has Kill. Or:
noc ports kill --port 3000
That is ports.kill. Read the process log before you kill Nocturnal's own ports.
Nocturnal's own ports
Daemon 17410. Web 17411. Do not kill those PIDs to "unstick" the UI. Read ~/.nocturnal/logs/ first.
API
The running engine exposes the same facts over HTTP. Open /api-docs on port 17410 for the current contract.