Skip to content

Commit 6ff7b97

Browse files
authored
chore: polish repository metadata and docs
Improve repository discoverability and onboarding by updating package metadata, refreshing the English and Chinese READMEs, and adding a root MIT license file.
1 parent ee627fc commit 6ff7b97

4 files changed

Lines changed: 281 additions & 297 deletions

File tree

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 B143KC47
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 128 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,207 +1,207 @@
11
# SSH MCP Server
22

3-
A **Model Context Protocol (MCP)** server that provides SSH remote command execution capabilities. It enables AI agents to discover, connect to, and execute commands on remote SSH hosts through a standardized MCP interface.
3+
[![GitHub stars](https://img.shields.io/github/stars/B143KC47/ssh_mcp?style=flat-square)](https://github.com/B143KC47/ssh_mcp/stargazers)
4+
[![License: MIT](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE)
5+
[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178c6?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
6+
[![MCP](https://img.shields.io/badge/MCP-compatible-6e56cf?style=flat-square)](https://modelcontextprotocol.io/)
7+
[![SSH](https://img.shields.io/badge/SSH-security--first-0f766e?style=flat-square)](https://www.openssh.com/)
48

5-
## Features
9+
**English** | [中文](README.zh-CN.md)
610

7-
- **Dual-scope configuration**: Project-level (`ssh.config`) and user-level (`~/.config/mcp-ssh/config`) SSH configs with automatic merging
8-
- **Connection pooling**: Reuse SSH connections across multiple commands with automatic idle cleanup
9-
- **Command security**: Built-in dangerous command blacklist + configurable per-host allow/deny lists
10-
- **Output management**: Automatic output truncation to prevent LLM context overflow
11-
- **Sensitive data protection**: Private keys never exposed in tool outputs; passwords via env vars only
12-
- **Standard SSH config syntax**: Uses OpenSSH config format — `Host`, `HostName`, `User`, `Port`, `IdentityFile`, etc.
11+
Secure SSH access for MCP clients. `ssh_mcp` lets Claude Desktop, VS Code Copilot, Augment, and other MCP-compatible agents run remote commands through a safety-first SSH proxy with OpenSSH config compatibility, connection pooling, and output guardrails.
1312

14-
## Quick Start
13+
## Why developers pick this project
1514

16-
### 1. Install
15+
- **Use the SSH config you already know**: standard OpenSSH fields like `Host`, `HostName`, `User`, `Port`, `IdentityFile`, and `ProxyJump`
16+
- **Safer than a raw shell bridge**: built-in dangerous command blocking, per-host allowlists/denylists, output caps, and secret redaction
17+
- **Fast for multi-step agent sessions**: pooled SSH connections reduce reconnect overhead
18+
- **Works with real MCP workflows**: designed for Claude Desktop, VS Code Copilot, Augment, and any MCP-compatible client
19+
- **Flexible for teams**: merge project-level and user-level configs so shared hosts stay global while project overrides stay local
1720

18-
```bash
19-
npm install
20-
npm run build
21-
```
21+
## Great fit for
2222

23-
### 2. Configure SSH hosts
23+
- AI-assisted production troubleshooting
24+
- Safe observability and read-only operations on remote servers
25+
- DevOps and platform engineering copilots
26+
- Internal tooling that needs SSH access without handing an agent unlimited shell freedom
2427

25-
Create a project-level config (`ssh.config` in your project root):
28+
## Quick start
2629

27-
```sshconfig
28-
Host my-server
29-
HostName 192.168.1.100
30-
User ubuntu
31-
Port 22
32-
IdentityFile ~/.ssh/id_rsa
33-
# mcp-ssh:denylist = rm -rf,mkfs,dd,shutdown,reboot
34-
```
35-
36-
Or initialize via the MCP tool:
30+
### 1. Install and build
3731

32+
```bash
33+
npm install
34+
npm run build
3835
```
39-
Use tool: ssh_init_config with scope="project"
40-
```
4136

42-
### 3. Add to MCP client
37+
### 2. Add the server to your MCP client
38+
39+
See the ready-to-copy examples in:
4340

44-
#### Claude Desktop / Augment
41+
- `examples/mcp-config.claude.example.json`
42+
- `examples/mcp-config.vscode.example.json`
4543

46-
Add to your MCP settings (`claude_desktop_config.json` or equivalent):
44+
Minimal Claude Desktop / Augment example:
4745

4846
```json
4947
{
5048
"mcpServers": {
5149
"ssh": {
5250
"command": "node",
53-
"args": ["path/to/ssh-mcp-server/dist/index.js", "--project-root", "/path/to/your/project"],
51+
"args": [
52+
"/absolute/path/to/ssh-mcp-server/dist/index.js",
53+
"--project-root",
54+
"/path/to/your/project"
55+
],
5456
"env": {}
5557
}
5658
}
5759
}
5860
```
5961

60-
#### Using npx (development)
62+
Minimal VS Code MCP example:
6163

6264
```json
6365
{
64-
"mcpServers": {
66+
"servers": {
6567
"ssh": {
66-
"command": "npx",
67-
"args": ["tsx", "path/to/ssh-mcp-server/src/index.ts", "--project-root", "."]
68+
"command": "node",
69+
"args": [
70+
"/absolute/path/to/ssh-mcp-server/dist/index.js",
71+
"--project-root",
72+
"${workspaceFolder}"
73+
]
6874
}
6975
}
7076
}
7177
```
7278

73-
## Configuration
79+
### 3. Configure SSH hosts
7480

75-
### Config file locations
81+
Copy `examples/ssh.config.example` to `ssh.config` in your project root, or initialize one through the MCP tool:
7682

77-
| Scope | Path | Purpose |
78-
|-------|------|---------|
79-
| Project | `<project-root>/ssh.config` | Hosts specific to this project |
80-
| User | `~/.config/mcp-ssh/config` | Shared hosts across all projects |
81-
82-
**Merge rule**: Project-level settings override user-level settings for hosts with the same name.
83-
84-
### SSH config syntax
83+
```text
84+
Use tool: ssh_init_config with scope="project"
85+
```
8586

86-
Standard OpenSSH config syntax is supported:
87+
Minimal example:
8788

8889
```sshconfig
89-
# Project-level ssh.config
90-
Host prod-db
91-
HostName db.prod.example.com
92-
User deploy
90+
Host my-server
91+
HostName 192.168.1.100
92+
User ubuntu
9393
Port 22
94-
IdentityFile ~/.ssh/deploy_key
95-
ConnectTimeout 10
96-
ServerAliveInterval 60
97-
# mcp-ssh:denylist = DROP TABLE,rm -rf /,mkfs
98-
99-
Host staging
100-
HostName staging.example.com
101-
User developer
102-
IdentityFile ~/.ssh/id_ed25519
103-
# mcp-ssh:allowlist = ls,cat,grep,find,ps,top,df,du,free,uptime
94+
IdentityFile ~/.ssh/id_rsa
95+
# mcp-ssh:denylist = rm -rf,mkfs,dd,shutdown,reboot
10496
```
10597

98+
### 4. Try a few prompts in your MCP client
99+
100+
- "List all configured SSH hosts."
101+
- "Test the SSH connection to `my-server`."
102+
- "Run `uptime && df -h` on `my-server`."
103+
- "Show me the merged SSH config for `my-server`."
104+
105+
## Core features
106+
107+
- **Dual-scope configuration**: project-level (`ssh.config`) + user-level (`~/.config/mcp-ssh/config`) with automatic merging
108+
- **Connection pooling**: reuse SSH connections across commands with idle cleanup
109+
- **Per-host security policy**: allowlists, denylists, max timeout, and max output size
110+
- **Output management**: automatic truncation to protect LLM context windows
111+
- **Sensitive data protection**: private keys and sensitive environment values are sanitized in output
112+
- **OpenSSH compatibility**: keep using your normal host aliases and SSH habits
113+
114+
## Configuration
115+
116+
### Config file locations
117+
118+
| Scope | Path | Purpose |
119+
|-------|------|---------|
120+
| Project | `<project-root>/ssh.config` | Hosts specific to the current project |
121+
| User | `~/.config/mcp-ssh/config` | Shared hosts across projects |
122+
123+
**Merge rule**: project-level settings override user-level settings for hosts with the same name.
124+
106125
### Security annotations
107126

108-
Add security policies as comments within Host blocks:
127+
Add policies as comments inside a `Host` block:
109128

110129
```sshconfig
111130
# mcp-ssh:denylist = cmd1,cmd2 # Block these command patterns
112-
# mcp-ssh:allowlist = cmd1,cmd2 # Only allow these patterns (overrides denylist)
131+
# mcp-ssh:allowlist = cmd1,cmd2 # Only allow these command patterns
113132
# mcp-ssh:maxTimeoutMs = 30000 # Max execution timeout for this host
114133
# mcp-ssh:maxOutputChars = 5000 # Max output characters for this host
115134
```
116135

117-
### Authentication
136+
### Authentication order
118137

119-
The server tries authentication methods in this order:
138+
1. **Private key** from `IdentityFile`
139+
2. **SSH agent** via `SSH_AUTH_SOCK` (Unix) or Pageant (Windows)
140+
3. **Password** via environment variable `SSH_PASSWORD_<HOST>`
120141

121-
1. **Private key** — from `IdentityFile` in SSH config
122-
2. **SSH Agent**`SSH_AUTH_SOCK` (Unix) or Pageant (Windows)
123-
3. **Password** — from environment variable `SSH_PASSWORD_<HOST>` (uppercase, special chars → `_`)
142+
Example: for host `my-server`, set `SSH_PASSWORD_MY_SERVER=secret`.
124143

125-
Example: For host `my-server`, set `SSH_PASSWORD_MY_SERVER=secret`.
144+
## Why this is better than a plain SSH wrapper
126145

127-
## CLI Options
128-
129-
```
130-
ssh-mcp-server [options]
131-
132-
--project-root <path> Project root directory (for project-level ssh.config)
133-
--user-config <path> Custom user config path (default: ~/.config/mcp-ssh/config)
134-
--strict-host-key Enable strict host key checking
135-
--no-strict-host-key Disable strict host key checking (default)
136-
--timeout <ms> Default command timeout in ms (default: 60000)
137-
--max-output <chars> Maximum output characters per stream (default: 10000)
138-
--max-connections <n> Maximum concurrent SSH connections (default: 5)
139-
--idle-timeout <ms> Connection idle timeout in ms (default: 600000)
140-
```
146+
| Plain remote exec bridge | SSH MCP Server |
147+
|---|---|
148+
| Often exposes a full shell with little policy control | Supports per-host allowlists / denylists |
149+
| Reconnects for every agent step | Reuses pooled connections |
150+
| Easy to overflow model context with huge outputs | Truncates output automatically |
151+
| Custom host definitions | Works with familiar OpenSSH config syntax |
152+
| Secrets may leak into logs | Sanitizes output and hides sensitive values |
141153

142-
## MCP Tools
154+
## MCP tools
143155

144156
| Tool | Description | Parameters |
145157
|------|-------------|------------|
146158
| `ssh_list_hosts` | List all available SSH hosts ||
147159
| `ssh_exec` | Execute a command on a remote host | `host`, `command`, `timeout_ms?` |
148-
| `ssh_init_config` | Initialize SSH config file | `scope` (project/user), `project_root?`, `hosts?` |
160+
| `ssh_init_config` | Initialize SSH config file | `scope`, `project_root?`, `hosts?` |
149161
| `ssh_get_config` | Get config for a specific host | `host` |
150162
| `ssh_test_connection` | Test connectivity to a host | `host` |
151-
| `ssh_disconnect` | Disconnect session(s) | `host?` |
163+
| `ssh_disconnect` | Disconnect one host or all active sessions | `host?` |
152164

153-
## MCP Resources
165+
## MCP resources
154166

155167
| URI | Description |
156168
|-----|-------------|
157169
| `ssh://hosts` | JSON list of all configured SSH hosts |
158170

159-
## Security
160-
161-
### Built-in protections
171+
## Security-first defaults
162172

163-
- **Command blacklist**: Dangerous commands blocked by default (`rm -rf /`, `mkfs`, `dd if=`, `shutdown`, `reboot`, fork bombs, firewall flush, credential file reads)
164-
- **Output sanitization**: Private keys and sensitive env vars redacted from output
165-
- **No credential exposure**: Private key paths shown truncated; passwords never in tool results
166-
- **Connection limits**: Max concurrent connections (default: 5) with idle timeout
167-
- **Input sanitization**: Null bytes stripped from commands
173+
- Dangerous commands such as `rm -rf /`, `mkfs`, `dd if=`, `shutdown`, and `reboot` are blocked by default
174+
- Private key material and sensitive env values are redacted from outputs
175+
- Commands are sanitized before execution
176+
- Concurrent connection count and idle lifetime are limited
168177

169-
### Recommendations
178+
Recommended for production:
170179

171-
1. Always use `IdentityFile` (key-based auth) over passwords
172-
2. Use per-host `# mcp-ssh:allowlist` for production servers
180+
1. Prefer `IdentityFile` over password auth
181+
2. Use `# mcp-ssh:allowlist` for production hosts
173182
3. Add `ssh.config` to `.gitignore` if it contains sensitive hostnames
174-
4. Enable `--strict-host-key` in production environments
175-
5. Use SSH certificates or `known_hosts` pinning for host verification
183+
4. Enable `--strict-host-key` in production
184+
5. Use SSH certificates or pinned `known_hosts` entries when possible
176185

177-
## Architecture
186+
## CLI options
178187

179-
```
180-
┌─────────────────────────────────────────────┐
181-
│ MCP Client (Claude/Augment/IDE) │
182-
│ ↕ JSON-RPC 2.0 over stdio │
183-
├─────────────────────────────────────────────┤
184-
│ MCP Server Layer │
185-
│ ├─ Tool handlers (ssh_exec, etc.) │
186-
│ ├─ Resource handlers (ssh://hosts) │
187-
│ └─ Logging notifications │
188-
├─────────────────────────────────────────────┤
189-
│ Config Layer │
190-
│ ├─ Parser (ssh-config lib) │
191-
│ ├─ Merger (project + user, project wins) │
192-
│ └─ Security policies (allowlist/denylist) │
193-
├─────────────────────────────────────────────┤
194-
│ SSH Layer │
195-
│ ├─ Connection Pool (ssh2 Client) │
196-
│ ├─ Command Executor (exec channels) │
197-
│ └─ Output truncation & sanitization │
198-
└─────────────────────────────────────────────┘
188+
```text
189+
ssh-mcp-server [options]
190+
191+
--project-root <path> Project root directory (for project-level ssh.config)
192+
--user-config <path> Custom user config path (default: ~/.config/mcp-ssh/config)
193+
--strict-host-key Enable strict host key checking
194+
--no-strict-host-key Disable strict host key checking (default)
195+
--timeout <ms> Default command timeout in ms (default: 60000)
196+
--max-output <chars> Maximum output characters per stream (default: 10000)
197+
--max-connections <n> Maximum concurrent SSH connections (default: 5)
198+
--idle-timeout <ms> Connection idle timeout in ms (default: 600000)
199199
```
200200

201201
## Development
202202

203203
```bash
204-
# Install deps
204+
# Install dependencies
205205
npm install
206206

207207
# Run in dev mode
@@ -210,13 +210,17 @@ npm run dev -- --project-root .
210210
# Build
211211
npm run build
212212

213-
# Run built version
213+
# Run the built server
214214
npm start -- --project-root .
215215

216216
# Debug with MCP Inspector
217217
npm run inspect
218218
```
219219

220+
## Contributing
221+
222+
Issues and pull requests are welcome. If you want support for more MCP clients, stronger security policies, or better SSH ergonomics, open an issue and share the workflow you want to enable.
223+
220224
## License
221225

222-
MIT
226+
MIT — see [LICENSE](LICENSE).

0 commit comments

Comments
 (0)