ssh-mcp-devops 2.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/index-v2.js ADDED
@@ -0,0 +1,427 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import {
5
+ CallToolRequestSchema,
6
+ ListToolsRequestSchema,
7
+ } from '@modelcontextprotocol/sdk/types.js';
8
+ import { SSHManager } from './ssh-manager-v2.js';
9
+ import { DockerManager } from './docker-manager.js';
10
+ import { SystemMonitor } from './system-monitor.js';
11
+ import { AuditLogger } from './audit-logger.js';
12
+ import { SecurityChecker } from './security-checker.js';
13
+
14
+ const server = new Server(
15
+ {
16
+ name: 'ssh-mcp-server',
17
+ version: '2.0.0',
18
+ },
19
+ {
20
+ capabilities: {
21
+ tools: {},
22
+ },
23
+ }
24
+ );
25
+
26
+ const sshManager = new SSHManager();
27
+ const dockerManager = new DockerManager(sshManager);
28
+ const systemMonitor = new SystemMonitor(sshManager);
29
+ const auditLogger = new AuditLogger();
30
+ const securityChecker = new SecurityChecker();
31
+
32
+ // 从环境变量读取SSH配置并自动连接
33
+ const sshConfig = {
34
+ host: process.env.SSH_HOST,
35
+ port: parseInt(process.env.SSH_PORT || '22'),
36
+ username: process.env.SSH_USERNAME,
37
+ password: process.env.SSH_PASSWORD,
38
+ privateKeyPath: process.env.SSH_PRIVATE_KEY_PATH,
39
+ };
40
+
41
+ // 如果配置了SSH信息,启动时自动连接
42
+ if (sshConfig.host && sshConfig.username) {
43
+ sshManager.autoConnect(sshConfig).catch(err => {
44
+ console.error('自动连接失败:', err.message);
45
+ });
46
+ }
47
+
48
+ // 工具列表
49
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
50
+ return {
51
+ tools: [
52
+ // SSH 基础工具
53
+ {
54
+ name: 'ssh_connect',
55
+ description: '连接到远程SSH服务器',
56
+ inputSchema: {
57
+ type: 'object',
58
+ properties: {
59
+ host: { type: 'string', description: 'SSH服务器地址' },
60
+ port: { type: 'number', description: 'SSH端口', default: 22 },
61
+ username: { type: 'string', description: '用户名' },
62
+ password: { type: 'string', description: '密码(可选)' },
63
+ privateKeyPath: { type: 'string', description: '私钥路径(可选)' },
64
+ },
65
+ required: ['host', 'username'],
66
+ },
67
+ },
68
+ {
69
+ name: 'ssh_exec',
70
+ description: '在远程服务器执行命令(危险命令需要确认)',
71
+ inputSchema: {
72
+ type: 'object',
73
+ properties: {
74
+ command: { type: 'string', description: '要执行的命令' },
75
+ confirm: { type: 'boolean', description: '确认执行危险操作', default: false },
76
+ timeout: { type: 'number', description: '超时时间(毫秒)', default: 300000 },
77
+ },
78
+ required: ['command'],
79
+ },
80
+ },
81
+ {
82
+ name: 'ssh_upload',
83
+ description: '上传文件到远程服务器',
84
+ inputSchema: {
85
+ type: 'object',
86
+ properties: {
87
+ localPath: { type: 'string', description: '本地文件路径' },
88
+ remotePath: { type: 'string', description: '远程目标路径' },
89
+ },
90
+ required: ['localPath', 'remotePath'],
91
+ },
92
+ },
93
+ {
94
+ name: 'ssh_download',
95
+ description: '从远程服务器下载文件',
96
+ inputSchema: {
97
+ type: 'object',
98
+ properties: {
99
+ remotePath: { type: 'string', description: '远程文件路径' },
100
+ localPath: { type: 'string', description: '本地保存路径' },
101
+ },
102
+ required: ['remotePath', 'localPath'],
103
+ },
104
+ },
105
+ {
106
+ name: 'ssh_deploy',
107
+ description: '自动部署项目(上传代码、安装依赖、重启服务)',
108
+ inputSchema: {
109
+ type: 'object',
110
+ properties: {
111
+ projectPath: { type: 'string', description: '本地项目路径' },
112
+ remotePath: { type: 'string', description: '远程部署路径' },
113
+ deployScript: { type: 'string', description: '部署脚本命令', default: 'npm install && npm run build && pm2 restart app' },
114
+ },
115
+ required: ['projectPath', 'remotePath'],
116
+ },
117
+ },
118
+
119
+ // Docker 管理工具
120
+ {
121
+ name: 'docker_list_containers',
122
+ description: '列出所有Docker容器',
123
+ inputSchema: {
124
+ type: 'object',
125
+ properties: {
126
+ all: { type: 'boolean', description: '是否显示所有容器(包括停止的)', default: true },
127
+ },
128
+ },
129
+ },
130
+ {
131
+ name: 'docker_list_images',
132
+ description: '列出所有Docker镜像',
133
+ inputSchema: { type: 'object', properties: {} },
134
+ },
135
+ {
136
+ name: 'docker_start',
137
+ description: '启动Docker容器',
138
+ inputSchema: {
139
+ type: 'object',
140
+ properties: {
141
+ container: { type: 'string', description: '容器名称或ID' },
142
+ },
143
+ required: ['container'],
144
+ },
145
+ },
146
+ {
147
+ name: 'docker_stop',
148
+ description: '停止Docker容器',
149
+ inputSchema: {
150
+ type: 'object',
151
+ properties: {
152
+ container: { type: 'string', description: '容器名称或ID' },
153
+ },
154
+ required: ['container'],
155
+ },
156
+ },
157
+ {
158
+ name: 'docker_restart',
159
+ description: '重启Docker容器',
160
+ inputSchema: {
161
+ type: 'object',
162
+ properties: {
163
+ container: { type: 'string', description: '容器名称或ID' },
164
+ },
165
+ required: ['container'],
166
+ },
167
+ },
168
+ {
169
+ name: 'docker_logs',
170
+ description: '查看Docker容器日志',
171
+ inputSchema: {
172
+ type: 'object',
173
+ properties: {
174
+ container: { type: 'string', description: '容器名称或ID' },
175
+ lines: { type: 'number', description: '显示行数', default: 100 },
176
+ },
177
+ required: ['container'],
178
+ },
179
+ },
180
+ {
181
+ name: 'docker_stats',
182
+ description: '查看Docker容器资源使用情况',
183
+ inputSchema: {
184
+ type: 'object',
185
+ properties: {
186
+ container: { type: 'string', description: '容器名称或ID' },
187
+ },
188
+ required: ['container'],
189
+ },
190
+ },
191
+ {
192
+ name: 'docker_exec',
193
+ description: '在Docker容器中执行命令',
194
+ inputSchema: {
195
+ type: 'object',
196
+ properties: {
197
+ container: { type: 'string', description: '容器名称或ID' },
198
+ command: { type: 'string', description: '要执行的命令' },
199
+ },
200
+ required: ['container', 'command'],
201
+ },
202
+ },
203
+
204
+ // 系统监控工具
205
+ {
206
+ name: 'system_health',
207
+ description: '获取系统健康状态(CPU、内存、磁盘、负载)',
208
+ inputSchema: { type: 'object', properties: {} },
209
+ },
210
+ {
211
+ name: 'system_info',
212
+ description: '获取系统详细信息',
213
+ inputSchema: { type: 'object', properties: {} },
214
+ },
215
+ {
216
+ name: 'system_processes',
217
+ description: '查看系统进程列表',
218
+ inputSchema: {
219
+ type: 'object',
220
+ properties: {
221
+ limit: { type: 'number', description: '显示进程数量', default: 10 },
222
+ },
223
+ },
224
+ },
225
+ {
226
+ name: 'system_logs',
227
+ description: '查看系统日志',
228
+ inputSchema: {
229
+ type: 'object',
230
+ properties: {
231
+ lines: { type: 'number', description: '显示行数', default: 50 },
232
+ },
233
+ },
234
+ },
235
+ {
236
+ name: 'system_ports',
237
+ description: '查看开放的端口',
238
+ inputSchema: { type: 'object', properties: {} },
239
+ },
240
+
241
+ // 审计日志
242
+ {
243
+ name: 'ssh_audit_log',
244
+ description: '查看操作审计日志',
245
+ inputSchema: {
246
+ type: 'object',
247
+ properties: {
248
+ limit: { type: 'number', description: '返回日志条数', default: 50 },
249
+ },
250
+ },
251
+ },
252
+ ],
253
+ };
254
+ });
255
+
256
+ // 工具调用处理
257
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
258
+ const { name, arguments: args } = request.params;
259
+
260
+ try {
261
+ switch (name) {
262
+ // SSH 基础操作
263
+ case 'ssh_connect': {
264
+ const result = await sshManager.connect(args);
265
+ auditLogger.log('ssh_connect', args.host, 'success');
266
+ return { content: [{ type: 'text', text: result }] };
267
+ }
268
+
269
+ case 'ssh_exec': {
270
+ const { command, confirm, timeout } = args;
271
+ const risk = securityChecker.checkCommand(command);
272
+
273
+ if (risk.isDangerous && !confirm) {
274
+ return {
275
+ content: [{
276
+ type: 'text',
277
+ text: `⚠️ 危险操作警告!\n命令: ${command}\n风险级别: ${risk.level}\n风险原因: ${risk.reason}\n\n请设置 confirm: true 来确认执行此操作。`
278
+ }],
279
+ isError: true,
280
+ };
281
+ }
282
+
283
+ const result = await sshManager.execCommand(command, { timeout });
284
+ auditLogger.log('ssh_exec', command, 'success', { risk: risk.level });
285
+ return { content: [{ type: 'text', text: result }] };
286
+ }
287
+
288
+ case 'ssh_upload': {
289
+ const { localPath, remotePath } = args;
290
+ const result = await sshManager.uploadFile(localPath, remotePath);
291
+ auditLogger.log('ssh_upload', `${localPath} -> ${remotePath}`, 'success');
292
+ return { content: [{ type: 'text', text: result }] };
293
+ }
294
+
295
+ case 'ssh_download': {
296
+ const { remotePath, localPath } = args;
297
+ const result = await sshManager.downloadFile(remotePath, localPath);
298
+ auditLogger.log('ssh_download', `${remotePath} -> ${localPath}`, 'success');
299
+ return { content: [{ type: 'text', text: result }] };
300
+ }
301
+
302
+ case 'ssh_deploy': {
303
+ const { projectPath, remotePath, deployScript } = args;
304
+ const result = await sshManager.deployProject(projectPath, remotePath, deployScript);
305
+ auditLogger.log('ssh_deploy', `${projectPath} -> ${remotePath}`, 'success');
306
+ return { content: [{ type: 'text', text: result }] };
307
+ }
308
+
309
+ // Docker 操作
310
+ case 'docker_list_containers': {
311
+ const containers = await dockerManager.listContainers(args.all !== false);
312
+ const formatted = containers.map(c =>
313
+ `${c.name} (${c.id.substring(0, 12)})\n 镜像: ${c.image}\n 状态: ${c.status}\n 端口: ${c.ports || '无'}`
314
+ ).join('\n\n');
315
+ auditLogger.log('docker_list_containers', 'list', 'success');
316
+ return { content: [{ type: 'text', text: formatted || '没有容器' }] };
317
+ }
318
+
319
+ case 'docker_list_images': {
320
+ const images = await dockerManager.listImages();
321
+ const formatted = images.map(i =>
322
+ `${i.name} (${i.id.substring(0, 12)}) - ${i.size}`
323
+ ).join('\n');
324
+ auditLogger.log('docker_list_images', 'list', 'success');
325
+ return { content: [{ type: 'text', text: formatted || '没有镜像' }] };
326
+ }
327
+
328
+ case 'docker_start': {
329
+ const result = await dockerManager.startContainer(args.container);
330
+ auditLogger.log('docker_start', args.container, 'success');
331
+ return { content: [{ type: 'text', text: result }] };
332
+ }
333
+
334
+ case 'docker_stop': {
335
+ const result = await dockerManager.stopContainer(args.container);
336
+ auditLogger.log('docker_stop', args.container, 'success');
337
+ return { content: [{ type: 'text', text: result }] };
338
+ }
339
+
340
+ case 'docker_restart': {
341
+ const result = await dockerManager.restartContainer(args.container);
342
+ auditLogger.log('docker_restart', args.container, 'success');
343
+ return { content: [{ type: 'text', text: result }] };
344
+ }
345
+
346
+ case 'docker_logs': {
347
+ const logs = await dockerManager.getContainerLogs(args.container, args.lines || 100);
348
+ auditLogger.log('docker_logs', args.container, 'success');
349
+ return { content: [{ type: 'text', text: logs }] };
350
+ }
351
+
352
+ case 'docker_stats': {
353
+ const stats = await dockerManager.getContainerStats(args.container);
354
+ const formatted = `容器: ${stats.container}\nCPU: ${stats.cpu}\n内存: ${stats.memory}\n网络: ${stats.network}\n磁盘IO: ${stats.blockIO}`;
355
+ auditLogger.log('docker_stats', args.container, 'success');
356
+ return { content: [{ type: 'text', text: formatted }] };
357
+ }
358
+
359
+ case 'docker_exec': {
360
+ const result = await dockerManager.execInContainer(args.container, args.command);
361
+ auditLogger.log('docker_exec', `${args.container}: ${args.command}`, 'success');
362
+ return { content: [{ type: 'text', text: result }] };
363
+ }
364
+
365
+ // 系统监控
366
+ case 'system_health': {
367
+ const health = await systemMonitor.getSystemHealth();
368
+ const formatted = `系统健康状态: ${health.overall === 'healthy' ? '✅ 健康' : '⚠️ 警告'}\n\nCPU使用率: ${health.cpu.usage.toFixed(2)}% (${health.cpu.status})\n内存使用率: ${health.memory.usage.toFixed(2)}% (${health.memory.status})\n磁盘使用率: ${health.disk.usage.toFixed(2)}% (${health.disk.status})\n系统负载: ${health.load.load1}, ${health.load.load5}, ${health.load.load15} (${health.load.status})`;
369
+ auditLogger.log('system_health', 'check', 'success');
370
+ return { content: [{ type: 'text', text: formatted }] };
371
+ }
372
+
373
+ case 'system_info': {
374
+ const info = await sshManager.getSystemInfo();
375
+ const formatted = `主机名: ${info.hostname}\n操作系统: ${info.os}\n内核版本: ${info.kernel}\n运行时间: ${info.uptime}\nCPU: ${info.cpu}\n内存: ${info.memory}\n磁盘: ${info.disk}`;
376
+ auditLogger.log('system_info', 'get', 'success');
377
+ return { content: [{ type: 'text', text: formatted }] };
378
+ }
379
+
380
+ case 'system_processes': {
381
+ const processes = await systemMonitor.getProcessList(args.limit || 10);
382
+ const formatted = processes.map(p =>
383
+ `${p.pid} | ${p.user} | CPU:${p.cpu}% | MEM:${p.memory}% | ${p.command}`
384
+ ).join('\n');
385
+ auditLogger.log('system_processes', 'list', 'success');
386
+ return { content: [{ type: 'text', text: formatted }] };
387
+ }
388
+
389
+ case 'system_logs': {
390
+ const logs = await systemMonitor.getSystemLogs(args.lines || 50);
391
+ auditLogger.log('system_logs', 'get', 'success');
392
+ return { content: [{ type: 'text', text: logs }] };
393
+ }
394
+
395
+ case 'system_ports': {
396
+ const ports = await systemMonitor.getOpenPorts();
397
+ const formatted = ports.map(p =>
398
+ `${p.protocol} | ${p.ip}:${p.port}`
399
+ ).join('\n');
400
+ auditLogger.log('system_ports', 'list', 'success');
401
+ return { content: [{ type: 'text', text: formatted || '没有开放端口' }] };
402
+ }
403
+
404
+ case 'ssh_audit_log': {
405
+ const logs = auditLogger.getLogs(args.limit || 50);
406
+ return { content: [{ type: 'text', text: JSON.stringify(logs, null, 2) }] };
407
+ }
408
+
409
+ default:
410
+ throw new Error(`Unknown tool: ${name}`);
411
+ }
412
+ } catch (error) {
413
+ auditLogger.log(name, JSON.stringify(args), 'error', { error: error.message });
414
+ return {
415
+ content: [{ type: 'text', text: `错误: ${error.message}` }],
416
+ isError: true,
417
+ };
418
+ }
419
+ });
420
+
421
+ async function main() {
422
+ const transport = new StdioServerTransport();
423
+ await server.connect(transport);
424
+ console.error('SSH MCP Server v2.0 running on stdio');
425
+ }
426
+
427
+ main().catch(console.error);
package/index.js ADDED
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import {
5
+ CallToolRequestSchema,
6
+ ListToolsRequestSchema,
7
+ } from '@modelcontextprotocol/sdk/types.js';
8
+ import { SSHManager } from './ssh-manager.js';
9
+ import { AuditLogger } from './audit-logger.js';
10
+ import { SecurityChecker } from './security-checker.js';
11
+
12
+ const server = new Server(
13
+ {
14
+ name: 'ssh-mcp-server',
15
+ version: '1.0.0',
16
+ },
17
+ {
18
+ capabilities: {
19
+ tools: {},
20
+ },
21
+ }
22
+ );
23
+
24
+ const sshManager = new SSHManager();
25
+ const auditLogger = new AuditLogger();
26
+ const securityChecker = new SecurityChecker();
27
+
28
+ // 从环境变量读取SSH配置并自动连接
29
+ const sshConfig = {
30
+ host: process.env.SSH_HOST,
31
+ port: parseInt(process.env.SSH_PORT || '22'),
32
+ username: process.env.SSH_USERNAME,
33
+ password: process.env.SSH_PASSWORD,
34
+ privateKeyPath: process.env.SSH_PRIVATE_KEY_PATH,
35
+ };
36
+
37
+ // 如果配置了SSH信息,启动时自动连接
38
+ if (sshConfig.host && sshConfig.username) {
39
+ sshManager.autoConnect(sshConfig).catch(err => {
40
+ console.error('自动连接失败:', err.message);
41
+ });
42
+ }
43
+
44
+ // 工具列表
45
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
46
+ return {
47
+ tools: [
48
+ {
49
+ name: 'ssh_connect',
50
+ description: '连接到远程SSH服务器',
51
+ inputSchema: {
52
+ type: 'object',
53
+ properties: {
54
+ host: { type: 'string', description: 'SSH服务器地址' },
55
+ port: { type: 'number', description: 'SSH端口', default: 22 },
56
+ username: { type: 'string', description: '用户名' },
57
+ password: { type: 'string', description: '密码(可选)' },
58
+ privateKey: { type: 'string', description: '私钥路径(可选)' },
59
+ },
60
+ required: ['host', 'username'],
61
+ },
62
+ },
63
+ {
64
+ name: 'ssh_exec',
65
+ description: '在远程服务器执行命令(危险命令需要确认)',
66
+ inputSchema: {
67
+ type: 'object',
68
+ properties: {
69
+ command: { type: 'string', description: '要执行的命令' },
70
+ confirm: { type: 'boolean', description: '确认执行危险操作', default: false },
71
+ },
72
+ required: ['command'],
73
+ },
74
+ },
75
+ {
76
+ name: 'ssh_upload',
77
+ description: '上传文件到远程服务器',
78
+ inputSchema: {
79
+ type: 'object',
80
+ properties: {
81
+ localPath: { type: 'string', description: '本地文件路径' },
82
+ remotePath: { type: 'string', description: '远程目标路径' },
83
+ },
84
+ required: ['localPath', 'remotePath'],
85
+ },
86
+ },
87
+ {
88
+ name: 'ssh_download',
89
+ description: '从远程服务器下载文件',
90
+ inputSchema: {
91
+ type: 'object',
92
+ properties: {
93
+ remotePath: { type: 'string', description: '远程文件路径' },
94
+ localPath: { type: 'string', description: '本地保存路径' },
95
+ },
96
+ required: ['remotePath', 'localPath'],
97
+ },
98
+ },
99
+ {
100
+ name: 'ssh_deploy',
101
+ description: '自动部署项目(上传代码、安装依赖、重启服务)',
102
+ inputSchema: {
103
+ type: 'object',
104
+ properties: {
105
+ projectPath: { type: 'string', description: '本地项目路径' },
106
+ remotePath: { type: 'string', description: '远程部署路径' },
107
+ deployScript: { type: 'string', description: '部署脚本命令', default: 'npm install && npm run build && pm2 restart app' },
108
+ },
109
+ required: ['projectPath', 'remotePath'],
110
+ },
111
+ },
112
+ {
113
+ name: 'ssh_audit_log',
114
+ description: '查看操作审计日志',
115
+ inputSchema: {
116
+ type: 'object',
117
+ properties: {
118
+ limit: { type: 'number', description: '返回日志条数', default: 50 },
119
+ },
120
+ },
121
+ },
122
+ ],
123
+ };
124
+ });
125
+
126
+ // 工具调用处理
127
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
128
+ const { name, arguments: args } = request.params;
129
+
130
+ try {
131
+ switch (name) {
132
+ case 'ssh_connect': {
133
+ const result = await sshManager.connect(args);
134
+ auditLogger.log('ssh_connect', args.host, 'success');
135
+ return { content: [{ type: 'text', text: result }] };
136
+ }
137
+
138
+ case 'ssh_exec': {
139
+ const { command, confirm } = args;
140
+ const risk = securityChecker.checkCommand(command);
141
+
142
+ if (risk.isDangerous && !confirm) {
143
+ return {
144
+ content: [{
145
+ type: 'text',
146
+ text: `⚠️ 危险操作警告!\n命令: ${command}\n风险: ${risk.reason}\n\n请设置 confirm: true 来确认执行此操作。`
147
+ }],
148
+ isError: true,
149
+ };
150
+ }
151
+
152
+ const result = await sshManager.execCommand(command);
153
+ auditLogger.log('ssh_exec', command, 'success', { risk: risk.level });
154
+ return { content: [{ type: 'text', text: result }] };
155
+ }
156
+
157
+ case 'ssh_upload': {
158
+ const { localPath, remotePath } = args;
159
+ const result = await sshManager.uploadFile(localPath, remotePath);
160
+ auditLogger.log('ssh_upload', `${localPath} -> ${remotePath}`, 'success');
161
+ return { content: [{ type: 'text', text: result }] };
162
+ }
163
+
164
+ case 'ssh_download': {
165
+ const { remotePath, localPath } = args;
166
+ const result = await sshManager.downloadFile(remotePath, localPath);
167
+ auditLogger.log('ssh_download', `${remotePath} -> ${localPath}`, 'success');
168
+ return { content: [{ type: 'text', text: result }] };
169
+ }
170
+
171
+ case 'ssh_deploy': {
172
+ const { projectPath, remotePath, deployScript } = args;
173
+ const result = await sshManager.deployProject(projectPath, remotePath, deployScript);
174
+ auditLogger.log('ssh_deploy', `${projectPath} -> ${remotePath}`, 'success');
175
+ return { content: [{ type: 'text', text: result }] };
176
+ }
177
+
178
+ case 'ssh_audit_log': {
179
+ const logs = auditLogger.getLogs(args.limit || 50);
180
+ return { content: [{ type: 'text', text: JSON.stringify(logs, null, 2) }] };
181
+ }
182
+
183
+ default:
184
+ throw new Error(`Unknown tool: ${name}`);
185
+ }
186
+ } catch (error) {
187
+ auditLogger.log(name, JSON.stringify(args), 'error', { error: error.message });
188
+ return {
189
+ content: [{ type: 'text', text: `错误: ${error.message}` }],
190
+ isError: true,
191
+ };
192
+ }
193
+ });
194
+
195
+ async function main() {
196
+ const transport = new StdioServerTransport();
197
+ await server.connect(transport);
198
+ console.error('SSH MCP Server running on stdio');
199
+ }
200
+
201
+ main().catch(console.error);
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "ssh-mcp-devops",
3
+ "version": "2.0.0",
4
+ "description": "SSH MCP Server for AI-powered DevOps with Docker and System Monitoring",
5
+ "type": "module",
6
+ "main": "index-v2.js",
7
+ "bin": "./index-v2.js",
8
+ "scripts": {
9
+ "start": "node index-v2.js",
10
+ "start:v1": "node index.js",
11
+ "dev": "node --watch index-v2.js",
12
+ "test": "node test-local.js"
13
+ },
14
+ "keywords": [
15
+ "mcp",
16
+ "ssh",
17
+ "devops",
18
+ "ai",
19
+ "docker",
20
+ "monitoring",
21
+ "automation",
22
+ "model-context-protocol"
23
+ ],
24
+ "author": "SSH-MCP Team",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/yourusername/ssh-mcp-server.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/yourusername/ssh-mcp-server/issues"
32
+ },
33
+ "homepage": "https://github.com/yourusername/ssh-mcp-server#readme",
34
+ "engines": {
35
+ "node": ">=18.0.0"
36
+ },
37
+ "files": [
38
+ "index.js",
39
+ "index-v2.js",
40
+ "ssh-manager.js",
41
+ "ssh-manager-v2.js",
42
+ "docker-manager.js",
43
+ "system-monitor.js",
44
+ "security-checker.js",
45
+ "audit-logger.js",
46
+ "README.md",
47
+ "LICENSE"
48
+ ],
49
+ "dependencies": {
50
+ "@modelcontextprotocol/sdk": "^1.0.4",
51
+ "ssh2": "^1.15.0",
52
+ "chalk": "^5.3.0"
53
+ }
54
+ }