mcpField
L
Let AI assistants operate your Linux servers — behind a human consent gate the model can't self-approve.

Let AI assistants operate your Linux servers — behind a human consent gate the model can't self-approve.

github.com/MHasnainJafriIDE 与编辑器56 周前更新

关于 Let AI assistants operate your Linux servers — behind a human consent gate the model can't self-approve.

一个 MCP 服务,让 AI 助手(Claude Desktop、Cursor、Windsurf)连接和操作 Linux 服务器,但所有改变生产服务器状态的操作都需要人工同意令牌批准。读操作始终允许,提供安全、可审计的 DevOps 自动化。

主要功能

  1. 01三级访问模式
  2. 02生产服务器写入保护
  3. 03出带外同意令牌
  4. 04命令参数 Shell 转义
  5. 05服务器配置文件扫描
  6. 06审计日志记录

适用场景

  1. 01生产服务器安全部署
  2. 02DevOps 自动化任务
  3. 03服务器诊断和监控
  4. 04版本控制和策略执行

MCP 相关

作为 MCP 服务暴露 Linux 服务器工具给客户端,要求所有改变性操作通过人工同意令牌验证,读操作默认允许。

详细介绍

devops-mcp

一个基于模式的 MCP(Model Context Protocol,模型上下文协议)服务,让 AI 助手(Claude Desktop、Cursor、Windsurf……)可以实际操作 Linux 服务器,但不会让它们获得完全控制权。

该模型可以连接、扫描、规划和部署——但每一步改变生产类服务器状态的操作都必须通过 AI 无法自行批准的同意关卡。发现功能在设计上是只读的。

┌─────────────────┐          MCP / stdio          ┌────────────────────┐
│  AI client      │  ───────────────────────────► │  devops-mcp        │
│  (Claude /      │                               │                    │
│   Cursor / …)   │  ◄─────────────────────────── │  ssh2 / docker /   │
└─────────────────┘                               │  child_process     │
                                                  └────────┬───────────┘
                                                           │ SSH
                                                           ▼
                                                   ┌────────────────┐
                                                   │  Your VPS      │
                                                   └────────────────┘

⚡ 首次设置(读一次,做一次)

恰好四个步骤。不要跳过第 2 步。

1. 安装
git clone <your-fork-url>.git devops-mcp
cd devops-mcp
npm install
npm run build

需要 Node ≥ 18。

2. 生成你的提升令牌并将其保存在不会丢失的地方
# Linux / macOS
openssl rand -hex 24

# Windows PowerShell
$bytes = New-Object byte[] 24; (New-Object System.Security.Cryptography.RNGCryptoServiceProvider).GetBytes($bytes); [BitConverter]::ToString($bytes).Replace("-","").ToLower()

# Or, via Node
node -e "console.log(require('crypto').randomBytes(24).toString('hex'))"

你会得到类似 6ba329add30b19a5a347178f7e3705fdea0ac1aa66cb9274 的东西。

🔑 在第 3 步之前保存此令牌。

此令牌是阻止 AI 获得无限制生产访问权的唯一防线。该模型永远看不到它。 每当 AI 想要提升到 PROVISION/FULL 模式、批准破坏性操作、更改服务器角色或在生产类服务器上写入时,你只需粘贴一次。

将其保存在密码管理器中。如果你丢失了它:

  • 你可以手动编辑 MCP 客户端的配置以设置新令牌,或者
  • 如果你仍然拥有旧令牌,可以要求 AI 调用 rotate_consent_token(如果两个都丢失了就不行了)。

没有恢复流程。这是关卡;我们没有提供后门。

3. 将 devops-mcp 添加到 MCP 客户端配置

对于 Claude Desktop,编辑 claude_desktop_config.json:

  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

添加(或合并到现有 mcpServers):

{
  "mcpServers": {
    "devops-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/devops-mcp/dist/index.js"],
      "env": {
        "DEVOPS_MCP_ELEVATION_TOKEN": "<paste your token from step 2 here>",
        "LOG_LEVEL": "info"
      }
    }
  }
}

相同的结构适用于 Cursor、Windsurf 和任何其他 MCP 客户端——env 块是传递机密的标准 MCP 方式。

4. 完全退出并重新打开 MCP 客户端

不是"关闭窗口"。在 Windows 上,这意味着系统托盘 → 退出。提升令牌在启动时读取;客户端必须重新启动才能生效。

完成。下次你和 AI 交谈时,说"在……添加我的服务器",它会引导你完成。


存在的原因

通用的"运行任何命令"MCP 服务在生产服务器上很危险。一个拥有对实时服务器完全 shell 访问权限的模型可以——而且会——重启错误的服务、部署到正在使用的端口、docker prune 一个数据库卷,或因为没有人告诉它不能就提升自己到 root。

devops-mcp 在读取和更改之间划出了一条硬线:

  • 读取总是被允许的(在只读的 SAFE 允许列表内)。
  • 在生产类服务器上更改需要人类的令牌——带外传递,对模型不可见。
  • 部署新项目通过端口冲突检查和可审查的脚本进行,而不是 40 个临时命令。

特性

访问控制
  • 三层模式:SAFE(默认,只读白名单)、PROVISION(系统安装,默认 1 小时过期)、FULL(root,默认 30 分钟过期)。
  • 带外同意令牌 — 提升权限和批准需要仅用户持有的字符串。大模型根本无法读取它。
  • 生产环境写入门控 — 在 role: production 服务(或任何扫描器标记为 productionLikely 的服务)上,任何非 SAFE 命令都需要 consentToken + acknowledgeProductionWrite: true。灾难性命令 — 不进行备份无法恢复的命令(rm 非临时路径、rm -rf /…、dd of=/dev/…、mkfs、SQL DROP TABLE/DATABASE、docker rmi、docker volume rm、docker rm -v、docker system prune)— 另外还需要 backupVerified: true。普通写入和可恢复操作(编辑文件、rm /tmp/scratch、简单 docker rm 可从镜像重新创建的容器)无需 backupVerified。拒绝会回显确切解析的命令。
  • 按服务策略 — allowedModes、blockedCommands、allowedPaths、requireApproval 位于 config/<server-id>/server.json 中,在每个 SSH 命令上强制执行。
  • 必需的 role — add_server 不会让 AI 无声地默认 role;它必须询问用户,响应包含 AI 回读给你的 roleConsequences 块。
  • 令牌轮换 — rotate_consent_token 生成新令牌(默认为空运行;apply: true 原子地更新你的 MCP 客户端配置)。
  • 凭证轮换 — update_server_credentials 轮换密码、交换 SSH 密钥(包括通过 keyPassphrase 的加密密钥),或在不重新添加服务的情况下迁移 host/user/port。role、限制和扫描配置文件保持不变。首先关闭到该服务的任何活跃会话,使用测试连接验证新凭证,并在生产环境上需要同意门控。
  • AWS / EC2 .pem 已就绪 — 使用 .pem 文件 + 用户名 + IP 进行登录。就地引用它(externalKeyPath)或将其复制到配置包中(keyFilePath);仅当密钥已加密时才添加 keyPassphrase。
  • 多个并发连接,由 serverId 键控 — MCP 为每个服务持有一个 SSH 连接,而不是一个全局槽。Claude Desktop 在所有对话中运行单个共享 MCP 进程;使用全局连接,两个对话在两个服务上工作会相互覆盖("会话 1 在服务 A 上,会话 2 连接到 B,现在 A 的命令被发送到 B")。键控连接让两者共存。run_command 接受 serverId:当恰好连接一个服务时可选,连接两个或更多个时必需 — 含糊调用被拒绝而不是猜测。每个 run_command 响应回显 target.serverId 和 activeConnections。
  • 防目标漂移 — run_command、set_mode 和 get_current_mode 响应都带有已连接的服务身份,因此对话永远不会无声地在错误的机器上结束。disconnect_server 接受可选的 serverId(或 "all")。
  • 会话感知的实时登录 — add_server 在其响应中显示当前连接的服务,并告知 AI 在不询问的情况下不要自动切换到新添加的服务。
发现与规划
  • 服务器发现扫描 — 操作系统、硬件、监听端口、已安装堆栈(docker / nginx / apache / node / pm2)、运行容器、解析的 nginx 站点、systemd 服务的只读探测。输出持久化为 ServerProfile。
  • 重新连接时的配置文件差异 — diff_server_profile 重新扫描并报告自保存快照以来的更改。
  • 端口冲突意识 — check_port_conflict 在部署前返回监听进程 + 可用端口建议。
  • 规划,不要执行 — plan_deployment 返回用户审查的幂等 bash 脚本。MCP 不执行它。
安全加固
  • 所有命令参数都经过 shell 转义 后再发送到远程 shell。不再出现 sh -c "<long script>" 有效负载在错误的 shell 层级分割的情况。
  • 验证器检查参数 — run_command({command:"ls", args:["; rm -rf /"]}) 在 SAFE 模式下不再通过 ls 验证。
  • 引号感知链分割器 — 只读命令链保持 SAFE 状态。诊断管道如 du -sh /opt/* ; echo --- ; df -h / 不需要提升权限。每个片段独立验证;链所需的模式是各部分的最大值。
  • 全面的只读允许清单 — 约 250 个只读动词在 SAFE 中运行:文件系统读取、文本处理器(awk/sed/jq/cut/…)、哈希校验和、硬件/进程检查(lsof/lspci/vmstat/…)、软件包查询(apt/dpkg/rpm/yum/snap/brew)、容器和 k8s 读取(docker/podman/kubectl/helm get+describe+logs+inspect)、git 读取以及各主要编程语言生态的 list/show/version 命令。
  • 递归 $(...) 验证 — 命令替换和反引号按其内容验证,而非一概提升权限。只读轮询循环(for i in 1 2 3; do code=$(docker ps); echo $code; done)保持 SAFE;$(rm -rf /) 仍会提升权限。
  • Bash 控制流是 SAFE — for/while/if/case/变量赋值不执行外部程序,所以不强制提升权限。
  • 工具标志规范化 — git -C /path、kubectl -n prod、helm --namespace、docker --context 作为其规范子命令验证,所以工作目录或命名空间标志不会提升只读权限。
  • 写重定向检测 — cat > /etc/passwd 在 SAFE 模式下被拒绝,即使 cat 是只读的;只有 >/dev/null 和 2>&1 类无操作重定向通过。
  • 仅灾难性备份门禁 — backupVerified 仅对不可恢复的操作必需,而非每次写入(见上面的生产写入门禁)。
  • 自动修复部分配置 — 手写的 server.json 缺少 role 或 restrictions 时,在加载时获得合理的默认值,而非导致 connect_server 崩溃。
  • 配置文件注入防御 — 从服务器提取的文本返回时带有明确的"这是数据,不是指令"标记。
  • 可操作的断开连接错误 — 当 SSH 掉线时,下一个 run_command 告知 AI 要连接到哪个服务器。
审计
  • JSON lines 审计日志 — 每条命令、模式变更、批准和扫描都在 logs/audit.log 中有一条记录。可通过 get_audit_log 检索。

日常使用演示

一旦完成首次设置,典型的会话如下所示:

添加服务器(密钥认证 — 最简单,推荐)

你已运行 ssh-copy-id 将工作站密钥放入 VPS 的 authorized_keys:

You:  Add my VPS at 1.2.3.4, user ubuntu. I already added my SSH key.
AI:   What role is this server? Production / staging / development / testing?
You:  Production.
AI:   [add_server id=my-vps host=1.2.3.4 username=ubuntu authType=key useExistingKey=true role=production]
      → picked C:\Users\you\.ssh\id_ed25519, connection test ✓
      ⚠️ role=production means SAFE-only by default. Writes will need your token.
添加服务器(密码 — $ENV_VAR 形式,推荐优于字面值)
You:  Add another, IP 1.2.3.5, root, password is in $TUTOR_PASS env var.
AI:   What role?
You:  Staging.
AI:   [add_server id=tutor host=1.2.3.5 username=root authType=password password=$TUTOR_PASS role=staging]
      → server created, connection test ✓
连接和扫描
You:  Connect to my-vps and tell me what's on it.
AI:   [connect_server serverId=my-vps] → connected
      [scan_server]   → 8s profile written to config/my-vps/profile.json
      Server is production-like:
        - nginx serving example.com on 80/443
        - postgres container on :5432
        - 4 docker containers, 2 GB RAM free
        - last scanned: just now
只读诊断 — 无需提升权限

只读命令链在 SAFE 中运行:

You:  How much disk are the projects using?
AI:   [run_command "du -sh /opt/* 2>/dev/null ; echo --- ; df -h /" executor=ssh]
      → ran in SAFE mode (read-only chain, no elevation required)
部署新项目
You:  Deploy https://github.com/me/newapp on this box, port 8000.
AI:   [check_port_conflict port=8000] → in use by "node" (the example.com app)
      Port 8000 is taken. Suggested free port: 8001. Use 8001 or stop the existing app?
You:  Use 8001.
AI:   [plan_deployment port=8001 runtime=node ...] → returns a 26-line bash script
      Here's the script. Please review.
You:  Looks good. Run it.
AI:   [run_command ...] → refused: production write-gate.
      To run this I need your elevation token and confirmation that a backup exists.
You:  Token is <paste>. Yes, snapshot taken this morning.
AI:   [run_command consentToken=<…> acknowledgeProductionWrite=true backupVerified=true]
      → ✓ deployed
轮换凭证(VPS 密码已更改,或你更换了 SSH 密钥)
You:  I rotated my-vps's root password. New one is in $MY_VPS_PASS_NEW.
AI:   my-vps is role=production — for the rotation I need your elevation token.
You:  Token is <paste>.
AI:   [update_server_credentials serverId=my-vps authType=password
        password=$MY_VPS_PASS_NEW consentToken=<…>]
      → closed active SSH session (was connected), new creds tested ✓
      Reconnect with connect_server when ready.
You:  Connect.
AI:   [connect_server serverId=my-vps] → ✓

角色、限制、被阻止命令列表和扫描配置文件被保留。仅认证字段改变。

稍后更新服务器角色
You:  Actually my-vps is staging now, not production.
AI:   This is a production-touching change, please confirm with the token.
You:  Token is <paste>.
AI:   [update_server serverId=my-vps role=staging applyRoleDefaults=true consentToken=<…>]
      → role changed; allowedModes now [SAFE, PROVISION].
轮换令牌(旧令牌已泄露,例如进入聊天)
You:  Generate a new elevation token and update Claude Desktop's config.
AI:   For verification, paste the current token.
You:  <paste current>
AI:   [rotate_consent_token consentToken=<current> apply=true]
      → 🔑 NEW TOKEN: <new>  ← SAVE THIS NOW, in a password manager.
      Claude Desktop must be fully restarted for the new token to take effect.
      Until then, the OLD token still works on this running session.

访问模式

模式默认过期时间允许的操作
SAFE无过期只读许可列表:ls、cat、df、ss、docker ps、nginx -T 等。所有 SAFE 命令的链式调用也可行。
PROVISION1 小时apt/yum、docker run/build/stop、systemctl start/stop、nginx、ufw、文件操作
FULL30 分钟任何操作,包括 fdisk、dd、shutdown、rm -rf /

提升权限需要:

  • acknowledgeRisk: true(由 AI 设置)
  • consentToken: "<your token>"(仅你拥有)

降级始终被允许且即时生效。会话自动过期回到 SAFE。


工具参考(32 个工具)

服务器生命周期
工具模式功能
add_serverSAFE一次性入门。五种身份验证方式:password(字面值或 $ENV_VAR)、keyFilePath(将密钥复制到配置)、privateKey(粘贴内联)、externalKeyPath(指向现有密钥而不复制)、useExistingKey(自动选择 ~/.ssh/id_*)。需要 role。自动测试连接。返回 roleConsequences。
update_serverSAFE更改角色、allowedModes、blockedCommands、allowedPaths、requireApproval、名称或描述。修改生产环境需要 consentToken。身份验证字段在此处不可变——请参阅 update_server_credentials。
update_server_credentialsSAFE轮换密码、交换 SSH 密钥、迁移主机/用户/端口。首先关闭与此服务器的任何活动 SSH 会话。默认测试新凭据。保留角色/限制/profile.json。生产服务器需要 consentToken。
setup_server_configSAFE更低级别:init / add / status。与原始 add_server 使用的相同。
list_serversSAFE列出所有已配置的服务器
test_connectionSAFE尝试 SSH 连接到已配置的服务器(不运行命令)
connect_serverSAFE打开工作 SSH 会话以供后续命令使用
disconnect_serverSAFE关闭 SSH 会话
发现(全部只读)
工具模式功能
scan_serverSAFE探测操作系统 / 硬件 / 端口 / 堆栈 / 工作负载。持久化保存到 config/<id>/profile.json。目标上无写入操作。
get_server_profileSAFE读取已保存的配置文件而无需重新扫描
diff_server_profileSAFE重新扫描并报告发生了什么更改。除非 accept: true,否则不覆盖已保存的配置文件
check_port_conflictSAFE端口 X 是否被占用?返回监听器和空闲端口建议
list_containersSAFE列出连接的服务器上的 Docker 容器
list_playbooksSAFE列出可用的配置 playbook
执行与部署
工具模式功能
run_commandvaries执行命令(本地 / ssh / docker)。参数被 shell 引用;链式命令被分割,每个片段都被验证;应用生产环境写入门禁。
plan_deploymentSAFE生成一个幂等的 bash 脚本(克隆 + 构建 + pm2/docker)。除非设置 acknowledgeConflict: true,否则拒绝端口冲突。不执行。
run_playbookPROVISION运行预定义的配置 playbook
install_dockerPROVISION安装 Docker + Compose
install_nginxPROVISION安装 Nginx
configure_nginxPROVISION生成 nginx 反向代理配置并重载。使用 heredoc 避免 shell 引用错误。
deploy_appvaries更底层的部署原语(git 克隆 + 构建 + 启动)。所有插值值都被 shell 引用。
container_actionSAFE / PROVISIONstart / stop / restart / logs / inspect
transfer_filesSAFE(下载)/ varies(上传)通过 SFTP 上传/下载文件、文件夹(递归)或存档。extract: true 在服务器上解包上传的 .zip/.tar.gz/.tgz/.tar/.tar.bz2/.tar.xz/.gz;verifyChecksum: true 对单个文件执行端到端 sha256 校验。上传到生产环保的服务器会触发写入门禁。
模式、同意与审计
工具功能
get_current_mode当前模式 + 权限 + 剩余时间
set_mode改变模式。提升权限需要 acknowledgeRisk + consentToken
approve_action批准一个待处理的高风险操作。需要 consentToken
list_pending_approvals列出队列中的批准请求
rotate_consent_token生成新的提升权限令牌。apply: true 原子性地重写 MCP 客户端配置。需要当前令牌。在重启客户端前请阅读响应警告。
generate_ssh_key生成有自动过期的会话 SSH 密钥对
revoke_ssh_key撤销会话 SSH 密钥
get_audit_log尾部/筛选 logs/audit.log(解析 JSON 行,按 since 和 action 筛选)
health_check存活性 + 版本 + 当前模式

认证选项(add_server)

五种认证方式,通过 authType 和相应的密钥/密码字段选择:

选项Schema 字段何时使用
密码authType:"password" + password(字面量或 $ENV_VAR)未配置密钥认证时。优先使用 $ENV_VAR 以防密码出现在配置文件中。
复制密钥文件authType:"key" + keyFilePath你有想与服务器配置一起存储的 PEM 文件(便携式包)
粘贴内联密钥authType:"key" + privateKey你只有密钥文本
指向现有密钥authType:"key" + externalKeyPath你已有 ~/.ssh/whatever — 不复制,仅引用。~ 会被展开。
自动查找密钥authType:"key" + useExistingKey: true你的默认 ~/.ssh/id_* 已在服务器的 authorized_keys 中。最简便。

处理器验证恰好一个密钥来源。不允许同时组合 useExistingKey 和 keyFilePath 等,会返回清晰的错误。

任何密钥路径(keyFilePath / externalKeyPath)都可选接受 keyPassphrase(字面量或 $ENV_VAR)来处理加密的私钥。

AWS EC2(.pem 文件的情况)

你获得一个 .pem 文件、一个用户名(ubuntu、ec2-user、admin 等)和一个公网 IP/DNS。有两种方式:

// Reference the .pem where it sits (recommended — nothing copied)
{
  "id": "my-ec2", "host": "ec2-1-2-3-4.compute.amazonaws.com",
  "username": "ec2-user", "authType": "key",
  "externalKeyPath": "C:\\Users\\you\\Downloads\\my-key.pem",
  "role": "production"
}

// Or copy the .pem into the server's config folder (portable bundle)
{
  "id": "my-ec2", "host": "1.2.3.4", "username": "ubuntu",
  "authType": "key",
  "keyFilePath": "C:\\Users\\you\\Downloads\\my-key.pem",
  "role": "staging"
}

大多数 AWS 密钥没有密码短语 — 省略 keyPassphrase。如果你的密钥已加密,添加 "keyPassphrase": "$MY_PEM_PASS" 并设置该环境变量。

现代 sshd + 密码认证:ssh2 需要 tryKeyboard: true 来适配使用 PAM 的 sshd 设置(Ubuntu 22.04+、Debian 12、Amazon Linux 2023、RHEL 9)。devops-mcp 会自动设置这个选项 — 即使服务器配置了 PasswordAuthentication no 并仅允许 keyboard-interactive,密码认证仍然有效。


磁盘上的服务配置

每个服务都位于自己的文件夹中:

config/
├── my-vps/
│   ├── server.json     # config (host, user, auth, role, restrictions)
│   ├── key.pem         # optional SSH private key (only if you used keyFilePath / privateKey)
│   └── profile.json    # written by scan_server
└── _example/
    └── server.json     # template

server.json 示例:

{
  "name": "Production Web",
  "host": "1.2.3.4",
  "port": 22,
  "username": "ubuntu",
  "authType": "key",
  "keyFile": "production.pem",
  "role": "production",
  "restrictions": {
    "allowedModes": ["SAFE"],
    "blockedCommands": ["rm -rf", "shutdown", "reboot", "dd"],
    "requireApproval": true
  },
  "description": "Main production web server"
}

对于 externalKeyPath 工作流(密钥保留在 ~/.ssh/):

{
  "name": "My VPS",
  "host": "1.2.3.4",
  "port": 22,
  "username": "ubuntu",
  "authType": "key",
  "externalKeyPath": "C:\\Users\\you\\.ssh\\id_ed25519",
  "role": "production"
}

对于密码认证(始终优先使用 $ENV_VAR):

{
  "authType": "password",
  "password": "$MY_VPS_PASS"
}

$NAME 在连接时解析为 process.env.NAME。不要提交字面密码。

如果 server.json 缺少 role 或具有 restrictions: {},MCP 会在加载时填入 role: "development" 的默认值(并在日志中发出警告)。这可以防止 connect_server 在手写配置上崩溃。


环境变量

变量用途默认值
DEVOPS_MCP_ELEVATION_TOKEN带外同意令牌。**设置此项。**没有它,set_mode / approve_action / 生产写入门控会接受 AI 自身的布尔值作为同意,服务器会在日志中记录大声警告。未设置(顾问模式)
DEVOPS_MCP_NO_CONSOLE_LOG设置为 1 以抑制 stderr 控制台日志(文件日志仍会写入)未设置
LOG_LEVELdebug / info / warn / errorinfo
LOG_DIR写入 combined.log、error.log、audit.log 的位置./logs
NODE_ENV(仅供参考;无论如何日志都会写入 stderr,以免 MCP stdio 被破坏)development

安全模型

devops-mcp 防护的内容
  • 模型在生产环境中盲目运行 — 对于具有 role: production 或 productionLikely: true 的服务器上的写命令,没有同意令牌 + 明确确认 + (对于灾难性、不可恢复的操作)backupVerified 会被拒绝。
  • 自我批准 — 模型无法伪造 consentToken,因为它永远看不到 DEVOPS_MCP_ELEVATION_TOKEN。
  • 参数注入 — run_command 的每个参数在到达远程 shell 之前都会被 shell 转义。sh -c 有效负载内的多行脚本保持完整。
  • args 中的隐蔽命令 — 验证器一起检查 command + args,所以 run_command({command:"ls", args:["; rm -rf /"]}) 正确地升级为 FULL。
  • 过度的链拒绝 — 只读命令链保持 SAFE。每个片段独立验证;仅最坏的片段生效。
  • 扫描内容中的提示词注入 — 横幅、容器标签、日志行返回时带有"不可信数据"标记。工具响应告诉模型:显示,不执行。
  • 无声端口冲突 — plan_deployment 和 check_port_conflict 在部署前识别冲突。
  • 部署/配置助手中的 shell 注入 — 每个插值值都被 shell 转义;nginx 配置通过 heredoc 写入;分支名称和环境变量键被验证。
  • 生产写入门控拒绝回显确切的命令 — 所以你可以读到即将运行的内容,而不是 AI 的转述。
devops-mcp 不做的事情
  • 它不会沙箱隔离连接的服务。一旦你使用令牌进入 FULL 模式, 大模型可以做 SSH 用户能做的任何事情。
  • 它不会加密你的 MCP 客户端配置中保存的同意令牌。
  • 它不会备份你的数据 — backupVerified 是人工证明, 而不是检查。

有关完整的威胁模型,请参阅 SECURITY.md。


令牌管理

提升令牌是存储在你的 MCP 客户端配置中的 DEVOPS_MCP_ELEVATION_TOKEN 静态字符串。它不会过期。

会过期的是:

  • FULL 模式会话 — 默认 30 分钟
  • PROVISION 模式会话 — 默认 1 小时
  • generate_ssh_key 生成的会话 SSH 密钥 — 默认 30 分钟

当模式会话超时时,它会回退到 SAFE;AI 会重新请求同一个令牌以重新提升权限。

轮换令牌
You:  Rotate the elevation token and update Claude Desktop's config.
AI:   For verification, paste the current token.
You:  <paste>
AI:   [rotate_consent_token consentToken=<current> apply=true]
      → new token: <new>
      → 🔑 SAVE THIS NOW. Without it you're locked out of every write operation.
      → Fully quit and reopen Claude Desktop to activate it.

MCP 会原子性地将新令牌写入你的客户端配置(仅限 DEVOPS_MCP_ELEVATION_TOKEN 密钥 — 文件中的其他所有内容都会 保留)。运行中的 MCP 进程会继续使用旧令牌,直到 你重启客户端。

如果你在轮换和重启之间丢失了旧和新令牌, 手动编辑客户端配置以设置新的 — 这是恢复流程。


项目布局

src/
├── index.ts                       # MCP entry point (stdio)
├── types/                         # TypeScript types
├── core/
│   ├── logger.ts                  # JSON-lines structured logger + audit logger
│   ├── mode-manager.ts            # SAFE / PROVISION / FULL state machine
│   ├── command-validator.ts       # Allowlist + quote-aware chain splitter + wrapper-token scan
│   ├── server-config-manager.ts   # config/<id>/server.json + profile.json + auto-heal
│   ├── server-scanner.ts          # SAFE-mode discovery (read-only by design)
│   ├── ssh-key-manager.ts         # Session SSH keys with auto-expiry
│   └── approval-manager.ts        # Approval queue
├── executors/                     # Local / SSH / Docker — all shell-quote args
├── playbooks/                     # Provisioning playbooks (Docker, Nginx, …)
└── tools/
    ├── tool-schemas.ts            # Zod schemas + MCP tool definitions
    └── tool-handlers.ts           # The actual handlers

开发

npm run dev        # watch mode (tsx)
npm run build      # tsc → dist/
npm test           # vitest
npm run test:run   # vitest run (CI mode)
npm run lint       # eslint src/**/*.ts

贡献

欢迎提交 PR。请参阅 CONTRIBUTING.md。

添加在连接的服务上写入的新工具时,请确保它 通过 BaseExecutor.execute() 运行,以便模式验证器和 生产写入门控应用。不要直接从处理程序调用 shell, 如果必须在 shell 命令中插值某个值,请使用 执行器中的 shellQuote 帮助器 — 此代码库中的历史 bug 都是引号 bug。

许可证

MIT — 见 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。