mcp-sysadmin

mcp-sysadmin

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.

Category
访问服务器

README

MCP Sysadmin

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-power
  • list-vm-snapshots, create-vm-snapshot
  • list-proxmox-tasks, get-proxmox-task
  • list-storage-usage, list-backups, create-backup
  • list-hetzner-firewalls, list-hetzner-volumes

Cloudflare (DNS / CDN)

  • list-zones, list-dns-records, get-dns-record
  • create-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 / iptables
  • list-systemd-units — failed / running / all
  • cert-status — certbot / fechas SSL
  • dns-lookup, check-endpoint
  • list-cron, list-timers
  • docker-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) y SYSADMIN_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)

  1. Sube la versión en package.json y src/index.ts
  2. Crea un GitHub Release (tag vX.Y.Z) → el workflow .github/workflows/publish.yml publica en GitHub Packages
  3. Verifica en Packages del repo: @kreodevs/mcp-sysadmin

Configuración

  1. Copia el inventario de ejemplo:
cp config/inventory.example.json config/inventory.json
  1. Edita config/inventory.json con tus hosts reales.

  2. 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 host
  • allowedTools — 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 ~/.npmrc o --registry=https://npm.pkg.github.com en los args de 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": "..."
      }
    }
  }
}

<details> <summary>Desarrollo local (clone del repo)</summary>

{
  "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"
      }
    }
  }
}

</details>


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, no env. El command debe 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_TOKEN obligatorio — falla al arrancar si falta
  • SSH usa allowlist estricta (sin cat/grep; lecturas solo vía ssh-read-file)
  • Prohibido password en inventario SSH
  • vm-power requiere confirmación incluso para start
  • 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 — siempre
  • ssh-read-file — siempre
  • vm-power — todas las acciones en producción; stop/shutdown/reboot/reset siempre
  • create-vm-snapshot — siempre
  • create-backup — siempre
  • create-dns-record, update-dns-record, delete-dns-record, purge-cache — siempre

Checklist pre-producción

  • [ ] SYSADMIN_PRODUCTION_MODE=true
  • [ ] SYSADMIN_CONFIRM_TOKEN generado (openssl rand -hex 32)
  • [ ] Fingerprint SSH en cada host
  • [ ] Tokens Proxmox / Hetzner / Cloudflare con permisos mínimos
  • [ ] verifySsl: true en Proxmox
  • [ ] allowedTools por host según necesidad
  • [ ] Inventario sin passwords en texto plano
  • [ ] Probar una operación destructiva con token manual

CI y publicación

Extensión

Para añadir otro proveedor (oVirt, VMware, AWS, etc.):

  1. Añade el provider en src/config/schema.ts
  2. Implementa cliente en src/providers/<nombre>/client.ts
  3. Regístralo en src/providers/registry.ts
  4. 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

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选