- 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>
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 topath(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 topath(string, required): Path where to write the filecontent(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 IDcommand(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:
- 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"}}'
- 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
- Claude Code Integration: Test MCP connector with Claude Code Messages API
- Agent Zero Integration: Create custom tool or HTTP client in Agent Zero
- HTTPS/TLS: Add TLS certificates for secure external access
- Authentication: Implement OAuth 2.0 Bearer token authentication
- Monitoring: Set up automated health checks and alerting
- 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