@yawlabs/ssh-mcp 0.3.0 → 0.5.0

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 CHANGED
@@ -73,10 +73,35 @@ Tools that fix your local SSH setup so everything else — git, deploys, tunnels
73
73
  | `ssh_download` | Download a file from a remote host to local filesystem. |
74
74
  | `ssh_ls` | List files in a directory on a remote host. |
75
75
 
76
+ ### Higher-level operations
77
+
78
+ Tools that wrap common patterns agents build with ssh_exec — faster and less error-prone.
79
+
80
+ | Tool | Description |
81
+ |------|-------------|
82
+ | `ssh_multi_exec` | Run a command on multiple hosts in parallel. Returns results per host. |
83
+ | `ssh_find` | Search for files remotely with structured parameters (name, type, size, depth). |
84
+ | `ssh_tail` | Read the last N lines of a file, optionally filtered by a grep pattern. |
85
+ | `ssh_service_status` | Check systemd service status (active, PID, uptime, description). |
86
+
76
87
  ### Auto-diagnostics
77
88
 
78
89
  When any remote operation fails, ssh-mcp automatically runs diagnostics and includes the results in the error response. Your agent doesn't need to call `ssh_diagnose` separately — it gets told what's wrong and how to fix it right in the error message.
79
90
 
91
+ ### Connection pooling
92
+
93
+ Remote operations reuse SSH connections automatically. When your agent makes multiple calls to the same host, the first call opens a connection and subsequent calls reuse it. Connections are kept alive for 60 seconds after the last use, then closed automatically.
94
+
95
+ ### SSH config support
96
+
97
+ All connections respect your `~/.ssh/config`. Host aliases, custom ports, usernames, identity files, and ProxyJump settings are used automatically. If you have `Host myserver` configured in your SSH config, just pass `host: "myserver"` — ssh-mcp resolves everything.
98
+
99
+ **ProxyJump / bastion hosts** are supported automatically. If your SSH config has `ProxyJump bastion` for a host, ssh-mcp connects through the bastion transparently. Chained proxies work too.
100
+
101
+ ### Windows support
102
+
103
+ 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.
104
+
80
105
  ## Authentication
81
106
 
82
107
  All remote operations accept connection parameters:
@@ -84,12 +109,12 @@ All remote operations accept connection parameters:
84
109
  | Parameter | Description | Default |
85
110
  |-----------|-------------|---------|
86
111
  | `host` | SSH hostname or IP (required) | — |
87
- | `port` | SSH port | `22` |
88
- | `username` | SSH username | Current user |
112
+ | `port` | SSH port | From SSH config or `22` |
113
+ | `username` | SSH username | From SSH config or current user |
89
114
  | `privateKeyPath` | Path to SSH private key | Auto-detect |
90
115
  | `password` | SSH password (prefer keys) | — |
91
116
 
92
- **Auth resolution order:** explicit key > explicit password > ssh-agent (`SSH_AUTH_SOCK`) > default key paths (`~/.ssh/id_ed25519`, `id_rsa`, `id_ecdsa`).
117
+ **Auth resolution order:** explicit key > explicit password > ssh-agent (`SSH_AUTH_SOCK`) > SSH config identity files > default key paths (`~/.ssh/id_ed25519`, `id_rsa`, `id_ecdsa`).
93
118
 
94
119
  ## Example workflows
95
120
 
@@ -123,7 +148,7 @@ Agent reports: "SSH server isn't running on new-server or port 22 is blocked"
123
148
  ## Programmatic usage
124
149
 
125
150
  ```typescript
126
- import { connect, exec, diagnose, ensureAgent, listSshKeys, checkGitSsh } from '@yawlabs/ssh-mcp';
151
+ import { connect, exec, diagnose, ensureAgent, listSshKeys, checkGitSsh, ConnectionPool } from '@yawlabs/ssh-mcp';
127
152
 
128
153
  // Fix SSH environment
129
154
  const agent = ensureAgent();
@@ -139,12 +164,25 @@ for (const key of keys) {
139
164
  console.log(`${key.name} (${key.type}) - ${key.loadedInAgent ? 'loaded' : 'not loaded'}`);
140
165
  }
141
166
 
142
- // Run a remote command
167
+ // Run a remote command (one-off)
143
168
  const client = await connect({ host: 'my-server', username: 'deploy' });
144
169
  const result = await exec(client, 'uptime');
145
170
  console.log(result.stdout);
146
171
  client.end();
147
172
 
173
+ // Run multiple commands with connection pooling
174
+ const pool = new ConnectionPool();
175
+ await pool.withConnection({ host: 'my-server' }, async (client) => {
176
+ const r1 = await exec(client, 'uptime');
177
+ console.log(r1.stdout);
178
+ });
179
+ // Connection stays open for 60s — next call reuses it
180
+ await pool.withConnection({ host: 'my-server' }, async (client) => {
181
+ const r2 = await exec(client, 'df -h');
182
+ console.log(r2.stdout);
183
+ });
184
+ pool.drain(); // close all connections when done
185
+
148
186
  // Diagnose issues
149
187
  const report = diagnose('my-server');
150
188
  console.log(report.overall); // "ok" | "warning" | "error"