mulpm manages multiple Mullvad WireGuard routes and optional HTTP proxies.
Configuration is stored in:
~/.config/mul-proxy-manager/config.yml
Important: This project was entirely generated by AI. I did not write or review a single line of code. It requires a thorough, thorough review before being trusted or used in production.
The devcontainer provides NET_ADMIN and /dev/net/tun. Route commands that
need network privileges automatically re-exec through the narrow internal sudo
helper; normal commands do not need to be run with sudo.
Cursor can use this same environment with Reopen in Container. The image also installs Cursor Agent CLI for terminal sessions:
cursor-agent --version
cursor-agentCursor itself runs on the host; the container provides the CLI and remote development dependencies. The CLI may prompt for authentication on first use.
mulpm account show # list accounts and validate them
mulpm account show --quiet # names only, no network check
mulpm account show --output json
mulpm account set NAME # prompt for a 16-digit account number
mulpm account set NAME --key # replace the account number
mulpm account set NAME --name NEW_NAME # rename an account
mulpm account up NAME
mulpm account down NAME
mulpm account restart NAME
mulpm account validate NAME
mulpm account routes NAME
mulpm account remove NAME # removes the key, keeps routesaccounts is an alias for account; list and rm are aliases where shown
by command help.
Routes always use separate account and route arguments:
mulpm route list
mulpm route list --quiet
mulpm route list --output json
mulpm route status
mulpm route status --output json
mulpm route create ACCOUNT ROUTE
mulpm route create ACCOUNT ROUTE --http 8080
mulpm route create ACCOUNT ROUTE --country
mulpm route edit ACCOUNT ROUTE
mulpm route edit ACCOUNT ROUTE --city
mulpm route rename ACCOUNT ROUTE NEW_ROUTE
mulpm route up ACCOUNT ROUTE
mulpm route down ACCOUNT ROUTE
mulpm route restart ACCOUNT ROUTE
mulpm route reload ACCOUNT ROUTE
mulpm route up ACCOUNT ROUTE --reload
mulpm route inspect ACCOUNT ROUTE
mulpm route remove ACCOUNT ROUTE
mulpm route remove ACCOUNT ROUTE --forceroute list is local and fast. route status performs live account, relay,
port, stale-config, and WireGuard validation. route inspect prints detailed
interface, address, policy-routing, peer, handshake, and transfer information.
Changing country prompts for country, city, and server. Changing city prompts for city and server. Changing server prompts only for server. Existing values start selected in the fuzzy selector. HTTP port prompts accept Enter to clear and Escape to leave the current value unchanged.
If a route's server changes while it is up, route edit prints the required
route up ACCOUNT ROUTE --reload command.
--force on route removal brings an active route down, stops its HTTP proxy,
removes policy routing and WireGuard configuration artifacts, deletes the
Mullvad device, and then removes the route locally.
Run a command through a route by name. The route must be up and have an HTTP proxy port configured:
mulpm proxy ACCOUNT ROUTE curl https://am.i.mullvad.net/connectedThe command inherits the current environment with HTTP_PROXY, http_proxy,
HTTPS_PROXY, and https_proxy set to the route's local proxy port.
mulpm server
mulpm server COUNTRY
mulpm server COUNTRY CITY
mulpm completion bash|zsh|fish
mulpm completion install zshDynamic shell completions use local account and route listings and include the current command options.
Set --http PORT on a route. When the route is brought up, 3proxy listens on
that port and binds outbound traffic to the route's WireGuard address:
curl -x http://127.0.0.1:8080 https://am.i.mullvad.net/connectedEach route receives its own policy-routing table and mark, so several routes can be active concurrently without replacing the container's main default route.
Build the image:
docker build -t mulpm .The container needs network administration capability and the TUN device:
docker run --rm -it \
--cap-add=NET_ADMIN \
--device=/dev/net/tun \
-v "$HOME/.config/mul-proxy-manager:/root/.config/mul-proxy-manager" \
mulpm route listRun mulpm as the container entrypoint by replacing route list with any
supported command. The image runs as root because WireGuard interface and
policy-routing operations require NET_ADMIN; keep the configuration volume
protected on the host.
For Docker Compose, save this as compose.yml:
services:
mulpm:
image: shotor/mul-proxy-manager:latest
command: route status
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
ports:
- "8081:8081"
- "8082:8082"
volumes:
- ./config.yml:/root/.config/mul-proxy-manager/config.yml
stdin_open: true
tty: trueStart it with:
docker compose -f compose.yml up --build