Skip to main content
Glama

journalmcp

tests

A read-only view of systemd and the journal, for people and for models: eight queries (units, failed units, timers, one unit's status, its unit file, the journal, the boot list and a summary) served by one Python core through two thin fronts, a command-line tool and an MCP server over stdio. It runs systemctl and journalctl as the user who starts it, never through a shell, caps what it returns, and redacts secrets from journal text before anything leaves the process.

Why this exists

"Why did that service fail?" is a question a model can help with, but only if it can see the unit, its journal and its unit file. Handing it a shell for that hands it systemctl stop too. journalmcp gives a model the reading half and nothing else: every command it can build starts with a read verb from one fixed list, and a test builds every one of them to check.

The same queries are a CLI, because the code a model calls should be code you can run yourself and get the same answer. Both fronts call the same core functions and emit the same JSON; parity tests compare them on the same recordings.

Related MCP server: claude-systemd-mcp

What it does

CLI subcommand

MCP tool

What it reads

units

list_units

the units a manager has loaded, filtered by --state, --type or --pattern

failed

failed_units

the units in the failed state

timers

list_timers

the timers, what each activates, and when it last ran and next runs

status

unit_status

one unit's load, active and sub state, description, result and main PID, plus its last journal entries

unit-file

unit_file

the unit file as systemctl cat prints it, drop-ins included

journal

journal

journal entries, filtered by unit, time, priority and a message pattern

boots

boots

the recorded boots, current boot first

summary

system_summary

the manager state, failed-unit and timer counts for both managers, and the boot time

The MCP front also offers one prompt, triage_failed_unit, which asks the model to call unit_status, journal and unit_file for one unit, in that order, and report the likely cause.

  • Scope. scope is user (your systemd --user manager; the CLI's default) or system. Nothing else is accepted. boots and summary take no scope.

  • --json. The CLI prints a table by default; --json prints the result object, which is the same object the MCP tool returns as structured content.

  • Caps. lines (--lines) asks for 1 to 1000 entries (default 100 for journal, 20 for status). Every string value is capped at 4096 bytes and every result at 65536. A cut is never silent: the result carries truncated: true, a cut value ends in [TRUNCATED], and the CLI's text ends with a [TRUNCATED] line.

  • Redaction. On by default, over every string taken from the journal, unit files and unit properties: PEM blocks, bearer credentials, password= and secret= pairs, and tokens each become a visible [REDACTED:<class>] marker. IP addresses are kept, because a firewall log is useless without them. JOURNALMCP_REDACT=off turns it off; JOURNALMCP_REDACT_PATTERNS=<file> adds your own regular expressions, one per line. Any other value of the switch is an error, so a typo cannot pass as either setting. Redaction is pattern matching: docs/security-model.md lists the credential shapes it does not catch in this version.

./journalmcp failed --scope system
./journalmcp status --unit cron.service --scope system --lines 5
./journalmcp journal --scope system --priority err --since=-1h --json

How it differs from systemd-mcp

openSUSE/systemd-mcp is the closest existing project, and it does more. Going by its README: it is built with go build and "directly connects to systemd via its C API and so doesn't need systemctl to run", where journalmcp is Python that runs systemctl and journalctl as argv lists. It can change units: its tool list includes change_unit_state ("start, stop, restart, reload, enable, disable"), and writes "trigger a polkit request"; journalmcp has no write operation at all. It installs with sudo make install, which places a gatekeeper in /usr/sbin with its own systemd units and polkit policy so it can read the whole journal; journalmcp runs from a checkout and reads only what the invoking user can already read. It offers an HTTP transport with OAuth2 alongside stdio; journalmcp speaks stdio only. Its tests include one "which tests authentication with oauth2 using a keycloak container"; journalmcp's suite replays recorded command output and touches neither systemd nor the network.

Installing

Needs Linux with systemd, Python 3.12 or newer, git and uv.

git clone https://github.com/hilliersmmain/journalmcp.git
cd journalmcp
uv sync --frozen
./journalmcp --version

uv sync --frozen builds .venv from uv.lock exactly; nothing is resolved afresh. The eight query subcommands and --version use only the standard library and run under the system python3 as well. ./journalmcp serve, the MCP server, needs the locked environment: under the system interpreter it prints one line saying so and exits 1.

Claude Code. The server is started through a small wrapper, tools/journalmcp-mcp, which runs it from the checkout's .venv under env -i with only HOME, PATH=/usr/bin:/bin, XDG_RUNTIME_DIR and the two redaction variables passed through. Copy it to a directory on your PATH, point it at your checkout, and register it:

cp tools/journalmcp-mcp ~/.local/bin/
claude mcp add journalmcp -- ~/.local/bin/journalmcp-mcp

The wrapper looks for the checkout at $HOME/Projects/journalmcp; if yours is elsewhere, edit the REPO= line in the copy, or set JOURNALMCP_REPO in the server's environment. bash tools/smoke-test-mcp ~/.local/bin/journalmcp-mcp sends one initialize request and prints PASS when the server answers cleanly.

Other MCP clients. docs/examples/mcp.json is a server entry to copy into your client's configuration. YOUR-USER in its path stands for your own home directory (a JSON file can carry no comment to say so):

{
  "mcpServers": {
    "journalmcp": {
      "command": "/home/YOUR-USER/.local/bin/journalmcp-mcp"
    }
  }
}

The skill. skill/SKILL.md teaches Claude Code to use the CLI directly. To use it, link it into your own skills directory, for example ln -s "$PWD/skill" ~/.claude/skills/journalmcp.

Security model

docs/security-model.md has one section per item, each naming the code, the test and the threat it answers:

  1. Read-only. Every argv starts with a read verb from one fixed list.

  2. argv only. No shell, no shell=True, no command built by joining strings.

  3. Unit names are validated against systemd's unit-name rules before use.

  4. Journal fields are allowlisted; hostname, machine id and command line are dropped.

  5. Output is capped by lines and bytes, with a visible truncation marker.

  6. Secrets are redacted from message text; configurable; IP addresses kept.

  7. Every subprocess has a timeout (10 seconds).

  8. No network calls; only the MCP front imports anything outside the standard library.

  9. No privilege escalation: no sudo, no pkexec, no setuid helper.

  10. The MCP wiring is a pinned env -i wrapper, never a launch that resolves packages at start-up.

What journalmcp claims about itself, and the test that proves each claim:

  • Read-only by construction: test_every_argv_starts_with_a_read_verb (tests/test_core.py) builds the argv of all eight operations and checks the verb; pytest -k read_verb.

  • One core serves a CLI and an MCP server: test_parity_cli_json_equals_mcp_structured_content (tests/test_parity.py) runs both fronts on the same recordings and compares the data; pytest -k parity.

  • It redacts secrets from journal text: test_redact_the_synthetic_secrets_recording (tests/test_journal.py) runs a recording of invented secrets through the core and finds none of them in the result; pytest -k redact.

  • It ships a documented security model: docs/security-model.md, with the ten numbered sections above, each naming its tests.

  • Its tests run against recorded fixtures: test_the_guard_stops_an_unmarked_test_at_the_real_runner (tests/test_runner.py) proves that a test reaching the real runner fails unless it is marked live; the recordings are in tests/fixtures/.

Tests

uv run --frozen pytest --collect-only -q | grep -c "::"

prints 599 on a fresh clone. uv run --frozen pytest -q runs them; six skip in a fresh clone, because they check the maintainer's private scrub inputs. The tests replay command output recorded from a real machine and scrubbed of its hostname, user names, addresses, machine id, disk and volume identifiers and the maintainer's own unit names; a guard in tests/conftest.py fails any test that reaches the real subprocess runner, so nothing in the run touches systemd or the network. Three opt-in tests marked live run against the real user manager (uv run --frozen pytest -m live); they are off by default and CI never selects them. CI also runs ruff check ., mypy --strict src and the launcher under an empty environment.

What it does not do

  • No unit changes. It cannot start, stop, restart, enable, disable, mask, edit or reload anything, in this version or through any parameter.

  • No privilege escalation. It reads what the invoking user can read; a user outside adm or systemd-journal sees their own journal, not the system's.

  • No network transport. The MCP server speaks stdio only: no HTTP, no socket, no listener.

  • No field selection beyond the parameters. A caller cannot name journal fields or pass journalctl options; filtering goes through unit, since, until, priority, grep and lines only.

  • No sandbox. Its guarantees are properties of the code, held by tests, not an operating-system boundary; the process has the invoking user's rights. What an MCP client then shows a model is the client's decision.

  • No escaping in the CLI's text view. Log text is printed as written, control characters included; --json escapes them.

Licence

MIT; see LICENSE.

Available Tools

8 tools
bootsA
Read-only

The boots the journal records; index 0 is the current boot. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
bootsYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the description's trailing 'Read-only' is redundant rather than additive. The genuinely useful disclosure is the index-0-is-current-boot ordering convention, which is behavior an agent cannot get from the annotations or the empty schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single compact sentence with the resource stated first and the ordering rule immediately after. Nothing is padded, and the one arguably redundant clause ('Read-only') costs almost nothing in length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no prose explanation, and annotations cover the safety profile. The description supplies the one non-obvious piece — boot indexing — making it sufficient for correct invocation, with only the missing relationship to the journal sibling as a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a parameterless tool is 4. No parameter information is missing or misleading.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific resource (the boot sessions recorded by the journal) and a concrete semantic detail — index 0 is the current boot — which tells an agent exactly what the list contains and how it is ordered. It is clearly distinct from siblings like journal, unit_status, or failed_units, though it never explicitly contrasts itself with them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The index-0 convention implies how the output is meant to be consumed (e.g., selecting a boot to query elsewhere), but there is no explicit when-to-use statement, no mention of the journal/boot relationship, and no alternatives named. Usage is inferable rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

failed_unitsA
Read-only

List the failed units of one manager. Read-only. scope is 'user' or 'system'.

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
scopeYes
unitsYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the description's 'Read-only' statement is redundant with structured data and earns no credit. It does add one piece of behavioral context — that the tool is scoped to a single manager's failed units — which is modest value beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the purpose, then the safety trait, then the parameter constraint. Only 'Read-only' is arguably wasted since annotations already state it.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and the one required parameter's values are given. The main remaining gap is that 'manager' is never defined and no sibling routing is offered, but for a single-parameter read tool this is close to sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the sole parameter has no enum in the schema, so the description carries the full burden; it does so by spelling out the allowed values 'user' or 'system'. That is exactly the information an agent needs to call the tool, though it omits the default and what each value selects.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the failed units') and narrows scope ('of one manager'), which distinguishes it from the sibling list_units that presumably returns all units. It does not explicitly name or contrast against list_units or the other siblings, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the agent can infer this is for diagnosing failed services rather than listing everything, but the description never says when to prefer failed_units over list_units or unit_status. No alternatives or preconditions are named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

journalA
Read-only

Journal entries, oldest first, reduced to an allowlist of fields. Read-only.

Filters: unit, since and until (such as '2026-10-03 12:00' or '-1h'), priority (such as 'err' or 'warning..crit'), grep (a regular expression on MESSAGE), lines (default 100, at most 1000). Secrets are redacted; text is capped at 4096 bytes per value and 65536 bytes in all, and a cut ends in [TRUNCATED] and sets truncated to true.

ParametersJSON Schema
NameRequiredDescriptionDefault
grepNo
unitNo
linesNo
scopeYes
sinceNo
untilNo
priorityNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
unitYes
scopeYes
entriesYes
truncatedYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnlyHint and openWorldHint, but the description adds real behavioral detail: secrets are redacted, values are capped at 4096 bytes and 65536 bytes overall, a cut appends [TRUNCATED] and sets truncated to true, and results are reduced to an allowlist. That is substantial data-handling context an agent cannot get from the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and read-only status are front-loaded, followed by a compact filter list and one dense paragraph on redaction and truncation. Every sentence carries information, though the truncation sentence packs several distinct facts into one run-on.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be described, and the description still adds the truncated flag and allowlist behavior. The remaining gap is the undocumented required 'scope' parameter, which an agent must guess at.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description carries the load, and it documents six of seven parameters with concrete syntax examples for since/until ('2026-10-03 12:00' or '-1h') and priority ('err', 'warning..crit'). It omits any explanation of the required 'scope' parameter, which is the one the agent must supply.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource (journal entries), states the ordering (oldest first) and the projection (allowlist of fields), so an agent knows it is a log-read tool. The verb is only implied by the noun phrase plus 'Read-only', and nothing distinguishes it from siblings such as boots or unit_status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The filter list (unit, since, until, priority, grep, lines) implies how to narrow a query but never says when to choose this tool over boots or unit_status. There are no exclusions or prerequisites, so usage is inferred rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_timersB
Read-only

List the timers of one manager, with next and last run times in microseconds since the epoch. Read-only. scope is 'user' or 'system'.

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
scopeYes
timersYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the 'Read-only' sentence largely repeats structured data rather than adding new context. It does add useful behavioral detail about the return format (next/last run times expressed in microseconds since the epoch), but says nothing about permissions, empty results, or pagination.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight clauses, front-loaded with the verb and resource, no filler. The scope clause is appended naturally at the end rather than buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is not needed. Combined with annotations covering the safety profile and the description supplying the scope enum values and time format, an agent has enough to invoke this correctly, with only minor gaps (permissions, behavior on empty results).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the parameter burden, and it does: it enumerates the valid scope values ('user' or 'system'), which the schema's bare untyped string property does not convey. It stops short of stating the default or whether scope is required, but the value domain is covered.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the timers of one manager') and specifies what the listing contains ('next and last run times in microseconds since the epoch'). It is unambiguous, though 'one manager' is slightly loose and there is no sibling that overlaps in resource to contrast against.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no prerequisites, and no routing to alternatives. Sibling list_units covers a related domain, but the description never explains when a timer listing is the right call versus a unit listing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_unitsB
Read-only

List the units systemd has in memory (systemctl list-units --all). Read-only.

scope is 'user' or 'system'. state filters on a LOAD, ACTIVE or SUB state, type on a unit type such as 'service', pattern on a glob over unit names.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNo
scopeYes
stateNo
patternNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
scopeYes
unitsYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the description's 'Read-only.' is largely redundant. The one piece of added context is that it reflects systemd's in-memory view rather than on-disk unit files, but nothing is said about volume of output or how it scales.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tight and front-loaded: the purpose and read-only nature come first, then one compact line per parameter. No filler sentences, though the parameter block reads as a run-on fragment list rather than clean structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be described, and the zero-coverage schema is compensated for by the parameter explanations. The remaining gap is sibling routing against failed_units/list_timers, which an agent would otherwise have to guess at.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description carries the full burden and largely does: it defines scope's domain ('user' or 'system'), explains state as a LOAD/ACTIVE/SUB state filter, type as a unit type such as 'service', and pattern as a glob over names. It stops short of examples or noting which parameters are optional/defaulted.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the units systemd has in memory') and pins it to the underlying command with `--all`. It does not, however, differentiate itself from closely related siblings like failed_units, list_timers, or unit_status, so an agent must infer the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use or when-not-to-use guidance, and no mention of the sibling tools that overlap heavily (failed_units, list_timers). The only routing signal is implicit in the parameter descriptions, which is not the same as usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

system_summaryB
Read-only

The system manager's state word, failed-unit and timer counts for both managers, and the current boot's first-entry time. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
stateYes
boot_timeYes
timers_userYes
timers_systemYes
failed_units_userYes
failed_units_systemYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, and the description merely restates 'Read-only', which adds no new safety information. It does add useful scope context by enumerating exactly which data points are returned, but omits anything about caching, staleness, or refresh behavior for a summary snapshot.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence with no filler, and it leads with the primary resource (the system manager's state). 'Both managers' is left unexpanded, which forces a small inference, but the description is otherwise tight and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no inputs and an output schema present, the definition has little left to carry, and the field enumeration is sufficient for an agent to select it. It would be fully complete with one clause routing the agent away from the per-unit sibling tools when only aggregate counts are needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. The description's enumeration of returned fields is not parameter semantics, but nothing is required of it here beyond confirming the absence of inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific aggregate resource — the system manager's state word, failed-unit and timer counts for both managers, and the boot's first-entry time — so an agent knows this is a roll-up view rather than a listing. However, it never differentiates itself from siblings like failed_units, list_timers, or unit_status, which appear to return the same underlying data at finer granularity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use or when-not-to-use guidance. The word 'summary' implies an overview role, but the description never states that an agent should prefer this over calling list_units/list_timers when it only needs counts, nor does it list any prerequisite.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unit_fileB
Read-only

The unit file text as systemctl cat prints it. Read-only.

Redacted, and capped at 65536 bytes; a cut ends in [TRUNCATED] and sets truncated to true.

ParametersJSON Schema
NameRequiredDescriptionDefault
unitYes
scopeYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
textYes
unitYes
scopeYes
truncatedYes

TDQS

B3.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations' readOnlyHint/openWorldHint, the description discloses redaction, a hard 65536-byte cap, the [TRUNCATED] sentinel, and that the truncated flag flips to true on a cut. That is genuinely useful operational context. It stops short of explaining why redaction occurs or whether scope affects which file is read.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences, front-loaded with the identity of the returned content, followed by the caveats. Nothing is padded and every clause adds information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-shape detail is not strictly required, and the truncation flag is still usefully surfaced. However, with two undocumented required parameters at 0% schema coverage, the definition is not complete enough for confident invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Both required parameters, unit and scope, have zero schema description coverage, so the description carries the full burden and fails it. It never explains what 'unit' should contain (name, instance, suffix?) or what values 'scope' accepts (system vs user), leaving an agent to guess at invocation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (the unit file text) and anchors it to a familiar reference ('as systemctl cat prints it'), which tells an agent exactly what content comes back. It does not differentiate itself from siblings like unit_status or list_units, which also concern units, so an agent must infer the distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description never says when to reach for this tool versus unit_status, list_units, or journal. 'Read-only' is the only routing hint, and it is already covered by annotations, so there is effectively no usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unit_statusA
Read-only

One unit's load, active and sub state, result and main PID, plus its last journal entries (default 20, at most 1000). Read-only.

Text is redacted and capped at 4096 bytes per value and 65536 bytes in all; a cut value ends in [TRUNCATED] and sets truncated to true.

ParametersJSON Schema
NameRequiredDescriptionDefault
unitYes
linesNo
scopeYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
unitYes
scopeYes
resultYes
entriesYes
sub_stateYes
truncatedYes
load_stateYes
descriptionYes
active_stateYes
exec_main_pidYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so 'Read-only' is redundant. However the description adds real behavioral context beyond structured data: per-value redaction, 4096-byte/65536-byte caps, the [TRUNCATED] marker, and the truncated flag — all of which affect how an agent must interpret the response.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the return payload, then the read-only note, then truncation semantics — logical ordering with no filler. The standalone 'Read-only' sentence duplicates the readOnlyHint annotation and is the one throwaway line.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-shape explanations are unnecessary, and the description usefully covers truncation semantics that the output schema alone would not convey. The remaining gap is the undocumented required 'scope' parameter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description is the only source. It explains 'lines' (default 20, max 1000) and implies 'unit' (single unit), but the required 'scope' parameter (system vs user, presumably) is never explained anywhere, leaving a required argument opaque.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific resource ('one unit') and enumerates exactly what status fields it returns — load, active/sub state, result, main PID, plus tailed journal entries. An agent can distinguish it from list_units, failed_units, and journal without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The single-unit framing implies 'use this for one named unit', but no sibling is named and no when-not-to-use condition is stated (e.g. use list_units to enumerate, journal for log-only retrieval). Usage is inferable but not guided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv0.1.0
    • First observedboots
    • First observedfailed_units
    • First observedjournal
    • First observedlist_timers
    • First observedlist_units
    • First observedsystem_summary
    • First observedunit_file
    • First observedunit_status

TDQS

A3.7/5.0

Scored across 8 tools

Disambiguation4/5

Most tools target distinct resources: boots, journal, unit_file, system_summary are clearly separate. However, failed_units is essentially a filtered subset of list_units, and unit_status overlaps with journal for a single unit, though descriptions clarify intended use.

Naming Consistency4/5

Names are all lowercase snake_case and readable, with noun_phrase style (list_units, unit_status, unit_file). Minor deviation: 'boots' and 'journal' are bare nouns that don't follow the verb_noun or list_ pattern used elsewhere, but the convention is largely predictable.

Tool Count5/5

Eight tools is well-scoped for a read-only systemd/journal inspection server, with each tool covering a meaningful slice of the domain without redundancy bloat.

Completeness4/5

For a read-only diagnostic surface, coverage is strong: units, failed units, timers, boots, journal filtering, unit files, and a system summary. Minor gaps like journal disk usage/rotation stats or per-boot statistics are absent but not blocking.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    Provides 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
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables read-only observability of a Linux host via MCP, exposing allowlisted systemd, docker, nginx, logs, disk, and cert info without shell access.
    MIT