@ebowwa/mcp-terminal 1.0.8
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/BUG-ANALYSIS.md +148 -0
- package/FIX-QUICK-REF.md +67 -0
- package/README.md +181 -0
- package/ROLLBACK.md +388 -0
- package/bun.lock +323 -0
- package/lmdb.db +0 -0
- package/lmdb.db-lock +0 -0
- package/package.json +40 -0
- package/stdio.js +555 -0
- package/test-fix.sh +273 -0
- package/wrapper.mjs +10 -0
package/test-fix.sh
ADDED
|
@@ -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/wrapper.mjs
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Terminal MCP Server - Node.js wrapper
|
|
4
|
+
*
|
|
5
|
+
* This wrapper ensures proper module resolution for the stdio.ts
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Use dynamic import to ensure @ebowwa/terminal is resolved correctly
|
|
9
|
+
const { default: run } = await import('./stdio.ts');
|
|
10
|
+
run();
|