@jadchene/mcp-ssh-service 1.4.0 → 1.4.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
@@ -193,12 +193,14 @@ args = ["--config", "./config.json"]
193
193
  * `execute_command` [Auth Required, single command only]
194
194
  * `echo`
195
195
 
196
- ### File Management (15)
196
+ ### File Management (17)
197
197
  * `upload_file` [Auth Required]
198
198
  * `download_file`
199
199
  * `ll`
200
200
  * `cat`
201
+ * `head`
201
202
  * `tail`
203
+ * `sed`
202
204
  * `grep`
203
205
  * `edit_text_file` [Auth Required]
204
206
  * `touch`
@@ -272,7 +274,7 @@ args = ["--config", "./config.json"]
272
274
  * `zip` [Auth Required]
273
275
  * `unzip` [Auth Required]
274
276
 
275
- Total: 79 tools.
277
+ Total: 81 tools.
276
278
 
277
279
  ---
278
280
 
@@ -115,11 +115,26 @@ export const toolDefinitions = [
115
115
  description: 'File reading: Reads text file content.',
116
116
  inputSchema: baseParams({ filePath: { type: 'string' }, ...grepParam }, ['filePath'])
117
117
  },
118
+ {
119
+ name: 'head',
120
+ description: 'File preview: Reads the first N lines of a file.',
121
+ inputSchema: baseParams({ filePath: { type: 'string' }, lines: { type: 'number' }, ...grepParam }, ['filePath'])
122
+ },
118
123
  {
119
124
  name: 'tail',
120
125
  description: 'Log inspection: Reads last N lines of a file.',
121
126
  inputSchema: baseParams({ filePath: { type: 'string' }, lines: { type: 'number' }, ...grepParam }, ['filePath'])
122
127
  },
128
+ {
129
+ name: 'sed',
130
+ description: 'Line range reading: Reads an inclusive line range from a text file.',
131
+ inputSchema: baseParams({
132
+ filePath: { type: 'string' },
133
+ startLine: { type: 'number' },
134
+ endLine: { type: 'number' },
135
+ ...grepParam
136
+ }, ['filePath', 'startLine', 'endLine'])
137
+ },
123
138
  {
124
139
  name: 'grep',
125
140
  description: 'Pattern search: Search for a regex pattern in a file.',
@@ -117,6 +117,14 @@ export class ToolHandlers {
117
117
  this.validateShellToken(value, `${fieldName}[${index}]`);
118
118
  }
119
119
  }
120
+ /**
121
+ * Validate positive line counts for text inspection helpers.
122
+ */
123
+ validatePositiveInteger(value, fieldName) {
124
+ if (!Number.isInteger(value) || value <= 0) {
125
+ throw new Error(`${fieldName} must be a positive integer.`);
126
+ }
127
+ }
120
128
  escapePerlEnvBase64(value) {
121
129
  return Buffer.from(value).toString('base64');
122
130
  }
@@ -212,6 +220,16 @@ export class ToolHandlers {
212
220
  if ((name === 'netstat' || name === 'ss') && Array.isArray(params.args)) {
213
221
  this.validateTokenArray(params.args, `${name}.args`);
214
222
  }
223
+ if ((name === 'head' || name === 'tail') && params.lines !== undefined) {
224
+ this.validatePositiveInteger(params.lines, `${name}.lines`);
225
+ }
226
+ if (name === 'sed') {
227
+ this.validatePositiveInteger(params.startLine, 'sed.startLine');
228
+ this.validatePositiveInteger(params.endLine, 'sed.endLine');
229
+ if (params.endLine < params.startLine) {
230
+ throw new Error(`sed.endLine must be greater than or equal to sed.startLine.`);
231
+ }
232
+ }
215
233
  if (name === 'docker_exec' && Array.isArray(params.args)) {
216
234
  for (const [index, arg] of params.args.entries()) {
217
235
  this.validateShellFragment(arg, `docker_exec.args[${index}]`);
@@ -241,7 +259,9 @@ export class ToolHandlers {
241
259
  case 'cd': return `cd ${this.shellEscape(params.path)}`;
242
260
  case 'll': return 'ls -l';
243
261
  case 'cat': return `cat ${this.shellEscape(params.filePath)}`;
262
+ case 'head': return `head -n ${params.lines || 40} ${this.shellEscape(params.filePath)}`;
244
263
  case 'tail': return `tail -n ${params.lines || 50} ${this.shellEscape(params.filePath)}`;
264
+ case 'sed': return `sed -n '${params.startLine},${params.endLine}p' ${this.shellEscape(params.filePath)}`;
245
265
  case 'grep': return `grep ${params.ignoreCase ? '-inE' : '-nE'} ${this.shellEscape(params.pattern)} ${this.shellEscape(params.filePath)}`;
246
266
  case 'edit_text_file':
247
267
  const edB64 = Buffer.from(params.content).toString('base64');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jadchene/mcp-ssh-service",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "A production-ready, highly secure SSH MCP server featuring stateless connections, two-step operation confirmation, and comprehensive DevOps tool integration.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",