FleetShell
Multi-server SSH command execution relay for Claude AI via Model Context Protocol (MCP)
FleetShell is an MCP relay server that allows Claude AI to execute commands across multiple remote servers via SSH. It runs as an HTTP server that Claude Desktop connects to via the MCP protocol, providing Claude with tools to manage your entire server fleet.
┌─────────────────┐ ┌──────────────────────────┐
│ Claude Desktop │─────HTTPS────▶│ FleetShell Relay MCP │
│ (Your Desktop) │ │ (Your Server) │
│ │ │ │
│ Uses: │ │ ┌────────────────────┐ │
│ npx mcp-remote │ │ │ 18 MCP Tools │ │
└─────────────────┘ │ └────────────────────┘ │
│ │ │
│ │ SSH │
│ ▼ │
│ ┌────────────────────┐ │
│ │ Target Servers │ │
│ │ (mail, web, db) │ │
│ └────────────────────┘ │
└──────────────────────────┘
Features
- 🔐 TOTP 2FA Authentication: Time-based one-time passwords required for all tool calls
- 29 Built-in MCP Tools: Server discovery, command execution, shell sessions, log analysis, service management, file operations, system info, prompt management, and marketplace integration
- MCP Aggregator: Integrate external MCP servers (Playwright, filesystem, etc.) and expose their tools through FleetShell
- Persistent SSH Shell Sessions: Maintain stateful SSH sessions across multiple commands for interactive workflows
- Prompt Database: Save and reuse AI prompts with file-based JSON storage
- MCP Marketplace: Browse and install MCP servers directly from FleetShell
- Secure by Design: API key + TOTP authentication, SSH key-based connections, dangerous command blocking
- Per-Server Context: Rich configuration files with service definitions, troubleshooting commands, and notes
- Parallel Execution: Run commands across multiple servers simultaneously
- HTTP/HTTPS Transport: Uses MCP Streamable HTTP for reliable communication
---
Table of Contents
- Quick Start
- TOTP 2FA Authentication
- Installation
- Deployment on a Server
- Configuration
- Managing Servers
- Managing External MCPs
- Shell Session Management
- Prompt Database
- MCP Marketplace
- Claude Desktop Setup
- Available MCP Tools
- Server Configuration Format
- Security Considerations
- Troubleshooting
- Running as a Systemd Service
---
Quick Start
# 1. Clone and install
git clone https://github.com/yourusername/fleetshell.git
cd fleetshell
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
# 2. Initialize FleetShell (generates SSH keys, TLS certs, API key)
fleetshell init
# 3. Copy the public key to your servers
fleetshell pubkey
# Add this key to ~/.ssh/authorized_keys on each target server
# 4. Add a server
fleetshell add-server
# 5. Test the connection
fleetshell test <server-id>
# 6. Start the MCP server
fleetshell serve
---
TOTP 2FA Authentication
FleetShell uses Time-based One-Time Passwords (TOTP) for two-factor authentication. This ensures that even if your API key is compromised, attackers cannot execute commands without access to your authenticator app.
How It Works
┌─────────────────┐ API Key ┌─────────────────┐
│ Claude Desktop │────────────────▶│ FleetShell │
│ │ │ (Validates) │
└─────────────────┘ └────────┬────────┘
│
▼
┌─────────────────┐
│ Session Created │
│ (Unauthenticated)│
└────────┬────────┘
│
┌─────────────────┐ │ Tool calls blocked
│ Authenticator │ │ (Error -32001)
│ App (6-digit) │ │
└────────┬────────┘ │
│ ▼
│ ┌───────────────────────────┐
└──────────▶│ authenticate(code="123456")│
└───────────────────────────┘
│
▼
┌─────────────────┐
│ Session Valid │
│ (1 hour expiry) │
└─────────────────┘
│
▼
┌─────────────────┐
│ All Tools Work │
└─────────────────┘
Initial Setup
When you run fleetshell init, a TOTP secret is generated and a QR code is displayed:
fleetshell init
Output includes: ``` ═══════════════════════════════════════════════════════════════════ 🔐 TOTP 2FA AUTHENTICATION SETUP ═══════════════════════════════════════════════════════════════════
Scan this QR code with your authenticator app: (Google Authenticator, Authy, 1Password, etc.)
█▀▀▀▀▀█ ▄▄▄▄▄ █▀▀▀▀▀█ █ ███ █ █▄▄▄█ █ ███ █ █ ▀▀▀ █ ▀▀▀▀▀ █ ▀▀▀ █ ▀▀▀▀▀▀▀ █ █ █ ▀▀▀▀▀▀▀ ...
Manual entry key: JBSWY3DPEHPK3PXP Account name: fleetshell-relay
IMPORTANT: Save this secret! You'll need it if you lose access to your authenticator app. Store it securely (password manager recommended).
═══════════════════════════════════════════════════════════════════ ```
- Open your authenticator app (Google Authenticator, Authy, 1Password, etc.)
- Scan the QR code or manually enter the secret key
- The app will now generate 6-digit codes that change every 30 seconds
Authentication Flow in Claude
When you first connect Claude Desktop to FleetShell after a restart (or session expiry), tool calls will be blocked until authenticated:
Step 1: Claude attempts a tool call `` User: "List all my servers" Claude: [Calls list_servers tool] Error: Authentication required. Please authenticate with a TOTP code using the authenticate tool. ``
Step 2: Claude authenticates `` User: "The code is 123456" Claude: [Calls authenticate(code="123456")] Result: Successfully authenticated. Session valid for 1 hour. ``
Step 3: All tools now work `` User: "Now list my servers" Claude: [Calls list_servers tool] Result: Found 3 servers... ``
Session Expiry
- Sessions are valid for 1 hour (3600 seconds)
- After expiry, Claude will need to re-authenticate
- Restarting FleetShell invalidates all sessions
CLI Commands for 2FA Management
# Display QR code again (if you need to re-add to authenticator)
fleetshell auth setup
# Check if MFA is enabled and configured
fleetshell auth status
# Test a TOTP code
fleetshell auth test 123456
# Disable MFA (not recommended for production)
fleetshell auth disable
# Re-enable MFA
fleetshell auth enable
Disabling 2FA (Development Only)
For development/testing, you can disable MFA:
fleetshell auth disable
This sets mfa.enabled: false in ~/.fleetshell/config.yaml. Not recommended for production.
Troubleshooting 2FA
"Authentication required" error keeps appearing
- Verify you're using the correct TOTP code (changes every 30 seconds)
- Ensure your system clock is accurate (TOTP is time-sensitive)
- Run
fleetshell auth test <code>to verify codes work
Lost access to authenticator app
- If you saved the secret key during init, add it to a new authenticator
- Otherwise, run
fleetshell auth setupto display the QR code again (requires server access)
Clock sync issues ```bash
Check server time
date
Sync with NTP (Ubuntu/Debian)
sudo timedatectl set-ntp true ```
Regenerate TOTP secret (if compromised) ```bash
Manually edit config to remove old secret, then re-init
rm ~/.fleetshell/config.yaml fleetshell init ```
---
Installation
Prerequisites
- Python 3.10 or higher
- pip (Python package manager)
- SSH access to target servers
Install from Source
# Clone the repository
git clone https://github.com/yourusername/fleetshell.git
cd fleetshell
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install FleetShell
pip install -e .
# Verify installation
fleetshell --version
Dependencies
FleetShell automatically installs these dependencies:
mcp>=0.9.0- MCP protocol SDKparamiko>=3.4.0- SSH librarypyyaml>=6.0- YAML configurationclick>=8.1.0- CLI frameworkcryptography>=41.0.0- TLS/SSH key generationfastapi>=0.104.0- HTTP frameworkuvicorn>=0.24.0- ASGI serverstarlette>=0.27.0- HTTP routingsse-starlette>=1.6.5- Server-sent events
---
Deployment on a Server
FleetShell is designed to run on a dedicated server (VM, LXC container, or bare metal) that has SSH access to your target servers.
Step 1: Set Up the Server
# On your FleetShell server (Ubuntu/Debian example)
sudo apt update
sudo apt install -y python3 python3-venv python3-pip git
# Create a dedicated user (optional but recommended)
sudo useradd -m -s /bin/bash fleetshell
sudo su - fleetshell
# Clone and install
git clone https://github.com/yourusername/fleetshell.git
cd fleetshell
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
Step 2: Initialize FleetShell
fleetshell init --hostname your-server-hostname.example.com
This creates:
~/.fleetshell/relay.key- SSH private key (keep secure!)~/.fleetshell/relay.pub- SSH public key (deploy to servers)~/.fleetshell/certs/cert.pem- TLS certificate~/.fleetshell/certs/key.pem- TLS private key~/.fleetshell/config.yaml- Main configuration with API key~/.fleetshell/servers/- Server configuration directory~/.fleetshell/mcps/- External MCP configuration directory
Step 3: Deploy SSH Key to Target Servers
Get the public key:
fleetshell pubkey
Output: `` ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGxxxxxxxxxxxxxxxxxxxxxx fleetshell-relay ``
Add this key to each target server:
# On each target server
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGxxxxxx fleetshell-relay" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Or use ssh-copy-id from your local machine first, then FleetShell.
Step 4: Add Target Servers
Interactive mode: ``bash fleetshell add-server ``
Or provide details directly: ``bash fleetshell add-server \ --id web-prod-01 \ --hostname web.example.com \ --user admin \ --port 22 \ --tags production,web,nginx \ --env production \ --purpose "Primary web server" ``
Step 5: Test Connections
# Test a specific server
fleetshell test web-prod-01
# List all servers
fleetshell list
Step 6: Configure Firewall
Open port 8080 (or your configured port) for incoming connections:
# UFW (Ubuntu)
sudo ufw allow 8080/tcp
# firewalld (RHEL/CentOS)
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload
# iptables
sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
Step 7: Start the Server
Development mode: ``bash fleetshell serve ``
For production, see Running as a Systemd Service.
---
Configuration
Main Configuration File
Location: ~/.fleetshell/config.yaml
relay:
private_key: ~/.fleetshell/relay.key
public_key: ~/.fleetshell/relay.pub
log_level: INFO
log_file: ~/.fleetshell/logs/relay.log
audit_log: ~/.fleetshell/logs/audit.log
http:
host: 0.0.0.0
port: 8080
use_tls: true
cert_file: ~/.fleetshell/certs/cert.pem
key_file: ~/.fleetshell/certs/key.pem
auth:
api_key: "your-generated-api-key"
security:
command_timeout: 60
max_command_length: 5000
dangerous_commands:
- "rm -rf /"
- "dd if="
- "mkfs"
- "shutdown"
- "reboot"
Configuration Options
| Option | Description | Default | |--------|-------------|---------| | relay.http.host | Interface to bind to | 0.0.0.0 | | relay.http.port | Port to listen on | 8080 | | relay.http.use_tls | Enable HTTPS | true | | security.command_timeout | Max command execution time (seconds) | 60 | | security.max_command_length | Max command string length | 5000 |
---
Managing Servers
Add a Server
# Interactive mode
fleetshell add-server
# With all options
fleetshell add-server \
--id mail-prod-01 \
--hostname mail.example.com \
--user root \
--port 22 \
--tags production,mail,postfix \
--env production \
--purpose "Primary mail server running Postfix and Dovecot"
List Servers
fleetshell list
Output: `` ID Hostname Environment Tags ───────────────────────────────────────────────────────────── mail-prod-01 mail.example.com production mail, postfix web-prod-01 web.example.com production web, nginx db-prod-01 db.example.com production database, postgres ``
Test Connection
fleetshell test mail-prod-01
Edit Server Configuration
fleetshell edit mail-prod-01
This opens the server's .conf file in your default editor, allowing you to add detailed context, service definitions, and troubleshooting commands.
Remove a Server
fleetshell remove mail-prod-01
---
Managing External MCPs
FleetShell can aggregate external MCP servers, exposing their tools through the unified FleetShell interface.
Add an External MCP
# Add Playwright MCP for browser automation
fleetshell mcp add playwright npx \
-a "-y" \
-a "@anthropic/mcp-playwright" \
--name "Playwright Browser" \
--description "Browser automation tools" \
--tags browser,automation
# Add filesystem MCP
fleetshell mcp add filesystem npx \
-a "-y" \
-a "@anthropic/mcp-filesystem" \
--env "ALLOWED_DIRECTORIES=/var/www,/home/user" \
--description "Local filesystem access"
List External MCPs
fleetshell mcp list
Test an MCP
fleetshell mcp test playwright
This starts the MCP, lists its tools, and stops it.
Enable/Disable MCPs
fleetshell mcp disable playwright
fleetshell mcp enable playwright
View MCP Logs
fleetshell mcp logs playwright -n 100
Remove an MCP
fleetshell mcp remove playwright
MCP Configuration Files
External MCPs are configured in ~/.fleetshell/mcps/*.conf:
# ~/.fleetshell/mcps/playwright.conf
id: playwright
name: Playwright Browser Automation
command: npx
args:
- "-y"
- "@anthropic/mcp-playwright"
env:
DISPLAY: ":0"
enabled: true
auto_start: true
description: "Browser automation tools for web scraping and testing"
tags:
- browser
- automation
---
Claude Desktop Setup
Step 1: Get Your API Key
The API key was generated during fleetshell init. Find it with:
cat ~/.fleetshell/config.yaml | grep api_key
Step 2: Configure Claude Desktop
On your desktop machine (where Claude Desktop runs), edit the Claude Desktop configuration:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json Linux: ~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"fleetshell": {
"command": "npx",
"args": [
"mcp-remote",
"https://YOUR_FLEETSHELL_SERVER:8080/mcp",
"--header",
"Authorization: Bearer ${FLEETSHELL_API_KEY}"
],
"env": {
"FLEETSHELL_API_KEY": "your-api-key-here"
}
}
}
}
Replace:
YOUR_FLEETSHELL_SERVERwith your FleetShell server's IP or hostnameyour-api-key-herewith the API key from config.yaml
Step 3: Restart Claude Desktop
Restart Claude Desktop to load the new MCP configuration.
Step 4: Verify Connection
In Claude, you should now have access to FleetShell tools. Try asking:
"List all my servers"
Claude will use the list_servers tool to show your configured servers.
---
Shell Session Management
FleetShell supports persistent SSH shell sessions, allowing you to maintain stateful connections across multiple commands. This is useful for interactive workflows that require environment variables, directory changes, or session state to persist.
Key Features
- Stateful Sessions: Environment variables, working directory, and session state persist across commands
- Multiple Concurrent Sessions: Create multiple sessions to different servers simultaneously
- Auto-Cleanup: Sessions automatically expire after 30 minutes of inactivity
- Session Listing: View all active sessions and their details
CLI Commands
# List active shell sessions (informational only)
fleetshell session list
Note: Session creation and execution are done through Claude using MCP tools.
MCP Tools
| Tool | Description | |------|-------------| | create_shell_session | Create a new persistent shell session on a server | | execute_in_session | Execute a command within an existing session | | close_shell_session | Close a shell session and clean up resources | | list_active_sessions | List all active shell sessions |
Usage Examples
Creating a session: `` User: "Create a shell session on web-prod-01" Claude: [Calls create_shell_session(server_id="web-prod-01")] Result: Created session 'sess_abc123' on web-prod-01 ``
Executing commands in a session: `` User: "In that session, cd to /var/www and run ls -la" Claude: [Calls execute_in_session(session_id="sess_abc123", command="cd /var/www && ls -la")] Result: [directory listing shown] ``
Setting environment variables: `` User: "Set DEBUG=true in the session" Claude: [Calls execute_in_session(session_id="sess_abc123", command="export DEBUG=true")] ``
Closing a session: `` User: "Close the session" Claude: [Calls close_shell_session(session_id="sess_abc123")] Result: Session closed successfully ``
Session Lifecycle
- Created: New session with invoke_shell()
- Active: Accepts commands, auto-extends on activity
- Idle: No commands for 30 minutes → auto-cleanup
- Closed: Manually closed or expired
---
Prompt Database
FleetShell includes a built-in prompt database for saving and reusing AI prompts. Prompts are stored as JSON files in ~/.fleetshell/prompts/.
Features
- File-Based Storage: Simple JSON format for easy backup and version control
- Full CRUD Operations: Create, read, update, and delete prompts
- Metadata Tracking: Automatic timestamps for creation and modification
- Name Validation: Alphanumeric names with hyphens and underscores only
- Claude Integration: Use prompts directly from Claude via MCP tools
CLI Commands
# Save a new prompt
fleetshell prompt save my-prompt \
--description "Analyze server logs for errors" \
--content "Please analyze the logs on {server} for any errors in the last 24 hours"
# List all prompts
fleetshell prompt list
# Show a specific prompt
fleetshell prompt show my-prompt
# Edit a prompt (opens in default editor)
fleetshell prompt edit my-prompt
# Delete a prompt
fleetshell prompt delete my-prompt
MCP Tools
| Tool | Description | |------|-------------| | save_prompt | Save a new prompt or update an existing one | | read_prompt | Retrieve a prompt by name | | list_prompts | List all saved prompts with metadata | | edit_prompt | Update prompt description or content | | delete_prompt | Delete a prompt |
Usage Examples
Saving a prompt from Claude: `` User: "Save this as a prompt named 'db-health': Check database health including connections, slow queries, and disk usage" Claude: [Calls save_prompt(name="db-health", description="Database health check", content="Check database...")] Result: Prompt 'db-health' saved successfully ``
Using a saved prompt: `` User: "Load the db-health prompt and run it on db-prod-01" Claude: [Calls read_prompt(name="db-health")] Result: [Prompt content retrieved] Claude: [Uses prompt content to execute appropriate commands] ``
Listing prompts: ``` User: "What prompts do I have saved?" Claude: [Calls list_prompts()] Result: Found 5 prompts:
- db-health: Database health check
- log-scanner: Analyze server logs for errors
- security-audit: Run security audit checklist
... ```
Prompt File Format
Prompts are stored in ~/.fleetshell/prompts/<name>.json:
{
"name": "db-health",
"description": "Database health check",
"content": "Check database health including connections, slow queries, and disk usage",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
---
MCP Marketplace
FleetShell includes a built-in MCP marketplace for discovering and installing external MCP servers. The marketplace simplifies the process of adding new capabilities to your FleetShell instance.
Features
- Curated Package List: Pre-configured list of popular MCP servers
- One-Click Installation: Automatically install and configure MCPs
- Auto-Configuration: Installed MCPs are automatically added to FleetShell
- Installation Tracking: View which MCPs are installed
- NPX-Based: Uses npx for seamless package execution
CLI Commands
# Browse available MCPs (informational - use Claude for installation)
fleetshell mcp list
Note: Marketplace browsing and installation are primarily done through Claude using MCP tools.
MCP Tools
| Tool | Description | |------|-------------| | browse_mcp_marketplace | Browse available MCP servers with details and search | | install_mcp | Install an MCP server from the marketplace |
Available Marketplace MCPs
The marketplace includes these popular MCP servers:
| Package | Description | Category | |---------|-------------|----------| | @modelcontextprotocol/server-playwright | Browser automation and web scraping | Automation | | @modelcontextprotocol/server-github | GitHub API integration | Development | | @modelcontextprotocol/server-postgres | PostgreSQL database operations | Database | | @modelcontextprotocol/server-filesystem | Local filesystem access | System | | @modelcontextprotocol/server-slack | Slack workspace integration | Communication | | @modelcontextprotocol/server-memory | Persistent memory/knowledge base | AI | | @modelcontextprotocol/server-puppeteer | Advanced browser automation | Automation | | @modelcontextprotocol/server-brave-search | Web search via Brave | Search |
Usage Examples
Browsing the marketplace: ``` User: "What MCPs are available in the marketplace?" Claude: [Calls browse_mcp_marketplace()] Result: 8 MCP servers available:
- Playwright - Browser automation and web scraping
- GitHub - GitHub API integration
... ```
Searching the marketplace: ``` User: "Show me browser-related MCPs" Claude: [Calls browse_mcp_marketplace(search_query="browser")] Result: Found 2 matching MCPs:
- Playwright: Browser automation
- Puppeteer: Advanced browser automation
**Installing an MCP:**
User: "Install the Playwright MCP" Claude: [Calls install_mcp(package_name="@modelcontextprotocol/server-playwright", auto_configure=true)] Result: Successfully installed Playwright MCP
- Package: @modelcontextprotocol/server-playwright
- ID: playwright
- Status: Enabled and ready to use
**Installation with custom configuration:**
User: "Install GitHub MCP but don't auto-configure it" Claude: [Calls install_mcp(package_name="@modelcontextprotocol/server-github", auto_configure=false)] Result: Package installed. Manual configuration required in ~/.fleetshell/mcps/ ```
Installation Process
When you install an MCP:
- Package is installed via
npx(no global installation needed) - A
.conffile is created in~/.fleetshell/mcps/ - MCP is automatically enabled if
auto_configure=true - Installation is tracked in
.installed_mcps.json - MCP tools are immediately available in FleetShell
Installed MCP Tracking
Installed MCPs are tracked in ~/.fleetshell/.installed_mcps.json:
{
"playwright": {
"package_name": "@modelcontextprotocol/server-playwright",
"installed_at": "2024-01-15T10:30:00Z",
"mcp_id": "playwright"
}
}
---
Available MCP Tools
FleetShell provides 29 built-in tools plus 2 aggregation tools:
Server Discovery
| Tool | Description | |------|-------------| | list_servers | List all registered servers with metadata | | search_servers | Search servers by tags, environment, or text query | | get_server_context | Get detailed context for a specific server |
Command Execution
| Tool | Description | |------|-------------| | execute_command | Execute a shell command on a remote server | | multi_server_execute | Execute the same command on multiple servers in parallel |
Log Analysis
| Tool | Description | |------|-------------| | search_logs | Search for patterns in log files using grep | | tail_logs | Get the last N lines from a log file | | analyze_logs | Analyze logs for errors, warnings, or get summary |
Service Management
| Tool | Description | |------|-------------| | get_service_status | Get the status of a systemd service | | restart_service | Restart a systemd service | | list_services | List all systemd services on a server |
File Operations
| Tool | Description | |------|-------------| | read_file | Read contents of a file on a remote server | | search_files | Search for files matching a pattern | | get_file_info | Get metadata about a file |
System Information
| Tool | Description | |------|-------------| | get_system_info | Get system information (OS, CPU, memory, uptime) | | get_disk_usage | Get disk usage for a path | | get_process_list | Get list of running processes |
Shell Session Management
| Tool | Description | |------|-------------| | create_shell_session | Create a new persistent shell session on a server | | execute_in_session | Execute a command within an existing shell session | | close_shell_session | Close a shell session and clean up resources | | list_active_sessions | List all active shell sessions with details |
Prompt Management
| Tool | Description | |------|-------------| | save_prompt | Save a new prompt or update an existing one | | read_prompt | Retrieve a prompt by name | | list_prompts | List all saved prompts with metadata | | edit_prompt | Update prompt description or content | | delete_prompt | Delete a prompt |
MCP Marketplace
| Tool | Description | |------|-------------| | browse_mcp_marketplace | Browse available MCP servers (with optional search) | | install_mcp | Install an MCP server from the marketplace |
External MCP Tools
| Tool | Description | |------|-------------| | list_external_mcps | List all registered external MCPs and their tools | | call_external_tool | Call a tool on an external MCP (namespaced as mcp_id.tool_name) |
---
Server Configuration Format
Each server has a .conf file in ~/.fleetshell/servers/:
# ~/.fleetshell/servers/mail-prod-01.conf
id: mail-prod-01
hostname: mail.example.com
ssh_user: admin
ssh_port: 22
tags:
- production
- mail-server
- ispconfig
context:
description: "Primary email server running Postfix, Dovecot, and ISPConfig"
purpose: "Handles all outbound email and 50+ mailboxes"
environment: production
critical_level: high
notes: |
- Migrated from old server in 2024
- Uses Let's Encrypt for TLS
- Backup runs nightly at 2am
services:
postfix:
description: "SMTP server"
log_path: /var/log/mail.log
config_path: /etc/postfix/main.cf
port: 25
critical: true
common_issues:
- "Queue backup = check disk space"
- "Connection refused = check firewall"
dovecot:
description: "IMAP/POP3 server"
log_path: /var/log/dovecot.log
config_path: /etc/dovecot/dovecot.conf
ports: [993, 143]
critical: true
nginx:
description: "Webmail proxy"
log_path: /var/log/nginx/error.log
ports: [80, 443]
paths:
mail_data: /var/vmail
backups: /backup/mail
logs: /var/log
troubleshooting:
check_queue: "mailq"
flush_queue: "postfix flush"
restart_mail: "systemctl restart postfix dovecot"
check_auth: "doveadm auth test user@example.com"
monitoring:
key_metrics:
- "Mail queue size"
- "Disk usage on /var/vmail"
- "Failed login attempts"
This rich context is provided to Claude when using get_server_context, giving Claude the information it needs to help troubleshoot and manage the server.
---
Security Considerations
Security Comparison
| Feature | Without 2FA | With 2FA (Default) | |---------|-------------|---------------------| | API Key Required | ✅ Yes | ✅ Yes | | TOTP Code Required | ❌ No | ✅ Yes | | Session Expiry | N/A | 1 hour | | Protection if API key leaked | ❌ None | ✅ Attacker needs authenticator | | Recommended for | Development | Production |
TOTP Two-Factor Authentication
FleetShell requires TOTP 2FA by default. Every tool call (except authenticate) is blocked until a valid 6-digit code is provided. This adds a critical layer of protection:
- API key alone is not enough: Even if your API key is compromised, attackers cannot execute commands
- Time-limited sessions: Sessions expire after 1 hour, limiting exposure window
- Standard TOTP: Works with any authenticator app (Google Authenticator, Authy, 1Password)
API Key Authentication
All MCP requests require a valid API key via the Authorization: Bearer <key> header.
SSH Key-Based Authentication
FleetShell uses a single SSH keypair for all server connections:
- Private key:
~/.fleetshell/relay.key(mode 600, never share) - Public key:
~/.fleetshell/relay.pub(deploy to servers)
Dangerous Command Blocking
Commands matching these patterns are blocked:
rm -rf /dd if=mkfsshutdownreboot- Fork bombs
TLS Encryption
HTTPS is enabled by default with self-signed certificates. For production:
- Replace self-signed certs with proper certificates (Let's Encrypt, etc.)
- Update
~/.fleetshell/config.yamlwith certificate paths
Audit Logging
All executed commands are logged to ~/.fleetshell/logs/audit.log:
{"timestamp": "2024-01-15T10:30:00", "server_id": "web-prod-01", "command": "uptime", "exit_code": 0, "success": true}
---
Troubleshooting
"Connection refused" when connecting to FleetShell
- Verify the server is running:
fleetshell serve - Check firewall allows port 8080
- Verify TLS certificates exist
"Unauthorized" from Claude Desktop
- Verify API key matches between Claude config and FleetShell config
- Check the Authorization header format:
Bearer <key>
SSH connection fails to target server
- Test SSH manually:
ssh -i ~/.fleetshell/relay.key user@hostname - Verify public key is in target's
~/.ssh/authorized_keys - Check SSH port is open
- Verify host key (FleetShell auto-accepts new hosts)
MCP tools not appearing in Claude
- Restart Claude Desktop
- Check Claude Desktop logs for MCP errors
- Verify mcp-remote is installed:
npm install -g mcp-remote
External MCP fails to start
- Test manually:
fleetshell mcp test <mcp-id> - Check logs:
fleetshell mcp logs <mcp-id> - Verify command exists:
which npx
---
Running as a Systemd Service
Create a systemd service file for production deployment:
sudo nano /etc/systemd/system/fleetshell.service
[Unit]
Description=FleetShell MCP Relay Server
After=network.target
[Service]
Type=simple
User=fleetshell
Group=fleetshell
WorkingDirectory=/home/fleetshell/fleetshell
Environment="PATH=/home/fleetshell/fleetshell/.venv/bin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/home/fleetshell/fleetshell/.venv/bin/fleetshell serve
Restart=always
RestartSec=5
# Security hardening
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/fleetshell/.fleetshell
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable fleetshell
sudo systemctl start fleetshell
# Check status
sudo systemctl status fleetshell
# View logs
sudo journalctl -u fleetshell -f
---
Directory Structure
~/.fleetshell/
├── config.yaml # Main configuration
├── relay.key # SSH private key (KEEP SECURE)
├── relay.pub # SSH public key (share with servers)
├── .installed_mcps.json # Marketplace installation tracking
├── certs/
│ ├── cert.pem # TLS certificate
│ └── key.pem # TLS private key
├── servers/ # Server configurations
│ ├── web-prod-01.conf
│ ├── mail-prod-01.conf
│ └── db-prod-01.conf
├── mcps/ # External MCP configurations
│ ├── playwright.conf
│ └── filesystem.conf
├── prompts/ # Saved prompts (JSON files)
│ ├── db-health.json
│ ├── log-scanner.json
│ └── security-audit.json
└── logs/
├── relay.log # Application logs
└── audit.log # Command audit log
---
CLI Reference
fleetshell --help # Show all commands
fleetshell init # Initialize configuration
fleetshell serve # Start MCP server
fleetshell add-server # Add a new server
fleetshell list # List all servers
fleetshell test <id> # Test server connection
fleetshell edit <id> # Edit server config
fleetshell remove <id> # Remove a server
fleetshell pubkey # Show SSH public key
fleetshell auth --help # 2FA authentication commands
fleetshell auth setup # Display QR code for authenticator
fleetshell auth status # Check if MFA is enabled
fleetshell auth test <code> # Test a TOTP code
fleetshell auth enable # Enable MFA
fleetshell auth disable # Disable MFA (dev only)
fleetshell mcp --help # MCP aggregator commands
fleetshell mcp add <id> <cmd> # Add external MCP
fleetshell mcp list # List external MCPs
fleetshell mcp test <id> # Test external MCP
fleetshell mcp logs <id> # Show MCP logs
fleetshell mcp enable <id> # Enable MCP
fleetshell mcp disable <id> # Disable MCP
fleetshell mcp remove <id> # Remove MCP
fleetshell prompt --help # Prompt management commands
fleetshell prompt save <name> # Save a new prompt
fleetshell prompt list # List all saved prompts
fleetshell prompt show <name> # Show a specific prompt
fleetshell prompt edit <name> # Edit a prompt
fleetshell prompt delete <nm> # Delete a prompt
fleetshell session --help # Shell session commands
fleetshell session list # List active sessions (informational)





