ee6c626a80f202709cab146140fa500b09fcb926
pfSense MCP
Model Context Protocol server for pfSense firewall management via the REST API v2 package (pfSense-pkg-RESTAPI). Sibling project to opnsense-mcp with the same safety model.
Features
- 55+ tools covering system status, interfaces, firewall rules, aliases, NAT, DHCP, diagnostics, routing, VPN (OpenVPN/IPsec/WireGuard), and DNS resolver
- Safety guardrails: writes disabled by default, dry-run mode, WAN any/any rule blocking, required description prefix
- Audit logging: all mutations logged to JSONL
applycontrol: write tools acceptapply=trueto apply immediately, or batch changes and call the apply tool
Prerequisites
pfSense does not ship a REST API. Install the free REST API v2 package on the firewall first:
# On the pfSense shell (adjust version to your pfSense release — see pfrest.org)
pkg-static add https://github.com/jaredhendrickson13/pfsense-api/releases/latest/download/pfSense-2.8.0-pkg-RESTAPI.pkg
Then in the web UI: System → REST API → Settings (enable), and System → REST API → Keys to generate an API key.
Quick Start
1. Install
pip install -e /path/to/pfsense-mcp
Or with the Hermes venv:
/usr/local/lib/hermes-agent/venv/bin/pip install -e /root/projects/pfsense-mcp
2. Configure environment
cp .env.example .env
| Variable | Default | Description |
|---|---|---|
PFSENSE_URL |
https://192.168.1.1 |
Firewall base URL |
PFSENSE_API_KEY |
— | REST API key (preferred) |
PFSENSE_USERNAME / PFSENSE_PASSWORD |
— | Basic auth fallback |
PFSENSE_VERIFY_SSL |
false |
Verify TLS certificate |
PFSENSE_ALLOW_WRITES |
false |
Enable mutating operations |
PFSENSE_DRY_RUN |
false |
Log writes without executing |
PFSENSE_REQUIRE_DESCRIPTION_PREFIX |
mcp: |
Prefix for new firewall rules (descr) |
PFSENSE_BLOCK_WAN_INBOUND_ANY |
true |
Block WAN any→any pass rules |
3. Register with Hermes
mcp_servers:
pfsense:
command: /usr/local/lib/hermes-agent/venv/bin/pfsense-mcp
timeout: 120
enabled: true
env:
PFSENSE_URL: "https://your-pfsense"
PFSENSE_API_KEY: "your-api-key"
PFSENSE_VERIFY_SSL: "false"
PFSENSE_ALLOW_WRITES: "false"
Then hermes mcp test pfsense and hermes gateway restart.
4. Register with Cursor (~/.cursor/mcp.json)
{
"mcpServers": {
"pfsense": {
"command": "pfsense-mcp",
"env": {
"PFSENSE_URL": "https://your-pfsense",
"PFSENSE_API_KEY": "your-api-key"
}
}
}
}
Tool Categories
Read-only (always available with valid credentials)
| Tool | Description |
|---|---|
pfsense_test_connection |
Verify API auth and connectivity |
pfsense_get_system_status |
CPU, memory, disk, uptime |
pfsense_get_interface_status |
Live interface status |
pfsense_list_firewall_rules |
Filter rules (with query filters) |
pfsense_list_firewall_states |
Active state table |
pfsense_list_aliases |
Firewall aliases |
pfsense_list_port_forwards |
Destination NAT rules |
pfsense_list_dhcp_leases |
DHCP lease table |
pfsense_get_arp_table |
ARP / IP→MAC |
pfsense_get_gateway_status |
Gateway health |
pfsense_get_firewall_log |
Firewall log |
pfsense_get_openvpn_status |
OpenVPN connected clients |
pfsense_get_ipsec_status |
IPsec SAs |
pfsense_list_wireguard_tunnels |
WireGuard (plugin) |
pfsense_list_dns_host_overrides |
Local DNS records |
pfsense_get_config_history |
Config change audit trail |
Write operations (require PFSENSE_ALLOW_WRITES=true)
| Tool | Description |
|---|---|
pfsense_add_firewall_rule |
Add filter rule (descr prefix required) |
pfsense_toggle_firewall_rule |
Enable/disable rule |
pfsense_apply_firewall |
Apply pending changes |
pfsense_add_alias / pfsense_update_alias |
Manage aliases |
pfsense_add_port_forward |
Add destination NAT |
pfsense_add_dhcp_static_mapping |
DHCP reservation |
pfsense_add_dns_host_override |
Local DNS record |
pfsense_add_static_route |
Static route |
pfsense_service_action |
Start/stop/restart services |
pfsense_kill_firewall_states |
Kill states by source |
pfsense_reboot |
Reboot (double confirm) |
Query filtering
List tools accept a query parameter with pfSense REST v2 query syntax:
query="interface=wan" exact match
query="descr__contains=mcp" substring
query="ip__startswith=10.77" prefix
query="interface=wan,protocol=tcp" multiple conditions
Differences vs opnsense-mcp
| Aspect | OPNsense | pfSense |
|---|---|---|
| API | Built-in (/api/module/controller/command) |
Package required (/api/v2/...) |
| Auth | key+secret basic auth | X-API-Key header or basic auth |
| IDs | UUIDs | Numeric ids (positional) |
| Apply | Savepoint + rollback workflow | apply=true param or apply endpoints |
| Rule description field | description |
descr |
Security Notes
- Never commit API keys; use environment variables or Hermes secrets.
- Start read-only (
PFSENSE_ALLOW_WRITES=false). - Create a dedicated pfSense user + API key with minimal privileges.
- Review the audit log at
PFSENSE_AUDIT_LOG_PATH. - pfSense numeric ids shift when objects are deleted — always list immediately before mutating by id.
License
MIT
Description
Languages
Python
100%