ssh-mcp 1.0.1 → 1.0.4
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/build/index.js +33 -10
- package/package.json +5 -4
package/build/index.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// This file should be renamed to index.ts for TypeScript support
|
|
2
|
-
import 'dotenv/config';
|
|
3
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
2
|
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
5
3
|
import { Client as SSHClient } from 'ssh2';
|
|
@@ -24,9 +22,22 @@ const PORT = argvConfig.port ? parseInt(argvConfig.port) : 22;
|
|
|
24
22
|
const USER = argvConfig.user;
|
|
25
23
|
const PASSWORD = argvConfig.password;
|
|
26
24
|
const KEY = argvConfig.key;
|
|
25
|
+
function validateConfig(config) {
|
|
26
|
+
const errors = [];
|
|
27
|
+
if (!config.host)
|
|
28
|
+
errors.push('Missing required --host');
|
|
29
|
+
if (!config.user)
|
|
30
|
+
errors.push('Missing required --user');
|
|
31
|
+
if (config.port && isNaN(Number(config.port)))
|
|
32
|
+
errors.push('Invalid --port');
|
|
33
|
+
if (errors.length > 0) {
|
|
34
|
+
throw new Error('Configuration error:\n' + errors.join('\n'));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
validateConfig(argvConfig);
|
|
27
38
|
const server = new McpServer({
|
|
28
39
|
name: 'SSH MCP Server',
|
|
29
|
-
version: '1.0.
|
|
40
|
+
version: '1.0.4',
|
|
30
41
|
capabilities: {
|
|
31
42
|
resources: {},
|
|
32
43
|
tools: {},
|
|
@@ -35,20 +46,32 @@ const server = new McpServer({
|
|
|
35
46
|
server.tool("exec", "Execute a shell command on the remote SSH server and return the output.", {
|
|
36
47
|
command: z.string().describe("Shell command to execute on the remote SSH server"),
|
|
37
48
|
}, async ({ command }) => {
|
|
49
|
+
// Sanitize command input
|
|
50
|
+
if (typeof command !== 'string' || !command.trim()) {
|
|
51
|
+
throw new McpError(ErrorCode.InternalError, 'Command must be a non-empty string.');
|
|
52
|
+
}
|
|
38
53
|
const sshConfig = {
|
|
39
54
|
host: HOST,
|
|
40
55
|
port: PORT,
|
|
41
56
|
username: USER,
|
|
42
57
|
};
|
|
43
|
-
|
|
44
|
-
|
|
58
|
+
try {
|
|
59
|
+
if (PASSWORD) {
|
|
60
|
+
sshConfig.password = PASSWORD;
|
|
61
|
+
}
|
|
62
|
+
else if (KEY) {
|
|
63
|
+
const fs = await import('fs/promises');
|
|
64
|
+
sshConfig.privateKey = await fs.readFile(KEY, 'utf8');
|
|
65
|
+
}
|
|
66
|
+
const result = await execSshCommand(sshConfig, command);
|
|
67
|
+
return result;
|
|
45
68
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
69
|
+
catch (err) {
|
|
70
|
+
// Wrap unexpected errors
|
|
71
|
+
if (err instanceof McpError)
|
|
72
|
+
throw err;
|
|
73
|
+
throw new McpError(ErrorCode.InternalError, `Unexpected error: ${err?.message || err}`);
|
|
49
74
|
}
|
|
50
|
-
const result = await execSshCommand(sshConfig, command);
|
|
51
|
-
return result;
|
|
52
75
|
});
|
|
53
76
|
async function execSshCommand(sshConfig, command) {
|
|
54
77
|
return new Promise((resolve, reject) => {
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ssh-mcp",
|
|
3
|
-
"
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"version": "1.0.4",
|
|
4
5
|
"description": "MCP server exposing SSH control for Linux and Windows systems via Model Context Protocol.",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"bin": {
|
|
7
|
-
"ssh-mcp": "
|
|
8
|
+
"ssh-mcp": "build/index.js"
|
|
8
9
|
},
|
|
9
10
|
"scripts": {
|
|
10
11
|
"prepare": "npm run build",
|
|
11
|
-
"build": "tsc
|
|
12
|
+
"build": "tsc && shx chmod +x build/*.js",
|
|
12
13
|
"inspect": "npx @modelcontextprotocol/inspector node build/index.js"
|
|
13
14
|
},
|
|
14
15
|
"files": [
|
|
@@ -16,13 +17,13 @@
|
|
|
16
17
|
],
|
|
17
18
|
"dependencies": {
|
|
18
19
|
"@modelcontextprotocol/sdk": "^1.10.2",
|
|
19
|
-
"dotenv": "^16.3.1",
|
|
20
20
|
"ssh2": "^1.11.0",
|
|
21
21
|
"zod": "^3.24.3"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/node": "^20.17.31",
|
|
25
25
|
"@types/ssh2": "^1.15.5",
|
|
26
|
+
"shx": "^0.4.0",
|
|
26
27
|
"typescript": "^5.4.5"
|
|
27
28
|
}
|
|
28
29
|
}
|