io.github.crunchtools/systemd
It provides MCP tools for managing and troubleshooting systemd units on a host via D-Bus.
List units or installed unit files, and inspect curated status or full properties.
Control unit lifecycle: start, stop, restart, reload, enable, disable, mask, unmask, and daemon-reload.
Write new unit files with optional start/enable and backups; decommission units with stop/disable/optional mask, backup, and removal.
Troubleshoot with journal queries, failed-unit listing, and pending/stuck job inspection.
Inspect timers, system manager state, host info, and logged-in sessions.
Refuse dangerous actions on core protected units, with an extendable denylist.
Manages the full lifecycle of systemd units on a Linux host via D-Bus: listing and inspecting units, starting/stopping/restarting/reloading, enabling/disabling/masking, authoring and removing unit files, querying the journal, triaging failed units and stuck jobs, listing timers, checking manager and host status, and listing login sessions.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@io.github.crunchtools/systemd list all failed units"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-systemd-crunchtools
MCP server for systemd unit management via D-Bus. Manages the full lifecycle of any systemd unit — not just Podman-managed containers: listing, status, lifecycle control, unit file authoring and decommissioning, journal queries, failed-unit and job triage, timers, host info, and login sessions.
Installation
# uvx (zero-install)
uvx mcp-systemd-crunchtools
# pip
pip install mcp-systemd-crunchtools
# Container
podman run \
-v /run/dbus/system_bus_socket:/run/dbus/system_bus_socket \
-v /etc/systemd/system:/etc/systemd/system \
--security-opt label=type:container_runtime_t \
quay.io/crunchtools/mcp-systemdThe D-Bus socket mount is required for every tool. The /etc/systemd/system mount is only required for unit_file_write_tool and unit_file_remove_tool — omit it to run the server read/lifecycle-only.
Do not add :z or :Z to the unit-directory mount. Both relabel the host
directory recursively — z to container_file_t, Z to a container-private
MCS label — and /etc/systemd/system is not a volume, it is host state whose
SELinux type is a real security boundary. One such mount rewrites the type on
every unit on the host, including sshd and dbus, and it does it again on
every container restart. container_runtime_t can already read and write
systemd_unit_file_t, which is what the relabel was buying, so the mount
needs no label option at all. Fix an already-relabeled host with
restorecon -RF /etc/systemd/system (-F is required because
container_file_t is a customizable type, so a plain restorecon declines).
Related MCP server: mcp-podman-crunchtools
Configuration
Variable | Required | Default | Description |
| No |
| D-Bus system bus socket path |
| No |
| Directory unit_file_write/remove operate on |
| No | — | Comma-separated units added to the built-in denylist |
Protected units
unit_stop, unit_restart, unit_disable, unit_mask, and unit_file_remove refuse to act on a small built-in denylist of core system units (dbus, sshd, networking, logind, journald). This cannot be bypassed — it exists so an agent can't take down the box it's running on. Add more units with SYSTEMD_EXTRA_PROTECTED_UNITS.
Claude Code Integration
claude mcp add mcp-systemd-crunchtools \
-- uvx mcp-systemd-crunchtoolsTools (21)
Units (3)
Tool | Description |
| List loaded units or installed unit files |
| Curated status (active state, PID, memory, CPU) |
| Full property dump (deps, exec settings, cgroup) |
Lifecycle (9)
Tool | Description |
| Start a unit |
| Stop a unit (protected-list guarded) |
| Restart a unit (protected-list guarded) |
| Reload a unit's config without restarting |
| Enable a unit to start on boot |
| Disable a unit from starting on boot (protected-list guarded) |
| Mask a unit (protected-list guarded) |
| Unmask a unit |
| Reload systemd's unit file cache |
Unit files (2)
Tool | Description |
| Write a new unit file (backs up any file it overwrites) |
| Decommission: stop, disable, back up, remove (protected-list guarded) |
Troubleshooting (3)
Tool | Description |
| Filtered journal query (unit, priority, since/until, pattern, boot) |
| List units in the 'failed' state |
| List pending/stuck jobs |
Timers (1)
Tool | Description |
| List timers with next/last elapse |
System (2)
Tool | Description |
| Manager state: running/degraded, failed/job counts, version |
| Hostname, kernel, OS |
Sessions (1)
Tool | Description |
| Who's logged in right now |
License
AGPL-3.0-or-later
Available Tools
21 toolsdaemon_reload_toolDaemon Reload ToolA
Reload systemd's unit file cache (equivalent to systemctl daemon-reload).
Inputs: no named parameters. Returns: object
failed_units_toolFailed Units ToolARead-only
List units currently in the 'failed' state — the first thing to check at 2AM.
Inputs: no named parameters. Returns: object
hostinfo_toolHostinfo ToolARead-only
Get host identity info: hostname, kernel, OS.
Inputs: no named parameters. Returns: object
journal_query_toolJournal Query ToolBRead-only
Query the journal — the main 2AM troubleshooting tool.
Inputs: boot, unit, lines, since, +3 more. Returns: object
list_jobs_toolList Jobs ToolARead-only
List pending systemd jobs — reveals stuck starts/stops/reloads.
Inputs: no named parameters. Returns: object
session_list_toolSession List ToolARead-only
List logged-in sessions — who's on this box right now.
Inputs: no named parameters. Returns: object
system_status_toolSystem Status ToolARead-only
Get overall systemd manager state: running/degraded, failed and job counts.
Inputs: no named parameters. Returns: object
timer_list_toolTimer List ToolARead-only
List systemd timers with their next and last elapse times.
A null next_elapse or last_trigger means systemd gave no renderable time: unset (the timer has not run yet), infinity (it will never fire again), or a value outside the renderable range. A timer whose properties could not be read at all carries an error field instead of the two times.
Inputs: no named parameters. Returns: object
unit_disable_toolUnit Disable ToolB
Disable a unit from starting on boot. Refused for units on the protected list.
Inputs: unit_name (required). Returns: object
unit_enable_toolUnit Enable ToolC
Enable a unit to start on boot.
Inputs: unit_name (required). Returns: object
unit_file_remove_toolUnit File Remove ToolA
Decommission a unit: stop, disable, optionally mask, back up and remove its file.
Refused for units on the protected list. Best-effort on stop/disable — a unit that's already stopped or was never enabled doesn't block file removal.
Inputs: unit_name (required), mask. Returns: object
unit_file_write_toolUnit File Write ToolA
Write a new unit file for setting up a service. Backs up any file it overwrites.
Requires the host's unit directory (default /etc/systemd/system) to be bind-mounted into the container. Runs daemon-reload after writing.
Inputs: content (required), unit_name (required), start, enable. Returns: object
unit_list_toolUnit List ToolCRead-only
List systemd units.
Inputs: mode, pattern, all_units. Returns: object
unit_mask_toolUnit Mask ToolA
Mask a unit so it cannot be started even manually. Refused for protected units.
Inputs: unit_name (required). Returns: object
unit_reload_toolUnit Reload ToolA
Ask a unit to reload its configuration without restarting.
Inputs: unit_name (required). Returns: object
unit_restart_toolUnit Restart ToolB
Restart a unit. Refused for units on the protected list.
Inputs: unit_name (required). Returns: object
unit_show_toolUnit Show ToolBRead-only
Dump the full property set for a unit (dependencies, exec settings, cgroup, etc).
Inputs: unit_name (required). Returns: object
unit_start_toolUnit Start ToolC
Start a unit.
Inputs: unit_name (required). Returns: object
unit_status_toolUnit Status ToolBRead-only
Get curated status for a unit: active/sub/load state, PID, memory, CPU.
Inputs: unit_name (required). Returns: object
unit_stop_toolUnit Stop ToolB
Stop a unit. Refused for units on the protected list.
Inputs: unit_name (required). Returns: object
unit_unmask_toolUnit Unmask ToolA
Unmask a previously masked unit.
Inputs: unit_name (required). Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 21 tools
Each tool maps to a distinct systemctl verb or resource, and the descriptions clearly separate near-neighbors like unit_status (curated: state/PID/memory/CPU) vs unit_show (full property dump). The main soft spot is unit_file_remove_tool, which internally does stop/disable/mask and therefore overlaps with unit_stop/unit_disable/unit_mask, though it is framed as a composite decommission operation.
The dominant pattern is noun_noun_verb_tool (unit_start_tool, timer_list_tool, journal_query_tool), applied consistently across the unit lifecycle. A handful of outliers (hostinfo_tool, failed_units_tool, list_jobs_tool) flip to verb-first or drop the prefix, but they remain readable and unambiguous.
21 tools is on the heavy side, but systemd genuinely exposes this many orthogonal operations (unit lifecycle, timers, journal, jobs, sessions, host identity). Every tool maps to a real systemctl/journalctl capability rather than being filler.
Full unit lifecycle is covered: write/remove, start/stop/restart/reload, enable/disable, mask/unmask, plus diagnostics (status, show, failed units, jobs, timers, journal, daemon-reload). Minor gaps exist — no way to read a unit file's raw contents (unit cat), no journal follow/live tail, and no drop-in override editing — but agents can work around these via unit_show and journal_query.
Maintenance
Related MCP Connectors
Start, pause, resume, and run commands and file operations in Linux sandboxes.
Linux server administration over OAuth MCP: shell, Docker, systemd, files and monitoring.
Securely control computers you explicitly pair through files, terminals, processes, screenshots, desktop UI/input, clipboard, browser automation, diagnostics, and document tools.
Start and manage Reason cloud coding agents, projects and sessions from any MCP client.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceProvides AI assistants with safe, read-only access to Linux systemd services, including status monitoring, log querying, and dependency analysis, with optional granular permissions for service management actions.2-
- AlicenseBqualityBmaintenanceEnables container, image, pod, network, volume, and system management via Podman REST API. Supports rootful and rootless Podman operations.30AGPL 3.0
- AlicenseAqualityDmaintenanceAn MCP server that reports on and manages systemd services using systemctl and journalctl, enabling service listing, status, logs, and control operations.5MIT
- FlicenseNot gradedqualityCmaintenanceControls a Linux host through structured interfaces like systemd, journald, and D-Bus for service management, journal queries, power operations, and more, with safety guards to prevent accidental damage.-