@yawlabs/ssh-mcp 0.11.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
Built and maintained by [Yaw Labs](https://yaw.sh).
|
|
9
9
|
|
|
10
|
+
[](https://mcp.hosting/install?name=SSH&command=npx&args=-y%2C%40yawlabs%2Fssh-mcp&description=Run%20commands%20on%20remote%20hosts%2C%20transfer%20files%2C%20manage%20SSH%20tunnels%20and%20keys&source=https%3A%2F%2Fgithub.com%2FYawLabs%2Fssh-mcp)
|
|
11
|
+
|
|
12
|
+
One click adds this to your [mcp.hosting](https://mcp.hosting) account so it syncs to every MCP client you use. Or install manually below.
|
|
13
|
+
|
|
10
14
|
## The problem
|
|
11
15
|
|
|
12
16
|
AI CLI tools run in subprocesses where SSH is constantly broken. The agent tries to `git pull` and gets `Permission denied (publickey)`. It tries to SSH into a server and the agent socket is stale. It tries to deploy and the host key changed because the instance was recreated. Every time, the AI has no idea what's wrong and spirals.
|
|
@@ -138,6 +142,29 @@ Blocked commands surface as a clear error mentioning which pattern (or which env
|
|
|
138
142
|
|
|
139
143
|
The structured higher-level tools (`ssh_find`, `ssh_tail`, `ssh_service_status`, SFTP ops) are exempt from policy. They build commands from typed parameters, so a tight `^ls` whitelist would otherwise force you to allow `^find `, `^tail `, `^systemctl ` just to keep those tools working — defeating the point of a tight whitelist.
|
|
140
144
|
|
|
145
|
+
#### Policy interaction with `ssh_exec`'s `env` parameter
|
|
146
|
+
|
|
147
|
+
When `ssh_exec` is called with `env: { KEY: "value" }`, the values are injected as a `KEY='value' ...` shell prefix before the command (see the `ssh_exec` description). **Policy is checked against the full prefixed command**, not the bare `command` argument. That's the safer ordering at the protocol layer — but it means whitelist patterns need to anticipate the prefix and must be **anchored**, not substring matches:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# WRONG -- blocks any ssh_exec call that uses `env`, because the final command
|
|
151
|
+
# starts with `KEY='value' ` and never matches `^ls`.
|
|
152
|
+
SSH_MCP_COMMAND_WHITELIST="^ls "
|
|
153
|
+
|
|
154
|
+
# RIGHT -- allow zero or more `KEY='value' ` prefixes before the real command.
|
|
155
|
+
SSH_MCP_COMMAND_WHITELIST="^([A-Za-z_][A-Za-z0-9_]*='[^']*' )*ls( |$)"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Avoid substring-match patterns** like ` ls ` if you're worried about a hostile agent. An agent could pass `env: { ATTACK: " ls " }` to make the final command `ATTACK=' ls ' rm -rf /`, which matches a substring ` ls ` and bypasses the whitelist. Anchored patterns of the form above don't have this weakness because they require the real command name to follow the env-prefix block, not appear inside a quoted env value.
|
|
159
|
+
|
|
160
|
+
Blacklists need the same care. `^rm ` blocks a bare `rm` call, but doesn't block `FOO='bar' rm`. Use the same env-prefix-tolerant anchor:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
SSH_MCP_COMMAND_BLACKLIST="^([A-Za-z_][A-Za-z0-9_]*='[^']*' )*rm( |$)"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
If you don't trust the agent's `env` values at all, the simplest mitigation is to leave `env` unused in your client config and pass everything through the `command` string yourself.
|
|
167
|
+
|
|
141
168
|
### Windows support
|
|
142
169
|
|
|
143
170
|
On Windows, ssh-mcp detects the OpenSSH Authentication Agent service automatically (via the `\\.\pipe\openssh-ssh-agent` named pipe). No `SSH_AUTH_SOCK` needed — just make sure the OpenSSH agent service is running.
|