wg-easy-mcp
以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →
A Model Context Protocol (MCP) server for administering wg-easy (WireGuard Easy) instances.
Lets MCP clients like Claude Code, Claude Desktop or Codex manage your WireGuard VPN: list, create, update, enable/disable and delete clients, fetch configuration files and QR codes, and inspect the server status — all through the wg-easy v15 REST API.
Eleven tools is the ceiling, not the floor: WG_EASY_ALLOW_TOOLS=essential
registers a curated six instead, and a model picks the right tool far more
reliably from six than from eleven — see
choosing which tools load.
is resolved against the colour scheme of the page showing it, so GitHub
picks the variant that matches its own theme toggle. npm strips and
when it sanitises the README and keeps the , which is why that
fallback brings its own dark card instead of relying on a media query. -->
What makes it different
**The full client lifecycle over the wg-easy v15 REST API**, including .conf
files, QR codes and one-time download links.
**Partial updates merge.** An update reads the current client state and changes
only the fields you named, instead of overwriting the rest with defaults.
**disable_client stays ungated on purpose.** Every other write asks a person
first through MCP elicitation; that one only ever withdraws access, and making it
harder would be making the safe move the slow one.
Requirements
- Node.js ≥ 22
- A running **wg-easy v15+** instance
- **2FA (TOTP) must be disabled** for the account used by this server — the wg-easy API only supports Basic Authentication and does not work with 2FA enabled
> **Note:** The wg-easy REST API is not yet declared stable and may change between releases. This server targets wg-easy v15.
Configuration
Configuration is provided via environment variables:
| Variable | Required | Description |
| ---------------------- | -------- | --------------------------------------------------------------------------------------- |
| WG_EASY_URL | yes | Base URL of the wg-easy web UI, e.g. https://vpn.example.com:51821 |
| WG_EASY_USERNAME | yes | Username of a wg-easy admin account |
| WG_EASY_PASSWORD | yes | Password of that account |
| WG_EASY_INSECURE_TLS | no | Set to true to accept self-signed TLS certificates (scoped to the wg-easy connection) |
| WG_EASY_ALLOW_TOOLS | no | Comma-separated tool names, list_* prefixes, or essential for a curated preset |
| WG_EASY_DENY_TOOLS | no | Same syntax; removed from whatever WG_EASY_ALLOW_TOOLS left |
| ELICITATION | no | false replaces the approval dialog with the two-call token. **Not prefixed** |
> **Use https://.** With a plain-http URL the Basic Auth credentials and all
> WireGuard private keys travel unencrypted; the server prints a warning unless
> the host is local. For self-signed certificates prefer a proper internal CA
> over WG_EASY_INSECURE_TLS.
Without credentials the server still starts and lists its tools (so registries
and inspectors can introspect it), but every tool call fails with setup
instructions instead of reaching the wg-easy API.
Choosing which tools load
WG_EASY_ALLOW_TOOLS and WG_EASY_DENY_TOOLS take comma-separated tool names;
a trailing * matches a whole family. essential is a curated preset of
six: get_server_info, list_clients, get_client, create_client, enable_client, disable_client.
get_client_config, get_client_qrcode and generate_one_time_link are not in
it, and neither is delete_client: all four either destroy something
irreversibly or hand out a peer's private key. Name them where you want them.
An entry that matches no tool aborts startup and names it, so a typo cannot
silently hide a tool — an absent tool is not something anyone traces back to an
environment variable. A filtered tool is never registered, so it is absent from
tools/list and unknown to tools/call alike, exactly like a write tool under
WG_EASY_READ_ONLY.
If you run several of these servers at once, mcp-hub
is the other answer — its /hub endpoint replaces every server's tools with six
meta-tools.
Installation
Claude Code
Claude Desktop
Add to your claude_desktop_config.json: