mcp-systemd
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., "@mcp-systemdlist all the systemd service and timer 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
Experimental semantic MCP interface for systemd.
The MCP server is the real implementation. The systemd backend is selected from configuration: an in-memory simulated backend (default) or the host's real system manager over D-Bus.
Architecture
The server uses a small hexagonal boundary:
MCP Resources / Tools
|
v
domain.Systemd
|
v
backend adapterThe domain model and Systemd port live under src/mcp_systemd/domain/. Concrete adapters live under src/mcp_systemd/backends/.
The default composition uses MockSystemd. Setting backend.type: dbus composes DbusSystemd against the local system manager instead. Resources and Tools depend only on the domain port, so the backend can be replaced without changing the MCP interface.
MCP URIs and payload serialization remain outside the domain model.
Related MCP server: Design System MCP Server
Resource templates
systemd://system/unit/{type}/{name}
systemd://user/{user}/unit/{type}/{name}
systemd://system/unit/{type}/{name}/definition
systemd://user/{user}/unit/{type}/{name}/definitionThe initial mock supports service and timer as unit types.
For each represented systemd manager, discovery follows the logical semantics of systemctl list-units --all, restricted to supported unit types. resources/list exposes the combined concrete Resource catalog across the represented managers on the host.
Reading a unit resource returns compact runtime state:
{
"description": "OpenSSH server daemon",
"load_state": "loaded",
"active_state": "active",
"sub_state": "running"
}The URI carries the unit identity, so the payload does not repeat the unit name.
The /definition sub-resource returns the unit file and drop-ins as text. It is separate because configuration content can be much larger and is not needed for most state-oriented decisions.
Model-facing tools
The server exposes semantic tools that make the Resource model usable even when an MCP harness does not expose Resource operations directly to the model:
list_units(type?, user?)discovers unit Resources;read_unit(uri)reads the compact current state of a unit;read_unit_definition(uri)reads its definition and drop-ins;list_unit_types()describes the unit types supported by mcp-systemd.
read_unit and read_unit_definition both accept the canonical base unit Resource URI. The model does not need to construct sub-resource URIs.
The Resources remain canonical. The first three tools are a semantic fallback and belong to the resource_api_fallback exposure group.
Tool exposure
Tool exposure is configured independently from MCP Tool Annotations.
Each tool can belong to zero or more exposure groups. Groups act as feature flags for the model-facing tool surface, and individual tools can be enabled or disabled as explicit overrides.
Example:
tools:
groups:
resource_api_fallback: true
enable: []
disable: []The default resource_api_fallback group contains:
list_units
read_unit
read_unit_definitionSet the group to false when the harness already provides equivalent model-controlled Resource discovery, sub-resource/template discovery, and reading.
An explicit per-tool override takes precedence over group membership:
tools:
groups:
resource_api_fallback: false
enable:
- read_unit
disable:
- list_unit_typesA tool cannot appear in both enable and disable.
Semantic evaluations
The evals/ directory contains repeatable model-facing evaluation cases for discovery, state inspection, unit definitions, unsupported capabilities, and token-efficient behavior.
Validate the corpus with:
uv run python evals/validate.pySee evals/README.md for the case format and execution protocol.
Tests
Run the unit and integration suites separately:
uv run python -m unittest discover -s tests/unit
uv run python -m unittest discover -s tests/integrationSemantic model behavior remains covered separately under evals/.
See tests/README.md for the TDD workflow and test-layer definitions.
A manual-only GitHub Actions workflow named CI runs the locked install, functional tests, and semantic-eval validation in a clean environment. It is not triggered by pushes or pull requests.
Run
uv sync --locked
uv run mcp-systemdRuntime dependencies are committed in uv.lock.
The server uses FastMCP HTTP transport.
By default it listens only on 127.0.0.1:48000.
Backends
The server can run against two backends, selected from configuration:
mock(default): the in-memory simulated backend used for development, tests, and semantic evaluation;dbus: the real system manager over D-Bus, read-only.
backend:
type: mockbackend:
type: dbusBackend selection is composition only. Building the server does not connect to D-Bus: the connection is lazy and happens on the first operation. Failures surface on that first operation and are never replaced by an automatic fallback to the mock.
With dbus, only system services and timers are supported:
discovery (
list_units) and fresh runtime-state reads (read_unit) work;unit definitions (
read_unit_definition) and user managers are not implemented and fail explicitly;list_unit_typeslists the supported domain unit types, not a backend capability matrix.
Capabilities are not inferred from the selected backend: tool exposure remains controlled by tools.groups, tools.enable, and tools.disable. The example below disables read_unit_definition for a D-Bus trial. Disabling the tool hides that tool only; the definition and user Resource templates still exist, and unsupported reads fail.
Configuration
The default configuration path is /etc/mcp-systemd/config.yaml.
When no --config is given, the default path is used if it exists; if it is absent, built-in defaults are used (mock backend, 127.0.0.1:48000).
An explicit path is required to exist: uv run mcp-systemd --config ./config.yaml exits nonzero if the file is missing or invalid, before any server is started.
Configuration is read once at startup; restart the server after changing it.
Example:
server:
host: 127.0.0.1
port: 48000
backend:
type: dbus
tools:
disable:
- read_unit_definitionbackend is optional. A missing backend section, or backend: {}, selects mock. Only type is allowed inside backend; unknown keys inside backend, unknown root keys, and unsupported backend types are rejected. Supported values are the exact, case-sensitive strings mock and dbus.
Launch with a configuration file:
uv run mcp-systemd --config ./config.yamlOn startup the CLI prints the selected backend to stderr, for example backend=dbus (local system manager). This announces the selection; it does not mean a D-Bus connection has been established.
This server cannot be deployed
Maintenance
Related MCP Connectors
Machine-readable utilities and datasets for AI agents.
Read-only tools over the Psychopathia Machinalis nosology: 79 conditions, 11 tools.
Machine-readable entity discovery with provenance, trust and verified source evidence.
Read-only QFactory catalog of agent workflows: search, get exact versions, schema, validate YAML.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables dynamic exploration of Angular library components by reading and analyzing the public API exports. Provides tools to list available components and retrieve detailed component information.-
- AlicenseNot gradedqualityDmaintenanceProvides resources, tools, and prompts for a Design System via MCP protocol, enabling component search, reading, and related component discovery.221 npmMIT
- AlicenseAqualityBmaintenanceProvides AI agents with offline access to OPC UA companion specification types, dependencies, and engineering units for industrial modeling.1184 npm2Apache 2.0
- AlicenseAqualityBmaintenanceExposes design system component documentation to LLM clients via MCP, allowing listing and retrieving component contexts from Markdown files with YAML frontmatter.27 npmMIT