Skip to main content
Glama

Describe what you want in plain language. Review a typed plan with risk levels. Approve explicitly. Watch it execute with live output. Atomic-host changes (rpm-ostree) roll back automatically on failure. Every action is Ed25519-signed and audited.

The AI never supplies a command. Every action is a typed operation with a formal risk level, and the daemon builds the command line itself from the action's own definition — some actions do run through sh -c, but the shell fragment is constructed by SysKnife, never by the model. The AI cannot touch your system directly. A privileged daemon executes only what you approve, writes a tamper-evident Ed25519-signed audit chain, and rolls back atomic-host (rpm-ostree) changes automatically on failure.

Why typed actions and not a guarded shell? Red-team research (GuardFall) found that 10 of 11 AI agents bypass raw-string shell guards — an allowlist or regex is filtering a language rich enough to hide intent. SysKnife removes the shell string entirely: the model emits typed actions, and a public-key-verifiable audit chain records every one.


Install

The fastest path is the setup wizard. It installs the daemon and wires SysKnife into your AI IDE — Claude Code, Cursor, or Codex CLI — so you can plan and execute from chat.

npx sysknife-setup

Needs Node 18 or newer. On Ubuntu 22.04 apt install nodejs gives Node 12, which is too old; the installer says so and how to get a current Node. No Rust toolchain and no compile: it downloads verified prebuilt binaries.

npm version

What this does:

  1. Downloads the prebuilt sysknife + sysknife-daemon binaries for your architecture (x86_64 / aarch64) from GitHub Releases, SHA-256-verifies each against the release checksum file — a mismatch aborts the install — and places them in ~/.local/bin (no sudo). Pass --no-binary to skip the download and build from source instead.

  2. Asks for your LLM provider, key, and model — OpenAI / Anthropic / Gemini / Ollama / Groq / DeepSeek / Mistral / xAI (Ollama needs no key). The key prompt is skipped when the matching env var is already set.

  3. Asks which AI integration to wire up (or pick --claude / --cursor / --codex / --all) and your daemon target(s) — socket, plus an optional vsock token for a remote VM.

  4. Writes the integration-specific MCP config (merging into any existing file, never clobbering) so the next chat session sees the sysknife_* tools — sysknife_plan, sysknife_execute, sysknife_history, sysknife_doctor, sysknife_audit_verify, and distro-compatible direct read-only queries such as sysknife_get_disk_usage — as first-class tools.

  5. Installs and starts the daemon as a service (last step) — a systemd user service by default (no sudo; kept alive across logout via linger). That service runs as you, so read-only actions work but mutating ones do not: installing packages or restarting services needs the system-level service, whose sudoers grants belong to the sysknife system user. Pick the system service on any host where you intend to change something, and pass --daemon-mode=system|user|skip to choose without a prompt. --daemon-mode=system does not install the system service from the wizard — it needs root-owned sudoers, polkit and helper policy that sudo make install owns — so it prints the exact sequence and reports the daemon as not yet installed.

    To verify the download against a checksum list you trust independently of the release, set SYSKNIFE_PINNED_SHA256SUMS=/path/to/sums; see SECURITY.md.

Client

Files written

Claude Code

.mcp.json + .claude/hookify.*.local.md

Cursor

.cursor/mcp.json + .cursor/rules/sysknife.mdc

Codex CLI

~/.codex/config.toml (appended) + AGENTS.md

Then in your chat: ask for what you want and review the plan with risk pills. Approve each transaction with sysknife approve <transaction-id> in a terminal, return the one-time receipts, and watch it execute. The daemon, not the prompt, enforces the receipt boundary.

Prefer the standalone CLI? Same engine, no IDE — see the CLI guide for sysknife "...", --dry-run, --json, approval prompts, and audit-log inspection.

Needs Rust stable and a C compiler (build-essential): the TLS and SQLite dependencies build native code, so a rustup-only machine stops at error: linker cc not found. cmake is not required. Budget 7 to 12 minutes for the ~400-crate build (6m56s on Ubuntu 24.04, 11m43s on 22.04).

sudo apt-get install -y build-essential
git clone https://github.com/lacs-project/sysknife
cd sysknife
make build                            # builds sysknife (CLI) + sysknife-daemon
sudo make install                     # installs both; daemon runs as a system service
sudo systemctl enable --now sysknife-daemon

# Join the socket group and one role group, or every request is refused with
# "Permission denied" before any role check runs: /run/sysknife is 0750
# sysknife:sysknife, and a sudo admin is not in that group automatically.
# Role groups: sysknife-observer (read-only), sysknife-dev (medium risk),
# sysknife-admin (high risk). Members of wheel are treated as admin.
sudo usermod -aG sysknife,sysknife-admin "$USER"
newgrp sysknife                       # or log out and back in

# Then wire your IDE — --no-binary skips the download since you just built them
# (--daemon-mode=skip: make install already set the service up)
npx sysknife-setup --no-binary --daemon-mode=skip

Uninstall

Whichever way you installed, there is one command for it.

# Removes what the wizard installed: the user service, the binaries in
# ~/.local/bin, and the MCP + agent config in the current directory.
npx sysknife-setup --uninstall

# See exactly what that would touch, without touching it.
npx sysknife-setup --uninstall --dry-run

Your audit history is kept by default. Removing the software should not destroy the record of what it did, so the audit database, the safety-audit log and ~/.config/sysknife are left in place and their paths printed. Delete those too, only if you mean to, with:

npx sysknife-setup --uninstall --purge   # names each file before deleting it

If you installed the system service with sudo make install, remove it with the Makefile that owns its sudoers grants, polkit rules and privileged helpers. --uninstall deliberately will not touch those, because half a removed privilege boundary is worse than none:

sudo make uninstall

All three Ubuntu LTS releases record a live-VM run of the 79-story Ubuntu suite, and each run has a replay twin that reproduces it: 22.04, 24.04 and 26.04 all at 79/79, every twin serving every call with zero misses. The runs are in tests/evidence/story-runs/. The suite grew from 50 when every Debian-only action got a story, GetHostState first. Fedora Atomic is the rpm-ostree target; record a current Silverblue 44 VM run before treating a release as current-validated. Plain Fedora Workstation and Server remain experimental until the dnf action family ships. See the distro support matrix for evidence and scope.

# Requires the sysknife binary (see manual install above, or `npx sysknife-setup`).
# Plans only: no daemon, no approval, no execution.
export ANTHROPIC_API_KEY=sk-ant-...
sysknife --dry-run "show disk usage and list services that ate cpu in the last hour"

Related MCP server: systerd-lite

Prefer the terminal? The CLI is a first-class path

Same engine, no IDE and no MCP client — plain language to a typed plan to live execution, straight from your shell, with --dry-run, --json, --yes up to a risk ceiling, and sysknife audit verify. This is a fully supported way to run SysKnife, not an afterthought. See the CLI guide.

Also: a desktop GUI — development paused. An experimental Tauri desktop app (sysknife-shell) wraps the same plan → approve → execute loop in a window. Its development is paused for now, and effort is going to Ubuntu across its supported versions instead. The code stays in the tree and still builds, but it is not being reviewed, tested, or extended, so reach for it only if you specifically want a graphical approval flow and can live with that. The MCP integration and the CLI are the maintained surfaces.

How it works

sysknife-brain   →   approval gate    →   sysknife-daemon
  (planner)         (you, in a         (executor)
   talks to LLM      terminal)          only privileged
   never to OS       shows the plan,    process; signs
                     takes y/n          every action

The approval gate is a surface, not a component. In the maintained paths it is sysknife approve <transaction-id> in your terminal — for the CLI and for MCP alike, which is why an AI client cannot approve its own plan. The paused Tauri GUI (sysknife-shell) is a third implementation of that same gate, not a step the other two route through.

  1. You type a natural-language request.

  2. The brain proposes a plan — each step is a typed action with a risk level (Low · Medium · High).

  3. The shell shows the plan with previews, side-effects, and rollback metadata.

  4. You approve each step explicitly (or set --yes up to a risk ceiling).

  5. The daemon executes, streams live output, rolls back automatically on high-risk failure.

  6. Every execution is logged to a hash-chained SQLite or Postgres audit trail you can verify with sysknife audit verify.

The brain proposes; only the daemon is privileged. The daemon enforces policy, executes typed actions, writes the signed chain, and triggers atomic-host rollback (rpm-ostree) on failure. The trust boundary is mechanical: no shell strings cross the wire.

Why not just X?

Tool

The gap

Open Interpreter

Runs arbitrary Python/Shell. No formal risk model. No audit chain.

Goose / Continue

General-purpose. Ad-hoc confirmation, not typed risk levels.

Claude Computer Use

Uncontrolled desktop automation, not system administration.

Ansible

YAML written in advance. Not conversational. No risk classification.

shell-gpt / Copilot

Suggests raw shell commands. You still run raw shell.

AIShell-Gate

Closest peer, but proprietary and closed; audit is symmetric HMAC (the verifier holds the signing secret, so a proof convinces no one else). No rollback.

Manual

No audit trail. No rollback. One typo = lost work.

SysKnife is different by construction: typed actions, an Ed25519-signed audit chain, explicit approval gate, automatic rollback for atomic-host (rpm-ostree) changes, polkit-mediated privilege boundary. The AI never holds a shell. See the full SysKnife vs. alternatives breakdown (AIShell-Gate, gate-oc-audit, MCP gateways, generic mcp-shell).

Status

The trust chain is built, tested, and shipping. Multi-distro is the active milestone.

Component

State

sysknife-brain — LLM planner, tool loop, safety fence

sysknife-daemon — 190 typed actions, auth, preview, transactions

Live IPC + streaming + atomic-host rollback (rpm-ostree)

Terminal approval gate — one-time, TTL-bounded receipts

MCP server (Claude Code / Cursor / any MCP client)

Tamper-evident Ed25519-signed audit chain

RFC 5424 syslog forwarding (Splunk / Sentinel / QRadar)

Postgres backend (RDS / Cloud SQL / Neon / Supabase)

Ubuntu support — 79/79 stories on a live 22.04 VM, recorded in tests/evidence/story-runs/

Every Ubuntu LTS validated — 22.04, 24.04 and 26.04 all at 79/79, each with a replay twin that reproduces it

Telegram approval interface

📋 roadmap

1,837 Rust tests and 72 frontend tests form the current deterministic release baseline.

Configure your LLM

SysKnife works with Ollama (no key, recommended for privacy / offline / homelab) or OpenAI, Anthropic, Gemini, Groq, DeepSeek, Mistral, xAI.

# ~/.config/sysknife/config.toml
[llm]
provider     = "ollama"          # or anthropic / openai / gemini / groq / ...
model        = "qwen3:8b"        # provider-specific
ollama_url   = "http://localhost:11434"
max_turns    = 10

[daemon]
socket   = "/run/sysknife/daemon.sock"
database = "/var/lib/sysknife/daemon.sqlite"

[storage]                         # production-recommended
backend = "postgres"
url     = "postgres://sysknife:${PG_PASSWORD}@db.example.com/audit?sslmode=verify-full"

Env vars always win over the config file. Full reference in docs/configuration.md.

MCP protocol

SysKnife implements the Model Context Protocol and exposes approval-gated planning and execution tools. sysknife_plan returns a daemon-issued transaction ID for each step. After reviewing the plan, the user runs sysknife approve <transaction-id> in a real terminal and gives the one-time receipt to the agent. sysknife_execute rejects missing, expired, mismatched, or replayed receipts. The MCP server cannot mint approval receipts itself.

Use the setup wizard (above) to wire it into Claude Code, Cursor, or Codex CLI. All config files that may contain API keys are created with chmod 0600.

Roadmap

See ROADMAP.md for the full milestone breakdown.

  • Ubuntu 22.04 — 79/79 stories on a live VM (recorded in tests/evidence/story-runs/)

  • Ubuntu 24.04 and 26.04 — 79/79 and 79/79 on live VMs; every LTS run has a replay twin that reproduces it

  • sysknife audit export — stored signed chain rows as JSON with --since / --limit

  • 📋 Telegram inline-button approvals

  • 📋 CEF / NDJSON output modes for SIEM ingest

  • 📋 Fleet plan/execute (one plan, N targets, parallel approval)

Protocol

SysKnife is the reference implementation of the LACS (Linux Agent Control Standard) protocol — typed actions, risk classification, approval gates, audit requirements. The spec is CC0 (public domain):

lacs-project/specification

Other implementations for other distros and languages are explicitly encouraged.

Contributing

We want help. Multi-distro is the highest-impact area to plug into right now — see docs/distro-support.md for the roadmap matrix and CONTRIBUTING.md for the workflow.

Issues labelled good first issue are scoped with clear acceptance criteria.

Thanks

Patches so far from @ITSMERNB, @QinXi-ai, @Osheun, @danial-razi, @vsolano9 and @Georgefifth. Every release names who fixed what in CHANGELOG.md.

If you send a patch, watching Releases is the quickest way to see it ship and to catch new good first issue entries as they land. A star helps other people find the project.

Documentation

Where to find SysKnife

Channel

Install

Notes

npm

npx sysknife-setup

npmjs.com/package/sysknife-setup — setup wizard; needs Node 18+, no compile

crates.io

cargo install sysknife-cli / cargo install sysknife-daemon

Needs build-essential; ~7-12 min build. Published by reviewed version tags; see docs/release.md

MCP Registry

io.github.lacs-project/sysknife

registry.modelcontextprotocol.io — resolves to the crates.io install above. Directory pages that sandbox a server list every tool but cannot call the ones needing the daemon; docs/mcp-registry.md explains the split

GitHub Releases

Download from Releases

Prebuilt x86_64 + aarch64 binaries with SHA-256 checksums on every tag

License

MIT. Free to use, modify, distribute, and embed in proprietary products without restriction.

The LACS specification is CC0 1.0 — public domain.


Available Tools

5 tools
sysknife_audit_verifyA

Verify the tamper-evident Ed25519-signed hash chain over the audit log. Returns status (intact/broken/cannot_verify), rows_checked, and, on broken, the first offending row. Read-only and safe to call without prior sysknife_plan.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
actualNoThe hex Ed25519 signature actually stored for the first broken row.
reasonNoHuman-readable explanation. Only set when `status == "cannot_verify"`.
statusYesOne of `"intact"`, `"broken"`, `"cannot_verify"`.
backendYesBackend label: a filesystem path for SQLite, the literal `"postgres"` for Postgres deployments.
expectedNoWhat verification expected for the first broken row (the literal `"valid ed25519 signature"`).
chain_statusYesThe transaction chain's own verdict: `"intact"`, `"broken"` or `"cannot_verify"`. Reported separately because `status` is the worst of three checks, so a broken *approval-event* chain sets `status` to `"broken"` while this stays `"intact"`. Read this one, not `status`, to decide whether the attribution counts below are findings or claims: without it an agent had no way to recover the chain verdict and would discard sound attribution.
rows_checkedYesNumber of audit rows the verifier successfully checked. `0` for `cannot_verify` outcomes that fail before the first row is read.
rows_censusedNoHow many rows were censused for attribution: every row read, whether or not it verified. `null` when the store could not be read at all, along with every count below, so a database nobody could open never reads as one where nothing was found. A readable but empty store reports `0`. When `chain_status` is not `"intact"` this can exceed `rows_checked`, and the difference is the part of the trail that was counted but not proven.
binding_statusYes`"consistent"` or `"missing_event"`: whether every event tip committed by a transaction row is still present in the event chain.
events_checkedYesNumber of approval events (grant / consume / revoke) checked in the second chain.
attributed_rowsNoHow many rows have a signed principal naming an account: a non-empty value under the `uid` or `token` scheme, which this build could read back as something the daemon itself could have written. Only a finding when `chain_status` is `"intact"`. Past a detected break the walk stopped checking, so those rows' principals are claims: some may be authentic, since deleting or reordering a row breaks the link while leaving later signatures valid, and this tool cannot say which.
rows_unattestedNoHow many rows have no principal any signature vouches for: the column is populated on an encoding that does not sign it, or holds a value this build cannot read back as one the daemon could have written, or the row declares an encoding this build does not know. This build writes none of those. The first two are out-of-band writes to investigate; the third means a newer SysKnife wrote the rows and the fix is to verify with a build at least that new.
first_broken_seqNoSequence number of the first row that broke the chain. Only set when `status == "broken"`.
unattributed_rowsNoHow many rows record that the daemon could not name the caller. `chain_status: "intact"` with a non-zero count here means the chain is sound and the attribution is not: report both, never the first alone. Since 0.4.0 this counts only rows whose `chain_version = 3` principal is signed as `none:unattributed`. 0.3.0 matched the column on any encoding, which meant an unsigned column could land here; such rows are now `rows_unattested`.
daemon_socket_caveatNoSet when `SYSKNIFE_SOCKET` names a daemon that may not live on this machine, because verification reads a local store while every other tool travels over that socket. `None` for the local-daemon case.
approval_events_statusYesResult of the approval-event chain walk: `"intact"`, `"broken"`, or `"cannot_verify"`. Reported separately from `status` so a clean authorisation trail can never paper over a tampered approval trail.
rows_naming_no_accountNoHow many rows name no account, for any reason. The complement of `attributed_rows` over `rows_censused`, provided so a reader does not have to add the three reasons and risk missing one.
rows_without_principalNoHow many rows carry no principal the signature covers, normally because they were signed before the column existed. Reported next to `unattributed_rows` because zero attribution failures over a pre-v3 database would otherwise read as full attribution. The two have different remedies: this one cannot be fixed, since backfilling a principal would rewrite the bytes the signature covers.
first_broken_transaction_idNoTransaction ID of the first broken row. Only set when `status == "broken"`.

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses read-only safety, the 'without prior plan' requirement, and the exact return values (status, rows_checked, first offending row). It does not cover potential edge cases like permissions or empty logs, but the core behavior is transparent.

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 sentences deliver purpose, safety, return values, and a usage note without any waste. The structure is front-loaded with the action and resource, making it easy to parse quickly.

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

Completeness5/5

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

For a parameterless tool with an output schema, the description provides complete context: what it verifies, its read-only nature, and what it returns. The output schema covers the detailed return structure, so the description suffices.

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 has zero parameters, so the baseline is 4. There is nothing for the description to add beyond the empty schema, and the description appropriately avoids invented parameter details.

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?

The description states a specific verb ('Verify') and a clear resource ('tamper-evident Ed25519-signed hash chain over the audit log'), which unambiguously distinguishes it from sibling tools like sysknife_execute and sysknife_plan. The mechanism and object are named precisely.

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

Usage Guidelines4/5

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

The description explicitly says it is 'Read-only and safe to call without prior sysknife_plan', giving direct usage context and a notable distinction from tools that may require a plan. It doesn't explicitly exclude any scenarios, but the verification purpose is clearly scoped.

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

sysknife_doctorA

Diagnose SysKnife: pings the daemon, reports the configured brain provider/model, the audit DB path, and a quick audit-chain status (intact/broken/unknown). Read-only and safe to call without prior sysknife_plan.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
distroYesDetected Linux distribution, e.g. `"Ubuntu 24.04"` or `"Fedora 41"`. Set to `"unknown (<reason>)"` when `/etc/os-release` cannot be read.
warningsYesNon-fatal warnings collected during the diagnostic run. Anything that could not be checked (state, brain config, audit chain, …) adds one entry here so the operator sees what was skipped and why.
brain_modelYesConfigured brain model identifier.
audit_db_pathYesResolved audit DB path. For Postgres deployments, the literal string `"postgres"` instead of a filesystem path.
daemon_socketYesResolved daemon socket target as a URI, e.g. `"unix:///run/sysknife/daemon.sock"` or `"vsock://3:7777"`. Accepted verbatim by `SYSKNIFE_SOCKET`.
brain_providerYesConfigured brain provider (`"anthropic"`, `"openai"`, `"ollama"`, …).
daemon_reachableYes`true` iff the daemon answered `query_state` within the socket timeout.
audit_chain_statusYes`"intact"` | `"broken"` | `"unknown"`. `"unknown"` covers all `CannotVerify` cases (missing key file, unreachable DB, etc.).

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, description carries full burden. It discloses read-only nature, pinging behavior, and output details. No mention of potential latency or failure modes, but sufficient.

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 sentences with zero waste. Front-loaded with purpose and key behavioral traits.

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

Completeness5/5

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

Given zero parameters and existence of output schema, description thoroughly covers purpose, behavior, and safety. No gaps.

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?

No parameters in schema; schema coverage 100%. Description adds no parameter info, but baseline of 4 applies as there are none to document.

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?

Description clearly states it diagnoses SysKnife by pinging daemon, reporting provider/model, audit DB path, and chain status. It distinguishes from sibling tools like sysknife_execute and sysknife_plan by emphasizing it's a read-only diagnostic.

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

Usage Guidelines4/5

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

Explicitly states it's read-only and safe without prior sysknife_plan, providing clear context. Could mention when to use alternatives, but the sibling differentiation is implicit.

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

sysknife_executeA

Execute exact steps produced by sysknife_plan. Every step requires a one-time receipt from an explicit sysknife approve <transaction-id> CLI confirmation; MCP cannot approve its own mutations.

ParametersJSON Schema
NameRequiredDescriptionDefault
stepsYesSteps to execute — take the `steps` array from `sysknife_plan` output.

Output Schema

ParametersJSON Schema
NameRequiredDescription
stepsYesResults for each executed step, in order.
needs_rebootYesTrue if any step requires a reboot to take effect.

TDQS

A4/5.0
Behavior3/5

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

With no annotations, description carries full burden. It discloses the approval receipt requirement and MCP self-approval limitation, but doesn't detail error behavior, idempotency, or side effects. Adequate but not comprehensive.

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 sentences, front-loaded with main purpose, zero wasted words. Every sentence earns its place.

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?

Given output schema exists, return values don't need elaboration. One-parameter tool with clear source (sysknife_plan) and approval constraint. Lacks error handling details but otherwise complete for the tool's complexity.

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 100% (StepToExecute fully defined). Description adds 'take the steps array from sysknife_plan output' – helpful but minimal beyond schema. Baseline 3 is appropriate.

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?

Description states 'Execute exact steps produced by sysknife_plan' – specific verb+resource, and clearly distinguishes from sibling tools like sysknife_plan and sysknife_audit_verify.

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

Usage Guidelines4/5

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

Provides critical usage context: each step needs a one-time receipt from CLI 'sysknife approve', and MCP cannot approve its own mutations. No explicit when-not-to-use, but the approval requirement effectively guides appropriate use.

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

sysknife_historyA

List past SysKnife audit-log entries. Read-only and safe to call without prior sysknife_plan. Filters: status (succeeded/failed/canceled/...), action (canonical action name), since (UTC RFC 3339 timestamp), limit (default 20). Returns a list of HistoryEntry rows.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of entries to return. Defaults to 20.
sinceNoShow only entries after this UTC RFC 3339 timestamp (e.g. `"2026-01-15T10:30:00Z"`).
actionNoFilter by action name (e.g. `"InstallPackages"`).
statusNoFilter by job status (e.g. `"succeeded"`, `"failed"`, `"canceled"`).

Output Schema

ParametersJSON Schema
NameRequiredDescription
entriesYes

TDQS

A4.5/5.0
Behavior4/5

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

No annotations are provided, so description carries the burden. Notes this is read-only and safe, lists filters and defaults. Could mention ordering or load implications, but sufficient for a simple list tool.

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?

Three sentences, front-loaded with core purpose. Every sentence adds value; no fluff.

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

Completeness5/5

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

Output schema exists, so return values don't need explanation. Covers purpose, filters, safety, prerequisites. Complete for a tool of this complexity.

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 100%, and description adds example values and defaults for each parameter (status values, action name, timestamp format, limit default). Adds meaning beyond schema.

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?

Description states 'List past SysKnife audit-log entries' with a clear verb and resource. Distinguishes from sibling tools (sysknife_plan, sysknife_execute, etc.) by focusing on history listing.

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

Usage Guidelines4/5

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

Explicitly says 'Read-only and safe to call without prior sysknife_plan', providing clear context for when to use. Does not explicitly exclude other scenarios, but the guidance is helpful.

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

sysknife_planA

Plan a Linux system administration intent. Returns typed steps with risk levels, resolved commands, and daemon transaction IDs. IMPORTANT: Present the plan, then STOP. The user must run sysknife approve <transaction-id> in a real terminal for each accepted step. Do not execute from chat approval alone.

ParametersJSON Schema
NameRequiredDescriptionDefault
intentYesNatural-language intent, e.g. "show disk usage" or "add vim to my system".

Output Schema

ParametersJSON Schema
NameRequiredDescription
stepsYesOrdered list of steps to execute.
intentYesThe original natural-language intent.
summaryYesOne-line summary of the plan.
explanationYesLonger explanation of why this plan was chosen.

TDQS

A4.5/5.0
Behavior4/5

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

Description reveals the output structure (typed steps, risk levels, commands, transaction IDs) and the critical workflow constraint (stop and wait for real terminal approval). No annotations are provided, so the description carries the full burden; it does not contradict any.

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?

Three concise sentences: the first describes purpose and output, the next two provide essential usage instructions. No redundant information, well front-loaded.

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

Completeness5/5

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

Given the output schema exists, the description appropriately summarizes return types. The usage workflow is fully explained, and the single parameter is well-covered. No gaps.

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?

The single parameter 'intent' has a complete description in the schema (100% coverage). The tool description does not add additional meaning beyond that, so baseline 3 is appropriate.

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?

The description clearly states it plans a Linux system administration intent and returns structured steps with risk levels, commands, and transaction IDs. It distinguishes from sibling tools like sysknife_execute and sysknife_audit_verify by focusing on the planning phase.

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

Usage Guidelines5/5

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

Explicitly instructs the agent to present the plan, then STOP, and requires the user to run 'sysknife approve' in a terminal. It also warns not to execute from chat approval alone, providing clear usage boundaries.

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. Dates show when Glama detected each change.

  1. 1 tool updatev0.5.0
    • Changedsysknife_audit_verify9 fields changed
      • addedOutput schema / properties / attributed_rows
        Added value: +{
        +  "description": "How many rows have a signed principal naming an account: a non-empty value\nunder the `uid` or `token` scheme, which this build could read back as\nsomething the daemon itself could have written.\n\nOnly a finding when `chain_status` is `\"intact\"`. Past a detected break the\nwalk stopped checking, so those rows' principals are claims: some may be\nauthentic, since deleting or reordering a row breaks the link while leaving\nlater signatures valid, and this tool cannot say which.",
        +  "format": "uint64",
        +  "minimum": 0,
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / chain_status
        Added value: +{
        +  "description": "The transaction chain's own verdict: `\"intact\"`, `\"broken\"` or\n`\"cannot_verify\"`.\n\nReported separately because `status` is the worst of three checks, so a\nbroken *approval-event* chain sets `status` to `\"broken\"` while this stays\n`\"intact\"`. Read this one, not `status`, to decide whether the attribution\ncounts below are findings or claims: without it an agent had no way to\nrecover the chain verdict and would discard sound attribution.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / rows_censused
        Added value: +{
        +  "description": "How many rows were censused for attribution: every row read, whether or\nnot it verified.\n\n`null` when the store could not be read at all, along with every count\nbelow, so a database nobody could open never reads as one where nothing was\nfound. A readable but empty store reports `0`.\n\nWhen `chain_status` is not `\"intact\"` this can exceed `rows_checked`, and\nthe difference is the part of the trail that was counted but not proven.",
        +  "format": "uint64",
        +  "minimum": 0,
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / rows_naming_no_account
        Added value: +{
        +  "description": "How many rows name no account, for any reason. The complement of\n`attributed_rows` over `rows_censused`, provided so a reader does not have\nto add the three reasons and risk missing one.",
        +  "format": "uint64",
        +  "minimum": 0,
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / rows_unattested
        Added value: +{
        +  "description": "How many rows have no principal any signature vouches for: the column is\npopulated on an encoding that does not sign it, or holds a value this build\ncannot read back as one the daemon could have written, or the row declares\nan encoding this build does not know.\n\nThis build writes none of those. The first two are out-of-band writes to\ninvestigate; the third means a newer SysKnife wrote the rows and the fix is\nto verify with a build at least that new.",
        +  "format": "uint64",
        +  "minimum": 0,
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / rows_without_principal
        Added value: +{
        +  "description": "How many rows carry no principal the signature covers, normally because\nthey were signed before the column existed.\n\nReported next to `unattributed_rows` because zero attribution failures\nover a pre-v3 database would otherwise read as full attribution. The two\nhave different remedies: this one cannot be fixed, since backfilling a\nprincipal would rewrite the bytes the signature covers.",
        +  "format": "uint64",
        +  "minimum": 0,
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • changedOutput schema / properties / unattributed_rows / description
        Previous value: -"How many verified rows record that the daemon could not name the caller.\n\n`status: \"intact\"` with a non-zero count here means the chain is sound and\nthe attribution is not: report both, never the first alone."New value: +"How many rows record that the daemon could not name the caller.\n\n`chain_status: \"intact\"` with a non-zero count here means the chain is sound\nand the attribution is not: report both, never the first alone.\n\nSince 0.4.0 this counts only rows whose `chain_version = 3` principal is\nsigned as `none:unattributed`. 0.3.0 matched the column on any encoding,\nwhich meant an unsigned column could land here; such rows are now\n`rows_unattested`."
      • changedOutput schema / properties / unattributed_rows / type
        Previous value: -"integer"New value: +[
        +  "integer",
        +  "null"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "status",
        -  "rows_checked",
        -  "events_checked",
        -  "approval_events_status",
        -  "binding_status",
        -  "backend",
        -  "unattributed_rows"
        -]New value: +[
        +  "status",
        +  "rows_checked",
        +  "events_checked",
        +  "approval_events_status",
        +  "binding_status",
        +  "backend",
        +  "chain_status"
        +]
  2. 1 tool updatev0.1.6
    • Changedsysknife_audit_verify3 fields changed
      • addedOutput schema / properties / daemon_socket_caveat
        Added value: +{
        +  "description": "Set when `SYSKNIFE_SOCKET` names a daemon that may not live on this\nmachine, because verification reads a local store while every other tool\ntravels over that socket. `None` for the local-daemon case.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / unattributed_rows
        Added value: +{
        +  "description": "How many verified rows record that the daemon could not name the caller.\n\n`status: \"intact\"` with a non-zero count here means the chain is sound and\nthe attribution is not: report both, never the first alone.",
        +  "format": "uint64",
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "status",
        -  "rows_checked",
        -  "events_checked",
        -  "approval_events_status",
        -  "binding_status",
        -  "backend"
        -]New value: +[
        +  "status",
        +  "rows_checked",
        +  "events_checked",
        +  "approval_events_status",
        +  "binding_status",
        +  "backend",
        +  "unattributed_rows"
        +]
  3. 2 tool updatesv0.1.5
    • Changedsysknife_execute1 field changed
      • addedOutput schema / $defs / StepResult / properties / rollback_ref
        Added value: +{
        +  "description": "Identifier of the rollback the daemon performed after a failure, when\none happened — e.g. the restored file or the previous deployment.\n`null` when the step succeeded or when nothing was rolled back.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
    • Changedsysknife_plan5 fields changed
      • addedOutput schema / $defs / PlanStepOutput / properties / current_state
        Added value: +{
        +  "default": null,
        +  "description": "Relevant system state as the daemon found it, before the change."
        +}
      • addedOutput schema / $defs / PlanStepOutput / properties / expected_side_effects
        Added value: +{
        +  "default": [],
        +  "description": "Side effects the daemon expects beyond the change itself.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / $defs / PlanStepOutput / properties / proposed_change
        Added value: +{
        +  "default": null,
        +  "description": "What the daemon will change, as it resolved it — not as the planner\ndescribed it. This is the substance of what the operator approves."
        +}
      • addedOutput schema / $defs / PlanStepOutput / properties / reboot_required
        Added value: +{
        +  "default": false,
        +  "description": "Whether applying this step requires a reboot to take effect.",
        +  "type": "boolean"
        +}
      • addedOutput schema / $defs / PlanStepOutput / properties / rollback_available
        Added value: +{
        +  "default": false,
        +  "description": "Whether this step can be rolled back automatically if it fails.",
        +  "type": "boolean"
        +}
  4. 1 tool updatev0.1.4
    • Changedsysknife_doctor1 field changed
      • changedOutput schema / properties / daemon_socket / description
        Previous value: -"Resolved daemon socket target, e.g. `\"Unix(\\\"/run/sysknife/daemon.sock\\\")\"`."New value: +"Resolved daemon socket target as a URI, e.g. `\"unix:///run/sysknife/daemon.sock\"`\nor `\"vsock://3:7777\"`. Accepted verbatim by `SYSKNIFE_SOCKET`."
  5. 5 tool updatesv0.1.2
    • Addedsysknife_audit_verify
    • Addedsysknife_doctor
    • Addedsysknife_execute
    • Addedsysknife_history
    • Addedsysknife_plan

TDQS

A4.4/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: planning, execution, history, health check, and audit verification. There is no overlap or ambiguity.

Naming Consistency4/5

All tools share the 'sysknife_' prefix, but naming patterns vary: 'audit_verify' uses a compound verb-noun, while others like 'doctor', 'execute', 'history', 'plan' are single words. This minor inconsistency prevents a perfect score.

Tool Count5/5

With 5 tools covering core workflows (plan, execute, diagnose, audit verify, history), the count is well-scoped for a sysadmin tool. Each tool earns its place.

Completeness4/5

The tool surface covers the main lifecycle: planning, execution, history, health, and audit integrity. A minor gap is the lack of a tool to view pending plans or cancel transactions, but agents can work around this via the CLI.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    A
    maintenance
    Provides policy-driven, auditable SSH access to server fleets for AI assistants with zero-trust security controls, command whitelisting, and comprehensive audit logging to safely manage infrastructure.
    13
    27
    Apache 2.0
  • F
    license
    Not graded
    quality
    D
    maintenance
    An AI-Native OS Core that enables LLMs to autonomously monitor, control, and optimize Linux systems with 200+ system control tools covering process management, security, containers, and self-editing capabilities.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    This is a Linux OS hardening tool. Take a fresh install and immediately harden the heck out of it using just your favourite LLM agent and natural language prompts. "Make my system secure" or "Do a full security audit of my system."
    19
    1
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lacs-project/sysknife'

If you have feedback or need assistance with the MCP directory API, please join our Discord server