MCP Hub
Back to servers

etphonehome-public

A remote access system using reverse SSH tunnels that allows AI agents like Claude to manage, explore, and execute commands on machines behind firewalls or NAT.

Stars
2
Tools
26
Updated
Jan 12, 2026

ET Phone Home

ET Phone Home logo

License: MIT Python 3.10+ Build Status MCP

Remote access system enabling Claude CLI to assist machines via reverse SSH tunnels.


Quick Reference

# Client Setup (one-time)
phonehome --init                    # Initialize config
phonehome --generate-key            # Generate SSH keypair
# Add public key to server's authorized_keys

# Client Connection
phonehome                           # Connect with config defaults
phonehome -s host.example.com -p 443  # Connect with overrides
phonehome --list-clients            # Query server for all clients

# Server (systemd recommended)
sudo systemctl start etphonehome-mcp   # Start MCP server
curl http://localhost:8765/health      # Health check

Claude CLI Examples:

"List all connected clients"
"Run 'df -h' on the laptop"
"Read /etc/hostname from production"
"Find clients with docker capability"

Overview

ET Phone Home allows remote machines to "phone home" to your Claude CLI instance, enabling Claude to:

  • Execute commands on remote machines
  • Read and write files
  • Transfer files between server and clients
  • Search and filter clients by capabilities, tags, or purpose

This is useful for assisting machines behind firewalls, NAT, or otherwise inaccessible networks.

Architecture

                           YOUR NETWORK                              REMOTE NETWORKS
    ┌─────────────────────────────────────────────┐      ┌─────────────────────────────────┐
    │                 SERVER HOST                 │      │         REMOTE CLIENTS          │
    │                                             │      │                                 │
    │  ┌─────────────┐      ┌─────────────────┐  │      │  ┌─────────┐    ┌─────────┐    │
    │  │ Claude CLI  │─────►│   MCP Server    │  │      │  │Client A │    │Client B │    │
    │  └─────────────┘      │ (HTTP/stdio)    │  │      │  │ (Linux) │    │(Windows)│    │
    │                       └────────┬────────┘  │      │  └────┬────┘    └────┬────┘    │
    │                                │           │      │       │              │         │
    │                       ┌────────▼────────┐  │      │       │              │         │
    │                       │  SSH Server     │◄─┼──────┼───────┴──────────────┘         │
    │                       │  (Port 443)     │  │      │    Reverse SSH Tunnels         │
    │                       └─────────────────┘  │      │                                 │
    └─────────────────────────────────────────────┘      └─────────────────────────────────┘

Data Flow:
1. Clients establish reverse SSH tunnels to server (outbound from client)
2. MCP server communicates with clients through tunnels
3. Claude CLI invokes MCP tools to manage remote clients

Features

FeatureDescription
Reverse TunnelsClients behind NAT/firewalls connect out to server
MCP IntegrationNative Claude CLI support via Model Context Protocol
Persistent IdentityClients maintain UUID across reconnections
Capability DetectionAuto-detects Docker, Python, GPU, etc.
Path RestrictionsOptional file system access limits
Auto-UpdatesClients can self-update from download server
Cross-PlatformLinux, Windows, with macOS planned
WebhooksHTTP notifications for client events
Rate LimitingPer-client request rate monitoring

Quick Start

Server Setup

  1. Install dependencies:

    cd etphonehome
    pip install -e ".[server]"
    
  2. Run setup script:

    ./scripts/setup_server.sh
    
  3. Configure SSH (see setup script output)

  4. Configure MCP server:

    Option A: stdio mode (launched by Claude Code):

    {
      "mcpServers": {
        "etphonehome": {
          "command": "python",
          "args": ["-m", "server.mcp_server"],
          "cwd": "/path/to/etphonehome"
        }
      }
    }
    

    Option B: HTTP daemon mode (persistent service):

    sudo ./scripts/deploy_mcp_service.sh
    

    Then configure Claude Code to connect via HTTP:

    {
      "mcpServers": {
        "etphonehome": {
          "type": "sse",
          "url": "http://localhost:8765/sse",
          "headers": {
            "Authorization": "Bearer YOUR_API_KEY"
          }
        }
      }
    }
    

Client Deployment

The client runs from the user's home folder without admin/root access.

Option A: Single Executable (Recommended)

# Linux - install to ~/phonehome/
mkdir -p ~/phonehome && cd ~/phonehome
curl -LO http://your-server/latest/phonehome-linux
chmod +x phonehome-linux
./phonehome-linux --init
./phonehome-linux --generate-key
./phonehome-linux -s your-server.example.com -p 443
# Windows - install to %USERPROFILE%\phonehome\
New-Item -ItemType Directory -Path "$env:USERPROFILE\phonehome" -Force
Set-Location "$env:USERPROFILE\phonehome"
Invoke-WebRequest -Uri "http://your-server/latest/phonehome-windows.exe" -OutFile "phonehome.exe"
.\phonehome.exe --init
.\phonehome.exe --generate-key
.\phonehome.exe -s your-server.example.com -p 443

Option B: Portable Archive

# Linux - install to ~/phonehome/
cd ~
curl -LO http://your-server/latest/phonehome-linux-x86_64.tar.gz
tar xzf phonehome-linux-x86_64.tar.gz
cd phonehome && ./setup.sh
./run.sh -s your-server.example.com
# Windows - install to %USERPROFILE%\phonehome\
Set-Location $env:USERPROFILE
Invoke-WebRequest -Uri "http://your-server/latest/phonehome-windows-amd64.zip" -OutFile "phonehome.zip"
Expand-Archive -Path "phonehome.zip" -DestinationPath "."
Set-Location phonehome
.\setup.bat
.\run.bat -s your-server.example.com

Option C: From Source (Development)

Note: When cloning, use a folder named etphonehome (not etphonehome-public). Documentation, scripts, and tests assume this folder name.

# Linux
cd ~
git clone https://github.com/jfreed-dev/etphonehome-public.git ~/etphonehome
cd ~/etphonehome
pip install -e .
phonehome --init && phonehome --generate-key
phonehome -s your-server.example.com -p 443
# Windows
Set-Location $env:USERPROFILE
git clone https://github.com/jfreed-dev/etphonehome-public.git "$env:USERPROFILE\etphonehome"
Set-Location "$env:USERPROFILE\etphonehome"
pip install -e .
phonehome --init
phonehome --generate-key
phonehome -s your-server.example.com -p 443

Client CLI Options

OptionDescription
--initInitialize config directory and create default config
--generate-keyGenerate a new SSH keypair
--show-keyDisplay the public key
--show-uuidDisplay the client UUID
--list-clientsQuery the server for all connected clients
-s, --serverOverride server hostname
-p, --portOverride server port
-v, --verboseEnable verbose logging

Post-Setup

  1. Add your public key to the server's authorized_keys:
    • Linux: ~/.etphonehome/id_ed25519.pub
    • Windows: %USERPROFILE%\.etphonehome\id_ed25519.pub
  2. Edit config with server details (optional if using CLI flags):
    • Linux: ~/.etphonehome/config.yaml
    • Windows: %USERPROFILE%\.etphonehome\config.yaml
  3. Connect: phonehome (Linux) or .\phonehome.exe (Windows)

Running as a Service

Client Service (Linux)

# User service (no root required)
./scripts/install-service.sh --user
systemctl --user enable --now phonehome

# Enable start on boot (before login)
loginctl enable-linger $USER

Service commands:

systemctl --user status phonehome     # Check status
systemctl --user restart phonehome    # Restart
journalctl --user -u phonehome -f     # View logs

MCP Server Daemon (Linux)

sudo ./scripts/deploy_mcp_service.sh

Server commands:

sudo systemctl status etphonehome-mcp    # Check status
sudo journalctl -u etphonehome-mcp -f    # View logs
curl http://localhost:8765/health        # Health check

Server CLI options:

OptionDefaultDescription
--transportstdioTransport mode: stdio or http
--host127.0.0.1HTTP server bind address
--port8765HTTP server port
--api-key(none)API key (or ETPHONEHOME_API_KEY env var)

MCP Tools Reference

Client Management

ToolDescription
list_clientsList all connected clients with status
select_clientChoose which client to interact with
find_clientSearch by name, purpose, tags, or capabilities
describe_clientGet detailed information about a client
update_clientUpdate metadata (display_name, purpose, tags)
accept_keyAccept a client's new SSH key after legitimate change
configure_clientSet per-client webhook URL and rate limits
get_rate_limit_statsGet rate limit statistics for a client

Remote Operations

ToolDescription
run_commandExecute shell commands
read_fileRead file contents
write_fileWrite to files
list_filesList directory contents
upload_fileSend file from server to client (SFTP)
download_fileFetch file from client to server (SFTP)
get_client_metricsGet system health metrics (CPU, memory, disk)

SSH Sessions

ToolDescription
ssh_session_openOpen persistent SSH session to remote host
ssh_session_commandRun command in session (state preserved)
ssh_session_sendSend input for interactive prompts
ssh_session_readRead output from session
ssh_session_closeClose session
ssh_session_listList active sessions
ssh_session_restoreRestore sessions after reconnect

File Exchange (R2)

ToolDescription
exchange_uploadUpload file to R2 storage
exchange_downloadDownload file from R2
exchange_listList pending transfers
exchange_deleteDelete transfer from R2

Server Features

Automatic Disconnect Detection

The server monitors client connections with automatic cleanup:

  • Heartbeats all clients every 30 seconds
  • Clients failing 3 consecutive checks are unregistered
  • 60-second grace period for new connections
  • Reconnecting clients are automatically re-registered

SSH Key Change Detection

When a client reconnects with a different SSH key:

  • Server flags it with key_mismatch: true
  • Use describe_client to see details
  • Use accept_key to accept legitimate changes (key rotation)
  • Investigate before accepting unexpected changes

Webhooks

Send HTTP notifications when events occur:

EventTrigger
client.connectedClient connects to server
client.disconnectedClient disconnects
client.key_mismatchSSH key changed
client.unhealthyHealth check failures
command_executedShell command run
file_accessedFile read/write/list

Configure via environment variables or per-client with configure_client. See Webhooks Guide for integration examples.

Rate Limiting

Monitor request frequency per client (warn-only mode):

  • Tracks requests per minute (RPM) and concurrent requests
  • Logs warnings when limits exceeded (does not block)
  • Per-client limits configurable via configure_client
  • View stats with get_rate_limit_stats

Configuration

Client Config

Location:

  • Linux: ~/.etphonehome/config.yaml
  • Windows: %USERPROFILE%\.etphonehome\config.yaml
server_host: localhost
server_port: 443
server_user: etphonehome
key_file: ~/.etphonehome/id_ed25519
client_id: myhost-abc123
reconnect_delay: 5
max_reconnect_delay: 300
allowed_paths: []  # Empty = all paths allowed
log_level: INFO

Security

FeatureDescription
SSH Keys OnlyPassword authentication not supported
Path RestrictionsOptional limits on accessible paths
Tunnel BindingReverse tunnels bind to localhost only
Key VerificationClient keys verified on each connection

Windows Security Notes

IssueSolution
Antivirus blocks executableAdd to exclusions, or use portable archive
SmartScreen warningClick "More info" → "Run anyway"
Firewall blocks connectionAllow outbound on port 443
PowerShell execution policySet-ExecutionPolicy RemoteSigned -Scope CurrentUser

Documentation

GuideDescription
API ReferenceComplete MCP tool reference, error codes, webhooks
MCP Server SetupComplete Linux/Windows server setup
SSH + Claude CodeRemote MCP access via SSH
Management GuideClient management workflows
Webhooks GuideWebhook integration examples
R2 Setup GuideCloudflare R2 storage configuration
Deployment GuideAnsible, Docker, Terraform automation
Hostinger SetupVPS deployment reference
Download ServerClient distribution setup
RoadmapPlanned features

Claude Code Skills

ET Phone Home includes specialized Claude Code skills for common workflows:

SkillDescription
etphonehome-remote-accessSafe remote access best practices
etphonehome-diagnosticsClient health monitoring
etphonehome-infrastructureClient management and organization
etphonehome-buildCross-architecture builds and publishing
etphonehome-file-exchangeR2 storage file transfers
etphonehome-windows-serverWindows Server and PowerShell

Skills are located in .claude/skills/ and activate automatically based on context.


Building Releases

# PyInstaller (single executable)
./build/pyinstaller/build_linux.sh
.\build\pyinstaller\build_windows.bat

# Portable archive (bundled Python)
./build/portable/package_linux.sh
.\build\portable\package_windows.ps1

Releases are automatically built via GitHub Actions on version tags (v*).

Development

pip install -e ".[dev]"        # Install dev dependencies
pre-commit install             # Set up pre-commit hooks
pytest                         # Run tests
pre-commit run --all-files     # Run all linters

License

MIT

Reviews

No reviews yet

Sign in to write a review