🚀 MCP Orchestrator — Servidor de orquestación SSH/SFTP
v11.8.0 Security Refresh — Las 82 herramientas ahora publican anotaciones MCP estándar. infra_overview sigue siendo ligero sin argumentos, pero infra_overview { alias: "..." } realiza un descubrimiento en vivo y correlaciona Nginx/dominios, puertos, Docker/Compose y servicios. Ver CHANGELOG.md.
Versión : 11.8.0
Herramientas : 82
Licencia : MIT
Node : >= 18.0.0
Changelog : CHANGELOG.md
Servidor MCP (Model Context Protocol, transporte stdio) que brinda a un agente de IA la capacidad de orquestar un parque de servidores: SSH, SFTP, edición de archivos local/remota (hash-safe), diffs entre servidores, shell PTY, snapshots de infraestructura, notas de protocolo, proyectos, sesiones de trabajo, inventario, confianza SSH (pubkey), grupos de alias y auditoría del parque.
✨ Puntos destacados (v11.6)
| Ámbito | Capacidad |
|---|
| Ejecución | task_exec multi-servidor / group:oci / dry-run destructivo / force |
| Archivos | file_read / file_edit (quirúrgico) / file_write + hash + dryRun + backup |
| Parque | notas, infra_audit, fleet_status, server_inventory |
| Proyectos | registro local↔remoto + project_diff |
| Trabajo | work_start → ediciones → work_end (nota de intervención automática) |
| Confianza | ssh_authorize_key (solo pubkey, dry_run por defecto) |
| Seguridad | secretos enmascarados, RO global + RO por alias, blocklist, pool SSH robusto |
📦 Instalación
git clone https://github.com/fkom13/mcp-sftp-orchestrator.git
cd sftp-mcp # ou tools/sftp-mcp
npm install
cp .env.example .env
# Éditer MCP_DATA_DIR et chemins de clés
Requisitos previos: Node.js >= 18
⚙️ Configuración (.env)
Todas las variables son opcionales.
| Variable | Predeterminado | Descripción |
|---|
MCP_DATA_DIR | ~/.config/mcp-orchestrator | Carpeta de datos (JSON, snapshots, proyectos…) |
MCP_SYNC_TIMEOUT_S | 120 | Retraso (s) antes de pasar una tarea a segundo plano |
MCP_DEFAULT_CMD_TIMEOUT_S | 600 | Timeout SSH de comando (s). 0 = infinito |
MCP_INTERACTIVE_CMD_TIMEOUT_S | 300 | Timeout interactivo (s). 0 = infinito |
MCP_MAX_WAIT_TIMEOUT_S | 600 | Timeout máximo task_wait (s) |
MAX_CONNECTIONS_PER_SERVER | 5 | Pool SSH máximo / servidor |
MIN_CONNECTIONS_PER_SERVER | 1 | Pool SSH mínimo / servidor |
IDLE_TIMEOUT | 300000 | Cierre de conexión inactiva (ms) |
KEEP_ALIVE_INTERVAL | 30000 | Keepalive SSH (ms) |
MAX_QUEUE_SIZE | 1000 | Tamaño máximo de cola de trabajos |
SAVE_INTERVAL | 5000 | Autoguardado de cola (ms) |
MCP_ALLOWED_ROOTS | (vacío) | Raíces permitidas para rutas locales (CSV) |
MCP_READONLY | false | 1 = rechaza escrituras / exec mutantes (global) |
MCP_COMPACT | false | 1 = respuestas truncadas (tokens de agente) |
MCP_DEBUG | false | Registros detallados en stderr |
Archivos bajo MCP_DATA_DIR
| Archivo | Contenido |
|---|
servers.json | Alias SSH (host, user, keyPath/password, port?, readonly?) |
apis.json | Catálogo de APIs (secretos enmascarados en herramientas de lectura) |
queue.json / queue.backup.json | Trabajos |
history.json | Historial de tareas |
server_notes.json | Protocolos / notas por servidor |
server_groups.json | Grupos de alias |
projects.json | Registro de proyectos |
work_sessions.json | Sesiones de trabajo |
policies.json | Blocklist de comandos |
tunnels.json / tunnel_allowlist.json | Túneles SSH |
infra_snapshots/ | Snapshots content-addressable |
🔌 Conexión de cliente MCP
Grok / config.toml
[mcp_servers.orchestrator]
command = "node"
args = ["/chemin/absolu/sftp-mcp/server.js"]
# optionnel:
# env = { MCP_DATA_DIR = "/chemin/absolu/sftp-mcp/data" }
OpenCode / Claude Desktop (JSON)
{
"mcpServers": {
"orchestrator": {
"command": "node",
"args": ["/chemin/absolu/sftp-mcp/server.js"],
"env": {
"MCP_DATA_DIR": "/chemin/absolu/sftp-mcp/data"
}
}
}
}
Después de modificar el código: recargar el servidor MCP (/mcps → r o reiniciar sesión). Verificar system_diagnostics → version: "11.8.0".
🧰 Referencia de herramientas (82)
Diagnóstico y auditoría
| Herramienta | Descripción |
|---|
help | Guía de herramientas + .env + consejos |
guide | Manual de IA (workflows, cheatsheet, errores comunes, auditoría, seguridad) |
system_diagnostics | Cola, pool, servidores/APIs enmascarados, versión, readOnly |
infra_audit | Resumen del parque + proyectos + notas + bloqueos |
infra_overview | Servidores + notas (vista ligera) |
fleet_status | Ping SSH paralelo (latencia, carga, disco) |
server_inventory | Inventario ligero (pm2/docker/disco/home, caché de 10 min) |
Servidores y grupos
| Herramienta | Descripción |
|---|
server_add | CRUD de alias (keyPath o password, port, readonly) |
server_list | Lista (contraseñas enmascaradas) |
server_remove | Elimina un alias |
server_group_list/set/remove | Grupos (oci, contabo…). Uso: group:oci o nombre de grupo |
Proyectos (v11.6)
| Herramienta | Descripción |
|---|
project_list / project_get / project_set / project_remove | Registro |
project_resolve | → { local, remote, ignore, runtime } |
project_diff | Diff local↔remoto del proyecto |
Ejemplo project_set:
{
"name": "p-image",
"local": { "path": "/home/.../dev-serveur/p-image" },
"servers": {
"prod": {
"alias": "fkomprodmini2_prod",
"path": "/home/ubuntu/p-image",
"runtime": { "pm2": "p-image", "port": 5002 },
"url": "https://pruna.esprit-artificiel.com"
}
},
"ignore": ["node_modules", ".git", "data"]
}
Sesiones de trabajo (v11.6)
| Herramienta | Descripción |
|---|
work_start | Abre un diario (alias, project, tag, snapshot opcional) |
work_log | Evento (file_edit, task_exec, …) |
work_list | Sesiones activas (+ historial) |
work_end | Cierre + server_note last_intervention |
Confianza SSH (v11.6)
| Herramienta | Descripción |
|---|
ssh_authorize_key | Agrega una pubkey en authorized_keys remoto. dry_run por defecto. Fuentes: string | local_path | alias |
{
"target_alias": "fkomprodmini1_prod",
"source": { "type": "alias", "alias": "vps_contabo" },
"comment": "fleet-from-contabo",
"dry_run": true
}
Políticas
| Herramienta | Descripción |
|---|
policy_blocklist_list/add/remove | Blocklist de comandos (también aplicada a shell + secuencias) |
Catálogo de API
| Herramienta | Descripción |
|---|
api_add / api_list / api_remove / api_check | Monitoreo (claves enmascaradas en listado) |
Ejecución de tareas
| Herramienta | Descripción |
|---|
task_exec | SSH; alias | array | all | group:x; dry_run/force destructivo |
task_exec_interactive | Prompts sí/no, menús |
task_exec_sequence | Secuencia en un servidor (política por paso) |
task_transfer | SFTP upload/download/server_to_server |
task_transfer_multi | Multi + globs |
Archivos / Diff / Shell / Snapshots
| Familia | Herramientas |
|---|
| Archivos | file_read, file_write, file_edit |
| Diff | diff_files, diff_folders, compare_all_sources |
| Shell | shell_create, shell_exec (+ skip_policy), shell_list, shell_close |
| Snapshots | snapshot_create/list/diff/restore/delete |
Edición segura: file_read → hash → file_edit + expectedHash (+ dryRun / backup).
Notas de servidor
| Herramienta | Descripción |
|---|
server_note_set/get/list/remove | Protocolo (descripción, servicios, advertencias, intervención) |
Monitoreo y registros
| Herramienta | Descripción |
|---|
get_system_resources | CPU / RAM / disco |
get_services_status | systemd / Docker / PM2 |
get_fail2ban_status | Fail2Ban |
check_api_health | HTTP vía SSH+curl |
get_pm2_logs / get_docker_logs / tail_file | Registros |
Cola
| Herramienta | Descripción |
|---|
task_queue / task_status / task_history / task_wait / task_logs | Seguimiento |
task_retry / task_retry_all | Reintento |
task_purge | Purga (dry_run por defecto) |
queue_stats / pool_stats | Estadísticas |
Tmux y túneles
| Herramienta | Descripción |
|---|
tmux_create/exec/read/list/kill | Sesiones tmux remotas |
tunnel_create/list/close | Túneles SSH local/remoto/socks |
tunnel_allowlist_add/remove | Puertos permitidos para túneles |
📖 Workflows de agente recomendados
Inicio de sesión
infra_audit (ou infra_overview)
fleet_status
project_list / project_resolve
Trabajo en un proyecto
work_start { project: "p-image", alias: "fkomprodmini2_prod", tag: "fix-x", message: "…" }
file_read → file_edit (expectedHash, dryRun puis apply)
work_log { type: "file_edit", path: "…" }
work_end { summary: "…" } → note serveur mise à jour
project_diff { name: "p-image" }
Comandos largos
task_exec { timeout: 0, … } → si > syncTimeout → task_wait { id }
Destinos multi-servidor
task_exec { alias: "group:oci", cmd: "hostname" }
task_exec { alias: "all", cmd: "uptime" }
🏗️ Arquitectura
Client MCP (stdio)
│
server.js ─── 82 tools
│
├── queue.js File d’attente persistante + purge/retry
├── ssh.js / sshPool Exécution + pool (retry safe, port configurable)
├── sftp.js Transferts (server_to_server via sourceAdapter/pool)
├── sourceAdapter.js Local fs | remote SFTP pool
├── fileOps.js Read/write/edit + hash + dryRun + backup
├── diffEngine.js / compareEngine.js / diffFormatter.js
├── shellSessions.js PTY persistants + policy
├── snapshotManager.js
├── projects.js / workSession.js / inventory.js / groups.js / fleet.js
├── sshTrust.js authorized_keys (pubkey only)
├── servers.js / apis.js / notes.js / policies.js / tunnels.js
├── history.js / guide.js / config.js / utils.js
Ciclo de vida de un trabajo
pending → running → completed | failed | partial
↓ (redémarrage MCP pendant running)
crashed → task_retry → pending
🔒 Seguridad
| Mecanismo | Detalle |
|---|
| Secretos | Enmascarados en api_list / diagnósticos (*** + últimos 4 caracteres) |
| Escape de shell | escapeShellArg en curl, registros, rutas |
| Blocklist | policies.json; shell + secuencia incluidos; skip_policy para forzar |
| RO global | MCP_READONLY=1 |
| RO alias | "readonly": true en servers.json |
| Destructivo | task_exec dry-run si patrón peligroso sin force:true |
| Confianza | Solo pubkey; dry_run por defecto |
| Claves | Preferir keyPath SSH; Vaultwarden para secretos de API |
🧪 Pruebas
npm test:unit # p0 + p1 + p16 (43 tests)
npm test # unit + smoke MCP + features
node diagnose.js # diagnostic local optionnel
| Archivo | Cobertura |
|---|
test_p0_unit.js | utils, políticas, redact, timeouts, versión |
test_p1_unit.js | grupos, purge, destructivo, entorno RO |
test_p16_unit.js | proyectos, sesión de trabajo, compact, sshTrust |
test_mcp.js | smoke SDK |
test_features.js | cola / pool / globs / prompts |
🛣️ Versiones recientes
| Versión | Contenido | Snapshot gencodedoc |
|---|
| 11.6.1 | Endurecimiento multi-agente: RO transversal, carpetas/fuerza servidor a servidor, raíces permitidas anti-symlink, quoting shell/tmux, cola + almacenes JSON atómicos | — |
| 11.6.0 | Proyectos, sesiones de trabajo, inventario, ssh_authorize_key, RO alias, compact | #23 (documentación final) |
| 11.4.0 | fleet, infra_audit, grupos, retry_all, purge, reescritura de pool | #21 |
| 11.3.0 | Enmascaramiento de secretos, política shell/seq, puerto SSH, espera parcial | #20 |
| 10.4–10.0 | operaciones de archivo, diff, shell, snapshots, notas, guía | #17–19 |
| 9.x / 8.x | SFTP force, timeouts, interactivo, seguridad básica | — |
Detalle: CHANGELOG.md · planes históricos: ROADMAP.md, ROADMAP_EXTENDED.md.
📄 Licencia
MIT — Copyright (c) 2025-2026 Franck (fkom13)