The Free Encyclopedia

Building MCP Servers as systemd User Services

theLAB's MCP (Model Context Protocol) tool servers run as systemd --user units under the youruser account rather than system-wide services. This keeps them in user scope (no root, user's environment and paths) — but it comes with one non-negotiable requirement.

Linger MUST stay enabled

By default, a user's systemd --user services start when the user logs in and stop when the last session ends. For always-on MCP servers that is fatal: between logins the units die, and the tablet/clients report "tool not provided."

The fix is to enable lingering so the user manager runs at boot, independent of interactive logins:

sudo loginctl enable-linger youruser
loginctl show-user youruser | grep Linger   # Linger=yes

If MCP tools vanish ("tool not provided"), check linger first. A reboot, a package update, or a re-provisioned box can silently drop it.

Anatomy of a unit

~/.config/systemd/user/mcp-myserver.service:

[Unit]
Description=MCP server — myserver
After=network-online.target

[Service]
ExecStart=/usr/bin/python3 /home/youruser/mcp/myserver/server.py
Restart=always
RestartSec=2
Environment=PYTHONUNBUFFERED=1

[Install]
WantedBy=default.target

Manage it in user scope (note --user, no sudo):

systemctl --user daemon-reload
systemctl --user enable --now mcp-myserver
systemctl --user status mcp-myserver
journalctl --user -u mcp-myserver -f

Checklist

  • [ ] loginctl enable-linger youruser done and verified
  • [ ] WantedBy=default.target (not multi-user.target — that's system scope)
  • [ ] Restart=always so a crash self-heals
  • [ ] Service reachable on the expected transport (stdio vs HTTP/SSE) for the client

See also: Building MCP Tools for a Local LLM.