FleetShell

Pela36/fleetshell-mcp
0 starsCommunity

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

Enables Claude AI to execute commands across multiple remote servers via SSH, with TOTP 2FA authentication and 29 built-in MCP tools for server management.

README.md

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

  1. Quick Start
  2. TOTP 2FA Authentication
  3. Installation
  4. Deployment on a Server
  5. Configuration
  6. Managing Servers
  7. Managing External MCPs
  8. Shell Session Management
  9. Prompt Database
  10. MCP Marketplace
  11. Claude Desktop Setup
  12. Available MCP Tools
  13. Server Configuration Format
  14. Security Considerations
  15. Troubleshooting
  16. 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).

═══════════════════════════════════════════════════════════════════ ```

  1. Open your authenticator app (Google Authenticator, Authy, 1Password, etc.)
  2. Scan the QR code or manually enter the secret key
  3. 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 setup to 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 SDK
  • paramiko>=3.4.0 - SSH library
  • pyyaml>=6.0 - YAML configuration
  • click>=8.1.0 - CLI framework
  • cryptography>=41.0.0 - TLS/SSH key generation
  • fastapi>=0.104.0 - HTTP framework
  • uvicorn>=0.24.0 - ASGI server
  • starlette>=0.27.0 - HTTP routing
  • sse-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_SERVER with your FleetShell server's IP or hostname
  • your-api-key-here with 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

  1. Created: New session with invoke_shell()
  2. Active: Accepts commands, auto-extends on activity
  3. Idle: No commands for 30 minutes → auto-cleanup
  4. 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:

  1. Playwright - Browser automation and web scraping
  2. 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:

  1. Package is installed via npx (no global installation needed)
  2. A .conf file is created in ~/.fleetshell/mcps/
  3. MCP is automatically enabled if auto_configure=true
  4. Installation is tracked in .installed_mcps.json
  5. 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=
  • mkfs
  • shutdown
  • reboot
  • Fork bombs

TLS Encryption

HTTPS is enabled by default with self-signed certificates. For production:

  1. Replace self-signed certs with proper certificates (Let's Encrypt, etc.)
  2. Update ~/.fleetshell/config.yaml with 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

  1. Verify the server is running: fleetshell serve
  2. Check firewall allows port 8080
  3. Verify TLS certificates exist

"Unauthorized" from Claude Desktop

  1. Verify API key matches between Claude config and FleetShell config
  2. Check the Authorization header format: Bearer <key>

SSH connection fails to target server

  1. Test SSH manually: ssh -i ~/.fleetshell/relay.key user@hostname
  2. Verify public key is in target's ~/.ssh/authorized_keys
  3. Check SSH port is open
  4. Verify host key (FleetShell auto-accepts new hosts)

MCP tools not appearing in Claude

  1. Restart Claude Desktop
  2. Check Claude Desktop logs for MCP errors
  3. Verify mcp-remote is installed: npm install -g mcp-remote

External MCP fails to start

  1. Test manually: fleetshell mcp test <mcp-id>
  2. Check logs: fleetshell mcp logs <mcp-id>
  3. 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)

Related MCP servers

Browse all →