Sign inSign up

lordraw/linux-mcp

By lordraw

Updated 3 months ago

a mcp server for linux

Image
0

448

lordraw/linux-mcp repository overview

linux-ssh-mcp

An MCP server that gives any AI client full control over your Linux fleet through SSH — no agent installed on the remote hosts, just standard OpenSSH.

Connect Claude Desktop, the Claude Code CLI, Cursor, Cline, or any Model Context Protocol-compatible client to this container and manage your servers with plain English.


What's inside

ComponentDetail
Base imagepython:3.12-slim
MCP protocol2024-11-05
Transportsstdio (JSON-RPC 2.0) · SSE (HTTP + Server-Sent Events)
SSH libraryparamiko
Tools exposed48
Auth methodsSSH key, password, or SSH agent
Sudo supportYes — via PTY + sudo -S
Multi-serverYes — parallel broadcast included

System packages pre-installed: openssh-client, openssl, iputils-ping, traceroute, git.
No secrets are baked into the image — credentials are passed at runtime via --env-file.


Transport modes

ModeWhen to useHow clients connect
stdio (default)Claude Desktop, Claude Code CLI — client spawns the container as a child processJSON-RPC 2.0 over stdin/stdout
sseCursor, Cline, Continue, or any HTTP-capable MCP client — container runs as a persistent servicehttp://<host>:<port>/sse

Quick start

stdio mode (Claude Desktop / Claude Code)
# 1. Create your .env from the template
curl -fsSL https://raw.githubusercontent.com/lordraw77/linux-mcp/main/.env.example -o .env
$EDITOR .env   # fill in your SSH servers

# 2. Run (keep -i so the MCP client can pipe JSON-RPC to stdin)
docker run --rm -i --env-file .env lordraw/linux-mcp
SSE mode (Cursor / Cline / HTTP clients)
# 1. Create your .env from the template (set UXMCP_TRANSPORT=sse)
curl -fsSL https://raw.githubusercontent.com/lordraw77/linux-mcp/main/.env.example -o .env
$EDITOR .env

# 2. Run as a persistent HTTP service
docker run --rm -p 9880:9880 \
  --env-file .env \
  -e UXMCP_TRANSPORT=sse \
  -e UXMCP_SSE_PORT=9880 \
  lordraw/linux-mcp

# Connect your MCP client to:  http://localhost:9880/sse

Configuration

All configuration lives in a single .env file.

Transport
# stdio (default) — client spawns the container via stdin/stdout
UXMCP_TRANSPORT=stdio

# sse — container runs as a persistent HTTP+SSE service
# UXMCP_TRANSPORT=sse
# UXMCP_SSE_HOST=0.0.0.0   # bind address (default: 0.0.0.0)
# UXMCP_SSE_PORT=8080       # TCP port     (default: 8080)
SSH servers

Add one numbered block per server; the loader stops at the first missing UXMCP_SERVER_N_HOST.

# ── Server 1: root via SSH key ─────────────────────────────────────────────
UXMCP_SERVER_1_LABEL=web-server
UXMCP_SERVER_1_HOST=192.168.1.10
UXMCP_SERVER_1_PORT=22
UXMCP_SERVER_1_USER=root
UXMCP_SERVER_1_KEY_PATH=/root/.ssh/id_ed25519

# ── Server 2: unprivileged user + sudo ────────────────────────────────────
UXMCP_SERVER_2_LABEL=db-server
UXMCP_SERVER_2_HOST=192.168.1.20
UXMCP_SERVER_2_PORT=22
UXMCP_SERVER_2_USER=deploy
UXMCP_SERVER_2_KEY_PATH=/home/user/.ssh/deploy_rsa
UXMCP_SERVER_2_SUDO_PASSWORD=s3cr3t

# ── Server 3: password auth ───────────────────────────────────────────────
UXMCP_SERVER_3_LABEL=backup
UXMCP_SERVER_3_HOST=10.0.0.5
UXMCP_SERVER_3_PORT=2222
UXMCP_SERVER_3_USER=admin
UXMCP_SERVER_3_PASSWORD=mypassword
UXMCP_SERVER_3_SUDO_PASSWORD=mypassword

Variable reference:

VariableRequiredDefaultDescription
UXMCP_TRANSPORTstdioTransport mode: stdio or sse
UXMCP_SSE_HOST0.0.0.0Bind address (SSE mode only)
UXMCP_SSE_PORT8080TCP port (SSE mode only)
UXMCP_SERVER_N_HOSTyesHostname or IP
UXMCP_SERVER_N_PORT22SSH port
UXMCP_SERVER_N_USERrootLogin username
UXMCP_SERVER_N_LABELserver-NHuman-readable name
UXMCP_SERVER_N_PASSWORDyes*SSH password (*if no key)
UXMCP_SERVER_N_KEY_PATHyes*Path to SSH private key
UXMCP_SERVER_N_SUDO_PASSWORDsame as PASSWORDPassword for sudo -S

If both KEY_PATH and PASSWORD are set, the key takes precedence.
If USER=root, use_sudo is silently ignored for all tools.

Mounting SSH keys

When using key-based auth, mount the key directory into the container so the path resolves:

docker run --rm -i \
  --env-file .env \
  -v $HOME/.ssh:/root/.ssh:ro \
  lordraw/linux-mcp

Docker Compose

The bundled docker-compose.yml provides two services selectable via profiles.

stdio (default)
docker compose run --rm linux-mcp
SSE (persistent HTTP service)
# Start in background
docker compose --profile sse up -d linux-mcp-sse

# View logs
docker compose logs -f linux-mcp-sse

# Stop
docker compose --profile sse down

The SSE service listens on UXMCP_SSE_PORT (default 8080, or override in .env).


Connecting to MCP clients

Claude Desktop — stdio

~/Library/Application Support/Claude/claude_desktop_config.json (macOS) /
%APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "linux-ssh": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "--env-file", "/path/to/.env",
        "-v", "/home/user/.ssh:/root/.ssh:ro",
        "lordraw/linux-mcp"
      ]
    }
  }
}
Claude Code CLI — stdio

.claude/settings.json in your project root:

{
  "mcpServers": {
    "linux-ssh": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "--env-file", "/path/to/.env",
        "-v", "/home/user/.ssh:/root/.ssh:ro",
        "lordraw/linux-mcp"
      ]
    }
  }
}
Cursor / Cline / Continue — SSE

Start the SSE service first (see above), then point the client at:

http://localhost:8080/sse

Cursor (.cursor/mcp.json):

{
  "mcpServers": {
    "linux-ssh": {
      "transport": "sse",
      "url": "http://localhost:8080/sse"
    }
  }
}

What you can ask

Once connected, talk to your servers in plain English. Examples:

Discovery & overview
Which servers are configured?
Show system info for all servers.
Commands
Run `uptime` on web-server.
Execute `df -h` on all servers simultaneously.
Run `systemctl status nginx` on web-server with sudo.
Files
Read /etc/nginx/nginx.conf from web-server.
Tail the last 100 lines of /var/log/syslog on db-server.
Create directory /opt/myapp/releases on web-server.
Download /etc/hosts from db-server.
Monitoring
Collect 5 CPU and memory samples from web-server, 3 seconds apart.
Show the top 10 processes by memory on db-server.
Services & processes
Restart the nginx service on web-server.
List all failing systemd units on db-server.
Kill process 1234 on web-server with sudo.
Docker
List running containers on web-server.
Show the last 200 log lines for the api container.
Restart the worker container on db-server.
Packages
Install htop on web-server.
List installed packages matching python on db-server.
Firewall
Show firewall rules on web-server.
Open port 8080/tcp on web-server.
Block port 3306/tcp on db-server.
Network
Ping 8.8.8.8 from web-server.
Traceroute to github.com from web-server.
Check if port 5432 is reachable on db-server.
Users & groups
List all non-system users on web-server.
Create user deploy with bash shell on web-server.
Show all groups on db-server.
Disk & storage
Show disk usage for /var on db-server.
List all mounted filesystems on web-server.
Cron
List all crontabs on web-server.
Add cron job "0 2 * * * /opt/backup.sh" on web-server.
Remove cron jobs matching backup from web-server.
SSL / TLS
Check the TLS certificate for example.com:443 via web-server.
Is the certificate for api.mycompany.com expiring soon?
Git
Show git status of /opt/myapp on web-server.
Pull the latest changes for /opt/myapp on web-server, branch main.
Show the last 5 commits for /opt/myapp on db-server.
Web servers
Reload nginx on web-server.
Test the Apache config on db-server.
Show nginx status on web-server.
Multi-server broadcast
Run free -m on web-server and db-server at the same time.
Deploy /opt/deploy.sh across all servers in parallel.

Tags

TagDescription
latestMost recent build from main
vX.Y.ZSpecific release
vX.Y.Z-N-gSHAPre-release / between tags

Source

GitHub: lordraw77/linux-mcp

Tag summary

Content type

Image

Digest

sha256:39bf6d237

Size

107 MB

Last updated

3 months ago

docker pull lordraw/linux-mcp