Skip to main content
Glama

wg-easy-mcp

CI npm version npm downloads node license container docs

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.

📖 Full documentation: wg-easy-mcp.ni-c.de

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.

Related MCP server: amp-mcp-server

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)

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.

Installation

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

Add to your 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

Add to your ~/.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" }

From source

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

A multi-arch image (linux/amd64, linux/arm64) with an SBOM and build provenance is published to GitHub Container Registry:

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

The image talks MCP over stdio, so clients need docker run -i (no port is exposed):

{
  "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"
      }
    }
  }
}

Tools

Tool

Description

list_clients

List all WireGuard clients with status and traffic statistics

get_client

Get the full details of a single client

create_client

Create a new client (name, optional expiresAt)

update_client

Update a client; only the provided fields are changed

enable_client / disable_client

Enable or disable a client

delete_client

Permanently delete a client — two-step, guarded by a confirmation token

get_client_config

Get the client's WireGuard .conf file

get_client_qrcode

Get the client configuration as a QR code (SVG)

generate_one_time_link

Generate a one-time config download link (requires one-time links to be enabled in wg-easy)

get_server_info

Release/update status, general settings and interface configuration (secrets redacted)

Safety

  • delete_client is a two-step operation: the first call returns a random confirmation token (valid for 5 minutes, bound to the client ID) and only a second call with that exact token deletes the client. Unlike a plain confirm=true parameter, the token cannot be guessed or pre-supplied by the model or by injected text.

  • get_server_info redacts secret fields (privateKey, preSharedKey, password, session/TOTP secrets) from the admin API responses.

  • Everything the wg-easy API returns carries an explicit untrusted-data marker and a 60 000-character budget. Client names, DNS entries and endpoints are free-form strings, so they are marked as data to report rather than instructions to follow, and a single oversized field cannot flood the model's context.

  • A WG_EASY_URL containing embedded credentials (user:password@host) is rejected at startup — they would otherwise be echoed in the startup log and prefixed onto every request.

  • Upstream error bodies are truncated and HTML error pages (reverse proxies) are dropped before being returned to the MCP client.

  • WG_EASY_INSECURE_TLS only relaxes certificate validation for the wg-easy connection — it does not disable TLS verification process-wide.

  • Tools carry MCP annotations (readOnlyHint, destructiveHint, idempotentHint) so hosts can apply appropriate permission policies.

  • Keep in mind that get_client_config and get_client_qrcode return the client's private key, and a generate_one_time_link URL allows an unauthenticated config download — treat tool output as sensitive.

The full trust model is in SECURITY.md and, in prose, at wg-easy-mcp.ni-c.de/guide/security.

Development

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

CI runs the suite on Node 22 and 24 and adds npm audit, CodeQL and a Trivy scan of the container image on both architectures. See CONTRIBUTING.md.

The documentation site lives in docs/ with its own manifest:

cd docs && npm install && npm run dev

Releasing

  1. Bump the version in package.json and add a CHANGELOG.md entry.

  2. Commit, then tag and push: git tag -a vX.Y.Z -m "vX.Y.Z" && git push origin main vX.Y.Z

The release workflow runs the test suite, publishes to npm (via trusted publishing, no token, with provenance), creates a GitHub release from the changelog entry and updates the entry in the official MCP Registry (io.github.ni-c/wg-easy-mcp, via GitHub OIDC). The container image is published to GHCR by the CI workflow on the same tag.

server.json lists both an npm and an OCI package; the registry job syncs the version into both before publishing. If it ever fails, fix main and re-run mcp-registry.yml via workflow_dispatch — re-running the tag job checks out the old tree.

License

MIT

Install Server
A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
Response time
1dRelease cycle
5Releases (12mo)
Commit activity

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • An MCP server that let you interact with Cycloid.io Internal Development Portal and Platform

  • MCP server wrapping the Tesla Fleet API and TeslaMate API

  • Tailscale device, route, DNS, key, user, and ACL management over MCP and CLI.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ni-c/wg-easy-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server