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>
This commit is contained in:
commit
7b98651e5a
5 files changed
+1321
No files matched your search
@@ -0,0 +1,400 @@
|
||||
# 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**:
|
||||
```json
|
||||
{
|
||||
"name": "ssh_list_hosts",
|
||||
"arguments": {}
|
||||
}
|
||||
```
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"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**:
|
||||
```json
|
||||
{
|
||||
"name": "ssh_exec",
|
||||
"arguments": {
|
||||
"host": "proton",
|
||||
"command": "hostname"
|
||||
}
|
||||
}
|
||||
```
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"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**:
|
||||
```json
|
||||
{
|
||||
"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**:
|
||||
```json
|
||||
{
|
||||
"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**:
|
||||
```json
|
||||
{
|
||||
"name": "ssh_docker_ps",
|
||||
"arguments": {
|
||||
"host": "proton"
|
||||
}
|
||||
}
|
||||
```
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"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**:
|
||||
```json
|
||||
{
|
||||
"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**:
|
||||
```json
|
||||
{
|
||||
"name": "lxc_exec",
|
||||
"arguments": {
|
||||
"container_id": "105",
|
||||
"command": "hostname"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## HTTP API Endpoints
|
||||
|
||||
### GET /
|
||||
Health check and server information
|
||||
```bash
|
||||
curl http://10.50.0.110:8081/
|
||||
```
|
||||
|
||||
### POST /tools
|
||||
List available MCP tools
|
||||
```bash
|
||||
curl -X POST http://10.50.0.110:8081/tools
|
||||
```
|
||||
|
||||
### POST /tools/call
|
||||
Call an MCP tool
|
||||
```bash
|
||||
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
|
||||
```bash
|
||||
curl http://10.50.0.110:8081/sse
|
||||
```
|
||||
|
||||
### GET /mcp/info
|
||||
MCP server information (MCP spec required)
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```python
|
||||
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**:
|
||||
```bash
|
||||
curl http://10.50.0.110:8081/tools/call \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "ssh_exec", "arguments": {"host": "proton", "command": "docker ps"}}'
|
||||
```
|
||||
|
||||
2. **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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
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
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# 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**
|
||||
Reference in new issue
Block a user