Create a plist at /Library/LaunchDaemons/com.example.mydaemon.plist owned by root:wheel with permissions 0644.
Set the required keys: Label matching the filename without .plist, ProgramArguments as an array of the executable and its arguments, and KeepAlive set to true to restart the process if it exits.
Add StandardOutPath and StandardErrorPath pointing to log files under /var/log/ for output capture.
Load the daemon: sudo launchctl load /Library/LaunchDaemons/com.example.mydaemon.plist
Check daemon status: sudo launchctl list | grep com.example.mydaemon — the PID column shows the running process ID.
Known gotchas
LaunchDaemons run as root by default; to run as a different user, add a UserName key with the target username, but the plist itself must still be owned root:wheel.
KeepAlive set to true with a crashing process creates a restart loop; use KeepAlive as a dictionary with keys like SuccessfulExit = false to restart only on abnormal exits.
Plist files in /Library/LaunchDaemons with wrong ownership or permissions are silently refused by launchd; always verify with ls -l after creating the file.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp