An MCP (Model Context Protocol) server for controlling Mullvad VPN through any MCP-compatible client — Claude Desktop, Cursor, Windsurf, and more.
All VPN interaction goes through the mullvad CLI. No direct API calls, no config file parsing, no credentials needed.
- Mullvad VPN app installed with the CLI available in your PATH
- Verify:
mullvad --version - Download Mullvad
- Verify:
- Python 3.11+
- uv package manager — install uv
git clone https://github.com/your-username/mullvad-mcp.git
cd mullvad-mcp
uv syncAdd to ~/.config/claude-desktop/claude_desktop_config.json (Linux) or ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"mullvad": {
"command": "uv",
"args": ["--directory", "/path/to/mullvad-mcp", "run", "mullvad-mcp"]
}
}
}Add to .cursor/mcp.json in your project or ~/.cursor/mcp.json globally:
{
"mcpServers": {
"mullvad": {
"command": "uv",
"args": ["--directory", "/path/to/mullvad-mcp", "run", "mullvad-mcp"]
}
}
}{
"mcpServers": {
"mullvad": {
"command": "uv",
"args": ["--directory", "/path/to/mullvad-mcp", "run", "mullvad-mcp"],
"transport": "stdio"
}
}
}| Tool | Description |
|---|---|
connect |
Connect to VPN, optionally specifying country/city/hostname |
disconnect |
Disconnect from VPN |
reconnect |
Reconnect, optionally to a new location |
| Tool | Description |
|---|---|
get_status |
Current connection state, server, protocol, IPs |
check_leak |
Query am.i.mullvad.net to verify VPN protection |
| Tool | Description |
|---|---|
list_countries |
All available countries with server counts |
list_cities |
Cities for a given country |
list_servers |
Servers with filters (country, city, owned_only) |
set_location |
Set preferred location by country, city, or hostname |
| Tool | Description |
|---|---|
get_account_info |
Masked account number, expiry date |
get_device_info |
Devices registered to the account |
| Tool | Description |
|---|---|
get_settings |
All current settings as a structured object |
set_killswitch |
Enable/disable lockdown mode |
set_daita |
Enable/disable DAITA (traffic analysis defence) |
set_multihop |
Enable/disable multihop with optional entry location |
set_dns |
Set DNS: default (with blocking options) or custom IPs |
set_protocol |
Configure WireGuard options (quantum resistance, IPv6) |
set_obfuscation |
Set anti-censorship mode (auto/off/udp2tcp/shadowsocks/etc) |
"Connect me to Sweden"
→ Calls
connect(country="se")— sets relay to Sweden and connects.
"Am I leaking?"
→ Calls
check_leak()— queries am.i.mullvad.net and reports whether traffic exits through Mullvad.
"What cities are available in Germany?"
→ Calls
list_cities(country="de")— returns Berlin, Frankfurt, etc. with server counts.
"Enable the kill switch and block ads"
→ Calls
set_killswitch(enabled=True)thenset_dns(block_ads=True).
| Variable | Default | Description |
|---|---|---|
MULLVAD_CLI_PATH |
Auto-detected | Override path to the mullvad binary |
MULLVAD_CLI_TIMEOUT |
10 |
CLI command timeout in seconds |
All tools call the mullvad CLI via subprocess. The CLI handles authentication natively — no API keys or secrets are needed. Output is parsed into structured dicts so LLMs can reason about the results.
MIT