@jadchene/mcp-ssh-service 1.0.0 → 1.1.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 CHANGED
@@ -1,143 +1,95 @@
1
- English | [简体中文](./README_zh.md)
2
-
3
- # 🚀 mcp-ssh
4
-
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
- [![Node.js Version](https://img.shields.io/badge/node-%3E%3D20.0.0-brightgreen)](https://nodejs.org/)
7
- [![MCP Ready](https://img.shields.io/badge/MCP-Ready-blue)](https://modelcontextprotocol.io/)
8
-
9
- A **production-grade** Model Context Protocol (MCP) server designed for secure, stateless SSH automation. This service empowers AI agents to manage remote infrastructure with **human-in-the-loop** safety and **semantic environment awareness**.
10
-
11
- ---
12
-
13
- ## 🌟 Key Pillars
14
-
15
- ### 🔒 Uncompromising Security
16
- * **Two-Step Confirmation**: High-risk operations (writes, deletes, restarts) return a `confirmationId`. Nothing happens until a human approves the specific transaction.
17
- * **Command Blacklist**: Real-time regex interception for catastrophic commands like `rm -rf /` or `mkfs`.
18
- * **Server-Level Read-Only**: Lock specific servers to a non-destructive mode at the configuration level.
19
- * **Restricted File Deletion**: Hardcoded prevention of accidental deletion of system-critical paths like `/etc` or `/usr`.
20
-
21
- ### 🧠 AI-Native Design
22
- * **Semantic Infrastructure Discovery**: AI can list servers and understand their purposes via natural language descriptions.
23
- * **Working Directory Aliases**: Map complex paths to simple aliases like `app-root` with descriptive metadata.
24
- * **Contextual Pre-checks**: Built-in tools to verify dependencies (Docker, Git) before execution.
25
-
26
- ---
27
-
28
- ## 🚀 Quick Start
29
-
30
- ### Installation
31
-
32
- ```bash
33
- # Install globally via npm
34
- npm install -g @jadchene/mcp-ssh-service
35
-
36
- # Start the server with a config file
37
- mcp-ssh-service --config ./config.json
1
+ # SSH MCP Service
2
+
3
+ A production-ready, highly secure Model Context Protocol (MCP) server for remote server management. It features stateless connections, lazy loading, and a mandatory two-step confirmation flow for high-risk operations.
4
+
5
+ ## Core Features
6
+
7
+ - **Stateless & Lazy Loading**: Connections are only established when a tool is called and closed immediately after execution. No persistent SSH tunnels.
8
+ - **Security First**:
9
+ - Mandatory manual confirmation for all "Write Actions" (e.g., `rm`, `restart`, `docker_stop`).
10
+ - Command blacklist (prevents `rm -rf /`, etc.).
11
+ - Restricted directory protection for safe deletions.
12
+ - **Context Aware**: Supports directory aliases and path mapping via `list_working_directories`.
13
+ - **Workflow Automation**: `execute_batch` allows running multiple commands in a single session with state (like `cd`) preserved between steps.
14
+
15
+ ## Tool List (45 Total)
16
+
17
+ ### 🛠️ Discovery & Core (8)
18
+ - `list_servers`: List all configured SSH servers.
19
+ - `ping_server`: Test connectivity to a specific server.
20
+ - `list_working_directories`: View path mappings/aliases.
21
+ - `check_dependencies`: Verify if required binaries (git, docker, etc.) are installed.
22
+ - `get_system_info`: Get CPU, memory, and kernel details.
23
+ - `pwd`: Show current remote path.
24
+ - `cd`: Change directory (effective within `execute_batch`).
25
+ - `execute_batch`: Run a sequence of tools in one session.
26
+
27
+ ### 💻 Shell & Basic (2)
28
+ - `execute_command` (*): Run any arbitrary shell command.
29
+ - `echo`: Print text or variables.
30
+
31
+ ### 📂 File Management (5)
32
+ - `upload_file` (*): Transfer file from local to remote.
33
+ - `download_file`: Transfer file from remote to local.
34
+ - `ll`: Detailed directory listing.
35
+ - `cat`: Read file content.
36
+ - `edit_text_file` (*): Replace file content (Safe Base64 transfer).
37
+ - `touch`: Create empty file or update timestamp.
38
+ - `find`: Search for files in a directory hierarchy.
39
+
40
+ ### 🐳 Docker & Compose (18)
41
+ - `docker_compose_up` (*), `docker_compose_down` (*), `docker_compose_stop` (*), `docker_compose_restart` (*)
42
+ - `docker_compose_logs`: View compose logs.
43
+ - `docker_ps`, `docker_images`
44
+ - `docker_pull` (*), `docker_cp` (*), `docker_stop` (*), `docker_rm` (*), `docker_start` (*), `docker_rmi` (*), `docker_commit` (*)
45
+ - `docker_logs`: Get container logs.
46
+ - `docker_load` (*), `docker_save` (*)
47
+
48
+ ### ⚙️ System Services (4)
49
+ - `systemctl_status`
50
+ - `systemctl_start` (*), `systemctl_stop` (*), `systemctl_restart` (*)
51
+
52
+ ### 🌐 Network & Stats (8)
53
+ - `ip_addr`: Show network interfaces.
54
+ - `firewall_cmd` (*): Manage firewall rules.
55
+ - `netstat`: Monitor ports and connections.
56
+ - `nvidia_smi`: GPU status.
57
+ - `ps`: Process snapshot.
58
+ - `df_h`: Disk usage.
59
+ - `du_sh`: Directory size estimation.
60
+
61
+ > (*) Requires manual confirmation.
62
+
63
+ ## Confirmation Protocol
64
+
65
+ For any tool marked with `(*)`, the service follows a two-step flow:
66
+ 1. **Request**: Call the tool with parameters. The server returns a `confirmationId` and `status: "pending"`.
67
+ 2. **Confirm**: Call the **same tool again** with `confirmExecution: true` and the provided `confirmationId`.
68
+
69
+ ## Configuration
70
+
71
+ External configuration `config.json` allows defining multiple servers and their working directory aliases:
72
+
73
+ ```json
74
+ {
75
+ "servers": {
76
+ "prod-web": {
77
+ "host": "192.168.1.100",
78
+ "user": "root",
79
+ "keyPath": "~/.ssh/id_rsa",
80
+ "workingDirectories": {
81
+ "app": { "path": "/var/www/html", "desc": "Web Root" },
82
+ "logs": { "path": "/var/log/nginx", "desc": "Nginx Logs" }
83
+ }
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ ## Installation
90
+
91
+ ```bash
92
+ npm install
93
+ npm run build
94
+ node dist/index.js
38
95
  ```
39
-
40
- ### Source Setup
41
-
42
- ```bash
43
- git clone https://github.com/jadchene/mcp-ssh.git
44
- cd mcp-ssh
45
- npm install
46
- npm run build
47
- node dist/index.js --config ./config.json
48
- ```
49
-
50
- ---
51
-
52
- ## ⚙️ Configuration Schema
53
-
54
- ### Global Settings
55
- | Parameter | Type | Description |
56
- | --- | --- | --- |
57
- | `logDir` | string | Directory for logs. Supports env vars like `${HOME}`. |
58
- | `commandBlacklist` | string[] | Prohibited command regex patterns (e.g., `["^rm -rf"]`). |
59
- | `defaultTimeout` | number | Command timeout in milliseconds (default: 60000). |
60
- | `servers` | object | Dictionary of server configs where key is the `serverAlias`. |
61
-
62
- ### Server Object
63
- | Parameter | Type | Description |
64
- | --- | --- | --- |
65
- | `host` | string | Remote IP or hostname. Supports env vars. |
66
- | `port` | number | SSH port (default: 22). |
67
- | `username` | string | SSH login user. |
68
- | `password` | string | SSH password. Use `${VAR}` for security. |
69
- | `privateKeyPath` | string | Path to private key file. |
70
- | `passphrase` | string | Passphrase for the private key. |
71
- | `readOnly` | boolean | Disables all write/modify tools for this server. |
72
- | `desc` | string | Server description shown in `list_servers`. |
73
- | `strictHostKeyChecking` | boolean | Set to `false` to bypass host key verification. |
74
- | `workingDirectories` | object | Semantic path mappings (Key: { path, desc }). |
75
- | `proxyJump` | object | Optional jump host (recursive server config). |
76
-
77
- ---
78
-
79
- ## ⚙️ Configuration Example
80
-
81
- ```json
82
- {
83
- "logDir": "./logs",
84
- "defaultTimeout": 60000,
85
- "commandBlacklist": ["^apt-get upgrade", "curl.*\\|.*sh"],
86
- "servers": {
87
- "prod-web": {
88
- "desc": "Primary API Cluster",
89
- "host": "10.0.0.5",
90
- "username": "deploy",
91
- "privateKeyPath": "~/.ssh/id_rsa",
92
- "passphrase": "${SSH_KEY_PWD}",
93
- "workingDirectories": {
94
- "logs": { "path": "/var/log/nginx", "desc": "Nginx access logs" }
95
- },
96
- "proxyJump": {
97
- "host": "bastion.example.com",
98
- "username": "jumpuser"
99
- }
100
- }
101
- }
102
- }
103
- ```
104
-
105
- ---
106
-
107
- ## 🛠️ Integrated Toolset (45 Tools)
108
-
109
- ### 📂 Discovery & Context
110
- * `list_servers`: Discovery available hosts.
111
- * `ping_server`: Test SSH connection & credentials.
112
- * `list_working_directories`: Get semantic path mappings.
113
- * `get_system_info`: CPU, Memory, and System Uptime.
114
- * `check_dependencies`: Verify remote binaries.
115
-
116
- ### 💻 Shell & Files
117
- * `execute_command`*, `execute_batch`*: Run single or sequenced shell commands.
118
- * `ll`, `cat`, `tail`, `grep`, `pwd`, `cd`: Browse and search remote files.
119
- * `upload_file`*, `download_file`: Transfer data.
120
- * `mkdir`*, `mv`*, `cp`*, `chmod`*, `rm_safe`*, `touch`*: File system management.
121
-
122
- ### 🐳 DevOps & Services
123
- * `docker_ps`, `docker_logs`, `docker_compose_up`*, `docker_compose_restart`*: Container orchestration.
124
- * `systemctl_status`, `systemctl_restart`*: System service control.
125
- * `git_status`, `git_pull`*: Version control.
126
- * `ip_addr`, `ping`, `netstat`, `df_h`, `nvidia_smi`: Diagnostics.
127
-
128
- *\* High-risk: Requires `confirmationId` and `confirmExecution: true`.*
129
-
130
- ---
131
-
132
- ## 🔐 The Confirmation Workflow
133
-
134
- 1. **Request**: AI calls `rm_safe({ path: '/tmp/old' })`.
135
- 2. **Intercept**: Server returns `status: "pending"` with a `confirmationId`.
136
- 3. **Human Input**: You review the action in your chat client and approve.
137
- 4. **Execution**: AI calls `rm_safe` again with the `confirmationId` and `confirmExecution: true`.
138
- 5. **Verify**: Server ensures parameters match exactly and executes the SSH command.
139
-
140
- ---
141
-
142
- ## 📄 License
143
- Released under the [MIT License](./LICENSE).
@@ -15,7 +15,7 @@ const confirmationParams = {
15
15
  const grepParam = { grep: { type: 'string', description: 'Filter output using regex pattern.' } };
16
16
  const cwdParam = { cwd: { type: 'string', description: 'Execution directory (supports aliases from list_working_directories).' } };
17
17
  export const toolDefinitions = [
18
- // --- Discovery ---
18
+ // --- Discovery (Core) ---
19
19
  {
20
20
  name: 'list_servers',
21
21
  description: 'Discovery tool: List all configured SSH servers, their hosts, and descriptions.',
@@ -36,7 +36,7 @@ export const toolDefinitions = [
36
36
  description: 'Environmental pre-check: Verifies if specific binaries exist on the remote server.',
37
37
  inputSchema: baseParams({ commands: { type: 'array', items: { type: 'string' } } }, ['commands'])
38
38
  },
39
- // --- System ---
39
+ // --- System (Core) ---
40
40
  {
41
41
  name: 'get_system_info',
42
42
  description: 'System health check: Returns current user, system uptime, kernel, and memory.',
@@ -52,7 +52,7 @@ export const toolDefinitions = [
52
52
  description: 'Directory navigation: Changes the working directory (effective within batch).',
53
53
  inputSchema: baseParams({ path: { type: 'string' } }, ['path'])
54
54
  },
55
- // --- Batch ---
55
+ // --- Batch (Core) ---
56
56
  {
57
57
  name: 'execute_batch',
58
58
  description: 'Workflow automation: Executes a sequence of multiple tools in a single persistent SSH session. REQUIRES CONFIRMATION if any sub-tool is high-risk.',
@@ -72,7 +72,7 @@ export const toolDefinitions = [
72
72
  ...confirmationParams
73
73
  }, ['commands'])
74
74
  },
75
- // --- Shell ---
75
+ // --- Shell & Basic (Requirements) ---
76
76
  {
77
77
  name: 'execute_command',
78
78
  description: 'Arbitrary execution: Runs any shell command via SSH. REQUIRES CONFIRMATION.',
@@ -82,7 +82,12 @@ export const toolDefinitions = [
82
82
  ...confirmationParams
83
83
  }, ['command'])
84
84
  },
85
- // --- Files ---
85
+ {
86
+ name: 'echo',
87
+ description: 'Print text or variables.',
88
+ inputSchema: baseParams({ text: { type: 'string' } }, ['text'])
89
+ },
90
+ // --- Files (Requirements) ---
86
91
  {
87
92
  name: 'upload_file',
88
93
  description: 'File transfer (Local -> Remote). REQUIRES CONFIRMATION.',
@@ -110,11 +115,6 @@ export const toolDefinitions = [
110
115
  description: 'File reading: Reads text file content.',
111
116
  inputSchema: baseParams({ filePath: { type: 'string' }, ...grepParam }, ['filePath'])
112
117
  },
113
- {
114
- name: 'tail',
115
- description: 'Log inspection: Reads last N lines of a file.',
116
- inputSchema: baseParams({ filePath: { type: 'string' }, lines: { type: 'number' }, ...grepParam }, ['filePath'])
117
- },
118
118
  {
119
119
  name: 'edit_text_file',
120
120
  description: 'File creation/overwrite: Completely replaces file content. REQUIRES CONFIRMATION.',
@@ -124,67 +124,17 @@ export const toolDefinitions = [
124
124
  ...confirmationParams
125
125
  }, ['filePath', 'content'])
126
126
  },
127
- {
128
- name: 'append_text_file',
129
- description: 'File appending: Adds text to end of file. REQUIRES CONFIRMATION.',
130
- inputSchema: baseParams({
131
- filePath: { type: 'string' },
132
- content: { type: 'string' },
133
- ...confirmationParams
134
- }, ['filePath', 'content'])
135
- },
136
- {
137
- name: 'mkdir',
138
- description: 'Directory creation: Creates a directory (mkdir -p). REQUIRES CONFIRMATION.',
139
- inputSchema: baseParams({ path: { type: 'string' }, ...confirmationParams }, ['path'])
140
- },
141
- {
142
- name: 'chmod',
143
- description: 'Permission management: Changes file or directory permissions. REQUIRES CONFIRMATION.',
144
- inputSchema: baseParams({ mode: { type: 'string' }, path: { type: 'string' }, ...confirmationParams }, ['mode', 'path'])
145
- },
146
- {
147
- name: 'mv',
148
- description: 'File movement/rename: Moves or renames files or directories. REQUIRES CONFIRMATION.',
149
- inputSchema: baseParams({ source: { type: 'string' }, destination: { type: 'string' }, ...confirmationParams }, ['source', 'destination'])
150
- },
151
- {
152
- name: 'cp',
153
- description: 'File copy: Copies files or directories. REQUIRES CONFIRMATION.',
154
- inputSchema: baseParams({
155
- source: { type: 'string' },
156
- destination: { type: 'string' },
157
- recursive: { type: 'boolean' },
158
- ...confirmationParams
159
- }, ['source', 'destination'])
160
- },
161
- {
162
- name: 'rm_safe',
163
- description: 'File deletion: Removes file or directory. REQUIRES CONFIRMATION.',
164
- inputSchema: baseParams({ path: { type: 'string' }, recursive: { type: 'boolean' }, ...confirmationParams }, ['path'])
165
- },
166
127
  {
167
128
  name: 'touch',
168
- description: 'Timestamp/File creation: Updates access time or creates empty file. REQUIRES CONFIRMATION.',
169
- inputSchema: baseParams({ filePath: { type: 'string' }, ...confirmationParams }, ['filePath'])
129
+ description: 'Timestamp/File creation: Updates access time or creates empty file.',
130
+ inputSchema: baseParams({ filePath: { type: 'string' } }, ['filePath'])
170
131
  },
171
- // --- Git ---
172
132
  {
173
- name: 'git_status',
174
- description: 'Git status: Displays repository status.',
175
- inputSchema: baseParams(cwdParam)
133
+ name: 'find',
134
+ description: 'Search for files in a directory hierarchy.',
135
+ inputSchema: baseParams({ path: { type: 'string' }, name: { type: 'string' }, ...grepParam }, ['path'])
176
136
  },
177
- {
178
- name: 'git_pull',
179
- description: 'Git update: Pulls latest changes. REQUIRES CONFIRMATION.',
180
- inputSchema: baseParams({ ...cwdParam, ...confirmationParams })
181
- },
182
- {
183
- name: 'git_log',
184
- description: 'Git history: Shows commit logs.',
185
- inputSchema: baseParams({ ...cwdParam, count: { type: 'number' } })
186
- },
187
- // --- Docker ---
137
+ // --- Docker & Compose (Requirements) ---
188
138
  {
189
139
  name: 'docker_compose_up',
190
140
  description: 'Deploy docker stack. REQUIRES CONFIRMATION.',
@@ -195,6 +145,11 @@ export const toolDefinitions = [
195
145
  description: 'Remove docker stack. REQUIRES CONFIRMATION.',
196
146
  inputSchema: baseParams({ ...cwdParam, ...confirmationParams }, ['cwd'])
197
147
  },
148
+ {
149
+ name: 'docker_compose_stop',
150
+ description: 'Stop docker stack. REQUIRES CONFIRMATION.',
151
+ inputSchema: baseParams({ ...cwdParam, ...confirmationParams }, ['cwd'])
152
+ },
198
153
  {
199
154
  name: 'docker_compose_logs',
200
155
  description: 'View compose logs.',
@@ -210,12 +165,62 @@ export const toolDefinitions = [
210
165
  description: 'List docker containers.',
211
166
  inputSchema: baseParams(grepParam)
212
167
  },
168
+ {
169
+ name: 'docker_images',
170
+ description: 'List docker images.',
171
+ inputSchema: baseParams(grepParam)
172
+ },
173
+ {
174
+ name: 'docker_pull',
175
+ description: 'Pull an image from a registry. REQUIRES CONFIRMATION.',
176
+ inputSchema: baseParams({ image: { type: 'string' }, ...confirmationParams }, ['image'])
177
+ },
178
+ {
179
+ name: 'docker_cp',
180
+ description: 'Copy files/folders between a container and the local filesystem. REQUIRES CONFIRMATION.',
181
+ inputSchema: baseParams({ source: { type: 'string' }, destination: { type: 'string' }, ...confirmationParams }, ['source', 'destination'])
182
+ },
183
+ {
184
+ name: 'docker_stop',
185
+ description: 'Stop one or more running containers. REQUIRES CONFIRMATION.',
186
+ inputSchema: baseParams({ container: { type: 'string' }, ...confirmationParams }, ['container'])
187
+ },
188
+ {
189
+ name: 'docker_rm',
190
+ description: 'Remove one or more containers. REQUIRES CONFIRMATION.',
191
+ inputSchema: baseParams({ container: { type: 'string' }, ...confirmationParams }, ['container'])
192
+ },
193
+ {
194
+ name: 'docker_start',
195
+ description: 'Start one or more stopped containers. REQUIRES CONFIRMATION.',
196
+ inputSchema: baseParams({ container: { type: 'string' }, ...confirmationParams }, ['container'])
197
+ },
198
+ {
199
+ name: 'docker_rmi',
200
+ description: 'Remove one or more images. REQUIRES CONFIRMATION.',
201
+ inputSchema: baseParams({ image: { type: 'string' }, ...confirmationParams }, ['image'])
202
+ },
203
+ {
204
+ name: 'docker_commit',
205
+ description: 'Create a new image from a container\'s changes. REQUIRES CONFIRMATION.',
206
+ inputSchema: baseParams({ container: { type: 'string' }, repository: { type: 'string' }, ...confirmationParams }, ['container', 'repository'])
207
+ },
213
208
  {
214
209
  name: 'docker_logs',
215
210
  description: 'Get container logs.',
216
211
  inputSchema: baseParams({ container: { type: 'string' }, lines: { type: 'number' }, ...grepParam }, ['container'])
217
212
  },
218
- // --- Service & Network ---
213
+ {
214
+ name: 'docker_load',
215
+ description: 'Load an image from a tar archive or STDIN. REQUIRES CONFIRMATION.',
216
+ inputSchema: baseParams({ path: { type: 'string' }, ...confirmationParams }, ['path'])
217
+ },
218
+ {
219
+ name: 'docker_save',
220
+ description: 'Save one or more images to a tar archive. REQUIRES CONFIRMATION.',
221
+ inputSchema: baseParams({ image: { type: 'string' }, path: { type: 'string' }, ...confirmationParams }, ['image', 'path'])
222
+ },
223
+ // --- Service & Network (Requirements) ---
219
224
  {
220
225
  name: 'systemctl_status',
221
226
  description: 'Check systemd service status.',
@@ -226,22 +231,42 @@ export const toolDefinitions = [
226
231
  description: 'Restart system service. REQUIRES CONFIRMATION.',
227
232
  inputSchema: baseParams({ service: { type: 'string' }, ...confirmationParams }, ['service'])
228
233
  },
234
+ {
235
+ name: 'systemctl_start',
236
+ description: 'Start system service. REQUIRES CONFIRMATION.',
237
+ inputSchema: baseParams({ service: { type: 'string' }, ...confirmationParams }, ['service'])
238
+ },
239
+ {
240
+ name: 'systemctl_stop',
241
+ description: 'Stop system service. REQUIRES CONFIRMATION.',
242
+ inputSchema: baseParams({ service: { type: 'string' }, ...confirmationParams }, ['service'])
243
+ },
229
244
  {
230
245
  name: 'ip_addr',
231
246
  description: 'Show network interface info.',
232
247
  inputSchema: baseParams(grepParam)
233
248
  },
234
249
  {
235
- name: 'ping',
236
- description: 'Verify host accessibility.',
237
- inputSchema: baseParams({ host: { type: 'string' }, count: { type: 'number' } }, ['host'])
250
+ name: 'firewall_cmd',
251
+ description: 'Control the runtime/permanent firewall. REQUIRES CONFIRMATION.',
252
+ inputSchema: baseParams({ args: { type: 'string' }, ...confirmationParams }, ['args'])
238
253
  },
239
254
  {
240
255
  name: 'netstat',
241
256
  description: 'Monitor ports/connections.',
242
257
  inputSchema: baseParams({ args: { type: 'string' }, ...grepParam })
243
258
  },
244
- // --- Stats ---
259
+ // --- Stats & Process (Requirements) ---
260
+ {
261
+ name: 'nvidia_smi',
262
+ description: 'GPU utilization status.',
263
+ inputSchema: baseParams()
264
+ },
265
+ {
266
+ name: 'ps',
267
+ description: 'Report a snapshot of the current processes.',
268
+ inputSchema: baseParams(grepParam)
269
+ },
245
270
  {
246
271
  name: 'df_h',
247
272
  description: 'System disk usage.',
@@ -251,10 +276,5 @@ export const toolDefinitions = [
251
276
  name: 'du_sh',
252
277
  description: 'Directory size estimation.',
253
278
  inputSchema: baseParams({ path: { type: 'string' }, ...grepParam }, ['path'])
254
- },
255
- {
256
- name: 'nvidia_smi',
257
- description: 'GPU utilization status.',
258
- inputSchema: baseParams()
259
279
  }
260
280
  ];
@@ -4,18 +4,23 @@ const WRITE_TOOLS = [
4
4
  'execute_command',
5
5
  'upload_file',
6
6
  'edit_text_file',
7
- 'append_text_file',
8
- 'mkdir',
9
- 'chmod',
10
- 'mv',
11
- 'cp',
12
- 'rm_safe',
13
- 'touch',
14
- 'git_pull',
15
7
  'docker_compose_up',
16
8
  'docker_compose_down',
9
+ 'docker_compose_stop',
17
10
  'docker_compose_restart',
18
- 'systemctl_restart'
11
+ 'docker_pull',
12
+ 'docker_cp',
13
+ 'docker_stop',
14
+ 'docker_rm',
15
+ 'docker_start',
16
+ 'docker_rmi',
17
+ 'docker_commit',
18
+ 'docker_load',
19
+ 'docker_save',
20
+ 'systemctl_restart',
21
+ 'systemctl_start',
22
+ 'systemctl_stop',
23
+ 'firewall_cmd'
19
24
  ];
20
25
  const DEFAULT_BLACKLIST = [
21
26
  /rm\s+-(rf|fr|r|f)\s+\//i,
@@ -63,41 +68,41 @@ export class ToolHandlers {
63
68
  case 'cd': return `cd ${params.path}`;
64
69
  case 'll': return 'ls -l';
65
70
  case 'cat': return `cat ${params.filePath}`;
66
- case 'tail': return `tail -n ${params.lines || 50} ${params.filePath}`;
67
- case 'mkdir': return `mkdir -p ${params.path}`;
68
- case 'chmod': return `chmod ${params.mode} ${params.path}`;
69
- case 'mv': return `mv -f ${params.source} ${params.destination}`;
70
- case 'cp': return `cp -f ${params.recursive ? '-r' : ''} ${params.source} ${params.destination}`;
71
- case 'rm_safe':
72
- const restricted = ['/', '/etc', '/usr', '/bin', '/var', '/root', '/home'];
73
- if (restricted.includes(params.path.trim()))
74
- throw new Error(`RM_SAFE: Denied for restricted directory.`);
75
- return `rm ${params.recursive ? '-rf' : '-f'} ${params.path}`;
76
- case 'touch': return `touch ${params.filePath}`;
77
- case 'append_text_file':
78
- const appB64 = Buffer.from(params.content).toString('base64');
79
- return `echo "${appB64}" | base64 -d >> ${params.filePath}`;
80
71
  case 'edit_text_file':
81
72
  const edB64 = Buffer.from(params.content).toString('base64');
82
73
  return `echo "${edB64}" | base64 -d > ${params.filePath}`;
83
- case 'git_status': return 'git status';
84
- case 'git_pull': return 'git pull --no-edit';
85
- case 'git_log': return `git log -n ${params.count || 10} --oneline`;
74
+ case 'touch': return `touch ${params.filePath}`;
75
+ case 'echo': return `echo "${params.text}"`;
76
+ case 'find': return `find ${params.path} -name "${params.name}"`;
86
77
  case 'execute_command': return params.command;
87
78
  case 'docker_compose_up': return 'docker-compose up -d';
88
79
  case 'docker_compose_down': return 'docker-compose down --remove-orphans';
80
+ case 'docker_compose_stop': return 'docker-compose stop';
89
81
  case 'docker_compose_logs': return `docker-compose logs -n ${params.lines || 100}`;
90
82
  case 'docker_compose_restart': return 'docker-compose restart';
91
83
  case 'docker_ps': return 'docker ps';
84
+ case 'docker_images': return 'docker images';
85
+ case 'docker_pull': return `docker pull ${params.image}`;
86
+ case 'docker_cp': return `docker cp ${params.source} ${params.destination}`;
87
+ case 'docker_stop': return `docker stop ${params.container}`;
88
+ case 'docker_rm': return `docker rm ${params.container}`;
89
+ case 'docker_start': return `docker start ${params.container}`;
90
+ case 'docker_rmi': return `docker rmi ${params.image}`;
91
+ case 'docker_commit': return `docker commit ${params.container} ${params.repository}`;
92
92
  case 'docker_logs': return `docker logs -n ${params.lines || 100} ${params.container}`;
93
+ case 'docker_load': return `docker load -i ${params.path}`;
94
+ case 'docker_save': return `docker save -o ${params.path} ${params.image}`;
93
95
  case 'systemctl_status': return `systemctl status ${params.service}`;
94
96
  case 'systemctl_restart': return `systemctl restart ${params.service}`;
97
+ case 'systemctl_start': return `systemctl start ${params.service}`;
98
+ case 'systemctl_stop': return `systemctl stop ${params.service}`;
95
99
  case 'ip_addr': return 'ip addr';
96
- case 'ping': return `ping -c ${params.count || 4} ${params.host}`;
100
+ case 'firewall_cmd': return `firewall-cmd ${params.args}`;
97
101
  case 'netstat': return `netstat ${params.args || '-tuln'}`;
98
102
  case 'df_h': return 'df -h';
99
103
  case 'du_sh': return `du -sh ${params.path}`;
100
104
  case 'nvidia_smi': return 'nvidia-smi';
105
+ case 'ps': return 'ps aux';
101
106
  default: return '';
102
107
  }
103
108
  }
package/package.json CHANGED
@@ -1,49 +1,49 @@
1
- {
2
- "name": "@jadchene/mcp-ssh-service",
3
- "version": "1.0.0",
4
- "description": "A production-ready, highly secure SSH MCP server featuring stateless connections, two-step operation confirmation, and comprehensive DevOps tool integration.",
5
- "main": "dist/index.js",
6
- "type": "module",
7
- "bin": {
8
- "mcp-ssh-service": "dist/index.js"
9
- },
10
- "files": [
11
- "dist"
12
- ],
13
- "scripts": {
14
- "build": "tsc",
15
- "prepare": "npm run build",
16
- "watch": "tsc -w",
17
- "prepublishOnly": "npm run build",
18
- "start": "node dist/index.js"
19
- },
20
- "keywords": [
21
- "mcp",
22
- "ssh",
23
- "model context protocol",
24
- "automation",
25
- "stateless"
26
- ],
27
- "author": "jadchene",
28
- "license": "MIT",
29
- "repository": {
30
- "type": "git",
31
- "url": "https://github.com/jadchene/mcp-ssh.git"
32
- },
33
- "bugs": {
34
- "url": "https://github.com/jadchene/mcp-ssh/issues"
35
- },
36
- "publishConfig": {
37
- "access": "public"
38
- },
39
- "dependencies": {
40
- "@modelcontextprotocol/sdk": "^1.0.1",
41
- "ssh2": "^1.15.0",
42
- "winston": "^3.11.0"
43
- },
44
- "devDependencies": {
45
- "@types/node": "^20.10.0",
46
- "@types/ssh2": "^1.11.19",
47
- "typescript": "^5.3.3"
48
- }
49
- }
1
+ {
2
+ "name": "@jadchene/mcp-ssh-service",
3
+ "version": "1.1.1",
4
+ "description": "A production-ready, highly secure SSH MCP server featuring stateless connections, two-step operation confirmation, and comprehensive DevOps tool integration.",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "mcp-ssh-service": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "prepare": "npm run build",
16
+ "watch": "tsc -w",
17
+ "prepublishOnly": "npm run build",
18
+ "start": "node dist/index.js"
19
+ },
20
+ "keywords": [
21
+ "mcp",
22
+ "ssh",
23
+ "model context protocol",
24
+ "automation",
25
+ "stateless"
26
+ ],
27
+ "author": "jadchene",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/jadchene/mcp-ssh.git"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/jadchene/mcp-ssh/issues"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.0.1",
41
+ "ssh2": "^1.15.0",
42
+ "winston": "^3.11.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^20.10.0",
46
+ "@types/ssh2": "^1.11.19",
47
+ "typescript": "^5.3.3"
48
+ }
49
+ }