Skip to main content
Glama

arch-mcp-server

https://github.com/DankyoDev/arch-mcp-server · https://www.npmjs.com/package/arch-mcp-server

npm license node

An MCP server for administering a Linux host (with first-class Arch support) from an agent: system state, systemd, journal, packages, network, disks, hardware, boot, sessions and security.

This is not an ssh wrapper. It is a layer of tasks: every tool returns compact, actionable JSON, and every response is measured in bytes so it does not burn context.

status:  complete implementation, 109 tools, v0.6.1
docs:    ./docs

Why it exists

An agent administering Linux today does this:

ssh host 'systemctl list-units --output=json'   -> 91 KB of JSON in context
ssh host 'journalctl -n 50 --output=json'       -> 63 KB, mostly useless metadata

With this MCP (measured against the dev/ environment):

sys_status()          -> 373 B, 1 call
svc_failed()          -> 100 B with 0 failed units
fs_usage()            -> 191 B
log_query(50)         -> ~1.5 KB with real entries

The 20 tasks in docs/06-testing.md section 6 average 291 tokens and at most 2 calls on the real host (20/20).

Related MCP server: linux-diag-mcp

Installation

From the repository (requires Node >= 20 and pnpm to build):

pnpm install
pnpm build
node dist/index.js        # stdio, ready for an MCP client

With npx, straight from the registry:

npx -y arch-mcp-server    # runs the `arch-mcp` bin

Globally from npm:

npm i -g arch-mcp-server
arch-mcp

You can also pack and install it locally:

pnpm pack
npm i -g ./arch-mcp-server-0.6.1.tgz
arch-mcp

Minimal configuration

Everything goes through the environment, never through tool parameters:

ARCH_MCP_HOST=127.0.0.1
ARCH_MCP_PORT=2222
ARCH_MCP_USER=root
ARCH_MCP_KEY=C:/Users/me/.ssh/id_ed25519

With those four variables and ARCH_MCP_MODE=readonly (the default) the server works without touching code. To operate as root without changing users:

ARCH_MCP_ALLOW_SUDO=1
# optional: restrict to specific binaries or prefixes
ARCH_MCP_SUDO_ALLOW=useradd,usermod,userdel,groupadd,chown,resolvectl,ip,renice

The SSH user needs NOPASSWD sudoers rules. Every other variable is documented in docs/11-configuration.md.

OpenCode

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "arch": {
        "type": "local",
        "command": ["node", "/path/to/arch-mcp-server/dist/index.js"],
        "environment": {
          "ARCH_MCP_HOST": "127.0.0.1",
          "ARCH_MCP_PORT": "2222",
          "ARCH_MCP_USER": "root",
          "ARCH_MCP_KEY": "C:/Users/me/.ssh/id_ed25519",
          "ARCH_MCP_MODE": "readonly",
          "ARCH_MCP_PROFILE": "core"
        }
      }
    }
  }
}

Claude Desktop / Cursor

{
  "mcpServers": {
    "arch": {
      "command": "node",
      "args": ["/path/to/arch-mcp-server/dist/index.js"],
      "env": {
        "ARCH_MCP_HOST": "127.0.0.1",
        "ARCH_MCP_PORT": "2222",
        "ARCH_MCP_USER": "root",
        "ARCH_MCP_KEY": "/home/me/.ssh/id_ed25519",
        "ARCH_MCP_MODE": "readonly"
      }
    }
  }
}

Profiles

Profile

Tools

Use

core (default)

12

90% of everyday diagnosis

readonly

63

full diagnosis without mutations

full

109

everything, including writes, jobs, daily operations, fallback and raw_exec

ARCH_MCP_PROFILE selects the profile. With Code Mode the definitions load on demand, so a large catalog does not inflate the context.

Security (summary)

  • Readonly by default. Mutations require ARCH_MCP_MODE=write plus a two-step confirmation token (TTL, single use, bound to the tool and its arguments).

  • Process denylist before execution: rm -rf /, mkfs, dd of=/dev/, --privileged, --cgroupns=host, --pid=host, --net=host, reboot, critical units (sshd, dbus, systemd-*), and writes to /etc/passwd, /etc/sudoers or SSH keys.

  • No interpolation: every command is argv quoted with shellQuote(); fs_write content travels over stdin.

  • JSONL audit with rotation at ~/.local/state/arch-mcp/audit.jsonl; tokens and file contents are redacted.

  • Rate limit of 30 calls per minute; raw_exec counts double.

  • exec only accepts a daily allowlist (rg, fd, jq, tar, rsync, curl, git, croc...) and asks for confirmation; exec_any and script_run require admin mode and an explicit opt-in.

  • raw_exec is off unless ARCH_MCP_ALLOW_RAW=1 and mode is admin, and it only accepts a binary allowlist (never shells).

Full detail in docs/05-security.md.

Daily operations and fallback

Three layers, from cheapest to most powerful:

  1. Native tools (fs_*, svc_*, pkg_*...): parsed, compact output.

  2. exec: daily binaries from an allowlist (rg, fd, jq, yq, tar, rsync, curl, wget, git, croc, checksums...) with shell-free argv and confirmation.

  3. exec_any / script_run: admin mode and opt-in. exec_any rejects shells and interpreters; script_run runs python/bash/node/perl/ruby inline or an existing script.

Every fallback call is recorded in ~/.local/state/arch-mcp/gaps.jsonl, and exec_gaps groups it by binary. gap_report records commands the agent ran outside the MCP. If ARCH_MCP_GAP_ENDPOINT is set, reports are sent to a collector (scripts/gap-receiver.mjs). The rule: a binary that keeps showing up in exec_gaps becomes a native tool or a parsed recipe.

Daily operations

  • Files: fs_mkdir, fs_copy, fs_move, fs_remove, fs_chmod, fs_chown, fs_symlink. All with dry_run and confirmation; fs_remove refuses /, /etc, /usr, /home...

  • Archives and hashes: fs_archive (tar/tgz), fs_archive_list, fs_checksum, fs_du.

  • Downloads: fetch_url with a byte cap and optional sha256; http_check for status and latency.

  • Network: net_ping (loss and rtt), net_route (add/delete route), net_dns_set (resolvectl), fw_rule (allow/deny/delete with ufw or firewalld).

  • Processes: proc_renice to change priority.

  • systemd: svc_unit_write/svc_unit_delete to create, replace or delete units in /etc/systemd/system with daemon-reload (and optional enable).

  • Users: usr_action to create, delete, lock, unlock or add to a group. It never touches root or the MCP user.

  • Root without changing users: ARCH_MCP_ALLOW_SUDO=1 runs tools with sudo -n as the same SSH user. The remote side needs NOPASSWD rules; see docs/11-configuration.md §11.

MCP resources

URI

Content

arch://rules

host owner rules (ARCH_MCP_RULES or ~/.config/arch-mcp/rules.md)

arch://capabilities

detected tools and features

arch://cheatsheet

which tool answers which question

HTTP transport (optional)

Off by default. For clients that do not speak stdio:

ARCH_MCP_HOST=... node dist/index.js --http --port 3333
# Streamable HTTP at http://127.0.0.1:3333/mcp

With ARCH_MCP_HTTP_TOKEN (at least 16 characters) the endpoint requires Authorization: Bearer <token>; without it the endpoint is open and only safe on localhost or behind a proxy. See docs/11-configuration.md §9.

Development

pnpm test        # 313 unit tests, no network
pnpm audit:tools # every tool against a host (mutations in dry_run)
pnpm measure     # 20 evals against a host (ARCH_MCP_*), measures tokens
pnpm fixtures    # recapture fixtures from the dev container
pnpm lint        # tsc --noEmit

The local test environment lives in dev/ (two disposable Arch containers). Tests never touch the real host.

Project status

  • Research and real measurements

  • Architecture and tool catalog

  • Output contracts, security, testing and roadmap

  • Implementation phases 0-5 (56 tools, evals, measurement)

  • Phase 6: resources, HTTP with optional bearer token, packaging and v0.2.0

  • Phase 7: exec/exec_any/script_run fallback, fs_grep, gap log and v0.3.0

  • Phase 8: files, archives, downloads, ping, routes, users and firewall, v0.4.0

  • Phase 9: sudo as the same user, symlinks, renice, DNS and v0.5.0

  • Post-roadmap coverage: AUR, kernel modules, sysctl, mounts, coredumps and local accounts, v0.6.0

A living map of which commands have a native tool, which go through exec and which remain out of scope: docs/13-command-coverage.md.

Available Tools

12 tools
fs_usageDisk usageA
Read-onlyIdempotent

Used space and inode usage per real mount. Pseudo filesystems are excluded unless include_pseudo is set.

Inputs: include_pseudo.

host_capabilitiesHost capabilitiesA
Read-onlyIdempotent

Which tools and features this host has (pacman, journald, sensors, nftables, AUR...), detected once at startup. Use it before calling a tool that may be unsupported.

Inputs: no named parameters.

log_errorsDeduplicated errorsA
Read-onlyIdempotent

Errors and worse from the current boot, deduplicated by unit and message with counts. Use it to spot recurring failures.

Inputs: limit.

log_queryJournal queryA
Read-onlyIdempotent

Journal entries filtered by unit, priority, time window or message text. Returns ts, prio and msg only; detailed adds unit, pid and boot.

Inputs: grep, unit, limit, since, +4 more.

net_portsListening portsA
Read-onlyIdempotent

Listening TCP/UDP ports with the owning process. Answers "is the port up?" and "who holds it?".

Inputs: port, limit, proto.

pkg_statusPackage statusB
Read-onlyIdempotent

Pending updates, orphans, sync age and cache size. Works without checkupdates; AUR updates are counted when yay or paru exists.

Inputs: no named parameters.

proc_listProcess listA
Read-onlyIdempotent

Processes filtered and sorted by CPU, memory or PID. Use it to find what consumes resources; rss is in bytes.

Inputs: sort, limit, cursor, detail, +1 more.

svc_failedFailed unitsA
Read-onlyIdempotent

Failed systemd units with their last error lines. Answers "why did it fail?" without pulling the whole journal.

Inputs: lines.

svc_listList systemd unitsB
Read-onlyIdempotent

Systemd units filtered by state, name or type. Returns unit, active and sub; detailed adds description and load state.

Inputs: type, limit, state, cursor, +2 more.

svc_statusUnit statusA
Read-onlyIdempotent

State, main PID, start time, restarts, memory, tasks and last error of one systemd unit. Use it before reading logs.

Inputs: unit (required), detail.

sys_infoHost identityA
Read-onlyIdempotent

Host identity: hostname, kernel, distro, arch, uptime, virtualization, CPU cores and memory. Call it first to learn what host you are on.

Inputs: no named parameters.

sys_statusHost health snapshotA
Read-onlyIdempotent

One call health snapshot: load, memory, disks, failed units, pending updates, reboot flag, max temperature and top processes. Use it to answer "is the server healthy?".

Inputs: detail.

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 12 tools

    Disambiguation5/5

    Each tool targets a distinct resource or question: host identity (sys_info), health snapshot (sys_status), capabilities (host_capabilities), disks (fs_usage), processes (proc_list), services (svc_list/svc_status/svc_failed), logs (log_query/log_errors), packages (pkg_status) and ports (net_ports). The aggregate-vs-detail pairs (sys_status vs fs_usage/proc_list, log_query vs log_errors, svc_list vs svc_status) are explicitly framed as summary versus drill-down, so an agent can choose correctly.

    Naming Consistency5/5

    All names are lower snake_case and follow a predictable domain-prefix + operation pattern (sys_, host_, fs_, proc_, svc_, log_, pkg_, net_). Within each domain the suffix consistently distinguishes list/status/query variants, so related tools sort and read together.

    Tool Count5/5

    Twelve tools is well within the sweet spot and each covers a distinct area of host inspection. No tool feels redundant or padded; the grouping (health, systemd, logs, packages, network) is coherent for a server admin MCP.

    Completeness4/5

    The surface is comprehensive for read-only diagnostics: identity, health, capabilities, disk, process, service, log, package and port visibility are all present with no obvious dead ends. Minor gaps remain for a sysadmin domain (e.g. service start/stop/restart, package install/update actions, disk SMART or network interface detail), but those are arguably out of scope for a monitoring-focused server.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      C
      maintenance
      Controls a Linux host through structured interfaces like systemd, journald, and D-Bus for service management, journal queries, power operations, and more, with safety guards to prevent accidental damage.
      -
    • A
      license
      A
      quality
      B
      maintenance
      Lets an AI assistant inspect a Linux machine through ten fixed read-only tools covering load, memory, disks, processes, ports, interfaces, systemd units, the journal, and allowlisted log files. All output is size-capped, control-character-stripped and secret-redacted, and nothing in the package can write to the system.
      10
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      Enables an agent to oversee and operate a fleet of Linux servers over the system ssh and Tailscale — inspecting host status, auditing configuration, tracking drift and reading history across many machines. Every mutating operation runs as a dry-run plan first and only applies after explicit confirmation of that exact plan, rolling out one host at a time with a local journal.
      63
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables an AI agent to drive a remote Linux machine over the LAN through a single TCP connection, exposing tools for shell commands, jobs, interactive PTYs, file read/write/search/transfer, process and service management, networking, packages, and power control, with optional multi-host switching. Operates without SSH or any Linux-side installation beyond one stdlib-only Python daemon, using a state-free binary protocol.
      MIT