Sysadmin
БесплатноНе проверенProvider-agnostic MCP server for managing heterogeneous infrastructure (SSH, Proxmox VE, Virtualizor, Hetzner Cloud, Cloudflare) via a JSON inventory, exposing
Описание
Provider-agnostic MCP server for managing heterogeneous infrastructure (SSH, Proxmox VE, Virtualizor, Hetzner Cloud, Cloudflare) via a JSON inventory, exposing tools for VM/container management, DNS, firewalls, and SSH operations.
README
Servidor MCP agnóstico de proveedor para administrar infraestructura heterogénea: servidores físicos, VPS por SSH, clusters Proxmox VE, paneles Virtualizor, Hetzner Cloud y Cloudflare.
A diferencia de MCPs atados a un hosting (p. ej. Cloudways), este proyecto usa un inventario JSON donde registras cada host con su proveedor y credenciales. Un mismo cliente MCP puede operar Proxmox en tu homelab, Virtualizor en un datacenter y servidores bare-metal en otra ubicación.
Arquitectura
flowchart LR
Client[Cliente MCP / Cursor] --> MCP[mcp-sysadmin]
MCP --> Inv[(inventory.json)]
MCP --> SSH[SSH]
MCP --> PVE[Proxmox API]
MCP --> VZ[Virtualizor API]
MCP --> HZ[Hetzner API]
MCP --> CF[Cloudflare API]
SSH --> Physical[Servidores físicos / VPS]
PVE --> VMs1[VMs KVM / LXC]
VZ --> VMs2[VPS OpenVZ/KVM/Xen]
HZ --> VMs3[Cloud Servers]
CF --> DNS[DNS / CDN / WAF]
Proveedores soportados
| Provider | Uso | Autenticación |
|---|---|---|
ssh |
Servidores físicos, VPS sin API, cualquier Linux | Clave privada o password |
proxmox |
Clusters / nodos Proxmox VE | API Token (PVEAPIToken) |
virtualizor |
Panel Virtualizor (Admin API) | apiKey + apiPass |
hetzner |
Hetzner Cloud (servidores, firewalls, volúmenes) | API Token (Bearer) |
cloudflare |
DNS, CDN, WAF (zonas y registros) | API Token (Bearer) |
Tools incluidos (38)
Inventario
list-hosts,get-host
Nodos / métricas
list-nodes,get-node-status,health-check
Máquinas virtuales / cloud
list-vms,list-containers,get-vm,vm-powerlist-vm-snapshots,create-vm-snapshotlist-proxmox-tasks,get-proxmox-tasklist-storage-usage,list-backups,create-backuplist-hetzner-firewalls,list-hetzner-volumes
Cloudflare (DNS / CDN)
list-zones,list-dns-records,get-dns-recordcreate-dns-record,update-dns-record,delete-dns-record(confirmToken)purge-cache(confirmToken)list-waf-rules
Red
list-network
SSH — operaciones controladas
ssh-exec,ssh-read-file(destructivas / confirmToken)
SSH — diagnóstico read-only
ssh-tail-log— journalctl o tail en/var/log/list-firewall-rules— UFW / nftables / iptableslist-systemd-units— failed / running / allcert-status— certbot / fechas SSLdns-lookup,check-endpointlist-cron,list-timersdocker-compose-ps
Instalación
📖 Manuales operativos: manuales/ — manual general y guías por provider.
Opción A — GitHub Packages + npx (recomendado)
Publicado en GitHub Packages como @kreodevs/mcp-sysadmin. No necesitas clonar el repo.
1. Registry de GitHub (una vez por máquina):
echo "@kreodevs:registry=https://npm.pkg.github.com" >> ~/.npmrc
O copia .npmrc.example. Los paquetes públicos no requieren token para instalar.
2. Inventario — crea tu inventory.json en cualquier ruta (p. ej. ~/mcp/inventory.json). Puedes basarte en config/inventory.example.json.
3. Probar en terminal:
export SYSADMIN_INVENTORY_PATH=~/mcp/inventory.json
export SYSADMIN_PRODUCTION_MODE=true
export SYSADMIN_CONFIRM_TOKEN=$(openssl rand -hex 32)
npx -y @kreodevs/mcp-sysadmin
4. Cliente MCP — configura npx (ver Instalación por cliente MCP abajo).
| Cliente | Botón 1 clic |
|---|---|
| Cursor | Add to Cursor |
| VS Code | Install MCP in VS Code |
⚠️ Tras el 1 clic, edita en el diálogo:
SYSADMIN_INVENTORY_PATH(ruta a tu inventario) ySYSADMIN_CONFIRM_TOKEN.
Generar enlaces personalizados:
SYSADMIN_INVENTORY_PATH=/ruta/a/inventory.json ./scripts/generate-install-links.sh
# Modo desarrollo local (clone): INSTALL_MODE=local ./scripts/generate-install-links.sh
Opción B — Desarrollo desde fuente
git clone https://github.com/kreodevs/mcp-sysadmin.git
cd mcp-sysadmin
npm install
npm run build
cp config/inventory.example.json config/inventory.json
Usa scripts/run-mcp.sh o npm run dev.
Publicar nueva versión (maintainers)
- Sube la versión en
package.jsonysrc/index.ts - Crea un GitHub Release (tag
vX.Y.Z) → el workflow .github/workflows/publish.yml publica en GitHub Packages - Verifica en Packages del repo:
@kreodevs/mcp-sysadmin
Configuración
- Copia el inventario de ejemplo:
cp config/inventory.example.json config/inventory.json
Edita
config/inventory.jsoncon tus hosts reales.Variables de entorno (opcional):
cp .env.example .env
SYSADMIN_INVENTORY_PATH=./config/inventory.json
SYSADMIN_PRODUCTION_MODE=true
SYSADMIN_CONFIRM_TOKEN=un-secreto-largo-que-el-llm-no-conoce
SYSADMIN_READ_ONLY=false
SYSADMIN_REQUIRE_CONFIRM=true
SYSADMIN_RATE_LIMIT_MAX=30
SYSADMIN_HTTP_TIMEOUT_MS=30000
SYSADMIN_SSH_TIMEOUT_MS=30000
ACL por host (inventario)
Cada host puede restringir qué tools puede usar el LLM:
{
"defaults": { "readOnly": false, "requireConfirm": true },
"hosts": [
{
"id": "pve-prod",
"readOnly": false,
"allowedTools": ["list-vms", "get-vm", "vm-power"],
"provider": "proxmox",
"...": "..."
}
]
}
readOnly: true— solo tools de lectura en ese hostallowedTools— lista blanca; si se omite, todas las tools del provider están permitidas
Referencias a secretos en el inventario
Puedes usar ${VAR} para no guardar credenciales en texto plano:
{
"tokenSecret": "${PROXMOX_HOMELAB_TOKEN}",
"apiKey": "${VIRTUALIZOR_API_KEY}",
"apiPass": "${VIRTUALIZOR_API_PASS}"
}
Ejemplo: Proxmox
{
"id": "pve-prod",
"name": "Proxmox Producción",
"provider": "proxmox",
"url": "https://10.0.0.2:8006",
"tokenId": "root@pam!cursor-mcp",
"tokenSecret": "${PROXMOX_TOKEN}",
"verifySsl": false,
"defaultNode": "pve1",
"tags": ["production"]
}
Crea el token en Proxmox: Datacenter → Permissions → API Tokens.
Ejemplo: Virtualizor
{
"id": "vz-panel",
"name": "Virtualizor DC1",
"provider": "virtualizor",
"url": "https://panel.example.com:4085",
"apiKey": "${VIRTUALIZOR_API_KEY}",
"apiPass": "${VIRTUALIZOR_API_PASS}",
"tags": ["vps"]
}
Ejemplo: Servidor físico (SSH)
{
"id": "metal-01",
"name": "Bare Metal Rack A",
"provider": "ssh",
"host": "203.0.113.50",
"port": 22,
"username": "root",
"privateKeyPath": "~/.ssh/id_ed25519",
"tags": ["physical", "production"]
}
Ejemplo: Hetzner Cloud
{
"id": "hz-cloud",
"name": "Hetzner Cloud",
"provider": "hetzner",
"apiToken": "${HETZNER_API_TOKEN}",
"defaultLocation": "fsn1",
"allowedTools": ["list-vms", "get-vm", "vm-power", "list-nodes", "health-check"],
"tags": ["cloud", "hetzner"]
}
Crea el token en Hetzner Cloud Console → Security → API Tokens (permisos Read & Write para power actions).
Ejemplo: Cloudflare
{
"id": "cf-main",
"name": "Cloudflare Production",
"provider": "cloudflare",
"apiToken": "${CLOUDFLARE_API_TOKEN}",
"defaultZoneId": "${CLOUDFLARE_ZONE_ID}",
"readOnly": true,
"allowedTools": ["list-zones", "list-dns-records", "get-dns-record", "list-waf-rules"],
"tags": ["dns", "cdn"]
}
Crea un API Token en Cloudflare con permisos mínimos: Zone → DNS (Read) y, si necesitas escritura, DNS Edit + Cache Purge.
Instalación por cliente MCP
Transporte stdio: el cliente lanza npx @kreodevs/mcp-sysadmin (GitHub Packages) o un script local en desarrollo.
Requisito previo: @kreodevs:registry=https://npm.pkg.github.com en
~/.npmrco--registry=https://npm.pkg.github.comen losargsde npx (incluido en los ejemplos).
Instalación rápida (1 clic)
Los botones de la sección Instalación → Opción A usan npx + GitHub Packages. Solo debes ajustar SYSADMIN_INVENTORY_PATH y SYSADMIN_CONFIRM_TOKEN en el diálogo del IDE.
# Enlaces con tu inventario:
SYSADMIN_INVENTORY_PATH=/ruta/a/inventory.json ./scripts/generate-install-links.sh
Cursor
Archivo: ~/.cursor/mcp.json (global) o .cursor/mcp.json (por proyecto)
UI: Settings → Tools & MCP → New MCP Server
Manual (GitHub Packages):
{
"mcpServers": {
"sysadmin": {
"command": "npx",
"args": ["-y", "--registry=https://npm.pkg.github.com", "@kreodevs/mcp-sysadmin"],
"env": {
"SYSADMIN_INVENTORY_PATH": "/ruta/a/inventory.json",
"SYSADMIN_PRODUCTION_MODE": "true",
"SYSADMIN_CONFIRM_TOKEN": "tu-secreto-humano",
"SYSADMIN_REQUIRE_CONFIRM": "true",
"PROXMOX_HOMELAB_TOKEN": "..."
}
}
}
}
Desarrollo local (clone del repo)
{
"mcpServers": {
"sysadmin": {
"command": "/ruta/absoluta/mcp-sysadmin/scripts/run-mcp.sh",
"env": {
"SYSADMIN_INVENTORY_PATH": "/ruta/absoluta/mcp-sysadmin/config/inventory.json",
"SYSADMIN_PRODUCTION_MODE": "true",
"SYSADMIN_CONFIRM_TOKEN": "tu-secreto-humano"
}
}
}
}
Claude Desktop
Archivo:
| SO | Ruta |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
UI: Settings → Developer → Edit Config
{
"mcpServers": {
"sysadmin": {
"command": "npx",
"args": ["-y", "--registry=https://npm.pkg.github.com", "@kreodevs/mcp-sysadmin"],
"env": {
"SYSADMIN_INVENTORY_PATH": "/ruta/a/inventory.json",
"SYSADMIN_PRODUCTION_MODE": "true",
"SYSADMIN_CONFIRM_TOKEN": "tu-secreto-humano"
}
}
}
}
Reinicia Claude Desktop tras guardar.
Claude Code (CLI)
claude mcp add sysadmin -- npx -y --registry=https://npm.pkg.github.com @kreodevs/mcp-sysadmin
Exporta SYSADMIN_INVENTORY_PATH y SYSADMIN_CONFIRM_TOKEN en el entorno o en la config de Claude Code.
OpenCode
Archivo: opencode.json / opencode.jsonc (proyecto) o ~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"sysadmin": {
"type": "local",
"command": [
"npx",
"-y",
"--registry=https://npm.pkg.github.com",
"@kreodevs/mcp-sysadmin"
],
"enabled": true,
"environment": {
"SYSADMIN_INVENTORY_PATH": "/ruta/a/inventory.json",
"SYSADMIN_PRODUCTION_MODE": "true",
"SYSADMIN_CONFIRM_TOKEN": "tu-secreto-humano",
"SYSADMIN_REQUIRE_CONFIRM": "true"
}
}
}
}
OpenCode usa
environment, noenv. Elcommanddebe ser un array.
opencode mcp add
opencode mcp list
VS Code
Archivo: .vscode/mcp.json (workspace)
Manual:
{
"servers": {
"sysadmin": {
"type": "stdio",
"command": "npx",
"args": ["-y", "--registry=https://npm.pkg.github.com", "@kreodevs/mcp-sysadmin"],
"env": {
"SYSADMIN_INVENTORY_PATH": "/ruta/a/inventory.json",
"SYSADMIN_PRODUCTION_MODE": "true",
"SYSADMIN_CONFIRM_TOKEN": "tu-secreto-humano"
}
}
}
}
Requiere GitHub Copilot con MCP o extensión compatible.
Windsurf (Cascade)
Archivo: ~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"sysadmin": {
"command": "npx",
"args": ["-y", "--registry=https://npm.pkg.github.com", "@kreodevs/mcp-sysadmin"],
"env": {
"SYSADMIN_INVENTORY_PATH": "/ruta/a/inventory.json",
"SYSADMIN_PRODUCTION_MODE": "true",
"SYSADMIN_CONFIRM_TOKEN": "tu-secreto-humano"
}
}
}
}
Pulsa Refresh en MCPs. Límite ~100 tools entre servidores.
Variables de entorno recomendadas (todos los clientes)
SYSADMIN_INVENTORY_PATH=/ruta/a/inventory.json
SYSADMIN_PRODUCTION_MODE=true
SYSADMIN_CONFIRM_TOKEN=<openssl rand -hex 32>
SYSADMIN_READ_ONLY=false
SYSADMIN_REQUIRE_CONFIRM=true
PROXMOX_HOMELAB_TOKEN=...
HETZNER_API_TOKEN=...
CLOUDFLARE_API_TOKEN=...
Desarrollo local del servidor (sin cliente MCP):
npm run dev
Seguridad
Modo producción
Activa siempre en prod:
SYSADMIN_PRODUCTION_MODE=true
SYSADMIN_CONFIRM_TOKEN=<secreto-largo-aleatorio>
Con esto:
- SSH exige
hostKeyFingerprint(anti-MITM) — falla al arrancar si falta SYSADMIN_CONFIRM_TOKENobligatorio — falla al arrancar si falta- SSH usa allowlist estricta (sin
cat/grep; lecturas solo víassh-read-file) - Prohibido
passworden inventario SSH vm-powerrequiere confirmación incluso parastart- Regex custom validadas (sin
.*ni patrones demasiado amplios)
Gate humano: confirmToken
El LLM puede poner confirm: true por prompt injection, pero no conoce SYSADMIN_CONFIRM_TOKEN (solo está en env del MCP, no en el chat):
{
"hostId": "bare-metal-01",
"command": "systemctl status nginx",
"confirm": true,
"confirmToken": "tu-secreto-humano-no-compartir-con-el-modelo"
}
Tú proporcionas el token cuando apruebas la operación.
Token de un solo uso (recomendado)
./scripts/mcp-approve.sh
# Válido 5 minutos; úsalo como confirmToken en la tool call
Alternativa: el token fijo SYSADMIN_CONFIRM_TOKEN en env MCP.
Obtener fingerprint SSH
ssh-keyscan -H 10.0.0.5 | ssh-keygen -lf -
# Copia la línea SHA256:... al inventario como hostKeyFingerprint
Controles implementados
| Control | Descripción |
|---|---|
| confirmToken | Secreto humano en env MCP; el modelo no lo tiene por defecto |
| Modo producción | Allowlist SSH, host key pinning, sin passwords SSH |
| Modo read-only | SYSADMIN_READ_ONLY=true bloquea tools de escritura |
| ACL por host | readOnly, allowedTools, allowedCommandPatterns |
| Allowlist SSH | Solo diagnóstico (systemctl status, journalctl, docker ps, etc.) — sin lectura de archivos |
| Lectura de archivos | Exclusivamente vía ssh-read-file (paths + symlinks + confirmToken) |
| cwd restringido | Solo /tmp, /var/log, /var/www, /home/*, /opt/* en ssh-exec |
| Regex inventario | Patrones custom validados; prohibido .* y regex demasiado amplias |
| Blocklist SSH | Capa extra: rm -rf, pipes a shell, multiline, etc. |
| Paths remotos | readlink -f antes de leer; bloqueo de shadow/symlink bypass |
| Rate limit | 30 req/tool/host/min (configurable) |
| TLS Proxmox | verifySsl default true |
| Redacción | Secretos, configs VM, errores API filtrados |
| Auditoría | JSON en stderr: [mcp-sysadmin:audit] |
Allowlist SSH por defecto
Incluye solo diagnóstico operativo: systemctl status, journalctl, docker ps/logs, kubectl get, ls, df, free, nginx -t, etc.
No incluye cat, grep, head, tail — usa ssh-read-file para leer archivos.
Añade patrones específicos en inventario (sin .*):
{
"allowedCommandPatterns": ["^systemctl restart nginx$"]
}
Tools que requieren confirm + confirmToken
ssh-exec— siempressh-read-file— siemprevm-power— todas las acciones en producción; stop/shutdown/reboot/reset siemprecreate-vm-snapshot— siemprecreate-backup— siemprecreate-dns-record,update-dns-record,delete-dns-record,purge-cache— siempre
Checklist pre-producción
-
SYSADMIN_PRODUCTION_MODE=true -
SYSADMIN_CONFIRM_TOKENgenerado (openssl rand -hex 32) - Fingerprint SSH en cada host
- Tokens Proxmox / Hetzner / Cloudflare con permisos mínimos
-
verifySsl: trueen Proxmox -
allowedToolspor host según necesidad - Inventario sin passwords en texto plano
- Probar una operación destructiva con token manual
CI y publicación
- CI: GitHub Actions ejecuta
typecheck+builden cada push/PR amain(.github/workflows/ci.yml) - Paquete npm: @kreodevs/mcp-sysadmin en GitHub Packages — publicado al crear un GitHub Release
Extensión
Para añadir otro proveedor (oVirt, VMware, AWS, etc.):
- Añade el provider en
src/config/schema.ts - Implementa cliente en
src/providers/<nombre>/client.ts - Regístralo en
src/providers/registry.ts - Expone tools en
src/tools/
La estructura sigue el patrón del cloudways-mcp-server, pero con inventario multi-proveedor en lugar de una API única.
Desarrollo
npm run typecheck
npm run build
Установка Sysadmin
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/kreodevs/mcp-sysadminFAQ
Sysadmin MCP бесплатный?
Да, Sysadmin MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Sysadmin?
Нет, Sysadmin работает без API-ключей и переменных окружения.
Sysadmin — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Sysadmin в Claude Desktop, Claude Code или Cursor?
Открой Sysadmin на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
GitHub
PRs, issues, code search, CI status
автор: GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
автор: mcpdotdirectCompare Sysadmin with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development
