@ebowwa/terminal 0.3.1 → 0.3.2

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.
Files changed (77) hide show
  1. package/package.json +8 -70
  2. package/dist/api.d.ts +0 -7
  3. package/dist/client.d.ts +0 -14
  4. package/dist/config.d.ts +0 -85
  5. package/dist/cpufeatures-vxqw2k6s.node +0 -0
  6. package/dist/error.d.ts +0 -7
  7. package/dist/exec.d.ts +0 -46
  8. package/dist/files.d.ts +0 -123
  9. package/dist/fingerprint.d.ts +0 -66
  10. package/dist/index.d.ts +0 -20
  11. package/dist/manager.d.ts +0 -102
  12. package/dist/mcp/cpufeatures-vxqw2k6s.node +0 -0
  13. package/dist/mcp/index.d.ts +0 -8
  14. package/dist/mcp/sshcrypto-gez6h7ch.node +0 -0
  15. package/dist/mcp/stdio.d.ts +0 -8
  16. package/dist/network-error-detector.d.ts +0 -18
  17. package/dist/pool.d.ts +0 -142
  18. package/dist/pty.d.ts +0 -58
  19. package/dist/resources.d.ts +0 -62
  20. package/dist/scp.d.ts +0 -29
  21. package/dist/sessions.d.ts +0 -100
  22. package/dist/sshcrypto-gez6h7ch.node +0 -0
  23. package/dist/tmux-exec.d.ts +0 -49
  24. package/dist/tmux-local.d.ts +0 -272
  25. package/dist/tmux-manager.d.ts +0 -327
  26. package/dist/tmux.d.ts +0 -212
  27. package/dist/types.d.ts +0 -17
  28. package/mcp/README.md +0 -181
  29. package/mcp/package.json +0 -40
  30. package/mcp/stdio.js +0 -555
  31. package/mcp/test-fix.sh +0 -273
  32. package/mcp/wrapper.mjs +0 -10
  33. package/src/api.js +0 -861
  34. package/src/api.ts +0 -752
  35. package/src/client.js +0 -92
  36. package/src/client.ts +0 -55
  37. package/src/config.js +0 -490
  38. package/src/config.ts +0 -489
  39. package/src/error.js +0 -32
  40. package/src/error.ts +0 -13
  41. package/src/exec.js +0 -183
  42. package/src/exec.ts +0 -128
  43. package/src/files.js +0 -521
  44. package/src/files.ts +0 -636
  45. package/src/fingerprint.js +0 -336
  46. package/src/fingerprint.ts +0 -263
  47. package/src/index.js +0 -127
  48. package/src/index.ts +0 -148
  49. package/src/manager.js +0 -358
  50. package/src/manager.ts +0 -319
  51. package/src/mcp/index.js +0 -555
  52. package/src/mcp/index.ts +0 -467
  53. package/src/mcp/stdio.js +0 -840
  54. package/src/mcp/stdio.ts +0 -708
  55. package/src/network-error-detector.js +0 -101
  56. package/src/network-error-detector.ts +0 -121
  57. package/src/pool.js +0 -840
  58. package/src/pool.ts +0 -662
  59. package/src/pty.js +0 -344
  60. package/src/pty.ts +0 -285
  61. package/src/resources.js +0 -64
  62. package/src/resources.ts +0 -72
  63. package/src/scp.js +0 -166
  64. package/src/scp.ts +0 -109
  65. package/src/sessions.js +0 -895
  66. package/src/sessions.ts +0 -861
  67. package/src/tmux-exec.js +0 -169
  68. package/src/tmux-exec.ts +0 -96
  69. package/src/tmux-local.js +0 -937
  70. package/src/tmux-local.ts +0 -839
  71. package/src/tmux-manager.js +0 -1026
  72. package/src/tmux-manager.ts +0 -962
  73. package/src/tmux.js +0 -826
  74. package/src/tmux.ts +0 -711
  75. package/src/types.js +0 -5
  76. package/src/types.ts +0 -19
  77. package/tsconfig.json +0 -28
package/src/mcp/stdio.js DELETED
@@ -1,840 +0,0 @@
1
- #!/usr/bin/env bun
2
- "use strict";
3
- /**
4
- * Terminal MCP Server (stdio protocol)
5
- *
6
- * Model Context Protocol server for terminal session management
7
- * Uses stdio transport for Claude Code integration
8
- */
9
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
10
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
11
- return new (P || (P = Promise))(function (resolve, reject) {
12
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
13
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
14
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
15
- step((generator = generator.apply(thisArg, _arguments || [])).next());
16
- });
17
- };
18
- var __generator = (this && this.__generator) || function (thisArg, body) {
19
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
20
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
21
- function verb(n) { return function (v) { return step([n, v]); }; }
22
- function step(op) {
23
- if (f) throw new TypeError("Generator is already executing.");
24
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
25
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
26
- if (y = 0, t) op = [op[0] & 2, t.value];
27
- switch (op[0]) {
28
- case 0: case 1: t = op; break;
29
- case 4: _.label++; return { value: op[1], done: false };
30
- case 5: _.label++; y = op[1]; op = [0]; continue;
31
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
32
- default:
33
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
34
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
35
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
36
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
37
- if (t[2]) _.ops.pop();
38
- _.trys.pop(); continue;
39
- }
40
- op = body.call(thisArg, _);
41
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
42
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
43
- }
44
- };
45
- var __asyncValues = (this && this.__asyncValues) || function (o) {
46
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
47
- var m = o[Symbol.asyncIterator], i;
48
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
49
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
50
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
51
- };
52
- Object.defineProperty(exports, "__esModule", { value: true });
53
- // Re-export terminal functions
54
- var terminal_1 = require("@ebowwa/terminal");
55
- // ==============
56
- // Tool Implementations
57
- //=============
58
- function listSessionsTool() {
59
- return __awaiter(this, void 0, void 0, function () {
60
- var sessions, lines, _i, sessions_1, session, active;
61
- return __generator(this, function (_a) {
62
- sessions = (0, terminal_1.getAllSessionInfo)();
63
- lines = [
64
- "🖥️ Active Terminal Sessions",
65
- "=".repeat(50),
66
- "",
67
- "Total sessions: ".concat(sessions.length),
68
- "",
69
- ];
70
- for (_i = 0, sessions_1 = sessions; _i < sessions_1.length; _i++) {
71
- session = sessions_1[_i];
72
- active = session.active ? "🟢" : "⚪";
73
- lines.push("".concat(active, " ").concat(session.id));
74
- lines.push(" Host: ".concat(session.host));
75
- lines.push(" Type: ".concat(session.type));
76
- lines.push(" Created: ".concat(new Date(session.createdAt).toLocaleString()));
77
- if (session.lastActivity) {
78
- lines.push(" Last activity: ".concat(new Date(session.lastActivity).toLocaleString()));
79
- }
80
- lines.push("");
81
- }
82
- return [2 /*return*/, lines.join("\n")];
83
- });
84
- });
85
- }
86
- function getSessionInfoTool(sessionId) {
87
- return __awaiter(this, void 0, void 0, function () {
88
- var info, lines, session, error_1;
89
- return __generator(this, function (_a) {
90
- switch (_a.label) {
91
- case 0:
92
- _a.trys.push([0, 2, , 3]);
93
- return [4 /*yield*/, (0, terminal_1.getSessionInfo)(sessionId)];
94
- case 1:
95
- info = _a.sent();
96
- lines = [
97
- "\uD83D\uDCCB Session: ".concat(sessionId),
98
- "=".repeat(50),
99
- "",
100
- "Host: ".concat(info.host),
101
- "Type: ".concat(info.type),
102
- "Active: ".concat(info.active ? "Yes" : "No"),
103
- "Created: ".concat(new Date(info.createdAt).toLocaleString()),
104
- ];
105
- if (info.lastActivity) {
106
- lines.push("Last activity: ".concat(new Date(info.lastActivity).toLocaleString()));
107
- }
108
- session = (0, terminal_1.getSession)(sessionId);
109
- if (session) {
110
- lines.push("");
111
- lines.push("PTY session: ".concat(session.ptyId || "N/A"));
112
- lines.push("WebSocket attached: ".concat(session.wsAttached ? "Yes" : "No"));
113
- }
114
- return [2 /*return*/, lines.join("\n")];
115
- case 2:
116
- error_1 = _a.sent();
117
- throw new Error("Failed to get session info: ".concat(error_1));
118
- case 3: return [2 /*return*/];
119
- }
120
- });
121
- });
122
- }
123
- function createSessionTool(host_1) {
124
- return __awaiter(this, arguments, void 0, function (host, type, command) {
125
- var session, error_2;
126
- if (type === void 0) { type = "ssh"; }
127
- return __generator(this, function (_a) {
128
- switch (_a.label) {
129
- case 0:
130
- _a.trys.push([0, 2, , 3]);
131
- return [4 /*yield*/, (0, terminal_1.getOrCreateSession)(host, {
132
- type: type,
133
- command: command,
134
- })];
135
- case 1:
136
- session = _a.sent();
137
- return [2 /*return*/, "\u2713 Created session ".concat(session.id, " for ").concat(host, " (").concat(type, ")")];
138
- case 2:
139
- error_2 = _a.sent();
140
- throw new Error("Failed to create session: ".concat(error_2));
141
- case 3: return [2 /*return*/];
142
- }
143
- });
144
- });
145
- }
146
- function writeCommandTool(sessionId, command) {
147
- return __awaiter(this, void 0, void 0, function () {
148
- var session, error_3;
149
- return __generator(this, function (_a) {
150
- switch (_a.label) {
151
- case 0:
152
- _a.trys.push([0, 2, , 3]);
153
- session = (0, terminal_1.getSession)(sessionId);
154
- if (!session) {
155
- throw new Error("Session ".concat(sessionId, " not found"));
156
- }
157
- return [4 /*yield*/, (0, terminal_1.writeToSession)(sessionId, command)];
158
- case 1:
159
- _a.sent();
160
- return [2 /*return*/, "\u2713 Command sent to session ".concat(sessionId)];
161
- case 2:
162
- error_3 = _a.sent();
163
- throw new Error("Failed to write command: ".concat(error_3));
164
- case 3: return [2 /*return*/];
165
- }
166
- });
167
- });
168
- }
169
- function resizeSessionTool(sessionId, rows, cols) {
170
- return __awaiter(this, void 0, void 0, function () {
171
- var error_4;
172
- return __generator(this, function (_a) {
173
- switch (_a.label) {
174
- case 0:
175
- _a.trys.push([0, 2, , 3]);
176
- return [4 /*yield*/, (0, terminal_1.resizeSession)(sessionId, rows, cols)];
177
- case 1:
178
- _a.sent();
179
- return [2 /*return*/, "\u2713 Resized session ".concat(sessionId, " to ").concat(rows, "x").concat(cols)];
180
- case 2:
181
- error_4 = _a.sent();
182
- throw new Error("Failed to resize session: ".concat(error_4));
183
- case 3: return [2 /*return*/];
184
- }
185
- });
186
- });
187
- }
188
- function closeSessionTool(sessionId) {
189
- return __awaiter(this, void 0, void 0, function () {
190
- var error_5;
191
- return __generator(this, function (_a) {
192
- switch (_a.label) {
193
- case 0:
194
- _a.trys.push([0, 2, , 3]);
195
- return [4 /*yield*/, (0, terminal_1.closeSession)(sessionId)];
196
- case 1:
197
- _a.sent();
198
- return [2 /*return*/, "\u2713 Closed session ".concat(sessionId)];
199
- case 2:
200
- error_5 = _a.sent();
201
- throw new Error("Failed to close session: ".concat(error_5));
202
- case 3: return [2 /*return*/];
203
- }
204
- });
205
- });
206
- }
207
- function execSSHTool(host, command, options) {
208
- return __awaiter(this, void 0, void 0, function () {
209
- var result, error_6;
210
- return __generator(this, function (_a) {
211
- switch (_a.label) {
212
- case 0:
213
- _a.trys.push([0, 2, , 3]);
214
- return [4 /*yield*/, (0, terminal_1.execSSH)(host, command, options)];
215
- case 1:
216
- result = _a.sent();
217
- return [2 /*return*/, result.stdout || result.stderr || "Command executed"];
218
- case 2:
219
- error_6 = _a.sent();
220
- throw new Error("SSH command failed: ".concat(error_6));
221
- case 3: return [2 /*return*/];
222
- }
223
- });
224
- });
225
- }
226
- function testConnectionTool(host) {
227
- return __awaiter(this, void 0, void 0, function () {
228
- var result, error_7;
229
- return __generator(this, function (_a) {
230
- switch (_a.label) {
231
- case 0:
232
- _a.trys.push([0, 2, , 3]);
233
- return [4 /*yield*/, (0, terminal_1.testSSHConnection)(host)];
234
- case 1:
235
- result = _a.sent();
236
- if (result.success) {
237
- return [2 /*return*/, "\u2713 Connection to ".concat(host, " successful\nLatency: ").concat(result.latency, "ms")];
238
- }
239
- else {
240
- throw new Error(result.error || "Connection failed");
241
- }
242
- return [3 /*break*/, 3];
243
- case 2:
244
- error_7 = _a.sent();
245
- throw new Error("Connection test failed: ".concat(error_7));
246
- case 3: return [2 /*return*/];
247
- }
248
- });
249
- });
250
- }
251
- function listTmuxSessionsTool() {
252
- return __awaiter(this, void 0, void 0, function () {
253
- var sessions, lines, _i, sessions_2, session, error_8;
254
- return __generator(this, function (_a) {
255
- switch (_a.label) {
256
- case 0:
257
- _a.trys.push([0, 3, , 4]);
258
- return [4 /*yield*/, (0, terminal_1.ensureTmux)()];
259
- case 1:
260
- _a.sent();
261
- return [4 /*yield*/, (0, terminal_1.listTmuxSessions)()];
262
- case 2:
263
- sessions = _a.sent();
264
- lines = [
265
- "🎬 Tmux Sessions",
266
- "=".repeat(50),
267
- "",
268
- ];
269
- if (sessions.length === 0) {
270
- lines.push("No active tmux sessions");
271
- }
272
- else {
273
- for (_i = 0, sessions_2 = sessions; _i < sessions_2.length; _i++) {
274
- session = sessions_2[_i];
275
- lines.push("".concat(session.name));
276
- lines.push(" Windows: ".concat(session.windows));
277
- lines.push(" Created: ".concat(new Date(session.created).toLocaleString()));
278
- lines.push("");
279
- }
280
- }
281
- return [2 /*return*/, lines.join("\n")];
282
- case 3:
283
- error_8 = _a.sent();
284
- throw new Error("Failed to list tmux sessions: ".concat(error_8));
285
- case 4: return [2 /*return*/];
286
- }
287
- });
288
- });
289
- }
290
- function listFilesTool(host_1) {
291
- return __awaiter(this, arguments, void 0, function (host, path) {
292
- var files, lines, _i, files_1, file, icon, size, error_9;
293
- if (path === void 0) { path = "."; }
294
- return __generator(this, function (_a) {
295
- switch (_a.label) {
296
- case 0:
297
- _a.trys.push([0, 2, , 3]);
298
- return [4 /*yield*/, (0, terminal_1.listFiles)(host, path)];
299
- case 1:
300
- files = _a.sent();
301
- lines = [
302
- "\uD83D\uDCC1 Files on ".concat(host, ":").concat(path),
303
- "=".repeat(50),
304
- "",
305
- ];
306
- for (_i = 0, files_1 = files; _i < files_1.length; _i++) {
307
- file = files_1[_i];
308
- icon = file.type === "directory" ? "📁" : "📄";
309
- size = file.size ? " (".concat(file.size, " bytes)") : "";
310
- lines.push("".concat(icon, " ").concat(file.name).concat(size));
311
- }
312
- return [2 /*return*/, lines.join("\n")];
313
- case 2:
314
- error_9 = _a.sent();
315
- throw new Error("Failed to list files: ".concat(error_9));
316
- case 3: return [2 /*return*/];
317
- }
318
- });
319
- });
320
- }
321
- function uploadFileTool(host, localPath, remotePath) {
322
- return __awaiter(this, void 0, void 0, function () {
323
- var error_10;
324
- return __generator(this, function (_a) {
325
- switch (_a.label) {
326
- case 0:
327
- _a.trys.push([0, 2, , 3]);
328
- return [4 /*yield*/, (0, terminal_1.scpUpload)(host, { localPath: localPath, remotePath: remotePath })];
329
- case 1:
330
- _a.sent();
331
- return [2 /*return*/, "\u2713 Uploaded ".concat(localPath, " to ").concat(host, ":").concat(remotePath)];
332
- case 2:
333
- error_10 = _a.sent();
334
- throw new Error("SCP upload failed: ".concat(error_10));
335
- case 3: return [2 /*return*/];
336
- }
337
- });
338
- });
339
- }
340
- function downloadFileTool(host, remotePath, localPath) {
341
- return __awaiter(this, void 0, void 0, function () {
342
- var error_11;
343
- return __generator(this, function (_a) {
344
- switch (_a.label) {
345
- case 0:
346
- _a.trys.push([0, 2, , 3]);
347
- return [4 /*yield*/, (0, terminal_1.scpDownload)(host, { remotePath: remotePath, localPath: localPath })];
348
- case 1:
349
- _a.sent();
350
- return [2 /*return*/, "\u2713 Downloaded ".concat(host, ":").concat(remotePath, " to ").concat(localPath)];
351
- case 2:
352
- error_11 = _a.sent();
353
- throw new Error("SCP download failed: ".concat(error_11));
354
- case 3: return [2 /*return*/];
355
- }
356
- });
357
- });
358
- }
359
- function getActiveConnectionsTool() {
360
- return __awaiter(this, void 0, void 0, function () {
361
- var connections, lines, _i, connections_1, conn;
362
- return __generator(this, function (_a) {
363
- try {
364
- connections = (0, terminal_1.getActiveSSHConnections)();
365
- lines = [
366
- "🔗 Active SSH Connections",
367
- "=".repeat(50),
368
- "",
369
- "Total connections: ".concat(connections.length),
370
- "",
371
- ];
372
- for (_i = 0, connections_1 = connections; _i < connections_1.length; _i++) {
373
- conn = connections_1[_i];
374
- lines.push("".concat(conn.host));
375
- lines.push(" Connected: ".concat(conn.connected ? "Yes" : "No"));
376
- lines.push(" Port: ".concat(conn.port || 22));
377
- lines.push("");
378
- }
379
- return [2 /*return*/, lines.join("\n")];
380
- }
381
- catch (error) {
382
- throw new Error("Failed to get connections: ".concat(error));
383
- }
384
- return [2 /*return*/];
385
- });
386
- });
387
- }
388
- // ==============
389
- // Tool Definitions
390
- //=============
391
- var TOOLS = [
392
- {
393
- name: "list_sessions",
394
- description: "List all active terminal sessions",
395
- inputSchema: {
396
- type: "object",
397
- properties: {},
398
- required: [],
399
- },
400
- },
401
- {
402
- name: "get_session_info",
403
- description: "Get detailed information about a specific terminal session",
404
- inputSchema: {
405
- type: "object",
406
- properties: {
407
- session_id: {
408
- type: "string",
409
- description: "The session ID to get info for",
410
- },
411
- },
412
- required: ["session_id"],
413
- },
414
- },
415
- {
416
- name: "create_session",
417
- description: "Create a new terminal session (SSH or PTY)",
418
- inputSchema: {
419
- type: "object",
420
- properties: {
421
- host: {
422
- type: "string",
423
- description: "SSH host in format user@host or just host",
424
- },
425
- type: {
426
- type: "string",
427
- description: "Session type: ssh or pty",
428
- enum: ["ssh", "pty"],
429
- },
430
- command: {
431
- type: "string",
432
- description: "Optional command to run on session creation",
433
- },
434
- },
435
- required: ["host"],
436
- },
437
- },
438
- {
439
- name: "write_command",
440
- description: "Write a command to an active terminal session",
441
- inputSchema: {
442
- type: "object",
443
- properties: {
444
- session_id: {
445
- type: "string",
446
- description: "The session ID to write to",
447
- },
448
- command: {
449
- type: "string",
450
- description: "The command to write to the session",
451
- },
452
- },
453
- required: ["session_id", "command"],
454
- },
455
- },
456
- {
457
- name: "resize_session",
458
- description: "Resize a terminal session",
459
- inputSchema: {
460
- type: "object",
461
- properties: {
462
- session_id: {
463
- type: "string",
464
- description: "The session ID to resize",
465
- },
466
- rows: {
467
- type: "number",
468
- description: "Number of rows",
469
- },
470
- cols: {
471
- type: "number",
472
- description: "Number of columns",
473
- },
474
- },
475
- required: ["session_id", "rows", "cols"],
476
- },
477
- },
478
- {
479
- name: "close_session",
480
- description: "Close a terminal session",
481
- inputSchema: {
482
- type: "object",
483
- properties: {
484
- session_id: {
485
- type: "string",
486
- description: "The session ID to close",
487
- },
488
- },
489
- required: ["session_id"],
490
- },
491
- },
492
- {
493
- name: "exec_ssh",
494
- description: "Execute a command via SSH",
495
- inputSchema: {
496
- type: "object",
497
- properties: {
498
- host: {
499
- type: "string",
500
- description: "SSH host in format user@host or just host",
501
- },
502
- command: {
503
- type: "string",
504
- description: "The command to execute",
505
- },
506
- },
507
- required: ["host", "command"],
508
- },
509
- },
510
- {
511
- name: "test_connection",
512
- description: "Test SSH connection to a host",
513
- inputSchema: {
514
- type: "object",
515
- properties: {
516
- host: {
517
- type: "string",
518
- description: "SSH host to test connection to",
519
- },
520
- },
521
- required: ["host"],
522
- },
523
- },
524
- {
525
- name: "list_tmux_sessions",
526
- description: "List all tmux sessions",
527
- inputSchema: {
528
- type: "object",
529
- properties: {},
530
- required: [],
531
- },
532
- },
533
- {
534
- name: "list_files",
535
- description: "List files on a remote host",
536
- inputSchema: {
537
- type: "object",
538
- properties: {
539
- host: {
540
- type: "string",
541
- description: "SSH host to list files on",
542
- },
543
- path: {
544
- type: "string",
545
- description: "Path to list (default: current directory)",
546
- },
547
- },
548
- required: ["host"],
549
- },
550
- },
551
- {
552
- name: "upload_file",
553
- description: "Upload a file via SCP",
554
- inputSchema: {
555
- type: "object",
556
- properties: {
557
- host: {
558
- type: "string",
559
- description: "SSH host to upload to",
560
- },
561
- local_path: {
562
- type: "string",
563
- description: "Local file path to upload",
564
- },
565
- remote_path: {
566
- type: "string",
567
- description: "Remote destination path",
568
- },
569
- },
570
- required: ["host", "local_path", "remote_path"],
571
- },
572
- },
573
- {
574
- name: "download_file",
575
- description: "Download a file via SCP",
576
- inputSchema: {
577
- type: "object",
578
- properties: {
579
- host: {
580
- type: "string",
581
- description: "SSH host to download from",
582
- },
583
- remote_path: {
584
- type: "string",
585
- description: "Remote file path to download",
586
- },
587
- local_path: {
588
- type: "string",
589
- description: "Local destination path",
590
- },
591
- },
592
- required: ["host", "remote_path", "local_path"],
593
- },
594
- },
595
- {
596
- name: "get_active_connections",
597
- description: "Get all active SSH connections",
598
- inputSchema: {
599
- type: "object",
600
- properties: {},
601
- required: [],
602
- },
603
- },
604
- ];
605
- // ==============
606
- // MCP Server
607
- //=============
608
- function handleToolCall(name, args) {
609
- return __awaiter(this, void 0, void 0, function () {
610
- var _a;
611
- return __generator(this, function (_b) {
612
- switch (_b.label) {
613
- case 0:
614
- _a = name;
615
- switch (_a) {
616
- case "list_sessions": return [3 /*break*/, 1];
617
- case "get_session_info": return [3 /*break*/, 3];
618
- case "create_session": return [3 /*break*/, 5];
619
- case "write_command": return [3 /*break*/, 7];
620
- case "resize_session": return [3 /*break*/, 9];
621
- case "close_session": return [3 /*break*/, 11];
622
- case "exec_ssh": return [3 /*break*/, 13];
623
- case "test_connection": return [3 /*break*/, 15];
624
- case "list_tmux_sessions": return [3 /*break*/, 17];
625
- case "list_files": return [3 /*break*/, 19];
626
- case "upload_file": return [3 /*break*/, 21];
627
- case "download_file": return [3 /*break*/, 23];
628
- case "get_active_connections": return [3 /*break*/, 25];
629
- }
630
- return [3 /*break*/, 27];
631
- case 1: return [4 /*yield*/, listSessionsTool()];
632
- case 2: return [2 /*return*/, _b.sent()];
633
- case 3: return [4 /*yield*/, getSessionInfoTool(args.session_id)];
634
- case 4: return [2 /*return*/, _b.sent()];
635
- case 5: return [4 /*yield*/, createSessionTool(args.host, args.type, args.command)];
636
- case 6: return [2 /*return*/, _b.sent()];
637
- case 7: return [4 /*yield*/, writeCommandTool(args.session_id, args.command)];
638
- case 8: return [2 /*return*/, _b.sent()];
639
- case 9: return [4 /*yield*/, resizeSessionTool(args.session_id, args.rows, args.cols)];
640
- case 10: return [2 /*return*/, _b.sent()];
641
- case 11: return [4 /*yield*/, closeSessionTool(args.session_id)];
642
- case 12: return [2 /*return*/, _b.sent()];
643
- case 13: return [4 /*yield*/, execSSHTool(args.host, args.command, args.options)];
644
- case 14: return [2 /*return*/, _b.sent()];
645
- case 15: return [4 /*yield*/, testConnectionTool(args.host)];
646
- case 16: return [2 /*return*/, _b.sent()];
647
- case 17: return [4 /*yield*/, listTmuxSessionsTool()];
648
- case 18: return [2 /*return*/, _b.sent()];
649
- case 19: return [4 /*yield*/, listFilesTool(args.host, args.path)];
650
- case 20: return [2 /*return*/, _b.sent()];
651
- case 21: return [4 /*yield*/, uploadFileTool(args.host, args.local_path, args.remote_path)];
652
- case 22: return [2 /*return*/, _b.sent()];
653
- case 23: return [4 /*yield*/, downloadFileTool(args.host, args.remote_path, args.local_path)];
654
- case 24: return [2 /*return*/, _b.sent()];
655
- case 25: return [4 /*yield*/, getActiveConnectionsTool()];
656
- case 26: return [2 /*return*/, _b.sent()];
657
- case 27: throw new Error("Unknown tool: ".concat(name));
658
- }
659
- });
660
- });
661
- }
662
- function sendMessage(message) {
663
- console.log(JSON.stringify(message));
664
- }
665
- function processMessage(message) {
666
- return __awaiter(this, void 0, void 0, function () {
667
- var id, method, params, _a, name_1, args, result, error_12;
668
- return __generator(this, function (_b) {
669
- switch (_b.label) {
670
- case 0:
671
- id = message.id, method = message.method, params = message.params;
672
- _b.label = 1;
673
- case 1:
674
- _b.trys.push([1, 9, , 10]);
675
- _a = method;
676
- switch (_a) {
677
- case "initialize": return [3 /*break*/, 2];
678
- case "tools/list": return [3 /*break*/, 3];
679
- case "tools/call": return [3 /*break*/, 4];
680
- case "shutdown": return [3 /*break*/, 6];
681
- }
682
- return [3 /*break*/, 7];
683
- case 2:
684
- sendMessage({
685
- jsonrpc: "2.0",
686
- id: id,
687
- result: {
688
- protocolVersion: "2024-11-05",
689
- capabilities: {
690
- tools: {},
691
- },
692
- serverInfo: {
693
- name: "terminal-mcp",
694
- version: "1.0.0",
695
- },
696
- },
697
- });
698
- return [3 /*break*/, 8];
699
- case 3:
700
- sendMessage({
701
- jsonrpc: "2.0",
702
- id: id,
703
- result: {
704
- tools: TOOLS,
705
- },
706
- });
707
- return [3 /*break*/, 8];
708
- case 4:
709
- name_1 = params.name, args = params.arguments;
710
- return [4 /*yield*/, handleToolCall(name_1, args || {})];
711
- case 5:
712
- result = _b.sent();
713
- sendMessage({
714
- jsonrpc: "2.0",
715
- id: id,
716
- result: {
717
- content: [
718
- {
719
- type: "text",
720
- text: result,
721
- },
722
- ],
723
- },
724
- });
725
- return [3 /*break*/, 8];
726
- case 6:
727
- sendMessage({
728
- jsonrpc: "2.0",
729
- id: id,
730
- result: {},
731
- });
732
- process.exit(0);
733
- return [3 /*break*/, 8];
734
- case 7:
735
- sendMessage({
736
- jsonrpc: "2.0",
737
- id: id,
738
- error: {
739
- code: -32601,
740
- message: "Method not found: ".concat(method),
741
- },
742
- });
743
- _b.label = 8;
744
- case 8: return [3 /*break*/, 10];
745
- case 9:
746
- error_12 = _b.sent();
747
- sendMessage({
748
- jsonrpc: "2.0",
749
- id: id,
750
- error: {
751
- code: -32603,
752
- message: "Internal error: ".concat(error_12),
753
- },
754
- });
755
- return [3 /*break*/, 10];
756
- case 10: return [2 /*return*/];
757
- }
758
- });
759
- });
760
- }
761
- // ==============
762
- // Main Loop
763
- //=============
764
- function main() {
765
- return __awaiter(this, void 0, void 0, function () {
766
- var decoder, buffer, _a, _b, _c, chunk, lines, _i, lines_1, line, message, error_13, e_1_1;
767
- var _d, e_1, _e, _f;
768
- return __generator(this, function (_g) {
769
- switch (_g.label) {
770
- case 0:
771
- decoder = new TextDecoder();
772
- buffer = "";
773
- _g.label = 1;
774
- case 1:
775
- _g.trys.push([1, 11, 12, 17]);
776
- _a = true, _b = __asyncValues(process.stdin);
777
- _g.label = 2;
778
- case 2: return [4 /*yield*/, _b.next()];
779
- case 3:
780
- if (!(_c = _g.sent(), _d = _c.done, !_d)) return [3 /*break*/, 10];
781
- _f = _c.value;
782
- _a = false;
783
- chunk = _f;
784
- buffer += decoder.decode(chunk);
785
- lines = buffer.split("\n");
786
- buffer = lines.pop() || "";
787
- _i = 0, lines_1 = lines;
788
- _g.label = 4;
789
- case 4:
790
- if (!(_i < lines_1.length)) return [3 /*break*/, 9];
791
- line = lines_1[_i];
792
- if (!line.trim())
793
- return [3 /*break*/, 8];
794
- _g.label = 5;
795
- case 5:
796
- _g.trys.push([5, 7, , 8]);
797
- message = JSON.parse(line);
798
- return [4 /*yield*/, processMessage(message)];
799
- case 6:
800
- _g.sent();
801
- return [3 /*break*/, 8];
802
- case 7:
803
- error_13 = _g.sent();
804
- sendMessage({
805
- jsonrpc: "2.0",
806
- error: {
807
- code: -32700,
808
- message: "Parse error: ".concat(error_13),
809
- },
810
- });
811
- return [3 /*break*/, 8];
812
- case 8:
813
- _i++;
814
- return [3 /*break*/, 4];
815
- case 9:
816
- _a = true;
817
- return [3 /*break*/, 2];
818
- case 10: return [3 /*break*/, 17];
819
- case 11:
820
- e_1_1 = _g.sent();
821
- e_1 = { error: e_1_1 };
822
- return [3 /*break*/, 17];
823
- case 12:
824
- _g.trys.push([12, , 15, 16]);
825
- if (!(!_a && !_d && (_e = _b.return))) return [3 /*break*/, 14];
826
- return [4 /*yield*/, _e.call(_b)];
827
- case 13:
828
- _g.sent();
829
- _g.label = 14;
830
- case 14: return [3 /*break*/, 16];
831
- case 15:
832
- if (e_1) throw e_1.error;
833
- return [7 /*endfinally*/];
834
- case 16: return [7 /*endfinally*/];
835
- case 17: return [2 /*return*/];
836
- }
837
- });
838
- });
839
- }
840
- main().catch(console.error);