mcpField
W
wg-easy

wg-easy

本地服务
wg-easy-mcp.ni-c.de安全02 天前更新

关于 wg-easy

wg-easy 是面向管理员的 MCP 服务,用于管理 wg-easy v15 WireGuard VPN 实例。它涵盖客户端生命周期、配置交付和服务器状态,并支持多数写入操作审批及工具筛选。

主要功能

  1. 01管理客户端的创建、更新、启用和删除
  2. 02获取客户端配置和二维码
  3. 03生成一次性配置下载链接
  4. 04查看服务器状态和客户端流量
  5. 05多数写入操作需审批
  6. 06通过预设筛选工具

适用场景

  1. 01开通或撤销 WireGuard VPN 访问权限
  2. 02通过文件或二维码分享客户端配置
  3. 03检查客户端活动和服务器状态

MCP 相关

通过 REST API 向 MCP 客户端提供 wg-easy v15 管理工具。多数写入操作通过 MCP elicitation 请求人工审批;禁用客户端不设审批门槛。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"ni-c-wg-easy": {
"command": "npx",
"args": [
"-y",
"wg-easy-mcp"
],
"env": {
"WG_EASY_URL": "<WG_EASY_URL>",
"WG_EASY_USERNAME": "<WG_EASY_USERNAME>",
"WG_EASY_PASSWORD": "<WG_EASY_PASSWORD>",
"WG_EASY_INSECURE_TLS": "<WG_EASY_INSECURE_TLS>",
"WG_EASY_READ_ONLY": "<WG_EASY_READ_ONLY>",
"WG_EASY_ALLOW_TOOLS": "<WG_EASY_ALLOW_TOOLS>",
"WG_EASY_DENY_TOOLS": "<WG_EASY_DENY_TOOLS>"
}
}
}
}
启动命令npx -y wg-easy-mcp
需要配置的环境变量
WG_EASY_URLBase URL of the wg-easy web UI, e.g. https://vpn.example.com:51821
WG_EASY_USERNAMEUsername of a wg-easy admin account (2FA must be disabled)
WG_EASY_PASSWORD密钥Password of the wg-easy admin account
WG_EASY_INSECURE_TLSSet to true to accept self-signed TLS certificates (scoped to the wg-easy connection)
WG_EASY_READ_ONLYSet to true to register only the read tools (default: false)
WG_EASY_ALLOW_TOOLSComma-separated tool names or list_* prefixes to register; 'essential' selects a curated preset (default: all tools)
WG_EASY_DENY_TOOLSComma-separated tool names or list_* prefixes to remove from whatever WG_EASY_ALLOW_TOOLS left

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmwg-easy-mcp0.6.0
ocighcr.io/ni-c/wg-easy-mcp:0.6.0

工具

11

收录的工具列表 · 更新于 2 周前

参数类型必填说明
sortenum否按名称升序或降序排序asc | desc
filterstring否可选的名称筛选条件(子串匹配)

详细介绍

wg-easy-mcp

CI OpenSSF Scorecard Socket Badge Glama score
npm version container image HTTP via mcp-hub
docs sponsor

一个用于管理 wg-easy(WireGuard Easy)实例的 Model Context Protocol(MCP)服务。

它允许 Claude Code、Claude Desktop 或 Codex 等 MCP 客户端管理你的 WireGuard VPN:列出、创建、更新、启用/禁用和删除客户端,获取配置文件和二维码,以及查看服务状态——所有操作均通过 wg-easy v15 REST API 完成。

11 个工具并非越多越好:设置 WG_EASY_ALLOW_TOOLS=essential 即可改为注册经过精选的 6 个工具。模型从 6 个工具中挑选合适项,远比从 11 个中可靠——请参阅 选择要加载的工具。

MCP 客户端通过 stdio 与 wg-easy-mcp 通信,后者使用 Basic Authentication 通过 HTTPS 调用 wg-easy v15 REST API

列出工具、将其缩减为精简预设,以及输错工具名称时导致启动中止

有何不同

通过 wg-easy v15 REST API 管理客户端的完整生命周期,包括 .conf 文件、二维码和一次性下载链接。

部分更新会进行合并。 更新时会读取当前客户端状态,只修改你指定的字段, 而不会用默认值覆盖其他内容。

有意不对 disable_client 设置门控。 其他所有写入操作都需要先通过 MCP elicitation 征求用户确认;而此操作只会撤销访问权限,增加操作难度只会让安全的选择变得更慢。

要求

  • Node.js ≥ 22
  • 正在运行的 wg-easy v15+ 实例
  • 此服务使用的账户必须禁用 2FA(TOTP)——wg-easy API 仅支持 Basic Authentication,启用 2FA 后无法使用

注意: wg-easy REST API 尚未声明为稳定,不同版本之间可能会有变化。本服务以 wg-easy v15 为目标版本。

配置

通过环境变量提供配置:

变量必填说明
WG_EASY_URL是wg-easy Web UI 的基础 URL,例如 https://vpn.example.com:51821
WG_EASY_USERNAME是wg-easy 管理员账户的用户名
WG_EASY_PASSWORD是该账户的密码
WG_EASY_INSECURE_TLS否设置为 true 以接受自签名 TLS 证书(仅对 wg-easy 连接生效)
WG_EASY_ALLOW_TOOLS否以逗号分隔的工具名称、list_* 前缀,或用于精选预设的 essential
WG_EASY_DENY_TOOLS否语法相同;从 WG_EASY_ALLOW_TOOLS 保留的工具中移除相应工具
ELICITATION否false 会用两次调用令牌替代审批对话框。无前缀

请使用 https://。 使用纯 http URL 时,Basic Auth 凭据和所有 WireGuard 私钥都会以未加密方式传输;除非主机位于本地,否则服务端会输出警告。对于自签名证书, 建议使用合适的内部 CA,而不是 WG_EASY_INSECURE_TLS。

没有凭据时,服务端仍会启动并列出其工具(因此注册表和检查器可以检查它),但每次工具调用都会失败,并显示设置说明,而不会访问 wg-easy API。

选择要加载的工具

WG_EASY_ALLOW_TOOLS 和 WG_EASY_DENY_TOOLS 接受以逗号分隔的工具名称; 末尾的 * 可匹配整个工具系列。essential 是包含以下六个工具的精选预设:get_server_info、list_clients、get_client、create_client、enable_client、disable_client。

get_client_config、get_client_qrcode 和 generate_one_time_link 不包含在其中, delete_client 也不包含:这四个工具要么会不可逆地销毁某些内容,要么会泄露对等方的私钥。需要时请明确指定它们。

WG_EASY_ALLOW_TOOLS=essential
WG_EASY_ALLOW_TOOLS=essential,get_client_config
WG_EASY_ALLOW_TOOLS=list_clients,get_client_config
WG_EASY_DENY_TOOLS=delete_client,create_client

如果某个条目与任何工具都不匹配,启动就会中止并指出该条目,因此拼写错误不会悄悄隐藏工具——没人会想到要回头检查环境变量里是否漏掉了工具。经过筛选的工具不会注册,因此它们既不会出现在 tools/list 中,也无法通过 tools/call 调用,这与 WG_EASY_READ_ONLY 下的写入工具完全相同。

如果你同时运行多个此类服务,mcp-hub 是另一种解决方案——它的 /hub 端点会用六个元工具替代所有服务的工具。

安装

Claude Code
claude mcp add wg-easy -s user \
  -e WG_EASY_URL=https://vpn.example.com:51821 \
  -e WG_EASY_USERNAME=admin \
  -e WG_EASY_PASSWORD=your-password \
  -- npx -y wg-easy-mcp
Claude Desktop

添加到你的 claude_desktop_config.json:

{
  "mcpServers": {
    "wg-easy": {
      "command": "npx",
      "args": ["-y", "wg-easy-mcp"],
      "env": {
        "WG_EASY_URL": "https://vpn.example.com:51821",
        "WG_EASY_USERNAME": "admin",
        "WG_EASY_PASSWORD": "your-password"
      }
    }
  }
}
Codex

添加到你的 ~/.codex/config.toml:

[mcp_servers.wg-easy]
command = "npx"
args = ["-y", "wg-easy-mcp"]
env = { WG_EASY_URL = "https://vpn.example.com:51821", WG_EASY_USERNAME = "admin", WG_EASY_PASSWORD = "your-password" }
从源代码安装
git clone https://github.com/ni-c/wg-easy-mcp.git
cd wg-easy-mcp
npm install
npm run build
# then use `node /path/to/wg-easy-mcp/dist/index.js` as the command
Docker

支持多架构(linux/amd64、linux/arm64)的镜像已发布到 GitHub Container Registry,并附带 SBOM 和构建来源证明:

docker run -i --rm \
  -e WG_EASY_URL=https://vpn.example.com:51821 \
  -e WG_EASY_USERNAME=admin \
  -e WG_EASY_PASSWORD=your-password \
  ghcr.io/ni-c/wg-easy-mcp:latest

该镜像通过 stdio 使用 MCP 通信,因此客户端需要使用 docker run -i(不会暴露端口):

{
  "mcpServers": {
    "wg-easy": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "WG_EASY_URL",
        "-e",
        "WG_EASY_USERNAME",
        "-e",
        "WG_EASY_PASSWORD",
        "ghcr.io/ni-c/wg-easy-mcp:latest"
      ],
      "env": {
        "WG_EASY_URL": "https://vpn.example.com:51821",
        "WG_EASY_USERNAME": "admin",
        "WG_EASY_PASSWORD": "your-password"
      }
    }
  }
}
通过 mcp-hub

无法启动本地进程的客户端——ChatGPT connectors、Claude 网页版、 Cursor、LibreChat——可通过 mcp-hub 连接 wg-easy-mcp:一个 容器即可通过 Streamable HTTP 提供多个 stdio MCP 服务,并通过单个密码进行 OAuth 2.1 登录, 还为无法使用 OAuth 的客户端提供长期有效的令牌。它的 /hub 端点通过六个元工具接入所有服务,因此一个连接器即可访问它们,无需在模型上下文中 加入 N×工具架构;它还支持两个协议版本——此服务提出的问题会经由它传递给另一端的人。

它的 /config/mcp.json 使用 Claude Code 的格式,因此配置项就是你已有的那个:

{
  "mcpServers": {
    "wg-easy": {
      "command": "npx",
      "args": ["-y", "wg-easy-mcp"],
      "env": { "WG_EASY_ALLOW_TOOLS": "essential" },
      "denyTools": ["delete_client"]
    }
  }
}

其中的 allowTools 和 denyTools 是 hub 自己按服务设置的过滤器,与 env 中的 *_ALLOW_TOOLS 并不相同——两者的区别,以及由此可能引发的错误,详见客户端指南。

工具

工具描述
list_clients列出所有 WireGuard 客户端及其状态和流量统计信息
get_client获取单个客户端的完整详情
create_client 👤创建新客户端(name、可选的 expiresAt)
update_client 👤更新客户端;仅修改提供的字段
enable_client 👤允许客户端重新连接——重新启用对端上已安装的密钥对
disable_client阻止客户端;保留其配置和密钥
delete_client 👤永久删除客户端
get_client_config获取客户端的 WireGuard .conf 文件
get_client_qrcode将客户端配置获取为二维码(SVG)
generate_one_time_link 👤生成一次性配置下载链接,有效期为 5 分钟
get_server_info版本发布/更新状态、常规设置和接口配置(已隐藏机密信息)

👤 通过 MCP elicitation 向用户发起请求 · 如果客户端无法显示对话框,则改用两次调用的 confirm_token。

结构化输出

每个工具都声明了 outputSchema,并在文本块之外通过 structuredContent 返回答案,因此客户端无需解析散文即可使用结果:

{
  "untrusted": true,
  "source": "wg-easy",
  "count": 2,
  "clients": [{ "id": 1, "name": "laptop", "enabled": true }],
}

untrusted 标记是一个字段,而不只是文本中的一句话,因为如果客户端读取结构化部分而忽略文本,就会直接获得没有任何说明的自由格式客户端名称、DNS 条目和端点。除 delete_client 外,每个工具都包含该标记;delete_client 报告的是此服务收到的 ID,而不是从实例返回的内容。

有三个答案调整了结构,原因也都相同:对于根节点不是对象的架构,改写后的 2025 年客户端会将其作为 {result: …} 提供服务,因此工具会因请求方不同而返回不同答案。

工具原来现在
list_clients裸数组{count, clients}
get_client_config.conf 文本{configuration}
get_client_qrcodeSVG 标记{svg}

现在,过大的答案会以对象的形式缩短,而不是像字符串那样截断:首先缩短最长的文本字段,然后删除列表条目,并通过 truncated 字段说明截去了什么以及截去了多少内容。按字节偏移截取的文档不是较短的答案,而是无法解析的答案——而且两个通道必须承载相同的值。

对于 wg-easy 发送的内容,描述中将每个字段都设为可选,并允许未知字段;只有此服务构建的内容才是精确的。SDK 会在每个结果发出前根据其架构进行验证,因此,如果结构过于严格,wg-easy 发布版一旦新增字段,就会导致工具彻底失败。

安全
  • 有五个工具会询问用户,而不只是询问模型。 create_client、 update_client、enable_client、delete_client 和 generate_one_time_link 会通过 MCP 引导在客户端支持时弹出真实对话框。五个工具中只有一个会销毁内容——其他工具会签发 VPN 凭据、重新启用凭据、扩大路由范围,以及生成一个无需身份验证、可发放私钥的 URL。disable_client 是唯一从不询问的写入工具:它只能撤销访问权限。如果客户端无法显示对话框,则会改用有效期为 5 分钟、且绑定到精确目标的随机令牌(对于 update_client,绑定到精确的编辑操作);这只能证明调用使用相同参数执行了两次,仅此而已。ELICITATION=false 会主动采用这种回退方式,但不会移除防护措施。请参阅询问用户。
  • 除非是关键信息,否则密钥材料一律脱敏。 字段名按其后缀匹配——password、passwd、passphrase、secret、token、apiKey、privateKey、preSharedKey,以及所有以 totp 开头的字段——因此,保存 metrics 令牌 argon2 哈希值的 metricsPassword 也会受到保护,wg-easy 生成的所有其他 <prefix>Secret 字段也一样。(key 不算后缀:否则 publicKey 也会被一并处理。)所有嵌套层级中的值都会替换为 [redacted]——包括包含 WireGuard _服务端_密钥的 get_server_info 管理员响应,以及包含各客户端_自身_密钥的 list_clients 和 get_client 响应。实时的一次性链接令牌也会在这两个工具的响应中脱敏,因为无需登录即可通过 GET /cnf/<token> 获取完整配置;expiresAt 会保留,因此列表仍会显示链接是否有效。get_client_config、get_client_qrcode 和 generate_one_time_link 是有意设置的例外:这些工具的用途就是向对等端提供配置,而且这是用户主动请求的。
  • wg-easy API 返回的所有内容都会带有明确的不可信数据标记,并受 60 000 个字符的预算限制;预算按实际输出的文本计算。客户端名称、DNS 条目和端点都是自由格式字符串,因此会被标记为需要报告的数据,而不是需要遵循的指令;其中的控制字符和双向文本覆盖字符会被剔除(字段名也一样),单个超大字段也无法占满模型的上下文。
  • 不会盲目信任实例发送的任何内容。 输出架构声明类型的每个字段都会在边界处进行检查,不符合要求时便会被排除,因此,某条记录中的 id 为字符串或数值为 1e999,都不会导致整个列表因 Output validation error 而失败。根本不是客户端记录的条目会计入 skipped,而不会被悄悄丢弃。
  • 响应正文设有上限(8 MiB;如果声明的 content-length 超限,则会在读取任何字节之前拒绝),并且会先读取状态码,再读取正文,因此即使大型代理页面挡在前面,401 仍会被识别为 401。登录遭拒后,会在十秒内从内存中重复返回该结果,而不是重试。
  • 如果 WG_EASY_URL 包含嵌入式凭据(user:password@host),则会在启动时拒绝该 URL——否则凭据会出现在启动日志中,并被附加到每个请求中。只会保留其源和路径,启动诊断信息也不会回显任何值。
  • 上游错误正文会标记为不可信,剔除控制字符,并截断至 200 个字符;HTML 错误页面(反向代理)会在返回给 MCP 客户端之前被丢弃。
  • 调用方输入均有长度限制:名称和筛选条件为 200 个字符,地址为 64 个字符,列表参数最多 64 项;客户端 ID 则通过模式约束,而不是在调用 Number() 后再限制。
  • WG_EASY_INSECURE_TLS 只会放宽 wg-easy 连接的证书验证,不会在整个进程范围内禁用 TLS 验证。
  • WG_EASY_READ_ONLY=true 只会注册 list_clients、get_client 和 get_server_info,不注册其他工具。 get_client_config 和 get_client_qrcode 虽然是读取操作,但仍不在其中:它们读取的是客户端的明文私钥;保留密钥泄露能力的只读模式,并非其名称所承诺的模式。
  • 工具带有 MCP 注解(readOnlyHint、destructiveHint、idempotentHint),以便宿主应用相应的权限策略。
  • 请注意,get_client_config 和 get_client_qrcode 会返回客户端的私钥,而 generate_one_time_link 生成的 URL 允许未经身份验证的配置下载——请将工具输出视为敏感信息。 完整的信任模型见 SECURITY.md,也可阅读 wg-easy-mcp.ni-c.de/guide/security 上的说明。

有意不提供的功能

仅支持 wg-easy v15 或更高版本。 较旧版本提供的是另一套基于会话的 API,本服务不支持。

不提供服务端管理功能。 这些工具涵盖客户端生命周期;实例自身的配置、管理员账户和主机均不在工具列表之内。

安全性

  • 有五个工具会通过 MCP 征询机制先征求用户同意:create_client、update_client、enable_client、delete_client 和 generate_one_time_link。其中只有一个会销毁内容;其他工具之所以也在列表中,是因为 destructiveHint 并不适用于它们的实际操作。新客户端凭据可访问 VPN 后的所有网络,update_client 可能扩大 serverAllowedIps 范围,而 enable_client 会重新启用已安装在对等端上的密钥对。
  • 批准仅对确切的编辑操作有效,因此批准重命名并不意味着之后可以调用工具扩大路由范围。
  • disable_client 有意不设审批门槛:它只会撤销访问权限;让安全的操作变得缓慢,并不是明智的取舍。
  • 客户端名称、地址和实例自身的字符串均标记为不可信数据;对于超长输出,会进行截断并说明省略了内容。
  • WG_EASY_READ_ONLY=true 只会注册读取工具。

文档

完整指南、工具参考和安全说明位于 wg-easy-mcp.ni-c.de(源码位于 docs/)。

开发

npm install
npm run build     # compile TypeScript to dist/
npm test          # run the vitest test suite
npm run lint      # oxlint + prettier check
npm run test:coverage

CI 会在 Node 22 和 24 上运行测试套件,并在两种架构上对容器镜像执行 npm audit、CodeQL 和 Trivy 扫描。请参阅 CONTRIBUTING.md。

文档站点位于 docs/,并有自己的清单文件:

cd docs && npm install && npm run dev
发布
  1. 更新 package.json 中的版本,并在 CHANGELOG.md 中添加条目。
  2. 提交,然后创建标签并推送:git tag -a vX.Y.Z -m "vX.Y.Z" && git push origin main vX.Y.Z

发布工作流会运行测试套件,通过 可信发布 发布到 npm(无需令牌,并附带来源证明),根据变更日志条目创建 GitHub 发布,并更新官方 MCP Registry 中的条目(io.github.ni-c/wg-easy-mcp,通过 GitHub OIDC)。CI 工作流会在同一标签上将容器镜像发布到 GHCR。

server.json 列出了 npm 和 OCI 两种软件包;注册表作业会在发布前将版本同步到两者。如果作业失败,请修复 main,然后通过 workflow_dispatch 重新运行 mcp-registry.yml——重新运行标签作业会检出旧版本的代码树。

发布

发布由标签驱动。更新 package.json,将 CHANGELOG.md 中的 [Unreleased] 说明移到新版本条目下并提交,然后:

git tag -s vX.Y.Z -m "vX.Y.Z"
git push origin main vX.Y.Z

发布工作流会通过可信发布(OIDC,并附带来源证明)发布到 npm,将多架构容器镜像推送到 GHCR,根据 CHANGELOG 条目创建 GitHub 发布,并更新官方 MCP 注册表中的条目。

贡献

欢迎提交问题、参与讨论和发起拉取请求——请参阅 CONTRIBUTING.md。如需报告漏洞,请使用 私密报告渠道, 而不要公开提交问题;相关政策见 SECURITY.md。

许可证

MIT © Willi Thiel

评论

支持 Markdown

第一次接触 MCP?

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

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