Labsco
MCP SERVER

Aegis-SSH-MCP

by sparksbenjamin

Let an agent run only the SSH commands you approved on a named Linux host — every command checked against a rule profile before any connection opens.

Editors, Terminals & Local Dev Environment
Summary
A whitelist, not a terminal.

The decision that matters is where validation happens: the command is parsed and matched against the host's rule profile before SSH is attempted, so a rejected command never reaches the machine. What you get is narrow by intent — one command per call, one host per endpoint, no shell — and an agent that needs two hosts needs two endpoints and two tokens. It replaces none of your existing controls: sudoers, Linux permissions and host hardening still decide what the SSH user can actually do.

What it is

A Go MCP bridge between an MCP client and your Linux hosts. Each host gets its own config file, its own SSE endpoint, its own bearer token and its own rule profile. A requested command is parsed, screened for shell control features and matched against that profile before a short-lived SSH session is opened at all; if it fails a check, SSH is never attempted.

What you get
  • One host-scoped tool per config file, named after the host alias, which runs a single approved command and returns its output — no persistent shell, no pseudo-terminal, no hidden session state
  • A dynamic profile variant whose tool call supplies the target host alongside the command, for fleets you do not want to enumerate one file at a time
  • Sixteen starter rule profiles: `readonly-safe`, `docker-readonly`, `docker-ops`, `systemd-ops`, `kubernetes-readonly`, `network-diagnostics`, `logs-readonly`, `package-readonly`, plus read-only and ops pairs for Debian, Ubuntu, RHEL and Proxmox
  • Screening before the network: redirects, chaining and command substitution are rejected, pipelines are limited to text filters such as `grep`, `head`, `tail`, `sort`, `uniq`, `wc`, `cut` and `tr`, then blacklists and whitelists are applied in that order
  • Per-host bearer tokens on the SSE endpoint, SSH host-key pinning through `host_key_fingerprint`, optional output redaction by regex, and an audit log of every attempt
  • Hot reload for config and rule changes, and a shell-less distroless container running as nonroot
Requirements

Docker Compose is the documented path, plus an MCP client with SSE support and a reachable Linux host. Per host you supply a JSON file in `configs/` carrying `alias`, `ssh_user`, `auth_method`, `key_path`, `rule_profile`, `host_key_fingerprint` and `api_keys`, and the SSH private key in `keys/`. The client connects to `http://localhost:8443/mcp/<alias>/sse` with `Authorization: Bearer` set to one of that host's api_keys. Key and password authentication are both supported; stdio works as well as SSE. Building from source needs Go. TLS is optional — put it behind a trusted reverse proxy if the endpoint is not local.

Setup effort

One command — docker compose up -d