Server data from the Official MCP Registry
OPNsense MCP Server — 72 tools for DNS, Firewall, DHCP, ACME, Routing, VLANs & more
OPNsense MCP Server — 72 tools for DNS, Firewall, DHCP, ACME, Routing, VLANs & more
Valid MCP server (1 strong, 1 medium validity signals). 8 known CVEs in dependencies (1 critical, 5 high severity) Package registry verified. Imported from the Official MCP Registry.
5 files analyzed · 9 issues found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
Unverified package source
We couldn't verify that the installable package matches the reviewed source code. Proceed with caution.
Set these up before or after installing:
Environment variable: OPNSENSE_URL
Environment variable: OPNSENSE_API_KEY
Environment variable: OPNSENSE_API_SECRET
Environment variable: OPNSENSE_VERIFY_SSL
Add this to your MCP configuration file:
{
"mcpServers": {
"io-github-itunified-io-opnsense": {
"env": {
"OPNSENSE_URL": "your-opnsense-url-here",
"OPNSENSE_API_KEY": "your-opnsense-api-key-here",
"OPNSENSE_API_SECRET": "your-opnsense-api-secret-here",
"OPNSENSE_VERIFY_SSL": "your-opnsense-verify-ssl-here"
},
"args": [
"-y",
"@itunified.io/mcp-opnsense"
],
"command": "npx"
}
}
}From the project's GitHub README.
Slim OPNsense MCP Server for managing firewall infrastructure via the OPNsense REST API.
No SSH. No shell execution. API-only. 3 runtime dependencies.
62 tools across 8 domains:
npm install
cp .env.example .env # Edit with your OPNsense API credentials
npm run build
node dist/index.js # stdio transport for MCP
mcp-opnsense supports opportunistic AppRole authentication against a HashiCorp Vault
instance. When Vault env vars are present, the server fetches OPNsense credentials from
KV v2 at startup. If they are absent, the server falls back silently to direct env vars or
MCP_SECRETS_FILE — no configuration change or restart required.
NAS_VAULT_ADDR in process.env.NAS_VAULT_ROLE_ID + NAS_VAULT_SECRET_ID),
reads the secret at <NAS_VAULT_KV_MOUNT>/data/<path>, and maps the KV fields to
OPNsense env vars.NAS_VAULT_ADDR is not set (or any Vault call fails), a single warning line is
written to stderr and the server continues with whatever env vars are already available.fetch built into Node 20+ — no additional runtime
dependencies are added.Explicit env vars > Vault > MCP_SECRETS_FILE > error (required var missing)
process.env are never overwritten by Vault.NAS_VAULT_ADDR is unset.MCP_SECRETS_FILE is the last fallback (see Loading Secrets from a File below).| Variable | Required | Description |
|---|---|---|
NAS_VAULT_ADDR | Yes* | Vault server address (e.g. https://vault.example.com:8200) |
NAS_VAULT_ROLE_ID | Yes* | AppRole role ID for this server |
NAS_VAULT_SECRET_ID | Yes* | AppRole secret ID for this server |
NAS_VAULT_KV_MOUNT | No | KV v2 mount path (default: kv) |
* Only required when using Vault. Without these, the server uses direct env vars or MCP_SECRETS_FILE.
Note:
OPNSENSE_VERIFY_SSL,OPNSENSE_TIMEOUT, and all SSH-related env vars (OPNSENSE_SSH_*) are not loaded from Vault. Set them directly in the MCP config or your shell environment.
The server reads from the path configured at startup (default: kv/data/opnsense/bifrost,
customisable via the KV mount). The secret must contain the following keys:
# Path: kv/your/opnsense/secret
{
"url": "https://your-opnsense.example.com",
"api_key": "your-api-key",
"api_secret": "your-api-secret"
}
Key mapping:
| KV field | Env var |
|---|---|
url | OPNSENSE_URL |
api_key | OPNSENSE_API_KEY |
api_secret | OPNSENSE_API_SECRET |
1. Write credentials to KV v2:
vault kv put kv/opnsense/your-firewall \
url=https://your-opnsense.example.com \
api_key=your-api-key \
api_secret=your-api-secret
2. Create a read-only policy:
# opnsense-read.hcl
path "kv/data/opnsense/*" {
capabilities = ["read"]
}
path "kv/metadata/opnsense/*" {
capabilities = ["list", "read"]
}
vault policy write opnsense-read opnsense-read.hcl
3. Enable AppRole auth and create a role:
vault auth enable approle
vault write auth/approle/role/mcp-opnsense \
token_policies="opnsense-read" \
token_ttl=1h \
token_max_ttl=4h \
secret_id_ttl=0
4. Retrieve the role credentials:
vault read auth/approle/role/mcp-opnsense/role-id
vault write -f auth/approle/role/mcp-opnsense/secret-id
Store the returned role_id and secret_id in your MCP config (see example below).
When using Vault, OPNsense credentials are not present in the config file. Only Vault authentication details and non-secret options are needed:
{
"mcpServers": {
"opnsense": {
"command": "npx",
"args": ["@itunified.io/mcp-opnsense"],
"env": {
"NAS_VAULT_ADDR": "https://vault.example.com:8200",
"NAS_VAULT_ROLE_ID": "your-role-id",
"NAS_VAULT_SECRET_ID": "your-secret-id",
"OPNSENSE_VERIFY_SSL": "true"
}
}
}
}
This keeps all OPNsense secrets out of config files and version control. The server authenticates to Vault on each startup and retrieves fresh credentials.
Add to .mcp.json in your project root:
{
"mcpServers": {
"opnsense": {
"command": "node",
"args": ["/path/to/mcp-opnsense/dist/index.js"],
"env": {
"OPNSENSE_URL": "https://your-opnsense.example.com",
"OPNSENSE_API_KEY": "your-api-key",
"OPNSENSE_API_SECRET": "your-api-secret",
"OPNSENSE_VERIFY_SSL": "true"
}
}
}
}
| Variable | Required | Default | Description |
|---|---|---|---|
OPNSENSE_URL | Yes | — | OPNsense base URL (e.g. https://192.168.1.1) |
OPNSENSE_API_KEY | Yes | — | API key for authentication |
OPNSENSE_API_SECRET | Yes | — | API secret for authentication |
OPNSENSE_VERIFY_SSL | No | true | Set to false for self-signed certificates |
OPNSENSE_TIMEOUT | No | 30000 | Request timeout in milliseconds |
MCP_SECRETS_FILE | No | — | Path to a key/value file to load on startup (see below) |
NAS_VAULT_ADDR | No | — | HashiCorp Vault URL, enables Vault AppRole loading (see below) |
NAS_VAULT_ROLE_ID | No | — | Vault AppRole role_id |
NAS_VAULT_SECRET_ID | No | — | Vault AppRole secret_id |
NAS_VAULT_KV_MOUNT | No | kv | Vault KV v2 mount path |
OPNSENSE_SSH_ENABLED | No | false | Enable SSH-backed tools (opnsense_if_assign, opnsense_if_configure) — see below |
OPNSENSE_SSH_HOST | If SSH enabled | — | SSH hostname of the OPNsense target |
OPNSENSE_SSH_USER | If SSH enabled | — | SSH login user (must have NOPASSWD sudo for the helper scripts) |
OPNSENSE_SSH_KEY_PATH | If SSH enabled | — | Path to the private key (e.g. ~/.ssh/id_ed25519) |
OPNSENSE_SSH_KNOWN_HOSTS | If SSH enabled | — | Path to a pre-populated known_hosts (strict checking, no TOFU) |
OPNSENSE_SSH_PORT | No | 22 | SSH port |
OPNSENSE_SSH_HELPER_DIR | No | /usr/local/opnsense/scripts/mcp | Remote directory holding if_assign.php / if_configure.php |
OPNSENSE_SSH_CONNECT_TIMEOUT | No | 10 | SSH connect timeout in seconds |
When the MCP server is launched from a context that does not inherit your shell
environment (e.g. a GUI desktop app launched via launchd), process.env may
be empty and tool calls will fail with Invalid URL errors. To avoid
system-wide environment hacks, point MCP_SECRETS_FILE at a file that holds
the required variables:
export MCP_SECRETS_FILE=~/.mcp-opnsense.env
The file is a simple KEY=value format (optionally prefixed with export,
with single or double quotes around values, # comments allowed). Example:
OPNSENSE_URL=https://your-opnsense.example.com
OPNSENSE_API_KEY=your-api-key
OPNSENSE_API_SECRET=your-api-secret
The OPNsense web UI "Download as .txt" button generates a two-line file with
lowercase key= / secret= pairs. That format is also recognized directly —
no rewriting needed:
key=your-api-key
secret=your-api-secret
Precedence: values in process.env always win over values from the file,
so the existing shell-based workflow stays fully backward compatible. Missing
or unreadable files are silently skipped (the server will fail with the usual
"required variable" error if nothing is set).
Security: the file holds plaintext credentials. Store it outside any git
repository and restrict permissions: chmod 600 ~/.mcp-opnsense.env.
If you run a central Vault instance, mcp-opnsense can fetch its credentials
at startup via AppRole instead of storing them in a file. Set:
export NAS_VAULT_ADDR=https://vault.example.com
export NAS_VAULT_ROLE_ID=<role-id>
export NAS_VAULT_SECRET_ID=<secret-id>
# optional — defaults to "kv"
export NAS_VAULT_KV_MOUNT=kv
The loader reads KV v2 at <mount>/data/opnsense/bifrost and expects three
keys: url, api_key, api_secret. Example Vault write:
vault kv put kv/opnsense/bifrost \
url=https://your-opnsense.example.com \
api_key=your-api-key \
api_secret=your-api-secret
Precedence: process.env > Vault > MCP_SECRETS_FILE. If NAS_VAULT_ADDR
is unset, Vault loading is a silent no-op — the server behaves exactly as
before. On any Vault error (network, auth, missing path), a single-line
warning is written to stderr and the server falls back to whatever env vars
are already set; it will then fail with the usual "required variable" error
if nothing remains.
Security: secret values are never logged. Only the KV path name and a
populated-count appear in stderr diagnostics. The loader uses the global
fetch (Node 20+) — no new runtime dependencies.
| Tool | Description |
|---|---|
opnsense_dns_list_overrides | List host overrides (A/AAAA/CNAME) |
opnsense_dns_add_override | Add a host override record |
opnsense_dns_delete_override | Delete a host override by UUID |
opnsense_dns_list_forwards | List DNS-over-TLS forwarding servers |
opnsense_dns_add_forward | Add a DNS forwarding server |
opnsense_dns_delete_forward | Delete a DNS forward by UUID |
opnsense_dns_list_blocklist | List domain overrides (blocked domains) |
opnsense_dns_block_domain | Block a domain |
opnsense_dns_unblock_domain | Unblock a domain by UUID |
opnsense_dns_flush_cache | Flush DNS cache and DNSBL data |
opnsense_dns_diagnostics | Dump DNS cache for diagnostics |
opnsense_dns_apply | Apply DNS changes (reconfigure Unbound) |
| Tool | Description |
|---|---|
opnsense_fw_list_rules | List all firewall filter rules |
opnsense_fw_add_rule | Create a firewall rule |
opnsense_fw_update_rule | Update a firewall rule by UUID |
opnsense_fw_delete_rule | Delete a firewall rule by UUID |
opnsense_fw_toggle_rule | Enable/disable a firewall rule |
opnsense_fw_reorder_rules | Change the evaluation order (sequence) of a rule — enforces whitelist-before-deny |
opnsense_fw_drift_check | Audit rule descriptions against a regex (default: ^#\d+: issue-reference prefix) |
opnsense_fw_list_aliases | List firewall aliases (host, network, port, URL) |
opnsense_fw_manage_alias | Create/update/delete aliases |
opnsense_fw_apply | Apply pending firewall changes |
| Tool | Description |
|---|---|
opnsense_diag_arp_table | Show ARP table (IP-to-MAC mappings) |
opnsense_diag_routes | Show routing table |
opnsense_diag_ping | Ping a host from OPNsense |
opnsense_diag_traceroute | Traceroute to a destination |
opnsense_diag_dns_lookup | Perform DNS lookup from OPNsense |
opnsense_diag_fw_states | List active firewall connection states |
opnsense_diag_fw_logs | Retrieve recent firewall log entries |
opnsense_diag_system_info | Get system status (CPU, memory, uptime, disk) |
| Tool | Description |
|---|---|
opnsense_if_list | List all network interfaces with device mappings |
opnsense_if_get | Get detailed interface configuration |
opnsense_if_stats | Get traffic statistics for all interfaces |
opnsense_if_assign | SSH-backed. Assign a VLAN/NIC device to a free optN slot (gap in the OPNsense REST API) |
opnsense_if_configure | SSH-backed. Set IPv4/IPv6 on an already-assigned optN slot (static, dhcp, dhcp6, track6, none) |
opnsense_if_assign and opnsense_if_configure are the only tools that do
not go through the OPNsense REST API. The REST API has no "Interfaces →
Assignments" endpoint, so mcp-opnsense invokes two small PHP helpers over
SSH + sudo instead. Both tools fail fast with a clear error if
OPNSENSE_SSH_ENABLED is not true, so non-SSH deployments are unaffected.
Setup on the OPNsense host:
opnsense-helpers/):
sudo install -m 0755 -o root -g wheel if_assign.php /usr/local/opnsense/scripts/mcp/
sudo install -m 0755 -o root -g wheel if_configure.php /usr/local/opnsense/scripts/mcp/
sudoers.d drop-in
that whitelists the exact helper invocations (see
opnsense-helpers/README.md for the recommended pattern — the glob MUST
end in * to accommodate the mandatory PHP -- separator).Setup on the mcp-opnsense host:
export OPNSENSE_SSH_ENABLED=true
export OPNSENSE_SSH_HOST=your-opnsense.example.com
export OPNSENSE_SSH_USER=claude
export OPNSENSE_SSH_KEY_PATH=~/.ssh/id_ed25519
export OPNSENSE_SSH_KNOWN_HOSTS=~/.ssh/known_hosts
The known_hosts file must be pre-populated — mcp-opnsense enforces strict
host key checking and will refuse to connect otherwise (no TOFU fallback).
Security posture:
ssh directly with an argv
array.BatchMode=yes + PreferredAuthentications=publickey disables password
and keyboard-interactive auth.config.xml, stamp every
write_config() with mcp-opnsense: ... for audit traceability, and use
numbered exit codes so the caller can distinguish "invalid args" from
"write_config failed" from "apply failed".See ADR-0092 (in the private infrastructure repo) for the full research spike, empirical findings, and rollback contract.
| Tool | Description |
|---|---|
opnsense_dhcp_list_leases | List all current DHCPv4 leases |
opnsense_dhcp_find_lease | Search leases by IP, MAC, or hostname |
opnsense_dhcp_list_static | List static DHCP mappings (reservations) |
opnsense_dhcp_add_static | Add a static DHCP mapping |
opnsense_dhcp_delete_static | Delete a static mapping by UUID |
| Tool | Description |
|---|---|
opnsense_sys_info | Get system status (hostname, versions, CPU, memory, uptime, disk) |
opnsense_sys_backup_list | List all configuration backups with timestamps and descriptions |
opnsense_sys_backup_download | Download configuration backup as XML (current or specific) |
opnsense_sys_backup_revert | Revert to a previous configuration backup (destructive) |
opnsense_sys_list_certs | List all certificates in the trust store |
opnsense_svc_list | List all services and their running status |
opnsense_svc_control | Start, stop, or restart a service by name |
| Tool | Description |
|---|---|
opnsense_acme_list_accounts | List ACME accounts (Let's Encrypt, ZeroSSL, etc.) |
opnsense_acme_add_account | Register a new ACME account with a CA |
opnsense_acme_delete_account | Delete an ACME account by UUID |
opnsense_acme_register_account | Trigger registration of an ACME account with its CA |
opnsense_acme_list_challenges | List all challenge/validation methods |
opnsense_acme_add_challenge | Add a DNS-01 challenge (Cloudflare, AWS, etc.) |
opnsense_acme_update_challenge | Update an existing challenge configuration |
opnsense_acme_delete_challenge | Delete a challenge by UUID |
opnsense_acme_list_certs | List all ACME certificates and their status |
opnsense_acme_create_cert | Create a new certificate request |
opnsense_acme_delete_cert | Delete an ACME certificate by UUID |
opnsense_acme_renew_cert | Trigger immediate certificate renewal |
opnsense_acme_settings | Get or update ACME service settings |
opnsense_acme_apply | Apply pending ACME configuration changes |
| Tool | Description |
|---|---|
opnsense_vlan_list | List configured 802.1Q VLAN interfaces (parent, tag, priority, description) |
opnsense_vlan_create | Create a VLAN interface on a parent device |
opnsense_vlan_update | Update VLAN tag, parent, priority, or description |
opnsense_vlan_delete | Delete a VLAN interface by UUID |
| Tool | Description |
|---|---|
opnsense_firmware_info | Get firmware version, architecture, update status |
opnsense_firmware_status | Check for available firmware upgrades |
opnsense_firmware_list_plugins | List all available and installed plugins |
opnsense_firmware_install | Install an OPNsense plugin package |
opnsense_firmware_remove | Remove a plugin package (requires confirmation) |
Claude Code skills compose MCP tools into higher-level workflows. See .claude/skills/README.md for detailed documentation.
| Skill | Slash Command | Description |
|---|---|---|
| opnsense-service-health | /opn-health | Health dashboard — system status, services, firmware, interfaces |
| opnsense-acme-renew | /opn-renew-cert | ACME certificate status check and renewal |
| opnsense-backup | /opn-backup | Configuration backup management — list, download, revert |
| opnsense-live-test | /opn-test | Live integration test — read + safe writes with cleanup |
| opnsense-diagnostics | — | Network connectivity diagnostics — ping, traceroute, DNS, ARP |
| opnsense-dns-management | — | DNS record management — add, delete, apply, verify resolution |
| opnsense-firewall-audit | — | Firewall security audit — permissive rules, disabled rules, patterns |
Some OPNsense operations are not available via the REST API and require manual GUI access:
ssl-certref can only be changed via System > Settings > Administration in the web UI. See docs/manual-operations.md.opnsense_sys_backup_revert to revert to local backups, or upload via the web GUI.confirm: true parameternpm test # Run unit tests (vitest)
npm run build # Compile TypeScript
npx tsc --noEmit # Type check only
See CONTRIBUTING.md for contribution guidelines.
This project is dual-licensed:
If you use mcp-opnsense in a proprietary product or SaaS offering, a commercial license is required. Support development by sponsoring us on GitHub.
Be the first to review this server!
by Modelcontextprotocol · Developer Tools
Read, search, and manipulate Git repositories programmatically
by Toleno · Developer Tools
Toleno Network MCP Server — Manage your Toleno mining account with Claude AI using natural language.
by mcp-marketplace · Developer Tools
Create, build, and publish Python MCP servers to PyPI — conversationally.
by Microsoft · Content & Media
Convert files (PDF, Word, Excel, images, audio) to Markdown for LLM consumption
by mcp-marketplace · Developer Tools
Scaffold, build, and publish TypeScript MCP servers to npm — conversationally
by mcp-marketplace · Finance
Free stock data and market news for any MCP-compatible AI assistant.