aegis_ssh_<alias>LABSCO 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,cutandtr, 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
Follow the published steps — docker compose pull
USE CASES
Letting an agent check on a Docker host
Point it at a host running the docker-readonly profile so it can inspect containers and logs, and nothing else.
Triaging a service without handing over a shell
Give the host the systemd-ops profile, so status checks, restarts and journal reads are allowed while everything else is refused.
Diagnosing reachability across a fleet
Use a dynamic profile where the tool call supplies the host, with the network-diagnostics rules deciding what may run on any of them.
Auditing what the agent tried
Read the log of every attempt, including the commands that were rejected before a connection was made.
2 tools
Listed in project docs. Your client may show a different list.
aegis_statusBEFORE YOU INSTALL
What to know first
Tools you get
2 tools named in the project's documentation. Tools are generated from your config: one aegis_ssh_<alias> tool per host config file plus aegis_status, and each endpoint and token sees only its allowed host. The audit log is a file, not a tool.
INSTALLATION
Connect your client
Server setup
git clone https://github.com/nextgridit-team/Aegis-SSH-MCP
cd Aegis-SSH-MCPNext to docker-compose.yml, create the folders configs and keys if they do not already exist, plus certs if you enable HTTPS.
Place the SSH private key Aegis should use in keys/.
Create configs/docker.json — the README's example is {"alias": "docker", "host_ip": "192.168.1.10", "ssh_port": 22, "ssh_user": "ops", "auth_method": "key", "key_path": "/keys/docker_ed25519", "rule_profile": "docker-readonly", "timeout_seconds": 30, "host_key_fingerprint": "SHA256:<YOUR_HOST_KEY>", "api_keys": ["<YOUR_DOCKER_KEY>"]} — put in your own host IP, a least-privileged SSH user, the private key's path inside the container, your host's real SSH host-key fingerprint, and a bearer token of your own in api_keys.
docker compose pull
docker compose up -d
docker compose logs -f aegis-ssh-mcpConnect the MCP client to the SSE endpoint http://localhost:8443/mcp/docker/sse, sending the header Authorization: Bearer followed by the api_key configured in configs/docker.json.
MCP Clients
LibreChat
192.168.100.184 — in allowedDomains and in the url — is a sample; yours is the address of the machine running Aegis. <YOUR_DOCKER_KEY> is one of the api_keys in configs/docker.json.
{
"mcpSettings": {
"allowedDomains": [
"192.168.100.184"
]
},
"mcpServers": {
"aegis-docker": {
"type": "sse",
"url": "http://192.168.100.184:8443/mcp/docker/sse",
"headers": {
"Authorization": "Bearer <YOUR_DOCKER_KEY>"
}
}
}
}Any MCP client — SSE
Use this SSE endpoint:
http://localhost:8443/mcp/docker/sseSend the bearer token configured in configs/docker.json in the header Authorization: Bearer <YOUR_DOCKER_KEY>
You can test reachability with curl — a valid token returns 200 OK and keeps the SSE stream open:
curl -i -N -H "Authorization: Bearer <YOUR_DOCKER_KEY>" http://localhost:8443/mcp/docker/sse