{"id":"812d738c-5982-431d-86ce-ca552ab337f6","slug":"ssh-mcp","kind":"mcp","name":"ssh-mcp","summary":"SSH MCP server: execute commands, transfer files, and forward ports on remote servers via MCP.","owner":"overklassniy","repoUrl":"https://github.com/overklassniy/ssh-mcp","license":"MIT","licenseTier":"permissive","trust":"community","stars":32,"match":null,"fewStars":false,"format":"mcp","createdAt":"2026-08-19T16:29:43.000Z","addedAt":"2026-10-14T03:48:01.648Z","logoUrl":"https://avatars.githubusercontent.com/u/92175277?u=a460aefa9e1697aacb73140770465ce18f5db98f&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["cloud-infra","developer-tools","files-documents"],"tags":["ai-agent","claude-code","cursor","devin","devops","go","golang","llm-tools"],"runtime":"go","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-15T03:07:27.233Z","sample":false,"url":"https://conduits.dev/tools/ssh-mcp","language":"Go","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"<p align=\"center\">\n  <img src=\"./assets/readme/hero.gif\" width=\"100%\" alt=\"ssh-mcp: an MCP server that gives AI assistants secure, scoped SSH access to remote servers. Light technical hero with a terminal prompt and an agent-to-remote connection line drawn through a policy gate.\">\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/overklassniy/ssh-mcp/actions/workflows/ci.yml\"><img src=\"https://img.shields.io/github/actions/workflow/status/overklassniy/ssh-mcp/ci.yml?style=flat-square&label=CI\" alt=\"CI status\"></a>\n  <a href=\"https://hub.docker.com/r/overklassniy/ssh-mcp\"><img src=\"https://img.shields.io/docker/v/overklassniy/ssh-mcp?style=flat-square&logo=docker&logoColor=white&label=Docker%20Hub\" alt=\"Docker Hub\"></a>\n  <a href=\"https://go.dev/doc/go1.26\"><img src=\"https://img.shields.io/badge/Go-1.26+-00ADD8?style=flat-square&logo=go&logoColor=white\" alt=\"Go 1.26+\"></a>\n  <a href=\"https://modelcontextprotocol.io/\"><img src=\"https://img.shields.io/badge/MCP-server-6E4B9E?style=flat-square\" alt=\"MCP server\"></a>\n  <a href=\"./LICENSE\"><img src=\"https://img.shields.io/github/license/overklassniy/ssh-mcp?style=flat-square\" alt=\"License: MIT\"></a>\n</p>\n\n# ssh-mcp\n\nAn MCP (Model Context Protocol) server that gives AI assistants secure,\nscoped SSH access to one or more remote servers.\n\n`ssh-mcp` runs over stdio and works with any MCP-compatible client:\nClaude Desktop, Claude Code, Cursor, Devin, VS Code, and Cline. It\nexposes eight tools for command execution, SFTP file transfer, directory\nsync, port forwarding, and remote system status collection.\n\n## Why it is different\n\nAI assistants that need to operate on remote servers typically either\nget a raw shell (unsafe, unscoped) or have no SSH access at all.\n`ssh-mcp` sits in between: it gives the agent a small, auditable set of\ntools, each gated by an optional command whitelist/blacklist and path\nrestrictions, so the operator controls exactly what the agent can do.\n\n- **Command policy** – `whitelist` and `blacklist` regex patterns gate\n  every command before execution. Without a whitelist, all commands are\n  allowed and a warning is logged at startup.\n- **Path restrictions** – `allowed_local_paths` and `allowed_remote_paths`\n  confine SFTP transfers to specific directories and reject path\n  traversal.\n- **Secrets via env vars** – password, passphrase, and 2FA code are\n  passed via environment variables, never on the command line.\n- **Hot-reload** – when started with `--config`, the config file is\n  watched for changes and reloaded without restarting the server. Add,\n  remove, or modify servers and the change takes effect within seconds.\n\n## Tools at a glance\n\n| Tool | Description |\n| --- | --- |\n| `execute-command` | Run a command on a remote server |\n| `upload` | Upload a local file via SFTP |\n| `download` | Download a remote file via SFTP |\n| `list-remote` | List a remote directory via SFTP |\n| `dir-sync` | Recursively sync a directory between local and remote |\n| `port-forward` | Open, close, and list local/remote port forwards |\n| `server-status` | Collect system status (CPU, memory, disk, GPU, services) |\n| `list-servers` | List configured servers and their connection status |\n\nSee [Tools](https://github.com/overklassniy/ssh-mcp/wiki/Tools) for arguments and examples.\n\n## How it works\n\n1. The AI client sends an MCP `tools/call` request over the `ssh-mcp`\n   process's stdin.\n2. `ssh-mcp` resolves the target connection (defaulting to the first\n   configured server).\n3. The command or transfer is validated against the server's command\n   policy and allowed paths.\n4. The operation runs over SSH/SFTP (or opens a port forward) with the\n   configured timeout and output cap.\n5. A structured result returns to the client. Errors carry a stable\n   `ssh.ToolError` code and a `Retriable` flag so the agent can decide\n   whether to retry.\n\nSee [Architecture](https://github.com/overklassniy/ssh-mcp/wiki/Architecture) for the package layout,\ndependency graph, and full request data flow.\n\n## Quickstart\n\n```sh\ngit clone https://github.com/overklassniy/ssh-mcp.git\ncd ssh-mcp\nmake build\n```\n\nCreate a minimal `ssh-mcp.toml`:\n\n```toml\n[[server]]\nname = \"web\"\nhost = \"example.com\"\nusername = \"deploy\"\nport = 22\nprivate_key = \"~/.ssh/id_ed25519\"\n```\n\nRegister it in your client:\n\n```sh\nssh-mcp install --client claude-code --config ./ssh-mcp.toml\n```\n\nRestart your AI client, then ask the agent:\n\n> Use the list-servers tool.\n\nYou should see your server with a `connected` or `disconnected` status.\n\n## Installation\n\nThree install paths produce the same result – an MCP server entry in\nyour client's config file. See [Installation](https://github.com/overklassniy/ssh-mcp/wiki/Installation) for\nthe full guide.\n\n- **Local binary** – `make build`, then `ssh-mcp install --client <client>\n  --config ./ssh-mcp.toml`. Supported clients: `claude-desktop`,\n  `claude-code`, `cursor`, `Devin`, `vscode`, `cline`.\n- **Docker** – `ssh-mcp install --client <client> --docker --config\n  ./ssh-mcp.toml`. Defaults to `ghcr.io/overklassniy/ssh-mcp:latest`.\n- **MCPB one-click bundle** – download the `.mcpb` bundle from the\n  Releases page and open it in a client that supports MCPB (Claude\n  Desktop, Claude Code, MCP for Windows).\n- **Paste-in config** – skip the installer and paste a ready-made\n  server entry directly into your client's config. The `snippet`\n  subcommand generates it for your exact setup:\n\n  ```sh\n  ssh-mcp snippet --docker --host 192.168.1.1 --user root\n  ssh-mcp snippet --gorun  --host 192.168.1.1 --user root\n  ```\n\n  Docker uses the published multi-arch image; `--gorun` uses\n  `go run github.com/overklassniy/ssh-mcp/cmd/ssh-mcp@latest` (the\n  Go-native equivalent of `npx -y <package>`, requires the Go\n  toolchain). Secrets stay in the `env` block, never in `args`. See\n  [Installation](https://github.com/overklassniy/ssh-mcp/wiki/Installation#option-d-paste-in-config) for\n  ready-to-paste JSON blocks.\n\nSingle-server mode skips the TOML file and takes connection details as\nCLI flags:\n\n```sh\nssh-mcp --host example.com --user deploy --port 22 \\\n  --private-key ~/.ssh/id_ed25519\n```\n\n### Paste-in config (go run)\n\nIf you have the Go toolchain (Go 1.26+) installed, you can skip the\nbinary build entirely. Add this entry to your client's `mcpServers`\nconfig (e.g. `~/.codeium/Devin/mcp_config.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"ssh-mcp\": {\n      \"command\": \"go\",\n      \"args\": [\n        \"run\",\n        \"github.com/overklassniy/ssh-mcp/cmd/ssh-mcp@latest\",\n        \"--host\", \"192.168.1.1\",\n        \"--port\", \"22\",\n        \"--user\", \"root\",\n        \"--transport\", \"exec\"\n      ],\n      \"env\": {\n        \"SSH_MCP_PASSWORD\": \"your-password\"\n      }\n    }\n  }\n}\n```\n\nOn first run, `go run` fetches and compiles the latest tagged release,\nthen starts the stdio MCP server. Subsequent runs use the build cache.\nFor private-key auth, replace `SSH_MCP_PASSWORD` with\n`SSH_MCP_PASSPHRASE` and add `--private-key` to `args`. Pin a specific\nversion by replacing `@latest` with `@v1.0.0`.\n\n## Configuration\n\n`ssh-mcp` is configured with a TOML file: a top-level `[defaults]`\nsection and one or more `[[server]]` entries. Each server inherits from\n`[defaults],` then from built-in defaults, and is validated at startup.\n\n```toml\n[defaults]\ncommand_timeout     = \"30s\"\nconnection_timeout  = \"30s\"\nsftp_timeout        = \"5m\"\nkeepalive_interval  = \"10s\"\nkeepalive_count_max = 3\nmax_output_bytes    = 10485760\ntransport           = \"exec\"\n\n[[server]]\nname     = \"web\"\nhost     = \"web.example.com\"\nusername = \"deploy\"\nport     = 22\nprivate_key = \"~/.ssh/id_ed25519\"\nwhitelist = [\"^systemctl status .*\", \"^journalctl .*\", \"^ls .*\"]\nallowed_remote_paths = [\"/var/log\", \"/srv\"]\nallowed_local_paths = [\"~/downloads\"]\n```\n\nSee [Configuration](https://github.com/overklassniy/ssh-mcp/wiki/Configuration) for the full reference:\nauth methods, command policy, path restrictions, keepalive, transport\nmodes, and validation rules.\n\n## Security model\n\n`ssh-mcp` does not verify remote host keys (`InsecureIgnoreHostKey`).\nSecurity is enforced through two operator-configured mechanisms:\n\n- **Command policy** – `whitelist`/`blacklist` regex patterns gate every\n  command, including the individual probe commands used by\n  `server-status`, so a restrictive whitelist cannot be bypassed.\n- **Path restrictions** – `allowed_local_paths` and `allowed_remote_paths`\n  confine SFTP operations; remote paths must be absolute POSIX paths.\n\nSensitive values are injected via environment variables:\n\n| Env var | Used for |\n| --- | --- |\n| `SSH_MCP_PASSWORD` | Password auth |\n| `SSH_MCP_PASSPHRASE` | Private key passphrase |\n| `SSH_MCP_2FA_CODE` | 2FA code for keyboard-interactive auth |\n\n## Compatibility\n\n- **Clients** – Claude Desktop, Claude Code, Cursor, Devin, VS Code,\n  Cline.\n- **Platforms** – Windows, macOS, Linux (`amd64`, `arm64`).\n- **Runtime** – Go 1.26+ to build, or a prebuilt binary from the\n  Releases page.\n\n## Documentation\n\n- [Installation](https://github.com/overklassniy/ssh-mcp/wiki/Installation) – local binary, Docker, and MCPB\n  one-click bundles.\n- [Configuration](https://github.com/overklassniy/ssh-mcp/wiki/Configuration) – full TOML reference.\n- [Tools](https://github.com/overklassniy/ssh-mcp/wiki/Tools) – the eight MCP tools, arguments, and examples.\n- [Architecture](https://github.com/overklassniy/ssh-mcp/wiki/Architecture) – package layout and request\n  data flow.\n- [Troubleshooting](https://github.com/overklassniy/ssh-mcp/wiki/Troubleshooting) – common issues and fixes.\n\nThe same pages are mirrored to the repository's GitHub Wiki by the\n`wiki-sync` workflow; edit them in `docs/`, not in the wiki UI.\n\n## Acknowledgements\n\nThis project was inspired by\n[classfang/ssh-mcp-server](https://github.com/classfang/ssh-mcp-server).\n\n## License\n\nMIT. See [LICENSE](LICENSE) for the full text. The project also declares\nMIT in `mcpb/manifest.json`.\n"}