homelab-mcp
by CTRQuko
README.md
[](https://github.com/CTRQuko/homelab-mcp/actions/workflows/ci.yml)
[](https://www.python.org/downloads/)
[](LICENSE)
# homelab-mcp
Coleccion de servidores MCP (Model Context Protocol) para gestionar un homelab con Proxmox, Linux, Windows, Docker, npm y Python.
Cada dominio corre como proceso independiente via `stdio`, se integra con Claude Code y cualquier cliente MCP compatible.
## Estructura
```
homelab-mcp/
├── homelab_mcp/
│ ├── config.py # Configuracion centralizada (.env + multi-nodo)
│ ├── base.py # Factory del servidor MCP + logging
│ ├── logging_conf.py # Setup de logging
│ ├── utils/
│ │ ├── paths.py # safe_path — sandbox de rutas
│ │ ├── subprocess_safe.py # run_safe — ejecucion con whitelist
│ │ ├── responses.py # ok() / error() / needs_confirmation()
│ │ └── claude_md_parser.py # Extrae config Proxmox de CLAUDE.md
│ ├── proxmox_mcp/server.py # Multi-nodo (pve, pve2, pve3...)
│ ├── linux_mcp/server.py
│ ├── windows_mcp/server.py
│ ├── docker_mcp/server.py
│ ├── npm_mcp/server.py
│ └── python_mcp/server.py
├── bin/
│ └── auto-config-from-claude.sh # Genera .env + proxmox_nodes.json
├── scripts/ # Lanzadores individuales y paralelo
├── tests/
├── .env.example
└── pyproject.toml
```
## Instalacion
```bash
git clone https://github.com/CTRQuko/homelab-mcp.git
cd homelab-mcp
cp .env.example .env # edita los valores reales
pip install -e .
# Con herramientas de desarrollo:
pip install -e ".[dev]"
# Solo tests:
pip install -e ".[test]"
```
## Auto-config desde CLAUDE.md
Si ya tienes configuracion Proxmox en `~/.claude/CLAUDE.md` y tokens en un fichero de secrets:
```bash
bash bin/auto-config-from-claude.sh
```
Esto genera automaticamente:
- `.env` con el nodo primario y todas las variables
- `proxmox_nodes.json` con todos los nodos detectados
Solo necesitas verificar que los valores son correctos.
## Variables de entorno (.env)
```env
# Proxmox API token (nodo primario)
PROXMOX_HOST=192.168.1.X
PROXMOX_USER=user@pam
PROXMOX_TOKEN_NAME=my-token
PROXMOX_TOKEN_VALUE=REEMPLAZAR
# Multi-nodo (opcional): fichero JSON con todos los nodos
# Generado por: bash bin/auto-config-from-claude.sh
# PROXMOX_NODES_FILE=proxmox_nodes.json
# Sandbox Linux (read/write dentro de esta ruta)
LINUX_BASE_PATH=/srv/homelab
# Sandbox Windows
WINDOWS_BASE_PATH=C:/homelab
# npm / Python sandboxes
NPM_BASE_PATH=.
PYTHON_BASE_PATH=.
# Docker socket (opcional)
DOCKER_HOST=unix:///var/run/docker.sock
# Nivel de log: DEBUG, INFO, WARNING, ERROR
LOG_LEVEL=INFO
```
### Multi-nodo Proxmox
Con `PROXMOX_NODES_FILE=proxmox_nodes.json`, los tools de Proxmox aceptan alias de nodo:
- `list_lxc("node1")` → conecta al primer nodo
- `list_lxc("node2")` → conecta al segundo nodo
- `list_lxc("node3")` → conecta al tercer nodo
Sin el fichero JSON, todo usa el nodo unico de `PROXMOX_HOST`.
## Ejecucion manual
```bash
homelab-proxmox-mcp
homelab-linux-mcp
homelab-windows-mcp
homelab-docker-mcp
homelab-npm-mcp
homelab-python-mcp
```
## Integracion en mcp.json
```json
{
"mcpServers": {
"homelab-proxmox": {
"command": "homelab-proxmox-mcp",
"args": []
},
"homelab-linux": {
"command": "homelab-linux-mcp",
"args": []
},
"homelab-windows": {
"command": "homelab-windows-mcp",
"args": []
},
"homelab-docker": {
"command": "homelab-docker-mcp",
"args": []
},
"homelab-npm": {
"command": "homelab-npm-mcp",
"args": []
},
"homelab-python": {
"command": "homelab-python-mcp",
"args": []
}
}
}
```
## Tools disponibles
### Proxmox MCP
| Tool | Descripcion |
|------|-------------|
| `list_nodes()` | Lista nodos del cluster |
| `get_node_status(node)` | CPU, memoria, uptime del nodo |
| `list_qemu(node)` | VMs QEMU/KVM del nodo |
| `list_lxc(node)` | Contenedores LXC del nodo |
| `get_vm_status(node, vmid, vm_type)` | Estado de VM o LXC |
| `start_vm(node, vmid, vm_type, confirm)` | Arrancar VM/LXC (requiere `confirm=True`) |
| `stop_vm(node, vmid, vm_type, confirm)` | Parar VM/LXC (requiere `confirm=True`) |
| `restart_vm(node, vmid, vm_type, confirm)` | Reiniciar VM/LXC (requiere `confirm=True`) |
### Linux MCP
| Tool | Descripcion |
|------|-------------|
| `read_file(rel_path)` | Leer fichero dentro del sandbox |
| `write_file(rel_path, content)` | Escribir fichero dentro del sandbox |
| `list_dir(rel_path)` | Listar directorio |
| `file_exists(rel_path)` | Comprobar existencia |
| `run_command(cmd)` | Comando whitelisted (ls, cat, df, du, grep, find, head, tail...) |
### Windows MCP
| Tool | Descripcion |
|------|-------------|
| `read_file(rel_path)` | Leer fichero dentro del sandbox |
| `write_file(rel_path, content)` | Escribir fichero dentro del sandbox |
| `list_dir(rel_path)` | Listar directorio |
| `file_exists(rel_path)` | Comprobar existencia |
| `run_powershell(cmd)` | PS de solo lectura (Get-*, Test-Path...) |
### Docker MCP
| Tool | Descripcion |
|------|-------------|
| `list_containers(all)` | Listar contenedores |
| `inspect_container(name)` | Inspeccionar configuracion |
| `get_container_logs(name, tail)` | Ultimas N lineas de logs |
| `restart_container(name, confirm)` | Reiniciar contenedor (requiere `confirm=True`) |
### npm MCP
| Tool | Descripcion |
|------|-------------|
| `npm_outdated(path)` | Dependencias desactualizadas |
| `npm_audit(path)` | Vulnerabilidades |
| `npm_list(path)` | Arbol de dependencias |
### Python MCP
| Tool | Descripcion |
|------|-------------|
| `python_version()` | Version Python del servidor |
| `pytest_run(path)` | Ejecutar tests |
| `ruff_check(path)` | Linting con ruff |
| `pip_list()` | Paquetes instalados |
## Tests
```bash
pytest
```
83 tests cubriendo todos los MCPs, utilidades y configuracion.
## Seguridad
### Sandboxes por MCP
| MCP | Variable .env | Default | Aplicado en |
|-----|---------------|---------|-------------|
| Linux | `LINUX_BASE_PATH` | `/srv/homelab` | `read_file`, `write_file`, `list_dir`, `file_exists`, `run_command` |
| Windows | `WINDOWS_BASE_PATH` | `C:/homelab` | `read_file`, `write_file`, `list_dir`, `file_exists`, `run_powershell` |
| npm | `NPM_BASE_PATH` | `.` | `npm_outdated`, `npm_audit`, `npm_list` |
| Python | `PYTHON_BASE_PATH` | `.` | `pytest_run`, `ruff_check` |
| Docker | — | — | No aplica (trabaja con nombres de contenedores) |
| Proxmox | — | — | No aplica (trabaja con la API autenticada) |
### Medidas de seguridad
- **Sandbox de rutas**: Linux, Windows, npm y Python MCP validan que todas las rutas se resuelvan dentro del directorio base configurado. Path traversal (`../..`) es rechazado usando `Path.relative_to()`.
- **Whitelist de comandos**: `run_command` (Linux) solo permite binarios explicitamente listados. Los comandos se parsean con `shlex` y se ejecutan sin `shell=True`.
- **PowerShell restringido**: Solo verbos de lectura (`Get-*`, `Test-Path`). Se bloquean pipes (`|`), punto y coma (`;`), ampersand (`&`), backticks, subexpresiones (`$()`), verbos destructivos (`Remove-*`, `Set-*`, `Invoke-*`, etc.) y binarios peligrosos (`rm`, `del`, `cmd`, etc.). Se ejecuta con `-ExecutionPolicy Restricted -NonInteractive`.
- **Docker con confirmacion**: `restart_container` requiere `confirm=True` explicito. Sin el devuelve un aviso de confirmacion.
- **Proxmox con confirmacion**: `start_vm`, `stop_vm` y `restart_vm` requieren `confirm=True` explicito. Se valida configuracion antes de conectar.
- **Sin secretos hardcodeados**: Todo por `.env`, nunca en el codigo.
### Limitaciones conocidas
- `run_safe` no soporta rutas absolutas con espacios como nombre de binario (e.g. `C:\Program Files\...`). Esto es intencional: usa nombres simples (`python`, `ls`).
- `run_powershell` pasa el comando como string a `-Command`; la validacion cubre la mayoria de vectores pero un escape creativo de PowerShell podria evadirla en teoria.
- No hay autenticacion entre el cliente MCP y el servidor; la seguridad recae en el control de acceso al proceso.
## Ejemplo mcp.json alternativo (con python -m)
Si prefieres invocar los servidores con `python -m` en lugar del entrypoint:
```json
{
"mcpServers": {
"proxmox": {
"command": "python",
"args": ["-m", "homelab_mcp.proxmox_mcp.server"],
"env": { "PYTHONPATH": "/path/to/homelab-mcp" },
"type": "stdio"
},
"linux": {
"command": "python",
"args": ["-m", "homelab_mcp.linux_mcp.server"],
"env": { "PYTHONPATH": "/path/to/homelab-mcp" },
"type": "stdio"
},
"docker": {
"command": "python",
"args": ["-m", "homelab_mcp.docker_mcp.server"],
"env": { "PYTHONPATH": "/path/to/homelab-mcp" },
"type": "stdio"
},
"windows": {
"command": "python",
"args": ["-m", "homelab_mcp.windows_mcp.server"],
"env": { "PYTHONPATH": "/path/to/homelab-mcp" },
"type": "stdio"
},
"npm": {
"command": "python",
"args": ["-m", "homelab_mcp.npm_mcp.server"],
"env": { "PYTHONPATH": "/path/to/homelab-mcp" },
"type": "stdio"
},
"python": {
"command": "python",
"args": ["-m", "homelab_mcp.python_mcp.server"],
"env": { "PYTHONPATH": "/path/to/homelab-mcp" },
"type": "stdio"
}
}
}
```
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
## License
[MIT](LICENSE)
TDQS
A3.6/5.0
Scored across 4 tools
Disambiguation5/5
Each tool targets a distinct operation on Docker containers: listing, inspecting, retrieving logs, and restarting. No functional overlap exists.
Naming Consistency5/5
All tool names follow a consistent verb_noun snake_case pattern (e.g., list_containers, inspect_container), making the set predictable.
Tool Count4/5
With 4 tools, the set is slightly small but well-scoped for basic container management and monitoring. It could benefit from a few more operations, but it remains focused.
Completeness3/5
The tools cover observation (list, inspect, logs) and one action (restart), but lack fundamental operations like start, stop, or remove containers, leaving notable workflow gaps.
Maintenance
ActivityInactive
ResponsivenessNo issues