VPS管理协议服务器

通过SSH管理VPS服务器的模型上下文协议(MCP)服务器,支持命令执行、文件传输、Docker容器管理和服务器文档维护。

  • by ereskovsky
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 ereskovsky/vps-mcp

使用说明

vps-mcp

用于通过SSH管理VPS服务器的MCP(模型上下文协议)服务器。将其连接到Claude Code、Claude Desktop或Claude.ai,以执行命令、传输文件、管理Docker容器和维护每台服务器的文档——所有这些都可以在Claude中完成。

俄语版

特性

  • SSH执行 --在远程服务器上运行命令和shell脚本
  • 文件传输 --SFTP加上三个远程友好通道:内联内容工具、流式HTTP端点和向服务器获取URL
  • Docker管理 — docker ps, docker compose, docker exec,部署应用程序
  • 服务器文档 --扫描服务器并为每台服务器生成/更新Markdown文档
  • 加密保管库 --使用AES-256-GCM+PBKDF2存储的服务器凭据

运作原理

Claude Code / Claude Desktop / Claude.ai
              │
              │  MCP protocol
              ▼
        vps-mcp (this server)
              │
              │  SSH / SFTP
              ▼
       Your VPS servers

vps-mcp将SSH密钥和密码存储在 加密保险库 (AES-256-GCM)。在每次工具调用时,它都会打开到目标服务器的SSH连接,执行操作并返回结果。

支持两种运输方式:

  • 标准 --本地使用(Claude Code,同一台机器上的Claude Desktop)
  • HTTP(流式HTTP) --用于远程访问(其他设备,Claude.ai网络)

安装

要求: Node.js 20+

git clone https://github.com/ereskovsky/vps-mcp
cd vps-mcp
npm install
npm run build

创建 .env 从模板中:

cp .env.example .env

编辑 .env:

# Master password for the encrypted vault. Pick any strong passphrase.
VAULT_PASSWORD=your-strong-passphrase

# Bearer token for HTTP mode (generate with: openssl rand -hex 32)
API_KEY=your-random-api-key

# HTTP port (default: 3001)
# PORT=3001

# For HTTP mode with OAuth (required for Claude.ai web)
BASE_URL=https://vps-mcp.yourdomain.com  # no port — required for OAuth metadata to work
CLIENT_ID=vps-mcp                         # any string, needed when adding the integration in Claude.ai
CLIENT_SECRET=                            # defaults to API_KEY if not set

本地使用(stdio)

此模式有效 无需任何服务器部署 --vps-mcp在您的计算机上运行,并通过SSH连接到vps服务器。

克劳德代码

claude mcp add vps-mcp -s user -e VAULT_PASSWORD="your-password" -- node "/path/to/vps-mcp/dist/index.js" --stdio

克劳德桌面版

添加 claude_desktop_config.json (~/Library/Application Support/Claude/ 在Mac上, %APPDATA%\Claude\ 在Windows上):

{
  "mcpServers": {
    "vps-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/vps-mcp/dist/index.js", "--stdio"],
      "env": {
        "VAULT_PASSWORD": "your-password"
      }
    }
  }
}

部署到VPS(HTTP模式)

需要从其他设备或Claude.ai网站进行远程访问。

1.准备

在您的VPS上克隆仓库。编辑 Caddyfile 并替换域:

vps-mcp.yourdomain.com {
    reverse_proxy vps-mcp:3001
}

确保您的域名的DNS A记录指向VPS IP。

2.开始

cp .env.example .env
# Fill in VAULT_PASSWORD and API_KEY

docker compose up -d

Caddy将通过Let's Encrypt自动获得TLS证书。

3.连接客户端

克劳德代码/克劳德桌面(远程):

claude mcp add vps-mcp -s user --transport http "https://vps-mcp.yourdomain.com/mcp" \
  --header "Authorization: Bearer your-api-key"

或者在配置中手动:

{
  "mcpServers": {
    "vps-mcp": {
      "url": "https://vps-mcp.yourdomain.com/mcp",
      "headers": {
        "Authorization": "Bearer your-api-key"
      }
    }
  }
}

连接到Claude.ai(网络,OAuth)

Claude.ai使用OAuth 2.0(authorization_code +PKCE)连接到远程MCP服务器。vps-mcp实现了完整的OAuth流程。

需求

  • 服务器已部署并可通过HTTPS访问
  • BASE_URL 在 .env 必须是公共领域 没有非标准端口 (例如。 https://vps-mcp.yourdomain.com,不 https://...:4443)--否则Claude.ai无法联系到 token_endpoint 来自OAuth元数据

步骤

  1. 打开 Claude.ai→ 设置→ 集成→ 添加集成
  2. 输入URL: https://vps-mcp.yourdomain.com/mcp
  3. 进入 客户端ID (价值 CLIENT_ID 从 .env)
  4. 进入 客户端密钥 (价值 CLIENT_SECRET 从 .env,默认为 API_KEY)
  5. Claude.ai将打开一个授权页面——确认访问

OAuth端点

端点 描述
GET /.well-known/oauth-authorization-server OAuth元数据(发现)
GET /oauth/authorize 授权页面(浏览器重定向)
POST /oauth/token 令牌的交换代码

将服务器添加到vault

通过SSH密钥(推荐)

首先用base64对私钥进行编码:

# Linux / Mac
base64 -w 0 ~/.ssh/id_ed25519

# Windows (PowerShell)
[Convert]::ToBase64String([IO.File]::ReadAllBytes("$env:USERPROFILE\.ssh\id_ed25519"))

然后打电话给 add_server 工具:

name: prod-1
host: 1.2.3.4
port: 22
username: root
authType: key
privateKey: <base64 string from above>
passphrase: <key passphrase, if any>
description: Main production server

通过密码

name: staging
host: 5.6.7.8
port: 22
username: ubuntu
authType: password
password: your-ssh-password
description: Staging environment

工具发现模型(渐进式发现)

当客户端连接时, tools/list 回报 只有4个元工具不是真正的18个。该模型使用它们来按需查找和调用实际工具,从而将LLM的“冷”上下文成本降至大致 1K代币,而不是5-10K.

元工具 它的作用
list_tool_categories 列出5个类别(注册表、ssh、文件、部署、文档)以及工具数量和描述。
search_tools 按以下方式搜索工具 query (名称/摘要/描述对应的子字符串)和/或 category.返回轻量级 {name, category, summary} --不是完整的模式。
get_tool_schemas 按名称返回1-10个工具的完整描述和JSON模式输入定义。
invoke_tool 执行一个真正的工具: {name, arguments}参数是严格根据工具的模式进行Zod验证的。

典型的LLM工作流程:

search_tools({query: "docker"})           → ["docker_ps", "docker_compose", "docker_exec", ...]
get_tool_schemas({names: ["docker_ps"]})  → full schema for docker_ps
invoke_tool({name: "docker_ps", arguments: {server: "prod"}}) → result

下面的真实工具被记录下来供人类参考——模型通过以下方式发现它们 search_tools / get_tool_schemas.

工具

注册表--服务器管理

list_servers

返回所有已注册的服务器。密码和密钥是 从未暴露.

add_server

参数 类型 必填 说明
name string yes 唯一标识符(字母、数字、, -_)
host string yes IP地址或主机名
port number no SSH端口(默认值:22)
username string yes SSH用户
authType key / password yes 身份验证类型
privateKey string 如果 key Base64编码的PEM私钥
passphrase string no 密钥短语
password string 如果 password SSH密码
description string 否 服务器描述

remove_server

参数 类型 说明
name string 要删除的服务器名称

SSH--命令执行

execute_command

在服务器上运行单个命令。

参数 类型 说明
server string vault中的服务器名称
command string Shell命令
→ execute_command(server="prod-1", command="df -h")
← { stdout: "...", stderr: "", exitCode: 0 }

execute_script

运行一个多行bash脚本。

参数 类型 说明
server string 服务器名称
script string Bash脚本(多行)

文件--SFTP传输

重要--本地模式与远程模式

upload_file / download_file 使用 localPath 在 MCP服务器自己的文件系统。在stdio模式下,这是您的机器(按预期工作)。在HTTP/远程模式(Claude.ai web)下,MCP服务器在VPS上运行-- localPath 则指VPS, 不是你的机器。对于以远程模式从计算机传输,请使用下面的内联内容工具或HTTP文件端点。

upload_file

通过SFTP将文件从MCP服务器的本地文件系统上传到目标VPS。

参数 类型 说明
server string 服务器名称
localPath string MCP服务器文件系统上的绝对路径
remotePath string 目标VPS上的绝对目标路径

download_file

通过SFTP将文件从目标VPS下载到MCP服务器的本地文件系统。

参数 类型 说明
server string 服务器名称
remotePath string 目标VPS上的路径
localPath string MCP服务器文件系统上的路径

upload_file_content

将内联内容写入远程文件——不需要MCP服务器端文件。在远程模式下,将此功能用于模型在对话中生成的配置、脚本和小代码文件。软天花板≈5 MB;对于较大的文件,请使用 POST /files/upload HTTP端点。

参数 类型 说明
server string 服务器名称
remotePath string 目标VPS上的绝对目标路径
content string 文件内容(文本或base64)
encoding utf8 / base64 默认值 utf8.使用 base64 对于二进制数据

download_file_content

读取远程文件并内联返回其内容。拒绝大于的文件 maxBytes 以保护对话上下文。

参数 类型 说明
server string 服务器名称
remotePath string 目标VPS上的路径
encoding utf8 / base64 默认值 utf8.使用 base64 对于二进制数据
maxBytes number 要读取的最大字节数。默认1 MB,硬上限5 MB

fetch_url_to_server

从公共URL下载文件 直接进入VPS 通过 curl.Bytes不会通过MCP主机或Claude——对于发布工件、transfer.sh链接、原始注册表、S3预签名URL来说非常方便。

参数 类型 说明
server string 服务器名称
url string http/https源URL
remotePath string VPS上的绝对目标
timeoutSec 编号 curl --max-time (默认值300,最大值3600)

list_remote_files

参数 类型 说明
server string 服务器名称
remotePath string 服务器上的目录路径
← [{ name, type, size, modifiedAt, permissions }]

HTTP文件端点(大文件,流式传输)

HTTP服务器同时暴露了两个端点 /mcp 用于传输任何大小的文件。它们通过SFTP在用户和目标VPS之间直接流式传输,因此绕过了MCP工具调用的内联内容大小限制。使用与相同的Bearer令牌 /mcp.

POST /files/upload?server=<name>&path=<absolute-remote-path>

正文:原始字节(Content-Type: application/octet-stream).答复: { ok: true, server, path, bytes }.

curl -H "Authorization: Bearer $API_KEY" \
  --data-binary "@./local-archive.tar.gz" \
  "https://vps-mcp.yourdomain.com/files/upload?server=prod-1&path=/tmp/local-archive.tar.gz"

PowerShell:

curl -H "Authorization: Bearer $env:API_KEY" `
  --data-binary "@./local-archive.tar.gz" `
  "https://vps-mcp.yourdomain.com/files/upload?server=prod-1&path=/tmp/local-archive.tar.gz"

目标目录必须已经存在(端点不会自动-mkdir).上传后,请Claude通过以下方式解压缩/移动/安装 execute_command.

GET /files/download?server=<name>&path=<absolute-remote-path>

将远程文件作为响应正文流式传输回来 Content-Disposition: attachment.

curl -H "Authorization: Bearer $API_KEY" \
  "https://vps-mcp.yourdomain.com/files/download?server=prod-1&path=/var/log/app.log" \
  -o app.log

Docker和部署

docker_ps

参数 类型 说明
server string 服务器名称
all boolean 包含已停止的容器(默认值:true)

docker_compose

参数 类型 说明
server string 服务器名称
path string 目录的绝对路径 docker-compose.yml
action enum up / down / restart / pull / logs / ps / build
service string (可选)特定服务名称
flags string (可选)额外标志

docker_exec

参数 类型 说明
server string 服务器名称
container string 容器名称或ID
command string 要执行的命令

deploy_app

部署应用程序:git pull→ 建造→ 重新启动。

参数 类型 说明
server string 服务器名称
path string 应用程序目录路径
branch string Git分支(默认值: main)
buildCommand string (可选)构建命令
restartCommand string (可选)重新启动命令

文档--服务器文档

scan_server

扫描服务器并返回完整快照:

  • 操作系统和内核版本
  • CPU和RAM
  • 磁盘使用情况
  • 运行时间
  • 运行Docker容器和镜像
  • 主动系统服务
  • 开放端口(ss/netstat)
  • 时钟守护作业

get_server_docs

从以下位置读取存储的Markdown文档 data/docs/{server}.md.

update_server_docs

写入或替换服务器的Markdown文档。

参数 类型 说明
server string 服务器名称
content string 完整Markdown内容

常见工作流程

安装新服务器

1. add_server        — register the server
2. execute_command   — verify connection: "uptime"
3. scan_server       — collect a state snapshot
4. update_server_docs — save documentation

部署应用程序

1. deploy_app        — git pull + build + restart
2. docker_ps         — check container status
3. docker_compose    — check logs: action="logs"

调试服务器问题

1. execute_command   — "journalctl -u nginx --since '10 minutes ago'"
2. docker_compose    — action="logs", flags="--tail=200"
3. execute_command   — "df -h && free -h"

安全

  • 金库 (data/servers.enc.json)用AES-256-GCM加密;密钥是通过PBKDF2(100000次迭代)从 VAULT_PASSWORD
  • SSH密钥和密码是 从未以明文形式存储或传输 --仅通过加密的保险库
  • vault文件和 data/ 目录位于 .gitignore --从未承诺回购
  • HTTP模式受承载令牌保护(API_KEY)根据每一个请求
  • 通过Claude.ai、OAuth 2.0连接时(authorization_code +PKCE)-没有对客户端的直接API密钥暴露
  • HTTPS由Caddy处理(通过Let's Encrypt自动TLS)
  • list_servers 日志永远不会暴露密钥或密码

RAM注释: 如果您的VPS内存有限(<512 MB),请避免运行 npm install 在服务器上——这可能会触发OOM杀手。在本地安装依赖项并上传 node_modules/.

项目结构

src/
  index.ts               # Entry point — picks stdio vs HTTP mode
  server.ts              # createServer() — registers ONLY the 4 meta-tools
  types.ts               # Shared types: ServerRecord, VaultData, CommandResult
  lib/
    credential-store.ts  # Encrypted vault (AES-256-GCM + PBKDF2)
    ssh-client.ts        # SSH wrapper: execCommand, execScript, SFTP upload/download/list
    doc-manager.ts       # Per-server Markdown docs (data/docs/{name}.md)
  tools/
    registry-core.ts     # Central registry, search, Zod→JSON Schema util, ToolDef type
    meta.ts              # The 4 meta-tools (list_tool_categories, search_tools, get_tool_schemas, invoke_tool)
    registry.ts          # getRegistryTools() — list_servers, add_server, remove_server
    ssh.ts               # getSshTools()      — execute_command, execute_script
    files.ts             # getFileTools()     — upload_file, download_file, upload_file_content, download_file_content, fetch_url_to_server, list_remote_files
    deploy.ts            # getDeployTools()   — docker_ps, docker_compose, docker_exec, deploy_app
    docs.ts              # getDocsTools()     — scan_server, get_server_docs, update_server_docs

许可证

麻省理工学院