vpnhop
Supports Cisco AnyConnect / ocserv VPN profiles via openconnect, allowing HTTP(S) requests to be routed through the VPN tunnel using username/password, TOTP, or certificate pinning authentication.
Supports Fortinet VPN profiles via openconnect, enabling HTTP(S) requests through a Fortinet tunnel with username/password and TOTP authentication.
Supports OpenVPN profiles, including AWS Client VPN and OpenVPN Connect .ovpn files, using OpenVPN 2.7 in a container with certificate or username/password authentication.
Supports IPsec IKEv2 VPN profiles using strongSwan swanctl, with EAP-MSCHAPv2 and PSK authentication, to route HTTP(S) requests through the tunnel.
Supports WireGuard VPN profiles using wg-quick with kernel support or wireguard-go fallback, authenticating with private keys and routing HTTP(S) requests through the tunnel.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@vpnhop use the work-vpn profile to GET https://internal.company.com/api/health"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
vpnhop
MCP server that sends API calls through a VPN without connecting your machine to the VPN. Each profile's VPN client runs in its own throwaway Docker container; requests run from inside it.
VPN | Client in container | Auth |
OpenVPN (incl. AWS Client VPN, OpenVPN Connect |
| certs, username/password |
WireGuard |
| private key |
Cisco AnyConnect / ocserv, GlobalProtect, Pulse/Ivanti, Juniper NC, Fortinet, F5, Array |
| username/password, TOTP, cert pin |
IPsec IKEv2 | strongSwan ( | EAP-MSCHAPv2, PSK |
How it works
No sudo, no host routes, no system VPN. Host traffic is never affected.
Secrets are resolved per connect from
env,fileorcommand(e.g.op read). They are piped into the container as a tar over stdin, so there's no host temp file, env var or bind mount.DNS is resolved inside the tunnel (pushed DNS, WireGuard
DNS=, ordns/searchDomainsoverrides).Tunnels connect on first
http_requestand close afteridleMinutes, or when the server exits.Client logs come back redacted, and only for tunnels this server started.
Related MCP server: pipepie
Tools
Tool | Does |
| Profiles, type, allowed hosts, tunnel state |
| HTTP(S) via a profile; auto-connects |
| Manual tunnel control |
| State, plus the redacted client log |
| Same as |
Install
Needs Docker Desktop (running) and Node.js 24+. One command installs and registers it with Claude Code:
curl -fsSL https://raw.githubusercontent.com/kylepantall/vpnhop/main/scripts/install.sh | bash -s -- --claudeWhat the installer does:
Installs into
~/.local/share/vpnhop, with avpnhoplauncher in~/.local/bin. The launcher uses the Node it found at install time.Builds the VPN runtime image.
Creates
~/.config/vpnhop/config.jsonfrom the example if you don't have one. Edit it to add your VPNs.Starts the new version: servers on the old build are stopped, and Claude starts the new one when it reconnects.
Options:
Pin a branch, tag or commit:
bash -s -- --claude <ref>.An existing
vpnhopentry stops the installer.--forcereplaces it.From a local checkout:
VPNHOP_SOURCE_DIR=~/Code/vpnhop bash scripts/install.sh --claude.VPNHOP_INSTALL_DIRandVPNHOP_BIN_DIRchoose other directories.
Start a new Claude session after installing.
Uninstall
curl -fsSL https://raw.githubusercontent.com/kylepantall/vpnhop/main/scripts/uninstall.sh | bashThis removes:
the Claude entry;
running servers;
tunnel containers and runtime images;
the launcher and the install directory.
Your config is kept. Add -s -- --purge to delete ~/.config/vpnhop as well.
Command line
Command | Does |
| MCP server on stdio |
| Checks GitHub for a newer release and reruns the installer for it. |
| Closes and restarts dangling instances (details below). macOS and Linux |
| Every profile and its tunnel state |
| Bring a tunnel up or down |
| GET a URL through a tunnel |
| Rebuild the runtime image |
What vpnhop refresh does:
Running servers close their tunnels, which reconnect on the next call.
Servers older than the installed build, or orphaned by a closed client, are stopped. Claude restarts them on reconnect.
Leftover tunnel containers and old runtime images are removed.
Releasing: bump version in package.json and src/version.ts, then publish a v<version> GitHub release. vpnhop update picks it up.
Config
~/.config/vpnhop/config.json (or $VPNHOP_CONFIG). See examples/config.json. Relative paths resolve against the config file's folder.
Field | Applies to | Notes |
| all |
|
| all | Override pushed DNS |
| all | Also settable under |
secrets | all |
|
⚠️ For OpenVPN, external ca/cert/key/tls-* files are copied in, and host hook scripts (up, down, …) are dropped.
Limits
SAML / browser SSO VPNs (AWS Client VPN federated auth, Okta-fronted GlobalProtect) need a human in a browser, so they can't run headless.
L2TP, PPTP and SSTP are not supported.
HTTP(S) only. There is no raw TCP or SOCKS proxy yet.
Develop
npm install
npm test # unit
npm run test:e2e # real WireGuard, OpenVPN and IPsec servers in Docker
npm run typecheckAvailable Tools
6 toolsconnectConnect a VPN profileAIdempotent
Starts the tunnel for a profile and waits until it is up (http_request also does this on demand). Reuses a running tunnel. On failure the error includes the redacted VPN client log.
Inputs: profile (required).
disconnectDisconnect a VPN profileBIdempotent
Stops and removes the tunnel container for a profile.
Inputs: profile (required).
http_requestHTTP request through a VPNADestructive
Sends an HTTP(S) request from inside the profile's tunnel (connecting first if needed) and returns status, headers and body. Text bodies come back as utf8, binary as base64; bodies over maxBodyBytes are truncated. Redirects are not followed unless followRedirects is set.
Inputs: url (required), profile (required), body, method, +6 more.
list_profilesList VPN profilesBRead-only
Configured VPN profiles with their type, description, allowed hosts and whether each tunnel is up.
Inputs: no named parameters.
refreshRefresh vpnhopAIdempotent
Closes every tunnel (they reconnect on the next call), recycles other running vpnhop servers, stops outdated or orphaned ones, and removes dangling tunnel containers and old runtime images. Use after a tunnel gets stuck or after updating vpnhop.
Inputs: no named parameters.
statusTunnel statusBRead-only
State of one or all tunnels, optionally with the last lines of the (redacted) VPN client log.
Inputs: logs, profile.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 6 tools
Each tool maps to a distinct operation: listing profiles, starting/stopping tunnels, inspecting status, sending proxied HTTP requests, and global refresh cleanup. Minor overlap exists because list_profiles reports whether tunnels are up and http_request connects on demand, but the descriptions clarify the intended use of each.
Names use lowercase snake_case and are readable, but conventions are mixed: list_profiles and http_request are verb_noun, connect/disconnect/refresh are bare verbs, and status is a noun. The pattern is understandable but not uniform.
Six tools is a tight, well-scoped set for VPN tunnel management and proxied HTTP requests. Every tool has a clear role and none feels redundant.
Core lifecycle is covered: list, connect, disconnect, status/logs, proxied requests, and global refresh. Profile creation/editing is absent, but profiles appear to be configured externally; a dedicated log-retrieval tool is also missing, though status exposes recent log lines.
Maintenance
Related MCP Connectors
Route HTTP requests through the Tor network. Rotating exit IPs, .onion support, no body logging.
Secure tunneling, reverse proxy and remote access for local applications.
Dedicated static outbound IPv4 over WireGuard. Free 7-day trial, no card, no sales call.
Remote shell and detached long-running jobs on your own machines — no SSH, open ports or VPN.
Related MCP Servers
- AlicenseAqualityCmaintenanceCredential isolation proxy for AI agents. Injects API keys at the network boundary so your agent never sees the raw credential. Supports domain allowlists, agent auth, policy enforcement, and audit logging.3141 npm16Apache 2.0
- AlicenseAqualityDmaintenanceSelf-hosted webhook relay and tunnel with Noise NK encryption. Inspect requests, replay webhooks, trace AI pipelines, connect/disconnect tunnels — 13 MCP tools. No tokens or passwords needed.138AGPL 3.0
- AlicenseNot gradedqualityBmaintenanceBounded egress gateway & secret proxy for AI agents and applications, enabling safe credential injection into upstream requests while keeping raw secrets out of LLM prompt contexts.24 npmMIT
- AlicenseNot gradedqualityCmaintenancePlaywright browser MCP for coding agents working behind a full-tunnel VPN. The tunnel stays up so the agent keeps reaching its API, while the browser's own traffic egresses through your real ISP — for services that reject the tunnel's exit IP: domestic APIs, payment and SMS gateways, bank endpoints. Per-socket binding plus a LAN-bound proxy, with per-host routing rules so you choose which hosts go80 npm4MIT