claude-ssh-mcp 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
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.
package/README.md ADDED
@@ -0,0 +1,89 @@
1
+ # MCP SSH Server
2
+
3
+ MCP addon for **Claude Desktop** — gives Claude SSH access to your servers.
4
+
5
+ ## Install
6
+
7
+ Run this one command (requires [Node.js](https://nodejs.org) 18+):
8
+
9
+ ```
10
+ npx -y claude-ssh-mcp
11
+ ```
12
+
13
+ It automatically adds itself to Claude Desktop. Restart Claude Desktop and you're done.
14
+
15
+ ## Usage
16
+
17
+ Just talk to Claude:
18
+
19
+ - *"Connect to 185.91.118.4 as root with password mypass, call it production"*
20
+ - *"Run `ls -la /var/www` on production"*
21
+ - *"Upload C:\Users\me\app.zip to /tmp/app.zip on production"*
22
+ - *"Download /var/log/error.log from production"*
23
+ - *"Connect to 10.0.0.5 as deploy with key at C:\Users\me\.ssh\id_rsa, name it staging"*
24
+ - *"Transfer /var/log/app.log from production to /tmp/app.log on staging"*
25
+ - *"List my servers"*
26
+ - *"Remove staging"*
27
+
28
+ ## Servers are saved
29
+
30
+ When you tell Claude to connect to a server, it's saved to `~/.mcp-ssh/servers.json`. Next time just say *"connect to production"* and it reconnects using the saved config.
31
+
32
+ You can also edit `servers.json` manually:
33
+
34
+ ```json
35
+ {
36
+ "production": {
37
+ "host": "185.91.118.4",
38
+ "port": 22,
39
+ "username": "root",
40
+ "password": "mypass"
41
+ },
42
+ "staging": {
43
+ "host": "10.0.0.5",
44
+ "port": 22,
45
+ "username": "deploy",
46
+ "privateKeyPath": "C:\\Users\\me\\.ssh\\id_rsa"
47
+ }
48
+ }
49
+ ```
50
+
51
+ ## Tools
52
+
53
+ | Tool | What it does |
54
+ |------|--------------|
55
+ | `ssh_connect` | Connect to a server (new or saved) |
56
+ | `ssh_disconnect` | Close a connection |
57
+ | `ssh_list_sessions` | Show all connections and saved servers |
58
+ | `ssh_remove_server` | Delete a saved server |
59
+ | `ssh_execute` | Run a shell command |
60
+ | `ssh_upload` | Upload a local file (SFTP) |
61
+ | `ssh_download` | Download a remote file (SFTP) |
62
+ | `ssh_transfer` | Copy a file between two servers |
63
+ | `ssh_list_files` | List remote directory contents |
64
+
65
+ ## Building from Source
66
+
67
+ ```bash
68
+ git clone https://github.com/MaraBank/mcp-ssh-server.git
69
+ cd mcp-ssh-server
70
+ npm install
71
+ npm run build
72
+ ```
73
+
74
+ Then point Claude Desktop config (`%APPDATA%\Claude\claude_desktop_config.json`) to your local build:
75
+
76
+ ```json
77
+ {
78
+ "mcpServers": {
79
+ "ssh": {
80
+ "command": "node",
81
+ "args": ["C:\\path\\to\\mcp-ssh-server\\build\\index.js"]
82
+ }
83
+ }
84
+ }
85
+ ```
86
+
87
+ ## License
88
+
89
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/build/index.js ADDED
@@ -0,0 +1,677 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
38
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
39
+ const ssh2_1 = require("ssh2");
40
+ const zod_1 = require("zod");
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const os = __importStar(require("os"));
44
+ const https = __importStar(require("https"));
45
+ const child_process_1 = require("child_process");
46
+ const SERVERS_DIR = path.join(os.homedir(), ".mcp-ssh");
47
+ const SERVERS_FILE = path.join(SERVERS_DIR, "servers.json");
48
+ function loadSavedServers() {
49
+ try {
50
+ if (fs.existsSync(SERVERS_FILE)) {
51
+ return JSON.parse(fs.readFileSync(SERVERS_FILE, "utf-8"));
52
+ }
53
+ }
54
+ catch { }
55
+ return {};
56
+ }
57
+ function writeSavedServers(servers) {
58
+ if (!fs.existsSync(SERVERS_DIR))
59
+ fs.mkdirSync(SERVERS_DIR, { recursive: true });
60
+ fs.writeFileSync(SERVERS_FILE, JSON.stringify(servers, null, 2));
61
+ try {
62
+ fs.chmodSync(SERVERS_FILE, 0o600);
63
+ }
64
+ catch { }
65
+ }
66
+ function saveServer(name, entry) {
67
+ const servers = loadSavedServers();
68
+ servers[name] = entry;
69
+ writeSavedServers(servers);
70
+ }
71
+ function deleteSavedServer(name) {
72
+ const servers = loadSavedServers();
73
+ if (!(name in servers))
74
+ return false;
75
+ delete servers[name];
76
+ writeSavedServers(servers);
77
+ return true;
78
+ }
79
+ const sessions = new Map();
80
+ function getSession(sessionName) {
81
+ const session = sessions.get(sessionName);
82
+ if (!session) {
83
+ throw new Error(`No active session named "${sessionName}". Use ssh_connect to connect or ssh_list_sessions to see available servers.`);
84
+ }
85
+ return session;
86
+ }
87
+ // ---------------------------------------------------------------------------
88
+ // SSH Keepalive & Auto-reconnect
89
+ // ---------------------------------------------------------------------------
90
+ const KEEPALIVE_INTERVAL = 30_000; // Send keepalive every 30 seconds
91
+ const RECONNECT_DELAY = 5_000; // Wait 5 seconds before reconnecting
92
+ const MAX_RECONNECT_ATTEMPTS = 3;
93
+ async function reconnectSession(sessionName, session, attempt = 1) {
94
+ if (attempt > MAX_RECONNECT_ATTEMPTS) {
95
+ console.error(`[claude-ssh-mcp] Failed to reconnect "${sessionName}" after ${MAX_RECONNECT_ATTEMPTS} attempts`);
96
+ sessions.delete(sessionName);
97
+ return false;
98
+ }
99
+ console.error(`[claude-ssh-mcp] Reconnecting "${sessionName}" (attempt ${attempt}/${MAX_RECONNECT_ATTEMPTS})...`);
100
+ const newClient = new ssh2_1.Client();
101
+ try {
102
+ await new Promise((resolve, reject) => {
103
+ const timeout = setTimeout(() => {
104
+ newClient.end();
105
+ reject(new Error("Connection timed out"));
106
+ }, 30_000);
107
+ newClient.on("ready", () => { clearTimeout(timeout); resolve(); });
108
+ newClient.on("error", (err) => { clearTimeout(timeout); reject(err); });
109
+ newClient.connect({
110
+ ...session.connectOptions,
111
+ keepaliveInterval: KEEPALIVE_INTERVAL,
112
+ keepaliveCountMax: 3,
113
+ });
114
+ });
115
+ // Setup event handlers for the new client
116
+ setupClientHandlers(sessionName, newClient, session.connectOptions);
117
+ // Update session with new client
118
+ session.client = newClient;
119
+ console.error(`[claude-ssh-mcp] Reconnected "${sessionName}" successfully`);
120
+ return true;
121
+ }
122
+ catch (err) {
123
+ console.error(`[claude-ssh-mcp] Reconnect attempt ${attempt} failed: ${err.message}`);
124
+ await new Promise(r => setTimeout(r, RECONNECT_DELAY));
125
+ return reconnectSession(sessionName, session, attempt + 1);
126
+ }
127
+ }
128
+ function setupClientHandlers(sessionName, client, connectOptions) {
129
+ client.on("close", () => {
130
+ const session = sessions.get(sessionName);
131
+ if (session && session.client === client) {
132
+ console.error(`[claude-ssh-mcp] Connection "${sessionName}" closed, attempting reconnect...`);
133
+ reconnectSession(sessionName, session);
134
+ }
135
+ });
136
+ client.on("end", () => {
137
+ // Only log, don't reconnect on clean end (user disconnect)
138
+ });
139
+ client.on("error", (err) => {
140
+ console.error(`[claude-ssh-mcp] Connection "${sessionName}" error: ${err.message}`);
141
+ });
142
+ }
143
+ // ---------------------------------------------------------------------------
144
+ // Helpers
145
+ // ---------------------------------------------------------------------------
146
+ function getSftp(client) {
147
+ return new Promise((resolve, reject) => {
148
+ client.sftp((err, sftp) => (err ? reject(err) : resolve(sftp)));
149
+ });
150
+ }
151
+ function execCommand(client, command) {
152
+ return new Promise((resolve, reject) => {
153
+ client.exec(command, (err, stream) => {
154
+ if (err)
155
+ return reject(err);
156
+ let stdout = "";
157
+ let stderr = "";
158
+ stream.on("close", (code) => resolve({ stdout, stderr, code: code ?? 0 }));
159
+ stream.on("data", (data) => { stdout += data.toString(); });
160
+ stream.stderr.on("data", (data) => { stderr += data.toString(); });
161
+ });
162
+ });
163
+ }
164
+ // ---------------------------------------------------------------------------
165
+ // MCP Server
166
+ // ---------------------------------------------------------------------------
167
+ const server = new mcp_js_1.McpServer({
168
+ name: "claude-ssh-mcp",
169
+ version: "1.0.0",
170
+ });
171
+ // ---- ssh_connect ----------------------------------------------------------
172
+ server.tool("ssh_connect", "Connect to a remote server via SSH. Provide full details for a new server (it will be saved for next time), or just the sessionName to reconnect to a previously saved server.", {
173
+ sessionName: zod_1.z.string().describe("Friendly name for this session (e.g. 'production'). If this matches a saved server and no host is given, the saved config is used."),
174
+ host: zod_1.z.string().optional().describe("Hostname or IP address. Omit to connect using a saved server."),
175
+ port: zod_1.z.number().int().min(1).max(65535).default(22).describe("SSH port (default 22)"),
176
+ username: zod_1.z.string().optional().describe("SSH username. Omit to use saved server config."),
177
+ password: zod_1.z.string().optional().describe("Password (omit if using key auth)"),
178
+ privateKeyPath: zod_1.z.string().optional().describe("Absolute path to a private key file"),
179
+ privateKey: zod_1.z.string().optional().describe("Private key contents as a string (not saved to disk)"),
180
+ passphrase: zod_1.z.string().optional().describe("Passphrase for the private key, if encrypted"),
181
+ }, async ({ sessionName, host, port, username, password, privateKeyPath, privateKey, passphrase }) => {
182
+ if (sessions.has(sessionName)) {
183
+ return {
184
+ content: [{ type: "text", text: `Session "${sessionName}" already exists. Disconnect first or choose a different name.` }],
185
+ isError: true,
186
+ };
187
+ }
188
+ // If host not provided, look up saved server
189
+ if (!host) {
190
+ const saved = loadSavedServers();
191
+ const entry = saved[sessionName];
192
+ if (!entry) {
193
+ return {
194
+ content: [{ type: "text", text: `No saved server named "${sessionName}" and no host provided. Provide host + username for a new connection.` }],
195
+ isError: true,
196
+ };
197
+ }
198
+ host = entry.host;
199
+ port = entry.port;
200
+ username = username ?? entry.username;
201
+ password = password ?? entry.password;
202
+ privateKeyPath = privateKeyPath ?? entry.privateKeyPath;
203
+ passphrase = passphrase ?? entry.passphrase;
204
+ }
205
+ if (!username) {
206
+ return {
207
+ content: [{ type: "text", text: "Username is required." }],
208
+ isError: true,
209
+ };
210
+ }
211
+ // Resolve private key
212
+ let resolvedKey;
213
+ if (privateKeyPath) {
214
+ const keyPath = path.resolve(privateKeyPath);
215
+ if (!fs.existsSync(keyPath)) {
216
+ return {
217
+ content: [{ type: "text", text: `Private key file not found: ${keyPath}` }],
218
+ isError: true,
219
+ };
220
+ }
221
+ resolvedKey = fs.readFileSync(keyPath);
222
+ }
223
+ else if (privateKey) {
224
+ resolvedKey = privateKey;
225
+ }
226
+ if (!password && !resolvedKey) {
227
+ return {
228
+ content: [{ type: "text", text: "Provide either a password or a private key." }],
229
+ isError: true,
230
+ };
231
+ }
232
+ const client = new ssh2_1.Client();
233
+ // Store connection options for reconnection (don't store inline privateKey)
234
+ const connectOptions = {
235
+ host,
236
+ port,
237
+ username,
238
+ password,
239
+ privateKey: resolvedKey,
240
+ passphrase,
241
+ keepaliveInterval: KEEPALIVE_INTERVAL,
242
+ keepaliveCountMax: 3, // Disconnect after 3 missed keepalives (90 seconds)
243
+ readyTimeout: 30_000,
244
+ };
245
+ try {
246
+ await new Promise((resolve, reject) => {
247
+ const timeout = setTimeout(() => {
248
+ client.end();
249
+ reject(new Error("Connection timed out after 30 seconds"));
250
+ }, 30_000);
251
+ client.on("ready", () => { clearTimeout(timeout); resolve(); });
252
+ client.on("error", (err) => { clearTimeout(timeout); reject(err); });
253
+ client.connect(connectOptions);
254
+ });
255
+ }
256
+ catch (err) {
257
+ return {
258
+ content: [{ type: "text", text: `Connection failed: ${err.message}` }],
259
+ isError: true,
260
+ };
261
+ }
262
+ // Setup keepalive and auto-reconnect handlers
263
+ setupClientHandlers(sessionName, client, connectOptions);
264
+ sessions.set(sessionName, { client, config: { host, port, username }, connectOptions });
265
+ // Auto-save server config (never save inline privateKey to disk)
266
+ saveServer(sessionName, {
267
+ host, port, username,
268
+ ...(password ? { password } : {}),
269
+ ...(privateKeyPath ? { privateKeyPath } : {}),
270
+ ...(passphrase ? { passphrase } : {}),
271
+ });
272
+ return {
273
+ content: [{ type: "text", text: `Connected to ${username}@${host}:${port} as "${sessionName}". Server saved for next time.` }],
274
+ };
275
+ });
276
+ // ---- ssh_disconnect -------------------------------------------------------
277
+ server.tool("ssh_disconnect", "Close an active SSH session.", {
278
+ sessionName: zod_1.z.string().describe("Name of the session to disconnect"),
279
+ }, async ({ sessionName }) => {
280
+ const session = sessions.get(sessionName);
281
+ if (!session) {
282
+ return {
283
+ content: [{ type: "text", text: `No active session "${sessionName}".` }],
284
+ isError: true,
285
+ };
286
+ }
287
+ session.client.end();
288
+ sessions.delete(sessionName);
289
+ return {
290
+ content: [{ type: "text", text: `Disconnected "${sessionName}". Server config is still saved — use ssh_connect to reconnect.` }],
291
+ };
292
+ });
293
+ // ---- ssh_list_sessions ----------------------------------------------------
294
+ server.tool("ssh_list_sessions", "List all active SSH sessions and saved servers.", {}, async () => {
295
+ const saved = loadSavedServers();
296
+ const allNames = new Set([...sessions.keys(), ...Object.keys(saved)]);
297
+ if (allNames.size === 0) {
298
+ return {
299
+ content: [{ type: "text", text: "No sessions or saved servers. Use ssh_connect to add one." }],
300
+ };
301
+ }
302
+ const lines = [];
303
+ for (const name of allNames) {
304
+ const active = sessions.has(name);
305
+ const entry = saved[name];
306
+ const info = active
307
+ ? sessions.get(name).config
308
+ : entry
309
+ ? { host: entry.host, port: entry.port, username: entry.username }
310
+ : null;
311
+ if (info) {
312
+ const status = active ? "connected" : "saved";
313
+ lines.push(`• ${name} — ${info.username}@${info.host}:${info.port} [${status}]`);
314
+ }
315
+ }
316
+ return {
317
+ content: [{ type: "text", text: lines.join("\n") }],
318
+ };
319
+ });
320
+ // ---- ssh_remove_server ----------------------------------------------------
321
+ server.tool("ssh_remove_server", "Remove a saved server from servers.json and disconnect if currently active.", {
322
+ sessionName: zod_1.z.string().describe("Name of the server to remove"),
323
+ }, async ({ sessionName }) => {
324
+ const session = sessions.get(sessionName);
325
+ if (session) {
326
+ session.client.end();
327
+ sessions.delete(sessionName);
328
+ }
329
+ const removed = deleteSavedServer(sessionName);
330
+ if (!removed && !session) {
331
+ return {
332
+ content: [{ type: "text", text: `No server named "${sessionName}".` }],
333
+ isError: true,
334
+ };
335
+ }
336
+ return {
337
+ content: [{ type: "text", text: `Removed "${sessionName}".` }],
338
+ };
339
+ });
340
+ // ---- ssh_execute ----------------------------------------------------------
341
+ server.tool("ssh_execute", "Execute a command on a connected remote server.", {
342
+ sessionName: zod_1.z.string().describe("Session to run the command on"),
343
+ command: zod_1.z.string().describe("Shell command to execute"),
344
+ }, async ({ sessionName, command }) => {
345
+ let session;
346
+ try {
347
+ session = getSession(sessionName);
348
+ }
349
+ catch (err) {
350
+ return { content: [{ type: "text", text: err.message }], isError: true };
351
+ }
352
+ try {
353
+ const { stdout, stderr, code } = await execCommand(session.client, command);
354
+ const parts = [];
355
+ if (stdout)
356
+ parts.push(stdout);
357
+ if (stderr)
358
+ parts.push(`[stderr]\n${stderr}`);
359
+ parts.push(`[exit code: ${code}]`);
360
+ return { content: [{ type: "text", text: parts.join("\n") }] };
361
+ }
362
+ catch (err) {
363
+ return {
364
+ content: [{ type: "text", text: `Execution failed: ${err.message}` }],
365
+ isError: true,
366
+ };
367
+ }
368
+ });
369
+ // ---- ssh_upload -----------------------------------------------------------
370
+ server.tool("ssh_upload", "Upload a local file to a remote server via SFTP.", {
371
+ sessionName: zod_1.z.string().describe("Session to upload to"),
372
+ localPath: zod_1.z.string().describe("Absolute path to the local file"),
373
+ remotePath: zod_1.z.string().describe("Absolute destination path on the remote server"),
374
+ }, async ({ sessionName, localPath, remotePath }) => {
375
+ let session;
376
+ try {
377
+ session = getSession(sessionName);
378
+ }
379
+ catch (err) {
380
+ return { content: [{ type: "text", text: err.message }], isError: true };
381
+ }
382
+ const resolved = path.resolve(localPath);
383
+ if (!fs.existsSync(resolved)) {
384
+ return {
385
+ content: [{ type: "text", text: `Local file not found: ${resolved}` }],
386
+ isError: true,
387
+ };
388
+ }
389
+ try {
390
+ const sftp = await getSftp(session.client);
391
+ await new Promise((resolve, reject) => {
392
+ sftp.fastPut(resolved, remotePath, (err) => (err ? reject(err) : resolve()));
393
+ });
394
+ return {
395
+ content: [{ type: "text", text: `Uploaded ${resolved} → ${session.config.host}:${remotePath}` }],
396
+ };
397
+ }
398
+ catch (err) {
399
+ return {
400
+ content: [{ type: "text", text: `Upload failed: ${err.message}` }],
401
+ isError: true,
402
+ };
403
+ }
404
+ });
405
+ // ---- ssh_download ---------------------------------------------------------
406
+ server.tool("ssh_download", "Download a file from a remote server to the local machine via SFTP.", {
407
+ sessionName: zod_1.z.string().describe("Session to download from"),
408
+ remotePath: zod_1.z.string().describe("Absolute path on the remote server"),
409
+ localPath: zod_1.z.string().describe("Absolute local destination path"),
410
+ }, async ({ sessionName, remotePath, localPath }) => {
411
+ let session;
412
+ try {
413
+ session = getSession(sessionName);
414
+ }
415
+ catch (err) {
416
+ return { content: [{ type: "text", text: err.message }], isError: true };
417
+ }
418
+ const resolved = path.resolve(localPath);
419
+ const dir = path.dirname(resolved);
420
+ if (!fs.existsSync(dir))
421
+ fs.mkdirSync(dir, { recursive: true });
422
+ try {
423
+ const sftp = await getSftp(session.client);
424
+ await new Promise((resolve, reject) => {
425
+ sftp.fastGet(remotePath, resolved, (err) => (err ? reject(err) : resolve()));
426
+ });
427
+ return {
428
+ content: [{ type: "text", text: `Downloaded ${session.config.host}:${remotePath} → ${resolved}` }],
429
+ };
430
+ }
431
+ catch (err) {
432
+ return {
433
+ content: [{ type: "text", text: `Download failed: ${err.message}` }],
434
+ isError: true,
435
+ };
436
+ }
437
+ });
438
+ // ---- ssh_transfer ---------------------------------------------------------
439
+ server.tool("ssh_transfer", "Transfer a file between two connected remote servers (source → destination) via SFTP.", {
440
+ sourceSession: zod_1.z.string().describe("Session name of the source server"),
441
+ sourceRemotePath: zod_1.z.string().describe("Absolute file path on the source server"),
442
+ destinationSession: zod_1.z.string().describe("Session name of the destination server"),
443
+ destinationRemotePath: zod_1.z.string().describe("Absolute file path on the destination server"),
444
+ }, async ({ sourceSession, sourceRemotePath, destinationSession, destinationRemotePath }) => {
445
+ let src;
446
+ let dst;
447
+ try {
448
+ src = getSession(sourceSession);
449
+ dst = getSession(destinationSession);
450
+ }
451
+ catch (err) {
452
+ return { content: [{ type: "text", text: err.message }], isError: true };
453
+ }
454
+ try {
455
+ const srcSftp = await getSftp(src.client);
456
+ const dstSftp = await getSftp(dst.client);
457
+ const data = await new Promise((resolve, reject) => {
458
+ const chunks = [];
459
+ const readStream = srcSftp.createReadStream(sourceRemotePath);
460
+ readStream.on("data", (chunk) => chunks.push(chunk));
461
+ readStream.on("end", () => resolve(Buffer.concat(chunks)));
462
+ readStream.on("error", reject);
463
+ });
464
+ await new Promise((resolve, reject) => {
465
+ const writeStream = dstSftp.createWriteStream(destinationRemotePath);
466
+ writeStream.on("close", () => resolve());
467
+ writeStream.on("error", reject);
468
+ writeStream.end(data);
469
+ });
470
+ return {
471
+ content: [{ type: "text", text: `Transferred ${src.config.host}:${sourceRemotePath} → ${dst.config.host}:${destinationRemotePath} (${data.length} bytes)` }],
472
+ };
473
+ }
474
+ catch (err) {
475
+ return {
476
+ content: [{ type: "text", text: `Transfer failed: ${err.message}` }],
477
+ isError: true,
478
+ };
479
+ }
480
+ });
481
+ // ---- ssh_list_files -------------------------------------------------------
482
+ server.tool("ssh_list_files", "List files and directories in a remote path via SFTP.", {
483
+ sessionName: zod_1.z.string().describe("Session to list files on"),
484
+ remotePath: zod_1.z.string().describe("Absolute directory path on the remote server"),
485
+ }, async ({ sessionName, remotePath }) => {
486
+ let session;
487
+ try {
488
+ session = getSession(sessionName);
489
+ }
490
+ catch (err) {
491
+ return { content: [{ type: "text", text: err.message }], isError: true };
492
+ }
493
+ try {
494
+ const sftp = await getSftp(session.client);
495
+ const list = await new Promise((resolve, reject) => {
496
+ sftp.readdir(remotePath, (err, list) => (err ? reject(err) : resolve(list)));
497
+ });
498
+ if (list.length === 0) {
499
+ return {
500
+ content: [{ type: "text", text: `Directory is empty: ${remotePath}` }],
501
+ };
502
+ }
503
+ const lines = list.map((entry) => {
504
+ const mode = entry.attrs.mode;
505
+ const isDir = (mode & 0o170000) === 0o040000;
506
+ const isLink = (mode & 0o170000) === 0o120000;
507
+ const typeChar = isDir ? "d" : isLink ? "l" : "-";
508
+ const size = entry.attrs.size ?? 0;
509
+ return `${typeChar} ${String(size).padStart(10)} ${entry.filename}`;
510
+ });
511
+ return {
512
+ content: [{ type: "text", text: `${remotePath} (${list.length} entries):\n${lines.join("\n")}` }],
513
+ };
514
+ }
515
+ catch (err) {
516
+ return {
517
+ content: [{ type: "text", text: `List failed: ${err.message}` }],
518
+ isError: true,
519
+ };
520
+ }
521
+ });
522
+ // ---------------------------------------------------------------------------
523
+ // Auto-update checker (runs every 2 hours)
524
+ // ---------------------------------------------------------------------------
525
+ const CURRENT_VERSION = "1.0.0";
526
+ const UPDATE_CHECK_INTERVAL = 2 * 60 * 60 * 1000; // 2 hours in ms
527
+ function fetchLatestVersion() {
528
+ return new Promise((resolve) => {
529
+ const req = https.get("https://raw.githubusercontent.com/MaraBank/claude-ssh-mcp/master/package.json", { timeout: 10000 }, (res) => {
530
+ if (res.statusCode !== 200) {
531
+ resolve(null);
532
+ return;
533
+ }
534
+ let data = "";
535
+ res.on("data", (chunk) => { data += chunk; });
536
+ res.on("end", () => {
537
+ try {
538
+ const pkg = JSON.parse(data);
539
+ resolve(pkg.version || null);
540
+ }
541
+ catch {
542
+ resolve(null);
543
+ }
544
+ });
545
+ });
546
+ req.on("error", () => resolve(null));
547
+ req.on("timeout", () => { req.destroy(); resolve(null); });
548
+ });
549
+ }
550
+ function compareVersions(current, latest) {
551
+ const c = current.split(".").map(Number);
552
+ const l = latest.split(".").map(Number);
553
+ for (let i = 0; i < 3; i++) {
554
+ if ((l[i] || 0) > (c[i] || 0))
555
+ return 1;
556
+ if ((l[i] || 0) < (c[i] || 0))
557
+ return -1;
558
+ }
559
+ return 0;
560
+ }
561
+ async function checkForUpdates() {
562
+ try {
563
+ const latest = await fetchLatestVersion();
564
+ if (latest && compareVersions(CURRENT_VERSION, latest) > 0) {
565
+ console.error(`[claude-ssh-mcp] Update available: ${CURRENT_VERSION} → ${latest}`);
566
+ console.error(`[claude-ssh-mcp] Run: npx -y claude-ssh-mcp@latest`);
567
+ // Try to auto-update by clearing npx cache for this package
568
+ try {
569
+ if (process.platform === "win32") {
570
+ (0, child_process_1.execSync)("npm cache clean --force", { stdio: "ignore" });
571
+ }
572
+ else {
573
+ (0, child_process_1.execSync)("npm cache clean --force", { stdio: "ignore" });
574
+ }
575
+ console.error("[claude-ssh-mcp] Cache cleared. Restart Claude Desktop to get the update.");
576
+ }
577
+ catch {
578
+ // Cache clear failed, user will need to update manually
579
+ }
580
+ }
581
+ }
582
+ catch {
583
+ // Update check failed silently
584
+ }
585
+ }
586
+ function startUpdateChecker() {
587
+ // Check immediately on startup (with a small delay to not block init)
588
+ setTimeout(checkForUpdates, 5000);
589
+ // Then check every 2 hours
590
+ setInterval(checkForUpdates, UPDATE_CHECK_INTERVAL);
591
+ }
592
+ // ---------------------------------------------------------------------------
593
+ // Installer — runs when user executes `npx -y claude-ssh-mcp` in a terminal
594
+ // ---------------------------------------------------------------------------
595
+ function getClaudeConfigPath() {
596
+ if (process.platform === "win32") {
597
+ const appData = process.env.APPDATA || path.join(os.homedir(), "AppData", "Roaming");
598
+ return path.join(appData, "Claude", "claude_desktop_config.json");
599
+ }
600
+ if (process.platform === "darwin") {
601
+ return path.join(os.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
602
+ }
603
+ return path.join(os.homedir(), ".config", "Claude", "claude_desktop_config.json");
604
+ }
605
+ function install() {
606
+ console.log("");
607
+ console.log(" MCP SSH Server — Setup");
608
+ console.log(" ──────────────────────");
609
+ console.log("");
610
+ const configPath = getClaudeConfigPath();
611
+ const configDir = path.dirname(configPath);
612
+ // Read existing config or start fresh
613
+ let config = {};
614
+ if (fs.existsSync(configPath)) {
615
+ try {
616
+ config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
617
+ }
618
+ catch {
619
+ config = {};
620
+ }
621
+ }
622
+ // Check if already installed
623
+ const existing = config?.mcpServers?.ssh;
624
+ if (existing && JSON.stringify(existing.args || []).includes("claude-ssh-mcp")) {
625
+ console.log(" Already installed!");
626
+ console.log("");
627
+ console.log(" Restart Claude Desktop if you haven't already, then tell Claude:");
628
+ console.log(' → "Connect to my server at 192.168.1.100 as root with password xyz"');
629
+ console.log("");
630
+ console.log(` Config: ${configPath}`);
631
+ console.log(` Servers: ${SERVERS_FILE}`);
632
+ console.log("");
633
+ return;
634
+ }
635
+ // Add our entry (preserves any existing mcpServers)
636
+ if (!config.mcpServers)
637
+ config.mcpServers = {};
638
+ config.mcpServers.ssh = {
639
+ command: "npx",
640
+ args: ["-y", "claude-ssh-mcp"],
641
+ };
642
+ // Write config
643
+ if (!fs.existsSync(configDir))
644
+ fs.mkdirSync(configDir, { recursive: true });
645
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
646
+ console.log(" Done! SSH server added to Claude Desktop.");
647
+ console.log("");
648
+ console.log(" Next:");
649
+ console.log(" 1. Restart Claude Desktop");
650
+ console.log(" 2. Tell Claude what server to connect to, for example:");
651
+ console.log(' "Connect to 185.91.118.4 as root, password mypass, call it production"');
652
+ console.log("");
653
+ console.log(" Claude will remember your servers. You can also edit them manually:");
654
+ console.log(` ${SERVERS_FILE}`);
655
+ console.log("");
656
+ }
657
+ // ---------------------------------------------------------------------------
658
+ // Entry point
659
+ // ---------------------------------------------------------------------------
660
+ async function main() {
661
+ // Terminal (user ran the command) → install into Claude Desktop
662
+ // Piped stdin (Claude Desktop launched us) → run as MCP server
663
+ if (process.stdin.isTTY) {
664
+ install();
665
+ return;
666
+ }
667
+ const transport = new stdio_js_1.StdioServerTransport();
668
+ await server.connect(transport);
669
+ console.error("MCP SSH Server running on stdio");
670
+ // Start background update checker
671
+ startUpdateChecker();
672
+ }
673
+ main().catch((err) => {
674
+ console.error("Fatal error:", err);
675
+ process.exit(1);
676
+ });
677
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "claude-ssh-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server addon for Claude Desktop — SSH into servers, run commands, transfer files",
5
+ "main": "build/index.js",
6
+ "bin": {
7
+ "claude-ssh-mcp": "build/index.js"
8
+ },
9
+ "files": [
10
+ "build/index.js",
11
+ "build/index.js.map",
12
+ "build/index.d.ts",
13
+ "README.md",
14
+ "LICENSE"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "prepublishOnly": "npm run build",
19
+ "start": "node build/index.js"
20
+ },
21
+ "keywords": [
22
+ "mcp",
23
+ "mcp-server",
24
+ "ssh",
25
+ "sftp",
26
+ "claude",
27
+ "claude-desktop",
28
+ "model-context-protocol",
29
+ "remote",
30
+ "server-management"
31
+ ],
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/MaraBank/mcp-ssh-server.git"
35
+ },
36
+ "homepage": "https://github.com/MaraBank/mcp-ssh-server",
37
+ "engines": {
38
+ "node": ">=18"
39
+ },
40
+ "dependencies": {
41
+ "@modelcontextprotocol/sdk": "^1.12.1",
42
+ "ssh2": "^1.16.0",
43
+ "zod": "^3.24.2"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^22.13.1",
47
+ "@types/ssh2": "^1.15.4",
48
+ "typescript": "^5.7.3"
49
+ },
50
+ "license": "MIT"
51
+ }