🚀 MCP Orchestrator — SSH/SFTP 编排服务
v11.8.0 安全更新 — 82 个工具现在均发布标准 MCP 注解。不带参数时,infra_overview 仍保持轻量;但使用 infra_overview { alias: "..." } 会执行实时发现,并关联 Nginx/域名、端口、Docker/Compose 和服务。请参阅 CHANGELOG.md。
版本:11.8.0
工具:82
许可证:MIT
Node:>= 18.0.0
变更日志:CHANGELOG.md
基于 MCP(Model Context Protocol,模型上下文协议)、使用 stdio 传输的 MCP 服务,可让 AI Agent 编排服务器群:SSH、SFTP、本地/远程文件编辑(哈希安全)、跨服务器差异对比、PTY shell、基础设施快照、协议笔记、项目、工作会话、清单、SSH 信任(公钥)、别名组和服务器群审计。
✨ 亮点(v11.6)
| 领域 | 功能 |
|---|
| 执行 | task_exec 多服务器 / group:oci / 破坏性操作 dry-run / force |
| 文件 | file_read / file_edit(精细编辑)/ file_write + hash + dryRun + backup |
| 服务器群 | 笔记、infra_audit、fleet_status、server_inventory |
| 项目 | 本地↔远程注册表 + project_diff |
| 工作 | work_start → edits → work_end(自动生成干预记录) |
| 信任 | ssh_authorize_key(仅公钥,默认 dry_run) |
| 安全 | 隐藏密钥、全局只读 + 按别名只读、阻止列表、稳健的 SSH 连接池 |
📦 安装
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
先决条件:Node.js >= 18
⚙️ 配置(.env)
所有变量均为可选。
| 变量 | 默认值 | 描述 |
|---|
MCP_DATA_DIR | ~/.config/mcp-orchestrator | 数据目录(JSON、快照、项目……) |
MCP_SYNC_TIMEOUT_S | 120 | 任务转入后台前的延迟(秒) |
MCP_DEFAULT_CMD_TIMEOUT_S | 600 | SSH 命令超时(秒)。0 = 无限 |
MCP_INTERACTIVE_CMD_TIMEOUT_S | 300 | 交互式命令超时(秒)。0 = 无限 |
MCP_MAX_WAIT_TIMEOUT_S | 600 | task_wait 最大超时(秒) |
MAX_CONNECTIONS_PER_SERVER | 5 | 每台服务器的 SSH 连接池上限 |
MIN_CONNECTIONS_PER_SERVER | 1 | 每台服务器的 SSH 连接池下限 |
IDLE_TIMEOUT | 300000 | 关闭空闲连接的时间(毫秒) |
KEEP_ALIVE_INTERVAL | 30000 | SSH 保活间隔(毫秒) |
MAX_QUEUE_SIZE | 1000 | 作业队列大小上限 |
SAVE_INTERVAL | 5000 | 队列自动保存间隔(毫秒) |
MCP_ALLOWED_ROOTS | (空) | 本地路径的允许根目录(CSV) |
MCP_READONLY | false | 1 = 拒绝写入 / 会更改状态的执行(全局) |
MCP_COMPACT | false | 1 = 截断响应(Agent 令牌) |
MCP_DEBUG | false | 将详细日志写入 stderr |
MCP_DATA_DIR 下的文件
| 文件 | 内容 |
|---|
servers.json | SSH 别名(host、user、keyPath/password、port?、readonly?) |
apis.json | API 目录(读取工具时隐藏密钥) |
queue.json / queue.backup.json | 作业 |
history.json | 任务历史记录 |
server_notes.json | 每台服务器的协议 / 笔记 |
server_groups.json | 别名组 |
projects.json | 项目注册表 |
work_sessions.json | 工作会话 |
policies.json | 命令阻止列表 |
tunnels.json / tunnel_allowlist.json | SSH 隧道 |
infra_snapshots/ | 内容寻址快照 |
🔌 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"
}
}
}
}
修改代码后:重新加载 MCP 服务(/mcps → r 或重启会话)。检查 system_diagnostics → version: "11.8.0"。
🧰 工具参考(82)
诊断与审计
| 工具 | 描述 |
|---|
help | 工具指南 + .env + 技巧 |
guide | AI 手册(工作流、速查表、注意事项、审计、安全) |
system_diagnostics | 队列、池、已隐藏的服务器/API、版本、readOnly |
infra_audit | 服务器群 + 项目 + 备注 + 崩溃情况摘要 |
infra_overview | 服务器 + 备注(轻量视图) |
fleet_status | 并行 SSH Ping(延迟、负载、磁盘) |
server_inventory | 轻量清单(pm2/docker/disk/home,缓存 10 分钟) |
服务器与组
| 工具 | 描述 |
|---|
server_add | CRUD 别名(keyPath 或 password、port、readonly) |
server_list | 列表(密码已隐藏) |
server_remove | 删除别名 |
server_group_list/set/remove | 组(oci、contabo…)。用法:group:oci 或组名 |
项目(v11.6)
| 工具 | 描述 |
|---|
project_list / project_get / project_set / project_remove | 注册表 |
project_resolve | → { local, remote, ignore, runtime } |
project_diff | 项目本地↔远程差异 |
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"]
}
工作会话(v11.6)
| 工具 | 描述 |
|---|
work_start | 打开日志(alias、project、tag、可选快照) |
work_log | 事件(file_edit、task_exec,…) |
work_list | 活跃会话(+ 历史记录) |
work_end | 结束会话 + server_note last_intervention |
SSH 信任(v11.6)
| 工具 | 描述 |
|---|
ssh_authorize_key | 将一条公钥添加到远程 authorized_keys。默认 dry_run。来源:string | local_path | alias |
{
"target_alias": "fkomprodmini1_prod",
"source": { "type": "alias", "alias": "vps_contabo" },
"comment": "fleet-from-contabo",
"dry_run": true
}
策略
| 工具 | 描述 |
|---|
policy_blocklist_list/add/remove | 命令阻止列表(也应用于 shell + 序列) |
API 目录
| 工具 | 描述 |
|---|
api_add / api_list / api_remove / api_check | 监控(列表中的密钥已隐藏) |
任务执行
| 工具 | 描述 |
|---|
task_exec | SSH;别名 | 数组 | all | group:x;破坏性操作使用 dry_run/force |
task_exec_interactive | 是/否提示、菜单 |
task_exec_sequence | 在一台服务器上执行序列(逐步应用策略) |
task_transfer | SFTP 上传/下载/server_to_server |
task_transfer_multi | 多项操作 + glob 模式 |
文件 / Diff / Shell / 快照
| 类别 | 工具 |
|---|
| 文件 | 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 |
| 快照 | snapshot_create/list/diff/restore/delete |
安全编辑:file_read → 哈希 → file_edit + expectedHash(+ dryRun / backup)。
服务器备注
| 工具 | 描述 |
|---|
server_note_set/get/list/remove | 协议(描述、服务、警告、干预) |
监控与日志
| 工具 | 描述 |
|---|
get_system_resources | CPU / RAM / 磁盘 |
get_services_status | systemd / Docker / PM2 |
get_fail2ban_status | Fail2Ban |
check_api_health | 通过 SSH+curl 检查 HTTP |
get_pm2_logs / get_docker_logs / tail_file | 日志 |
队列
| 工具 | 描述 |
|---|
task_queue / task_status / task_history / task_wait / task_logs | 跟踪 |
task_retry / task_retry_all | 重试 |
task_purge | 清理(默认 dry_run) |
queue_stats / pool_stats | 统计数据 |
Tmux 与隧道
| 工具 | 描述 |
|---|
tmux_create/exec/read/list/kill | 远程 tmux 会话 |
tunnel_create/list/close | 本地/远程/SOCKS SSH 隧道 |
tunnel_allowlist_add/remove | 隧道允许使用的端口 |
📖 推荐的 Agent 工作流
会话开始
infra_audit (ou infra_overview)
fleet_status
project_list / project_resolve
项目工作
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" }
长时间运行的命令
task_exec { timeout: 0, … } → si > syncTimeout → task_wait { id }
多服务目标
task_exec { alias: "group:oci", cmd: "hostname" }
task_exec { alias: "all", cmd: "uptime" }
🏗️ 架构
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
作业生命周期
pending → running → completed | failed | partial
↓ (redémarrage MCP pendant running)
crashed → task_retry → pending
🔒 安全
| 机制 | 详情 |
|---|
| 密钥 | 在 api_list / 诊断信息中隐藏(*** + 末尾 4 个字符) |
| Shell 转义 | 对 curl、日志、路径使用 escapeShellArg |
| 禁止列表 | policies.json;包含 shell + sequence;使用 skip_policy 强制执行 |
| 全局只读 | MCP_READONLY=1 |
| 别名只读 | 在 servers.json 中设置 "readonly": true |
| 破坏性操作 | 若存在危险模式且未设置 force:true,task_exec 将执行 dry-run |
| 信任 | 仅公钥;默认使用 dry_run |
| 密钥 | 优先使用 SSH keyPath;API 密钥使用 Vaultwarden |
🧪 测试
npm test:unit # p0 + p1 + p16 (43 tests)
npm test # unit + smoke MCP + features
node diagnose.js # diagnostic local optionnel
| 文件 | 覆盖范围 |
|---|
test_p0_unit.js | utils、policies、redact、timeouts、version |
test_p1_unit.js | groups、purge、destructive、RO env |
test_p16_unit.js | projects、work session、compact、sshTrust |
test_mcp.js | SDK 冒烟测试 |
test_features.js | queue / pool / globs / prompts |
🛣️ 最近版本
| 版本 | 内容 | gencodedoc 快照 |
|---|
| 11.6.1 | 多 Agent 加固:跨服务只读、服务间 dossiers/force、防符号链接的 allowed roots、shell/tmux 引号处理、queue + 原子 JSON 存储 | — |
| 11.6.0 | 项目、工作会话、inventory、ssh_authorize_key、别名只读、compact | #23(最终文档) |
| 11.4.0 | fleet、infra_audit、groups、retry_all、purge、pool 重写 | #21 |
| 11.3.0 | 密钥隐藏、shell/seq 策略、SSH 端口、部分等待 | #20 |
| 10.4–10.0 | 文件操作、diff、shell、快照、笔记、指南 | #17–19 |
| 9.x / 8.x | SFTP 强制、超时、交互、基础安全 | — |
详情:CHANGELOG.md · 历史计划:ROADMAP.md、ROADMAP_EXTENDED.md。
📄 许可证
MIT — 版权所有 (c) 2025-2026 Franck (fkom13)