๐ MCP ShellKeeper
Persistent Terminal Sessions + File Transfer for AI Assistants
SSH into servers, run commands, transfer files โ all through your AI assistant. No more stateless limitations.
Real-World Example โข Installation โข Core Features โข Use Cases โข Tools
๐ฏ The Problem
AI assistants like Cursor execute commands statelessly โ each command runs in a fresh environment:
โ ssh user@server # Hangs forever - no output until exit
โ Can't run commands after SSH
โ Each command starts from scratch
โ No way to transfer files to/from servers
โ Must re-authenticate for every operation
โจ The Solution
ShellKeeper transforms AI assistants into stateful operators with persistent sessions and file transfer capabilities.
๐ Core Features
๐ Stateful ExecutionTraditional AI (Stateless) ShellKeeper (Stateful) AI maintains full context between your questions! |
๐ฏ Persistent SessionsNatural Conversation Flow The AI remembers everything:
|
๐ Seamless File TransferJust Ask in Natural Language It just works:
|
๐ฌ Real-World Example
Watch how a natural conversation becomes automated operations:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ค YOU ASK:
"Debug the slow API on prod-server-01"
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ค AI EXECUTES:
[Connecting...]
โ ssh user@prod-server-01
โ
Connected to prod-server-01
[Investigating processes...]
โ ps aux | grep api
๐ API process found: PID 1234, using 98% CPU
[Checking logs...]
โ cd /var/log/api && tail -n 100 error.log
๐ ERROR: Memory leak in /api/v1/users endpoint
[Downloading for analysis...]
โ Download: /var/log/api/error.log โ ./local-debug/
โ
Downloaded 2.4MB (analyzed: 500+ memory errors)
[Applying fix...]
โ Upload: ./fixed-config.yml โ /app/config/
โ
Uploaded new rate-limiting config
[Restarting service...]
โ systemctl restart api-service
โ systemctl status api-service
โ
Service restarted, CPU now at 12%
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ค AI RESPONDS:
"Fixed! The API had a memory leak in the users endpoint.
โข Downloaded logs and found 500+ memory allocation errors
โข Applied rate-limiting configuration
โข Restarted service - CPU dropped from 98% to 12%
โข All operations completed in one persistent session"
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โจ All in ONE session, NO re-authentication needed! โจ
๐ฆ Installation
npm install -g mcp-shellkeeper
Configuration
Cursor Settings JSON: ( |
Claude Code Config file: ( |
VS Code (Cline) Settings JSON: |
Restart your AI assistant and you're ready! ๐
๐ก Use Cases
| Scenario | What You Ask | What AI Does |
|---|---|---|
| ๐ Debug Production | "Why is prod-api slow?" | SSH โ Check CPU/memory โ Download logs โ Analyze โ Upload fix โ Restart |
| ๐ Deploy Updates | "Deploy v2.0 to staging" | SSH โ Backup โ Upload files โ Migrate DB โ Restart โ Verify |
| ๐ง Update Configs | "Update SSL certs on web servers" | SSH โ Download old certs โ Upload new โ Test โ Reload nginx |
| ๐๏ธ Backup Database | "Backup prod DB to local" | SSH through bastion โ Dump DB โ Compress โ Download โ Verify |
| ๐ Analyze Logs | "Find all 500 errors today" | SSH โ Parse logs โ Download โ Analyze locally โ Report patterns |
| ๐ Batch Operations | "Update configs on all servers" | Parallel sessions โ Upload โ Restart โ Download results |
All through natural conversation with your AI! No scripts, no manual SSH juggling.
๐ Available Tools
The AI uses these tools automatically, but you can reference them for advanced use:
| Tool | Purpose | Key Features |
|---|---|---|
terminal_execute |
Run commands in persistent session | Timeout config, exit code capture, clean output |
terminal_upload_file |
Upload local โ remote (max 10MB) | Auto-detect directory, handle duplicates, works through SSH |
terminal_download_file |
Download remote โ local (max 10MB) | Auto-create dirs, preserve permissions, verify integrity |
terminal_new_session |
Create isolated session | Parallel operations, separate environments |
terminal_list_sessions |
View all active sessions | Status, uptime, last command |
terminal_close_session |
Clean up session | Free resources when done |
terminal_get_buffer |
Debug raw output | Useful for troubleshooting |
๐ก Tip: The AI handles these automatically based on your natural language requests!
๐ Security Best Practices
โ DO:
- Use SSH key authentication (not passwords):
ssh-keygen -t ed25519 - Jump through bastion hosts for production:
ssh -J bastion.com user@prod - Limit file upload destinations (avoid
/etc,/root,.ssh/) - Use read-only accounts for investigation
- Clean up sessions after tasks
- Audit all AI operations
โ DON'T:
- Store passwords in commands or configs
- Upload untrusted files to production
- Download sensitive data without encryption
- Run destructive commands without verification
- Grant unnecessary permissions
๐ ๏ธ How It Works
Persistent Sessions:
- Uses PTY (Pseudo-Terminal) for full TTY emulation with state persistence
- Smart markers detect command completion automatically
- Exit codes captured for error detection
- Output parsed clean (no ANSI codes)
File Transfer:
- Base64 encoding through existing SSH sessions (no separate SCP/SFTP)
- Works through jump hosts without re-authentication
- Max 10MB, 5-minute timeout (completes early if faster)
๐ Troubleshooting
Commands timeout or hang// Increase timeout for long-running commands
terminal_execute({
command: "npm install",
timeout: 120000 // 2 minutes
})
// Check if SSH keys are set up correctly
ssh -v user@server
SSH asks for password
# Set up passwordless authentication
ssh-keygen -t ed25519
ssh-copy-id user@server
# Verify
ssh user@server "echo Success"
File upload fails
// Check if in SSH session first
terminal_execute({ command: "pwd" }) // Verify you're on remote server
// Ensure remote directory exists
terminal_execute({ command: "mkdir -p /app/uploads" })
// Then upload
terminal_upload({ local_path: "file.txt", remote_path: "/app/uploads/file.txt" })
File download fails
// Verify remote file exists
terminal_execute({ command: "ls -lh /path/to/file" })
// Check permissions
terminal_execute({ command: "cat /path/to/file | wc -l" })
// Try download with absolute path
terminal_download({ remote_path: "/full/path/to/file", local_path: "./" })
Session becomes unresponsive
// List all sessions
terminal_list_sessions()
// Close problematic session
terminal_close_session({ session_id: "stuck-session" })
// Create fresh session
terminal_new_session({ session_id: "new-session" })
๐งช Development
# Clone repository
git clone https://github.com/tranhuucanh/mcp-shellkeeper.git
cd mcp-shellkeeper
# Install dependencies
npm install
# Build
npm run build
# Test locally with stdio transport
node dist/index.js
# Test with MCP Inspector
npm run inspector
๐ค Contributing
Contributions welcome! Help make AI-assisted server management better.
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open Pull Request
๐ License
MIT License - see LICENSE file for details.
You can:
- โ Use commercially
- โ Modify
- โ Distribute
- โ Private use
๐ Acknowledgments
- Built with Model Context Protocol SDK
- Uses node-pty for terminal emulation
- Inspired by the need for stateful command execution in AI workflows
๐ Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- MCP Community: Discord