relay-shell
A highly reliable, maximally capable Model Context Protocolserver for complete shell and SSH mastery.
relay-shell gives an MCP client (Claude, or any MCP-compatible agent) a robust,auditable interface to operate a Linux host and a fleet of remote hosts overSSH: one-shot command execution, long-lived interactive PTY sessions, scriptedruns, SFTP transfer, port forwarding, and host-inventory aware connectivity.
It is designed as operator infrastructure tooling for hosts you own andadminister. The default operating posture is native, full access (nosandbox), matching the way real administration is performed, paired with thedefensive controls a production operator actually needs: an append-only,output-hashed audit trail; a tiered-authority policy layer; secret redaction;strict resource and timeout bounds; and an optional OAuth 2.1 edge.
The architecture, security model, and deployment patterns are modeled on amature production MCP gateway and on established operational best practices.
Why
Engineers SSH into hosts and run commands from memory, with no structuredreasoning trail and no pre-execution review. A well-built MCP relay improveson that baseline: every action is captured with arguments, an output hash, anexit code, and a tier classification; limits and timeouts are enforcedcentrally; failure paths never crash the transport. The reasoning layer sitsinside the loop and can assess blast radius before acting.
Capabilities
Local shell
| Tool | Purpose |
|---|---|
shell_exec |
Run a command. Timeout/output clamps, cwd, env overlay, stdin, exit code. |
shell_script |
Run a multi-line script (bash/sh/python), optional set -euo pipefail. |
shell_spawn |
Start a persistent PTY session (REPLs, TUIs, prompts, long jobs). |
SSH
| Tool | Purpose |
|---|---|
ssh_exec |
Run a command on a remote host (jump host, key/agent, known-hosts policy). |
ssh_spawn |
Interactive remote PTY session. |
ssh_upload / ssh_download |
SFTP transfer (recursive supported). |
ssh_forward |
Local (L), remote (R), or dynamic SOCKS (D) forwarding. |
ssh_forward_list / ssh_forward_close |
Manage active forwards. |
ssh_check |
Connectivity probe across the inventory or a host list. |
ssh_hosts |
Resolved host inventory (~/.ssh/config + inventory file). |
Sessions (local PTY and SSH PTY, unified)
| Tool | Purpose |
|---|---|
session_send |
Send input (optionally with Enter) to a session. |
session_recv |
Read buffered/new output, with a short wait. |
session_resize |
Resize the PTY (cols x rows). |
session_kill |
Signal / terminate a session. |
session_list |
List active sessions with metadata. |
Diagnostics
| Tool | Purpose |
|---|---|
server_info |
Server version, effective limits, policy mode, audit path. |
Full reference: docs/tools.md.
Quickstart
git clone https://github.com/rmednitzer/relay-shell.git && cd relay-shell
python3 -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
# stdio transport (local agent / Claude Desktop / MCP Inspector)
relay-shell
# HTTP transport (streamable-http on 127.0.0.1:8080)
RELAY_SHELL_TRANSPORT=http relay-shell
Register with an MCP client (stdio):
{ "mcpServers": { "relay-shell": { "command": "relay-shell" } } }
Configuration is environment-driven; see .env.example anddocs/deployment.md.
Security posture
relay-shell runs unsandboxed with the privileges of its service account by design(see docs/adr/0002-no-sandbox-full-access.md):sandboxing the process would defeat the very capability it exists to provide.Safety is achieved with compensating controls, not by crippling the tool:
- Audit - every invocation appended as one JSON line with a SHA-256 hashof the output (never the output body), byte length, exit code, request andclient id, and the assessed tier. Append-only on disk; rotation-safe handler.
- Tiered authority - every call is classified Tier 0..3(
docs/adr/0003-tiered-authority.md).RELAY_SHELL_POLICY_MODEselectsopen(default),guarded, orreadonly. - Redaction - audited arguments are scrubbed for tokens, keys, and
Authorizationmaterial. - Bounds - timeout and output caps on every tool; bounded session countand buffers; idle/lifetime reaping.
- Optional OAuth 2.1 - DCR with single-client lockdown, PKCE, file-backedrotating tokens, lazy expiry (HTTP transport).
- Edge - a reference Caddy config restricts the endpoint to known CIDRswith TLS and security headers; systemd unit applies resource caps.
This server grants real administrative power. Run it only as a scoped serviceaccount, only on hosts you are authorized to administer, behind the networkcontrols in docs/deployment.md. SeeSECURITY.md for the threat model and reporting.
If your use case requires maximum model capability, relay-shell also supportsan explicit privileged posture (root/sudo workflows). Use that only on isolatedadministrative hosts with strict network controls and full audit shipping.
Layout
src/relay-shell/ server, config, audit, policy, redaction, sessions, tools, auth
deploy/ systemd unit + hardening drop-in, Caddyfile, logrotate, install.sh
docs/ architecture, tool reference, deployment, ADRs
tests/ unit + integration (in-process SSH server, no network)
Development
ruff check . && ruff format --check .
mypy
pytest
AI contributor guidance
AGENTS.md- repository-wide agent operating contractCLAUDE.md- Claude-focused development and review guidance
License
Apache-2.0. See LICENSE and NOTICE.