Files
ssh-mcp-server/docs/ssh-mcp-server-complete.md
Claude Code 7b98651e5a Initial commit: SSH-MCP server implementation
- SSH-MCP server with 7 infrastructure management tools
  * ssh_list_hosts - List all available hosts
  * ssh_exec - Execute commands on remote hosts
  * ssh_get_file / ssh_put_file - File operations
  * ssh_docker_ps - List Docker containers
  * lxc_list / lxc_exec - LXC container management

- HTTP/SSE transport wrapper for Claude Code integration
  * FastAPI-based HTTP server on port 8081
  * Server-Sent Events (SSE) support
  * MCP 2025 specification compliant

- Complete deployment on LXC 110 (10.50.0.110)
  * SSH key-based authentication (Ed25519)
  * Systemd service for automatic startup
  * Tested and verified on all infrastructure

- Comprehensive documentation
  * Complete deployment guide
  * Git collaboration workflow
  * API usage examples

Developed collaboratively by Claude Code and Agent Zero.

Infrastructure Access:
- photon.obnh.io (test target)
- proton.obr.sh (development server, hosts this repo)
- fry.obr.sh (migration target)
- Proxmox 10.50.0.72 (LXC/VM host)

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 13:31:07 +00:00

9.8 KiB

SSH-MCP Server - Deployment Complete

Overview

The SSH-MCP (Model Context Protocol) server is now fully operational, providing secure infrastructure access for Claude Code, zen-orchestrator agents, and Agent Zero.

Deployment Information

  • Server Location: LXC Container 110 (ssh-mcp-server)
  • IP Address: 10.50.0.110
  • HTTP Endpoint: http://10.50.0.110:8081
  • Status: OPERATIONAL

Architecture

┌─────────────────────────────────────────┐
│ Claude Code / Agent Zero (Clients)      │
│ - Messages API (Claude Code)            │
│ - FastA2A API (Agent Zero)              │
└─────────────┬───────────────────────────┘
              │ HTTP/SSE (Port 8081)
              ▼
┌─────────────────────────────────────────┐
│ SSH-MCP Server (10.50.0.110)            │
│ - FastAPI HTTP/SSE Wrapper              │
│ - MCP Protocol Handler                  │
│ - SSH Client                            │
└─────────────┬───────────────────────────┘
              │ SSH
              ▼
┌─────────────────────────────────────────┐
│ Infrastructure Targets                  │
│ - photon.obnh.io (46.247.109.251)       │
│ - proton.obr.sh (72.61.83.117)          │
│ - fry.obr.sh (v48682)                   │
│ - Proxmox (10.50.0.72)                  │
│ - All LXC/VMs in 10.50.0.0/24           │
└─────────────────────────────────────────┘

Available MCP Tools

1. ssh_list_hosts

Description: List all available infrastructure hosts Parameters: None Example:

{
  "name": "ssh_list_hosts",
  "arguments": {}
}

Response:

{
  "content": [{
    "type": "text",
    "text": "Available hosts:\n- photon: photon.obnh.io (Debian server with Traefik, Gitea, Mastodon)\n- proton: proton.obr.sh (Ubuntu server with Traefik, Gitea)\n- fry: fry.obr.sh (Ubuntu server (photon replacement))\n- proxmox: 10.50.0.72 (Proxmox host)"
  }]
}

2. ssh_exec

Description: Execute a command on a remote host via SSH Parameters:

  • host (string, required): Host to connect to (photon, proton, fry, proxmox)
  • command (string, required): Command to execute

Example:

{
  "name": "ssh_exec",
  "arguments": {
    "host": "proton",
    "command": "hostname"
  }
}

Response:

{
  "content": [{
    "type": "text",
    "text": "proton\n"
  }]
}

3. ssh_get_file

Description: Read a file from a remote host Parameters:

  • host (string, required): Host to connect to
  • path (string, required): Path to the file

Example:

{
  "name": "ssh_get_file",
  "arguments": {
    "host": "proton",
    "path": "/etc/hostname"
  }
}

4. ssh_put_file

Description: Write a file to a remote host Parameters:

  • host (string, required): Host to connect to
  • path (string, required): Path where to write the file
  • content (string, required): File content

Example:

{
  "name": "ssh_put_file",
  "arguments": {
    "host": "proton",
    "path": "/tmp/test.txt",
    "content": "Hello from MCP!"
  }
}

5. ssh_docker_ps

Description: List Docker containers on a remote host Parameters:

  • host (string, required): Host to connect to

Example:

{
  "name": "ssh_docker_ps",
  "arguments": {
    "host": "proton"
  }
}

Response:

{
  "content": [{
    "type": "text",
    "text": "traefik\tUp 19 hours\ttraefik:latest\ngitea\tUp 19 hours\tgitea/gitea:latest\n..."
  }]
}

6. lxc_list

Description: List LXC containers on Proxmox host Parameters:

  • proxmox_host (string, optional): Proxmox host (default: "proxmox")

Example:

{
  "name": "lxc_list",
  "arguments": {}
}

7. lxc_exec

Description: Execute command in an LXC container on Proxmox Parameters:

  • proxmox_host (string, optional): Proxmox host (default: "proxmox")
  • container_id (string, required): LXC container ID
  • command (string, required): Command to execute

Example:

{
  "name": "lxc_exec",
  "arguments": {
    "container_id": "105",
    "command": "hostname"
  }
}

HTTP API Endpoints

GET /

Health check and server information

curl http://10.50.0.110:8081/

POST /tools

List available MCP tools

curl -X POST http://10.50.0.110:8081/tools

POST /tools/call

Call an MCP tool

curl -X POST http://10.50.0.110:8081/tools/call \
  -H "Content-Type: application/json" \
  -d '{"name": "ssh_list_hosts", "arguments": {}}'

GET /sse

Server-Sent Events endpoint for Claude Code MCP connector

curl http://10.50.0.110:8081/sse

GET /mcp/info

MCP server information (MCP spec required)

curl http://10.50.0.110:8081/mcp/info

SSH Key Configuration

The SSH-MCP server uses Ed25519 SSH keys for authentication:

Public Key:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBLCeawNHnN5GQOunphtkNmKorjNP6RpXtyK33dBRMAw ssh-mcp-server@10.50.0.110

Configured on:

  • photon.obnh.io
  • proton.obr.sh
  • fry.obr.sh
  • Proxmox host (10.50.0.72)

Systemd Service

The SSH-MCP server runs as a systemd service:

# Service status
ssh root@10.50.0.110 systemctl status ssh-mcp-server

# Restart service
ssh root@10.50.0.110 systemctl restart ssh-mcp-server

# View logs
ssh root@10.50.0.110 journalctl -u ssh-mcp-server -f

Service file: /etc/systemd/system/ssh-mcp-server.service

File Locations

On LXC 110:

  • Server implementation: /opt/ssh-mcp-server/server.py
  • HTTP wrapper: /opt/ssh-mcp-server/http_wrapper.py
  • SSH config: /root/.ssh/config
  • SSH private key: /root/.ssh/id_ed25519
  • Service file: /etc/systemd/system/ssh-mcp-server.service

On Agent Zero (LXC 105):

  • Project documentation: /tmp/ssh-mcp-project/README.md
  • Implementation: /tmp/ssh-mcp-project/implementation/ssh_mcp_server.py

Integration with Claude Code

To use the SSH-MCP server with Claude Code, configure it via the Messages API:

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-sonnet-4-5-20250929",
    max_tokens=1024,
    mcp_servers=[
        {
            "type": "url",
            "name": "ssh-infrastructure",
            "url": "http://10.50.0.110:8081",
        }
    ],
    messages=[
        {"role": "user", "content": "List all infrastructure hosts"}
    ]
)

Integration with Agent Zero

Agent Zero can access the SSH-MCP server via:

  1. HTTP API:
curl http://10.50.0.110:8081/tools/call \
  -H "Content-Type: application/json" \
  -d '{"name": "ssh_exec", "arguments": {"host": "proton", "command": "docker ps"}}'
  1. FastA2A API (Agent Zero's API):
    • Agent Zero can be instructed to use the HTTP API endpoints
    • Shared filesystem: /tmp/ssh-mcp-project/

Testing

All tools have been tested and verified working:

ssh_list_hosts - Lists all hosts ssh_exec - Executes commands (tested: hostname on proton) ssh_docker_ps - Lists Docker containers (tested on proton) ssh_get_file - Reads remote files ssh_put_file - Writes remote files lxc_list - Lists LXC containers lxc_exec - Executes in LXC containers

Security

  • SSH key-based authentication (no passwords)
  • Ed25519 keys (modern, secure)
  • Unprivileged LXC container
  • SSH StrictHostKeyChecking=no (for internal network only)
  • Service runs as root (required for SSH access)

Monitoring

# Check service status
ssh root@10.50.0.110 systemctl status ssh-mcp-server

# Check if port 8081 is listening
ssh root@10.50.0.110 "ss -tlnp | grep 8081"

# Test HTTP endpoint
curl http://10.50.0.110:8081/health

# View real-time logs
ssh root@10.50.0.110 journalctl -u ssh-mcp-server -f

Troubleshooting

Service not running

ssh root@10.50.0.110 systemctl restart ssh-mcp-server
ssh root@10.50.0.110 journalctl -u ssh-mcp-server -n 50

SSH connectivity issues

# Test SSH from MCP server to target
ssh root@10.50.0.110 "ssh proton.obr.sh hostname"

# Check SSH key permissions
ssh root@10.50.0.110 "ls -la /root/.ssh/"

# Verify key is on target
ssh root@proton.obr.sh "grep ssh-mcp-server /root/.ssh/authorized_keys"

HTTP endpoint not responding

# Check if uvicorn is running
ssh root@10.50.0.110 "ps aux | grep uvicorn"

# Check port binding
ssh root@10.50.0.110 "ss -tlnp | grep 8081"

# Check firewall
ssh root@10.50.0.110 "iptables -L -n | grep 8081"

Next Steps

  1. Claude Code Integration: Test MCP connector with Claude Code Messages API
  2. Agent Zero Integration: Create custom tool or HTTP client in Agent Zero
  3. HTTPS/TLS: Add TLS certificates for secure external access
  4. Authentication: Implement OAuth 2.0 Bearer token authentication
  5. Monitoring: Set up automated health checks and alerting
  6. Documentation: Import this guide into Agent Zero's knowledge base

Success Criteria

LXC container 110 created and operational SSH keys configured on all infrastructure hosts MCP server implementation complete HTTP/SSE transport wrapper functional All 7 MCP tools tested and working Systemd service enabled and running Documentation complete

Completion Date

2025-11-13 13:15 UTC

Contact & Support

  • Server: ssh-mcp-server (LXC 110)
  • Access: ssh root@10.50.0.110
  • HTTP: http://10.50.0.110:8081
  • Documentation: /home/olaf/proton/ssh-mcp-server-complete.md

Status: FULLY OPERATIONAL