@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/ROLLBACK.md
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
# Terminal MCP Rollback Plan
|
|
2
|
+
|
|
3
|
+
**Team:** terminal-mcp-fix
|
|
4
|
+
**Date:** 2026-02-05
|
|
5
|
+
**Safety Engineer:** safety agent
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Executive Summary
|
|
10
|
+
|
|
11
|
+
This document provides comprehensive rollback procedures for the terminal MCP recursive loop fix. The fix addresses a critical bug where tool implementation functions had naming conflicts with imported terminal functions, causing infinite recursion.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Bug Analysis
|
|
16
|
+
|
|
17
|
+
### Root Cause
|
|
18
|
+
|
|
19
|
+
The terminal MCP stdio server had naming collisions between:
|
|
20
|
+
1. **Imported terminal functions** (e.g., `execSSH`, `listTmuxSessions`, `listFiles`)
|
|
21
|
+
2. **MCP tool wrapper functions** (e.g., `execSSHTool`, `listTmuxSessionsTool`, `listFilesTool`)
|
|
22
|
+
|
|
23
|
+
When the MCP server tried to call an imported function, it instead called its own wrapper function, causing infinite recursion.
|
|
24
|
+
|
|
25
|
+
### Affected Files
|
|
26
|
+
|
|
27
|
+
- `/packages/src/terminal/mcp/stdio.ts` - **CRITICAL**
|
|
28
|
+
- `/packages/src/terminal/mcp/index.ts` - HTTP version (similar pattern)
|
|
29
|
+
|
|
30
|
+
### Critical Code Locations
|
|
31
|
+
|
|
32
|
+
#### stdio.ts Line 561 (BUGGY)
|
|
33
|
+
```typescript
|
|
34
|
+
case "list_sessions":
|
|
35
|
+
return await listSessions(); // BUG: Calls itself instead of listSessionsTool()
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
#### stdio.ts Line 577 (BUGGY)
|
|
39
|
+
```typescript
|
|
40
|
+
case "list_tmux_sessions":
|
|
41
|
+
return await listTmuxSessions(); // BUG: Recursive call to imported function
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### stdio.ts Line 579 (BUGGY)
|
|
45
|
+
```typescript
|
|
46
|
+
case "list_files":
|
|
47
|
+
return await listFiles(args.host, args.path); // BUG: Recursive call
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Changes Being Made
|
|
53
|
+
|
|
54
|
+
### Diff Summary
|
|
55
|
+
|
|
56
|
+
```diff
|
|
57
|
+
diff --git a/src/terminal/mcp/stdio.ts b/src/terminal/mcp/stdio.ts
|
|
58
|
+
@@ -120,7 +120,7 @@ interface MCPTool {
|
|
59
|
+
// Tool Implementations
|
|
60
|
+
//=============
|
|
61
|
+
|
|
62
|
+
-async function listSessions(): Promise<string> {
|
|
63
|
+
+async function listSessionsTool(): Promise<string> {
|
|
64
|
+
const sessions = getAllSessionInfo();
|
|
65
|
+
...
|
|
66
|
+
|
|
67
|
+
@@ -145,7 +145,7 @@ async function listSessions(): Promise<string> {
|
|
68
|
+
return lines.join("\n");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
-async function getSessionInfo(sessionId: string): Promise<string> {
|
|
72
|
+
+async function getSessionInfoTool(sessionId: string): Promise<string> {
|
|
73
|
+
...
|
|
74
|
+
|
|
75
|
+
@@ -220,7 +220,7 @@ async function closeSession(sessionId: string): Promise<string> {
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
-async function execSSH(host: string, command: string, options?: Partial<SSHOptions>): Promise<string> {
|
|
80
|
+
+async function execSSHTool(host: string, command: string, options?: Partial<SSHOptions>): Promise<string> {
|
|
81
|
+
...
|
|
82
|
+
|
|
83
|
+
@@ -242,7 +242,7 @@ async function testConnection(host: string): Promise<string> {
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
-async function listTmuxSessions(): Promise<string> {
|
|
88
|
+
+async function listTmuxSessionsTool(): Promise<string> {
|
|
89
|
+
...
|
|
90
|
+
|
|
91
|
+
@@ -269,7 +269,7 @@ async function listTmuxSessions(): Promise<string> {
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
-async function listFiles(host: string, path: string = "."): Promise<string> {
|
|
96
|
+
+async function listFilesTool(host: string, path: string = "."): Promise<string> {
|
|
97
|
+
...
|
|
98
|
+
|
|
99
|
+
@@ -560,29 +560,29 @@ async function handleToolCall(name: string, args: any): Promise<string> {
|
|
100
|
+
case "list_sessions":
|
|
101
|
+
- return await listSessions();
|
|
102
|
+
+ return await listSessionsTool();
|
|
103
|
+
case "get_session_info":
|
|
104
|
+
return await getSessionInfoTool(args.session_id);
|
|
105
|
+
case "create_session":
|
|
106
|
+
return await createSessionTool(args.host, args.type, args.command);
|
|
107
|
+
case "write_command":
|
|
108
|
+
return await writeCommandTool(args.session_id, args.command);
|
|
109
|
+
case "resize_session":
|
|
110
|
+
return await resizeSessionTool(args.session_id, args.rows, args.cols);
|
|
111
|
+
case "close_session":
|
|
112
|
+
return await closeSessionTool(args.session_id);
|
|
113
|
+
case "exec_ssh":
|
|
114
|
+
- return await execSSH(args.host, args.command, args.options);
|
|
115
|
+
+ return await execSSHTool(args.host, args.command, args.options);
|
|
116
|
+
case "test_connection":
|
|
117
|
+
return await testConnection(args.host);
|
|
118
|
+
case "list_tmux_sessions":
|
|
119
|
+
- return await listTmuxSessions();
|
|
120
|
+
+ return await listTmuxSessionsTool();
|
|
121
|
+
case "list_files":
|
|
122
|
+
- return await listFiles(args.host, args.path);
|
|
123
|
+
+ return await listFilesTool(args.host, args.path);
|
|
124
|
+
case "upload_file":
|
|
125
|
+
return await uploadFileTool(args.host, args.local_path, args.remote_path);
|
|
126
|
+
case "download_file":
|
|
127
|
+
return await downloadFileTool(args.host, args.remote_path, args.local_path);
|
|
128
|
+
case "get_active_connections":
|
|
129
|
+
return await getActiveConnectionsTool();
|
|
130
|
+
default:
|
|
131
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Rollback Procedures
|
|
137
|
+
|
|
138
|
+
### Quick Rollback (Emergency)
|
|
139
|
+
|
|
140
|
+
If the fix causes unexpected issues:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# 1. Navigate to packages directory
|
|
144
|
+
cd /Users/ebowwa/Desktop/codespaces/packages
|
|
145
|
+
|
|
146
|
+
# 2. Restore original file from git
|
|
147
|
+
git checkout HEAD -- src/terminal/mcp/stdio.ts
|
|
148
|
+
|
|
149
|
+
# 3. Rebuild if needed
|
|
150
|
+
cd src/terminal/mcp
|
|
151
|
+
bun build stdio.ts --outfile stdio.js
|
|
152
|
+
|
|
153
|
+
# 4. Restart MCP server
|
|
154
|
+
# Kill existing process and restart
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Complete Rollback to Last Known Good
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# 1. Check current state
|
|
161
|
+
cd /Users/ebowwa/Desktop/codespaces/packages
|
|
162
|
+
git log --oneline -5
|
|
163
|
+
|
|
164
|
+
# 2. Reset to last known good commit
|
|
165
|
+
# (Identify commit before the fix)
|
|
166
|
+
git reset --hard <commit-hash>
|
|
167
|
+
|
|
168
|
+
# 3. Force push if already pushed (USE WITH CAUTION)
|
|
169
|
+
git push --force origin feat/glm-daemon
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Selective Rollback (Partial Fix)
|
|
173
|
+
|
|
174
|
+
If only certain functions need reverting:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Restore specific function from git
|
|
178
|
+
git checkout HEAD -- src/terminal/mcp/stdio.ts
|
|
179
|
+
|
|
180
|
+
# Then manually cherry-pick specific fixes
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Verification Checklist
|
|
186
|
+
|
|
187
|
+
Before deploying the fix, verify:
|
|
188
|
+
|
|
189
|
+
### Code Review
|
|
190
|
+
- [ ] All tool wrapper functions have `Tool` suffix
|
|
191
|
+
- [ ] No function names shadow imported functions
|
|
192
|
+
- [ ] `handleToolCall` uses correct function names
|
|
193
|
+
- [ ] All MCP tools mapped to correct implementations
|
|
194
|
+
|
|
195
|
+
### Testing
|
|
196
|
+
- [ ] No recursion in `execSSH`
|
|
197
|
+
- [ ] No recursion in `listTmuxSessions`
|
|
198
|
+
- [ ] No recursion in `listFiles`
|
|
199
|
+
- [ ] No recursion in `listSessions`
|
|
200
|
+
- [ ] No recursion in `getSessionInfo`
|
|
201
|
+
- [ ] No recursion in `createSession`
|
|
202
|
+
- [ ] No recursion in `writeCommand`
|
|
203
|
+
- [ ] No recursion in `resizeSession`
|
|
204
|
+
- [ ] No recursion in `closeSession`
|
|
205
|
+
- [ ] No recursion in `uploadFile`
|
|
206
|
+
- [ ] No recursion in `downloadFile`
|
|
207
|
+
- [ ] No recursion in `getActiveConnections`
|
|
208
|
+
|
|
209
|
+
### MCP Protocol
|
|
210
|
+
- [ ] MCP protocol initialization works
|
|
211
|
+
- [ ] Tools list endpoint returns correct tools
|
|
212
|
+
- [ ] Tools can be called successfully
|
|
213
|
+
- [ ] Error handling works correctly
|
|
214
|
+
|
|
215
|
+
### Integration Testing
|
|
216
|
+
- [ ] Can connect to VPS via SSH
|
|
217
|
+
- [ ] Can list tmux sessions
|
|
218
|
+
- [ ] Can list files on remote host
|
|
219
|
+
- [ ] Can execute commands via SSH
|
|
220
|
+
- [ ] Discord bot integration works
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Monitoring After Deployment
|
|
225
|
+
|
|
226
|
+
### Key Metrics to Monitor
|
|
227
|
+
|
|
228
|
+
1. **Process Health**
|
|
229
|
+
- CPU usage (should be normal, not 100%)
|
|
230
|
+
- Memory usage (should not grow indefinitely)
|
|
231
|
+
- Process uptime (should not crash/restart loop)
|
|
232
|
+
|
|
233
|
+
2. **MCP Server Health**
|
|
234
|
+
- Response times (should be < 1s for most operations)
|
|
235
|
+
- Error rates (should be near zero)
|
|
236
|
+
- Successful tool executions
|
|
237
|
+
|
|
238
|
+
3. **Discord Bot**
|
|
239
|
+
- Bot responsiveness
|
|
240
|
+
- Command execution success rate
|
|
241
|
+
- No "hang" or timeout issues
|
|
242
|
+
|
|
243
|
+
### Warning Signs
|
|
244
|
+
|
|
245
|
+
**IMMEDIATE ROLLBACK IF:**
|
|
246
|
+
- CPU usage spikes to 100% (indicates recursion)
|
|
247
|
+
- Memory grows indefinitely (indicates memory leak)
|
|
248
|
+
- Process crashes within 5 minutes
|
|
249
|
+
- Discord bot becomes unresponsive
|
|
250
|
+
- SSH connections fail or timeout
|
|
251
|
+
|
|
252
|
+
### Log Monitoring
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
# Monitor for recursion errors
|
|
256
|
+
tail -f /var/log/terminal-mcp.log | grep -i "maximum call stack"
|
|
257
|
+
|
|
258
|
+
# Monitor for high CPU
|
|
259
|
+
top -p $(pgrep -f "stdio.ts")
|
|
260
|
+
|
|
261
|
+
# Monitor for process crashes
|
|
262
|
+
watch -n 5 'pgrep -f "stdio.ts" || echo "PROCESS DOWN"'
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Recovery Steps
|
|
268
|
+
|
|
269
|
+
If Rollback is Needed
|
|
270
|
+
|
|
271
|
+
1. **Immediate Actions**
|
|
272
|
+
```bash
|
|
273
|
+
# Kill the MCP process
|
|
274
|
+
pkill -f "stdio.ts"
|
|
275
|
+
|
|
276
|
+
# Restore from git
|
|
277
|
+
cd /Users/ebowwa/Desktop/codespaces/packages
|
|
278
|
+
git checkout HEAD -- src/terminal/mcp/stdio.ts
|
|
279
|
+
|
|
280
|
+
# Rebuild
|
|
281
|
+
bun build src/terminal/mcp/stdio.ts --outfile src/terminal/mcp/stdio.js
|
|
282
|
+
|
|
283
|
+
# Restart
|
|
284
|
+
# Use your normal startup procedure
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
2. **Verify Rollback**
|
|
288
|
+
```bash
|
|
289
|
+
# Test basic functionality
|
|
290
|
+
curl http://localhost:8913/health
|
|
291
|
+
|
|
292
|
+
# Test MCP connection
|
|
293
|
+
# Your MCP test script
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
3. **Document Incident**
|
|
297
|
+
- What went wrong
|
|
298
|
+
- When it was detected
|
|
299
|
+
- What was rolled back
|
|
300
|
+
- Lessons learned
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Prevention for Future
|
|
305
|
+
|
|
306
|
+
### Code Review Checklist
|
|
307
|
+
|
|
308
|
+
Before merging any MCP server changes:
|
|
309
|
+
|
|
310
|
+
- [ ] No function name shadowing
|
|
311
|
+
- [ ] All tool wrappers have distinct names
|
|
312
|
+
- [ ] Imports are aliased if conflicts exist
|
|
313
|
+
- [ ] Static analysis passes
|
|
314
|
+
- [ ] Manual testing completed
|
|
315
|
+
|
|
316
|
+
### Development Guidelines
|
|
317
|
+
|
|
318
|
+
1. **Naming Convention**
|
|
319
|
+
- MCP tool implementations: `*Tool` suffix
|
|
320
|
+
- Imported functions: use `as` alias if needed
|
|
321
|
+
- Never use same name for different purposes
|
|
322
|
+
|
|
323
|
+
2. **Testing**
|
|
324
|
+
- Always test with real MCP client
|
|
325
|
+
- Test each tool individually
|
|
326
|
+
- Test error conditions
|
|
327
|
+
- Monitor for recursion (CPU spikes)
|
|
328
|
+
|
|
329
|
+
3. **Code Review**
|
|
330
|
+
- Peer review required for MCP changes
|
|
331
|
+
- Check for naming conflicts
|
|
332
|
+
- Verify no shadowing
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Contact Information
|
|
337
|
+
|
|
338
|
+
**Team Lead:** team-lead
|
|
339
|
+
**Safety Engineer:** safety agent
|
|
340
|
+
**Fixer:** fixer agent
|
|
341
|
+
**Tester:** tester agent
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Appendix: Git Commands Reference
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
# View current changes
|
|
349
|
+
git diff src/terminal/mcp/stdio.ts
|
|
350
|
+
|
|
351
|
+
# View file history
|
|
352
|
+
git log --oneline -10 -- src/terminal/mcp/stdio.ts
|
|
353
|
+
|
|
354
|
+
# Show specific commit
|
|
355
|
+
git show <commit-hash>:src/terminal/mcp/stdio.ts
|
|
356
|
+
|
|
357
|
+
# Create backup before changes
|
|
358
|
+
cp src/terminal/mcp/stdio.ts src/terminal/mcp/stdio.ts.backup
|
|
359
|
+
|
|
360
|
+
# Restore from backup
|
|
361
|
+
cp src/terminal/mcp/stdio.ts.backup src/terminal/mcp/stdio.ts
|
|
362
|
+
|
|
363
|
+
# Stash changes temporarily
|
|
364
|
+
git stash push -m "backup before fix" src/terminal/mcp/stdio.ts
|
|
365
|
+
|
|
366
|
+
# Unstash if needed
|
|
367
|
+
git stash pop
|
|
368
|
+
|
|
369
|
+
# Create rollback branch
|
|
370
|
+
git checkout -b rollback/terminal-mcp-fix
|
|
371
|
+
|
|
372
|
+
# Merge rollback to main
|
|
373
|
+
git checkout feat/glm-daemon
|
|
374
|
+
git merge rollback/terminal-mcp-fix
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## Status
|
|
380
|
+
|
|
381
|
+
- [ ] Rollback plan created
|
|
382
|
+
- [ ] Team notified
|
|
383
|
+
- [ ] Backup procedures tested
|
|
384
|
+
- [ ] Monitoring in place
|
|
385
|
+
- [ ] Ready for deployment
|
|
386
|
+
|
|
387
|
+
**Last Updated:** 2026-02-05
|
|
388
|
+
**Document Version:** 1.0
|