Ssh Companion

security MCP Server

๐Ÿค–๐Ÿ‘๏ธ ๐Ÿ’ป Real-time SSH and shell session observer for Claude Code. Capture at the byte stream, advise without access.

Verified
securitysecurity
3 views0 stars0 forksApache-2.0

Why This Matters

Discovered via github-topic:mcp-server and last synced 3mo ago.

Verified
Source
github-topic:mcp-server
Stars
0
Last synced
3mo ago
Install
Check source

Install

Install instructions not detected yet

Check the source repository for the latest setup steps.

View source instructions
2
Tools
0
Resources
0
Prompts
Standard I/O
Transport

Available Tools (2)

SSH

R end L[("~/.ssh-companion-sessions/*.log")] subgraph srv ["MCP server"] S["server.py\nstrips ANSI"] end CC(["Claude Code"]) T -->

stdio

CC ``` ## ๐Ÿ“‹ Prerequisites - Docker - tmux (Linux) or Windows Terminal / `wt` (Windows) - [Claude Code CLI](https://claude.ai/code) ## ๐Ÿš€ Setup ### 1. Start the container Pull the pre-built image from GitHub Container Registry and run it: ```bash docker run -d --name ssh-companion \ -v ~/.ssh:/home/companion/.ssh \ -v ~/.ssh-companion-sessions:/sessions \ --restart unless-stopped \ ghcr.io/gregolsky/ssh-companion:latest ``` **About the key mount:** `ssh` runs *inside* the container as a non-root `companion` user, so it can only read keys that are visible inside the container. The `-v ~/.ssh:/home/companion/.ssh` line above mounts your host SSH directory at the companion user's home โ€” your usual keys (`id_ed25519`, `id_rsa`, etc.) and `known_hosts` are picked up as normal, and new hosts can be written back to `known_hosts`. Add `:ro` to the mount if you want to keep it read-only (note: this breaks first-time host-key acceptance). **UID caveat:** the prebuilt image pins `companion` to UID/GID 1000, which matches most single-user Linux desktops. If `id -u` on your host isn't 1000, the container won't be able to read your keys or write session logs โ€” build from source instead: ```bash git clone https://github.com/gregolsky/ssh-companion.git cd ssh-companion ./build.sh # picks up your host UID/GID automatically ``` If your keys live elsewhere, mount that directory instead (or in addition). Examples: ```bash # Throwaway key at /tmp/temp-key on the host: -v /tmp:/tmp # Project-local keys under ~/work/keys: -v ~/work/keys:/home/companion/keys:ro # then: ssh -i /home/companion/keys/<name> user@host ``` Prefer not to mount keys at all? Start your SSH agent on the host, forward it with `-A` (`./companion.sh ssh -A user@host`), and the container uses your agent over the forwarded socket. **Alternative โ€” build from source:** ```bash git clone https://github.com/gregolsky/ssh-companion.git cd ssh-companion ./start-mcp-server.sh ``` ### 2. MCP server registration The launch scripts manage this automatically. Each time you run `companion.sh` or `companion-local.sh` a uniquely-named entry is added to the project-local `.mcp.json`: ``` ssh-companion-prod-db-1-12345 โ†’ scoped to prod-db-1 ssh-companion-staging-67890 โ†’ scoped to staging ``` The entry is removed automatically when you close the session (tmux pane or terminal window). Stale entries left behind by `kill -9` or power loss are pruned the next time a companion script runs. Because `.mcp.json` is runtime-managed it is gitignored. You should open Claude Code **from within the `ssh-companion` directory** (or a directory that contains its `.mcp.json`) so the project-scoped file is loaded. If you open Claude separately before launching a companion script it will not see the MCP entry. Each MCP instance is scoped to one SSH host, so Claude's tools (`focus_session`, `read_session_since`, `search_session`) work without specifying a hostname โ€” they automatically target the right server. When working with multiple servers at once, Claude can call tools on different instances simultaneously. ## ๐Ÿ’ป Usage ### SSH session (Linux) Opens the SSH session on the left and Claude on the right, side by side. ```bash # Default keys from ~/.ssh (works out of the box if you used the mount # from the Setup step above): ./companion.sh ssh ubuntu@prod-db-1 # Specific key โ€” the path is resolved inside the container, so the # directory must be mounted (see "About the key mount" above): ./companion.sh ssh -i /home/companion/.ssh/work_key ubuntu@prod-db-1 # Agent forwarding โ€” no key mount needed: ./companion.sh ssh -A ubuntu@prod-db-1 ``` ### SSH session (Windows) ```powershell .\companion.ps1 ssh ubuntu@prod-db-1 .\companion.ps1 ssh -i ~\.ssh\key.pem ubuntu@prod-db-1 ``` ### Local shell session Observe a local bash session โ€” no SSH, no Docker for the capture side. ```bash ./companion-local.sh ``` Claude sees it as hostname `local`. The MCP server still runs inside the `ssh-companion` container, so the container must be running before launching `companion-local.sh`. The script will start it automatically if it isn't already running. ### Layout options Both `companion.sh` and `companion-local.sh` accept: - `--split` (default) โ€” tmux side-by-side pane (prefix remapped to `C-q`) - `--windows` โ€” two separate terminal windows `--windows` auto-detects the terminal emulator (gnome-terminal, konsole, alacritty, kitty, wezterm, xfce4-terminal, xterm, or the Debian `x-terminal-emulator` alternative). Override with `COMPANION_TERMINAL_APP`: ```bash COMPANION_TERMINAL_APP=alacritty ./companion.sh --windows ssh user@host ``` If tmux is missing and no layout is specified, the scripts fall back to `--windows` automatically. On Windows, `companion.ps1` supports `-Split` / `-Windows` switches. ### Manual SSH (if you prefer your own terminal layout) ```bash # Add this alias to ~/.bashrc or ~/.zshrc alias ssh='docker exec -it ssh-companion ssh' # Then use ssh normally โ€” sessions are captured automatically ssh user@prod-db-1 ``` ### Ask Claude for help Once you're in a session, switch to the Claude pane and ask: ``` What's happening on prod-db-1? ``` Claude will call `focus_session("prod-db-1")` and read the last 200 lines of your session. ### Active watch mode (default) By default, every `companion.sh` and `companion-local.sh` launch boots Claude into a `/loop` that watches the session every ~60s and advises on what the user is doing โ€” errors, non-zero exits, OOM messages, high load, stack traces. To disable it: ```bash ./companion.sh --no-watch ssh ubuntu@prod-db-1 ./companion-local.sh --no-watch ``` To override the default watcher with a custom prompt, use `--instructions-loop`: ```bash ./companion.sh --instructions-loop "Watch prod-db-1 every 30 seconds. \ Call read_session_since with the last byte_offset each time. \ Alert me if you see errors, OOM messages, or high load." \ ssh ubuntu@prod-db-1 ``` Works the same with `companion-local.sh`. Flags must come before the `ssh` subcommand. ### Performance checklist (`/ssh-perf`) Type `/ssh-perf` in the Claude pane to start a guided walkthrough of Brendan Gregg's 60-second Linux performance checklist. Claude presents each command for you to paste in the left pane, reads the output via `read_session_since`, interprets the key fields (CPU saturation, I/O wait, swap pressure, TCP errors), and tracks a progress checklist across the session. After all 10 steps it summarizes the top bottlenecks and suggests follow-up commands. ## ๐Ÿ› ๏ธ MCP Tools

Works Well With - Skills