Goal:
neuralmind watchandneuralmind servesurvive reboots, crashes, and tmux closes. The synapse layer accumulates 24/7 instead of only while you’re actively coding, and the graph view canvas is always athttp://127.0.0.1:8765/when you want to look at it.
Why always-on matters more in v0.11.0+. The directional transition signal (
neuralmind next <file>,neuralmind_next_likelyMCP tool) needs a long observation window to converge — you might edit ten files together but only get nine ordered pairs between them, so transitions accumulate slower than co-activation. Running the watcher as a service means every edit during deep-work sessions feeds the transition graph, not just the edits that happen while a query is open.
Three platforms, same shape: pick the template, point it at your
project, enable it. The templates live in scripts/systemd/
and scripts/launchd/ in this repo.
The PyPI wheel doesn’t include the repo’s scripts/ directory — it
ships only the importable neuralmind package. If you installed via
pip / pipx / uv / Docker, pull the templates straight from
GitHub:
# Linux — systemd
mkdir -p ~/.config/systemd/user
curl -fsSL https://raw.githubusercontent.com/dfrostar/neuralmind/main/scripts/systemd/neuralmind-watch.service \
-o ~/.config/systemd/user/neuralmind-watch.service
curl -fsSL https://raw.githubusercontent.com/dfrostar/neuralmind/main/scripts/systemd/neuralmind-serve.service \
-o ~/.config/systemd/user/neuralmind-serve.service
# macOS — launchd
curl -fsSL https://raw.githubusercontent.com/dfrostar/neuralmind/main/scripts/launchd/com.neuralmind.watch.plist \
-o ~/Library/LaunchAgents/com.neuralmind.watch.plist
curl -fsSL https://raw.githubusercontent.com/dfrostar/neuralmind/main/scripts/launchd/com.neuralmind.serve.plist \
-o ~/Library/LaunchAgents/com.neuralmind.serve.plist
The cp scripts/... commands below assume you have a repo checkout —
substitute one of the curl lines above if you don’t.
NeuralMind ships a /healthz endpoint on the graph-view server
(GET /healthz → {"status": "ok", "version": "..."}, no auth). The
systemd unit uses it in ExecStartPost to fail fast if serve didn’t
come up; Docker HEALTHCHECK and any external monitor can probe the
same endpoint.
User-scope (no root). The unit lives in ~/.config/systemd/user/ and
is enabled per-login user.
# 1. Copy the templates
mkdir -p ~/.config/systemd/user
cp scripts/systemd/neuralmind-watch.service ~/.config/systemd/user/
cp scripts/systemd/neuralmind-serve.service ~/.config/systemd/user/
# 2. Edit the WorkingDirectory line in both files to your project path:
# WorkingDirectory=%h/your-project
$EDITOR ~/.config/systemd/user/neuralmind-watch.service
$EDITOR ~/.config/systemd/user/neuralmind-serve.service
# 3. Enable + start
systemctl --user daemon-reload
systemctl --user enable --now neuralmind-watch
systemctl --user enable --now neuralmind-serve
# 4. Verify both are up and /healthz responds
systemctl --user status neuralmind-watch neuralmind-serve
curl -fsS http://127.0.0.1:8765/healthz
# {"status": "ok", "version": "0.8.0"}
# The graph view canvas itself requires the per-session token. The
# tokenized URL prints to journalctl on every startup:
journalctl --user -u neuralmind-serve | grep -F "http://127.0.0.1:8765/"
# (or pass --no-auth in ExecStart if you understand the implications)
# 5. Tail logs
journalctl --user -u neuralmind-watch -f
journalctl --user -u neuralmind-serve -f
User units don’t run when no user session is active by default. If you need it across logouts, enable lingering:
sudo loginctl enable-linger "$USER"
To uninstall:
systemctl --user disable --now neuralmind-watch neuralmind-serve
rm ~/.config/systemd/user/neuralmind-{watch,serve}.service
The plists live in ~/Library/LaunchAgents/ and run under your user
session — RunAtLoad + KeepAlive together mean “start at login, restart
if it crashes.”
# 1. Copy the templates
cp scripts/launchd/com.neuralmind.watch.plist ~/Library/LaunchAgents/
cp scripts/launchd/com.neuralmind.serve.plist ~/Library/LaunchAgents/
# 2. Edit both files — replace YOUR_USERNAME and the project path:
# WorkingDirectory → /Users/YOUR_USERNAME/your-project
# StandardOutPath → /Users/YOUR_USERNAME/Library/Logs/...
# StandardErrorPath → /Users/YOUR_USERNAME/Library/Logs/...
$EDITOR ~/Library/LaunchAgents/com.neuralmind.watch.plist
$EDITOR ~/Library/LaunchAgents/com.neuralmind.serve.plist
# 3. Load
launchctl load -w ~/Library/LaunchAgents/com.neuralmind.watch.plist
launchctl load -w ~/Library/LaunchAgents/com.neuralmind.serve.plist
# 4. Verify
launchctl list | grep com.neuralmind
curl -fsS http://127.0.0.1:8765/healthz
# 5. Tail logs
tail -f ~/Library/Logs/neuralmind-watch.out.log
tail -f ~/Library/Logs/neuralmind-serve.out.log
The which neuralmind path matters — if you installed via pipx,
your binary is in ~/.local/bin/neuralmind, not /usr/local/bin/neuralmind.
Update the ProgramArguments array’s first element accordingly. If
you use pyenv or a per-project venv, point at the absolute path of
that venv’s neuralmind binary, not the system one.
To unload:
launchctl unload -w ~/Library/LaunchAgents/com.neuralmind.{watch,serve}.plist
rm ~/Library/LaunchAgents/com.neuralmind.{watch,serve}.plist
Run-at-startup tasks for neuralmind watch and neuralmind serve.
The Scheduling Guide has the full PowerShell script + Task Scheduler GUI walkthrough. Short version:
# Register the always-on watcher (replaces the file polling daemon).
# ExecutionTimeLimit = 0 disables Task Scheduler's default 72-hour cap.
Register-ScheduledTask -TaskName "NeuralMind-Watch" `
-Action (New-ScheduledTaskAction `
-Execute "neuralmind" `
-Argument "watch C:\path\to\your-project --quiet") `
-Trigger (New-ScheduledTaskTrigger -AtLogOn) `
-Settings (New-ScheduledTaskSettingsSet -StartWhenAvailable `
-ExecutionTimeLimit (New-TimeSpan -Seconds 0) `
-RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1))
# Register the always-on graph view. --no-browser keeps it from
# spawning a browser on every login.
Register-ScheduledTask -TaskName "NeuralMind-Serve" `
-Action (New-ScheduledTaskAction `
-Execute "neuralmind" `
-Argument "serve C:\path\to\your-project --port 8765 --no-browser") `
-Trigger (New-ScheduledTaskTrigger -AtLogOn) `
-Settings (New-ScheduledTaskSettingsSet -StartWhenAvailable `
-ExecutionTimeLimit (New-TimeSpan -Seconds 0) `
-RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1))
# Verify
Get-ScheduledTask NeuralMind-*
Invoke-WebRequest -UseBasicParsing http://127.0.0.1:8765/healthz
If you run NeuralMind via the repo-root Dockerfile, add a HEALTHCHECK
that probes /healthz:
The repo-root Dockerfile is python:slim-based and does not
include curl. Use a stdlib Python probe instead so the HEALTHCHECK
works without adding a package:
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
CMD python -c "import urllib.request, sys; r = urllib.request.urlopen('http://127.0.0.1:8765/healthz', timeout=2); sys.exit(0 if r.status == 200 else 1)" || exit 1
--start-period=60s matches the systemd template’s readiness window
— neuralmind serve builds the embedding index before binding the
HTTP socket, and first runs on large projects can take a while.
The shipped Dockerfile doesn’t bake this in by default because the
default container command is neuralmind --help, not serve. Add
the directive in your downstream image when you do run serve as
the container entrypoint.
The synapse store is shared across all processes that touch the same
project. With neuralmind watch running 24/7:
file_activity event that the
graph view’s canvas pulses on and the synapse layer reinforces.With neuralmind serve running 24/7:
http://127.0.0.1:8765/ is always there. No “wait, I need to
start the canvas first” friction when you want to debug a retrieval.Pair with the v0.6.0 multi-agent walkthrough for the full “one brain, many agents” story.
/healthz returns 404You’re on NeuralMind < v0.8. The endpoint shipped in v0.8. Upgrade:
pip install --upgrade neuralmind # or pipx upgrade / uv pip install -U
For the systemd unit: remove the ExecStartPost line or drop the
probe loop until you upgrade.
Check the logs for the root cause:
journalctl --user -u neuralmind-watch --since "5 minutes ago"
Common causes:
neuralmind binary not on the PATH for the systemd Service env.
Pass an explicit absolute path in ExecStart (e.g.
/home/$USER/.local/bin/neuralmind).WorkingDirectory doesn’t exist or doesn’t have a graphify-out/
yet. Run neuralmind build . in the
project first.You loaded the plist with the wrong path or the file has a typo. Try:
plutil -lint ~/Library/LaunchAgents/com.neuralmind.watch.plist
If plutil reports OK and launchctl load -w ... still fails, check
that the Label inside the plist matches the filename
(com.neuralmind.watch).
Check /healthz first — if that returns OK, the server is up but the
graph isn’t indexed yet. Run neuralmind build . in the project.