@ebowwa/terminal 0.2.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/mcp/README.md ADDED
@@ -0,0 +1,181 @@
1
+ # Terminal MCP Server
2
+
3
+ Model Context Protocol server for terminal session management, SSH operations, tmux integration, and file operations.
4
+
5
+ ## Features
6
+
7
+ - **Session Management**: Create, list, manage terminal sessions
8
+ - **SSH Operations**: Execute commands, test connections, manage SSH pool
9
+ - **Tmux Integration**: List and manage tmux sessions
10
+ - **File Operations**: List, upload, download files via SCP
11
+ - **PTY Operations**: Create and manage PTY sessions
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ bun install
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Start the MCP Server
22
+
23
+ ```bash
24
+ # Default port 8913
25
+ bun run mcp
26
+
27
+ # Custom port
28
+ MCP_PORT=8914 bun run mcp
29
+
30
+ # Dev mode (with port 8913)
31
+ bun run mcp-dev
32
+ ```
33
+
34
+ ### Available Tools
35
+
36
+ #### Session Management
37
+
38
+ | Tool | Description | Arguments |
39
+ |------|-------------|------------|
40
+ | `list_sessions` | List all active terminal sessions | none |
41
+ | `get_session_info` | Get detailed info about a session | `session_id` |
42
+ | `create_session` | Create a new terminal session | `host`, `type?`, `command?` |
43
+ | `write_command` | Write a command to a session | `session_id`, `command` |
44
+ | `resize_session` | Resize a session terminal | `session_id`, `rows`, `cols` |
45
+ | `close_session` | Close a terminal session | `session_id` |
46
+
47
+ #### SSH Operations
48
+
49
+ | Tool | Description | Arguments |
50
+ |------|-------------|------------|
51
+ | `exec_ssh` | Execute command via SSH | `host`, `command`, `options?` |
52
+ | `test_connection` | Test SSH connection | `host` |
53
+
54
+ #### Tmux Operations
55
+
56
+ | Tool | Description | Arguments |
57
+ |------|-------------|------------|
58
+ | `list_tmux_sessions` | List all tmux sessions | none |
59
+
60
+ #### File Operations
61
+
62
+ | Tool | Description | Arguments |
63
+ |------|-------------|------------|
64
+ | `list_files` | List files on remote host | `host`, `path?` |
65
+ | `upload_file` | Upload file via SCP | `host`, `local_path`, `remote_path` |
66
+ | `download_file` | Download file via SCP | `host`, `remote_path`, `local_path` |
67
+
68
+ #### Connection Management
69
+
70
+ | Tool | Description | Arguments |
71
+ |------|-------------|------------|
72
+ | `get_active_connections` | Get active SSH connections | none |
73
+
74
+ ## API Endpoints
75
+
76
+ ### Health Check
77
+
78
+ ```bash
79
+ curl http://localhost:8913/health
80
+ ```
81
+
82
+ Response:
83
+ ```json
84
+ {
85
+ "status": "ok",
86
+ "port": 8913,
87
+ "service": "terminal-mcp"
88
+ }
89
+ ```
90
+
91
+ ### List Available Tools
92
+
93
+ ```bash
94
+ curl http://localhost:8913/mcp
95
+ ```
96
+
97
+ ### Execute Tool
98
+
99
+ ```bash
100
+ curl -X POST http://localhost:8913/mcp \
101
+ -H "Content-Type: application/json" \
102
+ -d '{
103
+ "tool": "list_sessions",
104
+ "args": {}
105
+ }'
106
+ ```
107
+
108
+ ## Examples
109
+
110
+ ### List All Sessions
111
+
112
+ ```bash
113
+ curl -X POST http://localhost:8913/mcp \
114
+ -H "Content-Type: application/json" \
115
+ -d '{"tool": "list_sessions"}'
116
+ ```
117
+
118
+ ### Create SSH Session
119
+
120
+ ```bash
121
+ curl -X POST http://localhost:8913/mcp \
122
+ -H "Content-Type: application/json" \
123
+ -d '{
124
+ "tool": "create_session",
125
+ "args": {
126
+ "host": "user@server.com",
127
+ "type": "ssh"
128
+ }
129
+ }'
130
+ ```
131
+
132
+ ### Execute SSH Command
133
+
134
+ ```bash
135
+ curl -X POST http://localhost:8913/mcp \
136
+ -H "Content-Type: application/json" \
137
+ -d '{
138
+ "tool": "exec_ssh",
139
+ "args": {
140
+ "host": "user@server.com",
141
+ "command": "ls -la"
142
+ }
143
+ }'
144
+ ```
145
+
146
+ ### List Tmux Sessions
147
+
148
+ ```bash
149
+ curl -X POST http://localhost:8913/mcp \
150
+ -H "Content-Type: application/json" \
151
+ -d '{"tool": "list_tmux_sessions"}'
152
+ ```
153
+
154
+ ### Upload File
155
+
156
+ ```bash
157
+ curl -X POST http://localhost:8913/mcp \
158
+ -H "Content-Type: application/json" \
159
+ -d '{
160
+ "tool": "upload_file",
161
+ "args": {
162
+ "host": "user@server.com",
163
+ "local_path": "/local/file.txt",
164
+ "remote_path": "/remote/file.txt"
165
+ }
166
+ }'
167
+ ```
168
+
169
+ ## Integration with Claude
170
+
171
+ This MCP server can be integrated with Claude Code or other MCP-compatible clients to provide terminal management capabilities.
172
+
173
+ ## Dependencies
174
+
175
+ - `node-ssh`: SSH client functionality
176
+ - `hono`: HTTP server framework
177
+ - `zod`: Schema validation
178
+
179
+ ## License
180
+
181
+ MIT
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@ebowwa/terminal-mcp",
3
+ "version": "1.0.0",
4
+ "description": "Terminal session management MCP server with SSH, tmux, and file operations",
5
+ "type": "module",
6
+ "main": "stdio.ts",
7
+ "bin": {
8
+ "terminal-mcp": "stdio.ts"
9
+ },
10
+ "scripts": {
11
+ "dev": "bun --hot stdio.ts",
12
+ "start": "bun stdio.ts"
13
+ },
14
+ "keywords": [
15
+ "mcp",
16
+ "terminal",
17
+ "ssh",
18
+ "tmux",
19
+ "session-management"
20
+ ],
21
+ "author": "ebowwa",
22
+ "license": "MIT",
23
+ "dependencies": {
24
+ "node-ssh": "^13.2.1",
25
+ "hono": "^4.11.3",
26
+ "zod": "^3.24.1"
27
+ },
28
+ "devDependencies": {
29
+ "@types/bun": "latest"
30
+ },
31
+ "peerDependencies": {
32
+ "bun": ">=1.0.0"
33
+ }
34
+ }
@@ -0,0 +1,273 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Terminal MCP Fix Test Suite
4
+ # ===========================
5
+ # Tests the recursive loop bug fix for exec_ssh tool
6
+ #
7
+ # BUG DESCRIPTION:
8
+ # The execSSHTool function was calling execSSH with wrong parameter order:
9
+ # - WRONG: execSSH(host, command, options)
10
+ # - RIGHT: execSSH(command, options)
11
+ # - The options parameter must include the 'host' field
12
+ #
13
+ # Author: Test Engineer (team-lead request)
14
+ # Date: 2026-02-05
15
+ #
16
+
17
+ set -euo pipefail
18
+
19
+ # Colors for output
20
+ RED='\033[0;31m'
21
+ GREEN='\033[0;32m'
22
+ YELLOW='\033[1;33m'
23
+ BLUE='\033[0;34m'
24
+ NC='\033[0m' # No Color
25
+
26
+ # Test configuration
27
+ TEST_TIMEOUT=10 # seconds
28
+ MEMORY_LIMIT_MB=500
29
+ TEST_PORT=8913
30
+
31
+ # Test results
32
+ TESTS_PASSED=0
33
+ TESTS_FAILED=0
34
+
35
+ # Safe test commands (read-only, non-destructive)
36
+ SAFE_COMMANDS=(
37
+ "echo 'test'"
38
+ "whoami"
39
+ "pwd"
40
+ "uname -m"
41
+ "date +%s"
42
+ )
43
+
44
+ log_info() {
45
+ echo -e "${BLUE}[INFO]${NC} $*"
46
+ }
47
+
48
+ log_success() {
49
+ echo -e "${GREEN}[PASS]${NC} $*"
50
+ ((TESTS_PASSED++))
51
+ }
52
+
53
+ log_error() {
54
+ echo -e "${RED}[FAIL]${NC} $*"
55
+ ((TESTS_FAILED++))
56
+ }
57
+
58
+ log_warning() {
59
+ echo -e "${YELLOW}[WARN]${NC} $*"
60
+ }
61
+
62
+ # Test 1: Verify MCP server starts correctly
63
+ test_server_startup() {
64
+ log_info "Test 1: Starting MCP server on port $TEST_PORT..."
65
+
66
+ # Start server in background
67
+ cd /Users/ebowwa/Desktop/codespaces/packages/src/terminal/mcp
68
+ MCP_PORT=$TEST_PORT bun stdio.ts &
69
+ SERVER_PID=$!
70
+
71
+ # Wait for server to start
72
+ sleep 2
73
+
74
+ # Check if process is still running
75
+ if ps -p $SERVER_PID > /dev/null 2>&1; then
76
+ log_success "MCP server started successfully (PID: $SERVER_PID)"
77
+ echo $SERVER_PID > /tmp/terminal-mcp-test.pid
78
+ return 0
79
+ else
80
+ log_error "MCP server failed to start"
81
+ return 1
82
+ fi
83
+ }
84
+
85
+ # Test 2: Verify no infinite recursion on exec_ssh calls
86
+ test_no_recursion() {
87
+ log_info "Test 2: Testing for recursive loop bug..."
88
+
89
+ # Test each safe command
90
+ for cmd in "${SAFE_COMMANDS[@]}"; do
91
+ log_info " Testing command: $cmd"
92
+
93
+ # Create test request
94
+ cat > /tmp/test_request.json <<EOF
95
+ {
96
+ "jsonrpc": "2.0",
97
+ "id": 1,
98
+ "method": "tools/call",
99
+ "params": {
100
+ "name": "exec_ssh",
101
+ "arguments": {
102
+ "host": "localhost",
103
+ "command": "$cmd"
104
+ }
105
+ }
106
+ }
107
+ EOF
108
+
109
+ # Execute with timeout to catch infinite loops
110
+ timeout $TEST_TIMEOUT cat /tmp/test_request.json | \
111
+ MCP_PORT=$TEST_PORT bun stdio.ts > /tmp/test_response.json 2>&1 || {
112
+ log_error "Command timed out or failed: $cmd"
113
+ cat /tmp/test_response.json
114
+ return 1
115
+ }
116
+
117
+ # Check response
118
+ if grep -q '"result"' /tmp/test_response.json; then
119
+ log_success "Command executed without recursion: $cmd"
120
+ else
121
+ log_error "Invalid response for command: $cmd"
122
+ cat /tmp/test_response.json
123
+ return 1
124
+ fi
125
+ done
126
+
127
+ return 0
128
+ }
129
+
130
+ # Test 3: Memory leak detection
131
+ test_memory_leak() {
132
+ log_info "Test 3: Testing for memory leaks..."
133
+
134
+ # Get initial memory
135
+ local initial_mem=$(ps -o rss= -p $SERVER_PID 2>/dev/null || echo "0")
136
+
137
+ # Execute multiple commands
138
+ for i in {1..50}; do
139
+ echo "echo 'iteration-$i'" | \
140
+ MCP_PORT=$TEST_PORT bun stdio.ts > /dev/null 2>&1
141
+ done
142
+
143
+ # Get final memory
144
+ local final_mem=$(ps -o rss= -p $SERVER_PID 2>/dev/null || echo "0")
145
+
146
+ # Calculate memory growth (in MB)
147
+ local mem_growth=$(( ($final_mem - $initial_mem) / 1024 ))
148
+
149
+ log_info " Memory growth: ${mem_growth}MB"
150
+
151
+ if [ $mem_growth -lt $MEMORY_LIMIT_MB ]; then
152
+ log_success "Memory usage within acceptable limits"
153
+ return 0
154
+ else
155
+ log_error "Excessive memory growth detected: ${mem_growth}MB"
156
+ return 1
157
+ fi
158
+ }
159
+
160
+ # Test 4: Parameter validation
161
+ test_parameter_validation() {
162
+ log_info "Test 4: Testing parameter validation..."
163
+
164
+ # Test with missing host parameter
165
+ cat > /tmp/test_invalid.json <<EOF
166
+ {
167
+ "jsonrpc": "2.0",
168
+ "id": 2,
169
+ "method": "tools/call",
170
+ "params": {
171
+ "name": "exec_ssh",
172
+ "arguments": {
173
+ "command": "echo test"
174
+ }
175
+ }
176
+ }
177
+ EOF
178
+
179
+ timeout 5 cat /tmp/test_invalid.json | \
180
+ MCP_PORT=$TEST_PORT bun stdio.ts > /tmp/test_invalid_response.json 2>&1
181
+
182
+ if grep -q '"error"' /tmp/test_invalid_response.json || \
183
+ grep -q 'required' /tmp/test_invalid_response.json; then
184
+ log_success "Parameter validation working correctly"
185
+ return 0
186
+ else
187
+ log_warning "Parameter validation may not be working"
188
+ return 1
189
+ fi
190
+ }
191
+
192
+ # Test 5: List available tools
193
+ test_list_tools() {
194
+ log_info "Test 5: Listing available tools..."
195
+
196
+ cat > /tmp/test_list.json <<EOF
197
+ {
198
+ "jsonrpc": "2.0",
199
+ "id": 3,
200
+ "method": "tools/list"
201
+ }
202
+ EOF
203
+
204
+ timeout 5 cat /tmp/test_list.json | \
205
+ MCP_PORT=$TEST_PORT bun stdio.ts > /tmp/test_list_response.json 2>&1
206
+
207
+ if grep -q '"tools"' /tmp/test_list_response.json && \
208
+ grep -q '"exec_ssh"' /tmp/test_list_response.json; then
209
+ log_success "Tools list includes exec_ssh"
210
+ return 0
211
+ else
212
+ log_error "Tools list incomplete"
213
+ cat /tmp/test_list_response.json
214
+ return 1
215
+ fi
216
+ }
217
+
218
+ # Cleanup function
219
+ cleanup() {
220
+ log_info "Cleaning up..."
221
+
222
+ # Kill server if running
223
+ if [ -f /tmp/terminal-mcp-test.pid ]; then
224
+ SERVER_PID=$(cat /tmp/terminal-mcp-test.pid)
225
+ if ps -p $SERVER_PID > /dev/null 2>&1; then
226
+ kill $SERVER_PID 2>/dev/null || true
227
+ log_info "Killed MCP server (PID: $SERVER_PID)"
228
+ fi
229
+ rm -f /tmp/terminal-mcp-test.pid
230
+ fi
231
+
232
+ # Clean up test files
233
+ rm -f /tmp/test_*.json
234
+
235
+ # Display results
236
+ echo ""
237
+ echo "==================================="
238
+ echo "Test Results Summary"
239
+ echo "==================================="
240
+ echo -e "Passed: ${GREEN}${TESTS_PASSED}${NC}"
241
+ echo -e "Failed: ${RED}${TESTS_FAILED}${NC}"
242
+ echo "==================================="
243
+
244
+ if [ $TESTS_FAILED -eq 0 ]; then
245
+ echo -e "${GREEN}All tests passed!${NC}"
246
+ exit 0
247
+ else
248
+ echo -e "${RED}Some tests failed!${NC}"
249
+ exit 1
250
+ fi
251
+ }
252
+
253
+ # Trap cleanup on exit
254
+ trap cleanup EXIT
255
+
256
+ # Main test execution
257
+ main() {
258
+ log_info "Terminal MCP Fix Test Suite"
259
+ log_info "=============================="
260
+ echo ""
261
+
262
+ # Run tests
263
+ test_server_startup || exit 1
264
+ test_list_tools || true
265
+ test_no_recursion || true
266
+ test_memory_leak || true
267
+ test_parameter_validation || true
268
+
269
+ # Cleanup will be called by trap
270
+ }
271
+
272
+ # Run main function
273
+ main "$@"
package/package.json ADDED
@@ -0,0 +1,118 @@
1
+ {
2
+ "name": "@ebowwa/terminal",
3
+ "version": "0.2.0",
4
+ "description": "Terminal session management with tmux integration, SSH client, WebSocket support, and MCP interface",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./sessions": {
14
+ "types": "./dist/sessions.d.ts",
15
+ "default": "./dist/sessions.js"
16
+ },
17
+ "./tmux": {
18
+ "types": "./dist/tmux.d.ts",
19
+ "default": "./dist/tmux.js"
20
+ },
21
+ "./manager": {
22
+ "types": "./dist/manager.d.ts",
23
+ "default": "./dist/manager.js"
24
+ },
25
+ "./types": {
26
+ "types": "./dist/types.d.ts",
27
+ "default": "./dist/types.js"
28
+ },
29
+ "./api": {
30
+ "types": "./dist/api.d.ts",
31
+ "default": "./dist/api.js"
32
+ },
33
+ "./config": {
34
+ "types": "./dist/config.d.ts",
35
+ "default": "./dist/config.js"
36
+ },
37
+ "./pool": {
38
+ "types": "./dist/pool.d.ts",
39
+ "default": "./dist/pool.js"
40
+ },
41
+ "./exec": {
42
+ "types": "./dist/exec.d.ts",
43
+ "default": "./dist/exec.js"
44
+ },
45
+ "./pty": {
46
+ "types": "./dist/pty.d.ts",
47
+ "default": "./dist/pty.js"
48
+ },
49
+ "./files": {
50
+ "types": "./dist/files.d.ts",
51
+ "default": "./dist/files.js"
52
+ },
53
+ "./scp": {
54
+ "types": "./dist/scp.d.ts",
55
+ "default": "./dist/scp.js"
56
+ },
57
+ "./fingerprint": {
58
+ "types": "./dist/fingerprint.d.ts",
59
+ "default": "./dist/fingerprint.js"
60
+ },
61
+ "./tmux-exec": {
62
+ "types": "./dist/tmux-exec.d.ts",
63
+ "default": "./dist/tmux-exec.js"
64
+ },
65
+ "./client": {
66
+ "types": "./dist/client.d.ts",
67
+ "default": "./dist/client.js"
68
+ },
69
+ "./network-error-detector": {
70
+ "types": "./dist/network-error-detector.d.ts",
71
+ "default": "./dist/network-error-detector.js"
72
+ },
73
+ "./mcp": {
74
+ "types": "./src/mcp/index.ts",
75
+ "default": "./dist/mcp/index.js"
76
+ }
77
+ },
78
+ "scripts": {
79
+ "mcp": "bun run src/mcp/index.ts",
80
+ "mcp-dev": "MCP_PORT=8913 bun run src/mcp/index.ts",
81
+ "mcp-stdio": "bun run src/mcp/stdio.ts"
82
+ },
83
+ "keywords": [
84
+ "terminal",
85
+ "tmux",
86
+ "ssh",
87
+ "session",
88
+ "websocket",
89
+ "mcp",
90
+ "pty",
91
+ "cli",
92
+ "remote"
93
+ ],
94
+ "author": "Ebowwa Labs <labs@ebowwa.com>",
95
+ "license": "MIT",
96
+ "homepage": "https://github.com/ebowwa/terminal#readme",
97
+ "repository": {
98
+ "type": "git",
99
+ "url": "git+https://github.com/ebowwa/terminal.git",
100
+ "directory": "/"
101
+ },
102
+ "bugs": {
103
+ "url": "https://github.com/ebowwa/terminal/issues"
104
+ },
105
+ "engines": {
106
+ "node": ">=18.0.0"
107
+ },
108
+ "dependencies": {
109
+ "@ebowwa/codespaces-types": "^1.1.0",
110
+ "node-ssh": "^13.2.1",
111
+ "hono": "^4.11.3",
112
+ "zod": "^3.24.1"
113
+ },
114
+ "devDependencies": {
115
+ "@types/bun": "latest",
116
+ "@types/node-ssh": "^11.0.0"
117
+ }
118
+ }