add_dhcp_static_mapping
Create a DHCP static mapping (IP reservation) for a MAC address.
Staged until apply_changes('dhcp') is called or apply=true is passed.
Inspect and change a pfSense firewall — rules, DHCP reservations, DNS overrides — with every write staged rather than live, and every destructive call held behind a confirmation.
LABSCO SUMMARY
A bad rule applied instantly can lock you out of the box you are talking to, so the two-step shape matters more here than in most integrations: writes land in the config marked applied: false, and nothing reaches the packet filter until you apply the subsystem or explicitly pass apply=true. Destructive calls go further and refuse the first attempt outright. One thing to know before you use apply_changes: it activates everything staged in that subsystem, including whatever a human left pending in the pfSense web interface and has not reviewed.
A client for a pfSense box's REST API: 19 tools across system status, firewall rules and aliases, DHCP leases and reservations, DNS resolver overrides, gateway and ARP monitoring, and service control.
A pfSense instance running 2.7.x or 2.8.x with the pfrest REST API package installed, and a user account with API access. Python 3.11 or newer — uvx mcp-pfsense is the shortest route. PFSENSE_HOST and PFSENSE_PASSWORD are required; username defaults to admin, port to 443, scheme to https, and SSL verification is off by default. One tool needs a newer API than the rest: listing DHCP static mappings requires pfrest v2.7.0 or later.
One command plus credentials — uvx mcp-pfsense, then supply credentials
USE CASES
Read the ARP table and the active leases instead of opening the web interface.
Create it staged, check what is pending, then activate it deliberately.
Reserve the IP against its MAC, then apply the DHCP subsystem when you are ready.
Add a host override in the resolver rather than editing hosts files on every machine.
Read gateway latency, packet loss and online state, then restart the service that is stuck.
List the rules per interface and read the alias groups they reference.
Counted once with only startup setup. Other versions, modes or optional credentials may expose a different list.
add_dhcp_static_mappingCreate a DHCP static mapping (IP reservation) for a MAC address.
Staged until apply_changes('dhcp') is called or apply=true is passed.
add_dns_host_overrideCreate a DNS host override entry in Unbound DNS Resolver.
Staged until apply_changes('dns') is called or apply=true is passed.
add_firewall_ruleAdd a firewall rule. Type is 'pass', 'block', or 'reject'.
The rule is staged (not active) until apply_changes('firewall') is called or apply=true is passed here.
apply_changesApply ALL staged changes of a subsystem ('firewall', 'dhcp' or 'dns'). Requires confirm=true.
This reloads the subsystem, activating every pending change — including any a human staged in the pfSense WebGUI and has not reviewed yet.
delete_dhcp_static_mappingDelete a DHCP static mapping. Requires confirm=true.
interface is the mapping's DHCP server — the parent_id value returned by list_dhcp_static_mappings; mapping_id is its id there. Staged until apply_changes('dhcp') is called or apply=true is passed.
delete_dns_host_overrideDelete a DNS host override by ID. Requires confirm=true.
Staged until apply_changes('dns') is called or apply=true is passed.
delete_firewall_ruleDelete a firewall rule by its ID (the id from list_firewall_rules). Requires confirm=true.
Staged until apply_changes('firewall') is called or apply=true is passed.
get_arp_tableGet ARP table showing connected devices (IP, MAC, interface).
get_gateway_statusGet gateway status including latency, packet loss, and online state.
get_interfacesList all network interfaces with status and configuration.
get_pending_changesCheck whether a subsystem ('firewall', 'dhcp' or 'dns') has staged, unapplied changes.
get_system_statusGet pfSense system status including version, CPU, memory, uptime, and temperature.
list_dhcp_leasesList active DHCP leases showing IP, MAC, hostname, and lease times.
list_dhcp_static_mappingsList DHCP static mappings (IP reservations), optionally filtered by interface.
Each mapping carries parent_id (its DHCP server / interface) — pass that as interface to delete_dhcp_static_mapping.
list_dns_host_overridesList DNS Resolver host overrides (local DNS entries).
list_firewall_aliasesList firewall aliases (IP groups, port groups, URL lists).
list_firewall_rulesList firewall rules, optionally filtered by interface.
list_servicesList all services and their running status.
restart_serviceRestart a service by name. Requires confirm=true.
BEFORE YOU INSTALL
19 tools when we connected. Writes are staged until apply_changes runs with confirm true, and destructive tools warn first, running only when called again with confirm true. pfrest's read_only option makes writes report success but store nothing.
Both documented clients run the server on your machine.
CONTEXT COST
Rated by the size of the 19 tool definitions that ride along on every turn, not by how many there are
INSTALLATION
uvx mcp-pfsense{
"mcpServers": {
"pfsense": {
"command": "uvx",
"args": [
"mcp-pfsense"
],
"env": {
"PFSENSE_HOST": "10.10.10.1",
"PFSENSE_PASSWORD": "<YOUR_PFSENSE_PASSWORD>"
}
}
}
}claude mcp add pfsense -- uvx mcp-pfsenseThen set PFSENSE_HOST and PFSENSE_PASSWORD (required) in your shell or .env file.