reticle serve starts the daemon: the WebSocket bridge your app dials into, plus the tool engine behind it. It spawns a detached child and then waits for that child to answer /status before reporting success.
reticle mcp, which starts a daemon itself if one is not already up.
Flags
The HTTP flags are honoured or refused, never silently dropped: against an already-running daemon that does not serve the requested verify port,
serve --http exits 1 and names both ports. A running daemon keeps the flags it was started with, so reticle stop, then serve again. A verify port that cannot be bound fails the daemon start with a reticle_daemon_start_failed line naming that port.
What it prints
One structured line. When a daemon already owns the port, it says so and does nothing:reticle_daemon_spawned with the port:
python3 -m http.server 4498 holding the port and the punctuation between the two halves of the reason shown as ...:
Exit codes
serve reports the bind, not the spawn. It used to exit 0 the moment it forked, while the
child died on an EADDRINUSE nobody joined back up. It now waits for the daemon to answer.Worked example
What the daemon is
The bridge, the tool engine, and where
.reticle/ lives.