Skip to main content

mcp-pfsense

PyPI Python License: MIT

MCP server for managing pfSense firewalls through AI assistants like Claude, ChatGPT, and Copilot.

Requires: pfrest package installed on your pfSense instance (provides the REST API).

Features

19 tools across 7 categories:

Category Tools Description
System get_system_status, get_interfaces Version, CPU, memory, uptime, temperature, network interfaces
Firewall list_firewall_rules, add_firewall_rule, delete_firewall_rule, list_firewall_aliases Rule management with interface filtering, alias listing
DHCP list_dhcp_leases, list_dhcp_static_mappings, add_dhcp_static_mapping, delete_dhcp_static_mapping Active leases, IP reservations
DNS list_dns_host_overrides, add_dns_host_override, delete_dns_host_override Unbound DNS Resolver host overrides
Pending changes get_pending_changes, apply_changes See what is staged per subsystem (firewall, dhcp, dns) and apply it
Monitoring get_gateway_status, get_arp_table, list_services Gateway health, connected devices, service status
Services restart_service Restart any pfSense service

Safety

  • Two-step confirmation for destructive operations (delete rules, delete mappings, restart services, apply changes): the tool returns a warning on first call and only executes when called again with confirm=true.
  • Writes are staged, not live. Like the pfSense WebGUI, add_* and delete_* store the change in the config but do not activate it. The tool response says so (applied: false, plus a pending note). Activate with apply_changes(subsystem, confirm=true) — which reloads that subsystem, including anything a human left staged in the WebGUI — or pass apply=true on the write itself when you explicitly want a one-shot change. Nothing the assistant does reaches the packet filter without one of those two explicit steps.
  • delete_dhcp_static_mapping takes the mapping's interface (its parent_id in list_dhcp_static_mappings) and mapping_id; a mapping is addressed by both.

Installation

# Using uvx (recommended)
uvx mcp-pfsense

# Using pip
pip install mcp-pfsense

Prerequisites

  1. pfSense with pfrest package installed
  2. A user account with API access (typically admin)

Configuration

Set environment variables:

Variable Required Default Description
PFSENSE_HOST Yes pfSense hostname or IP
PFSENSE_PASSWORD Yes API user password
PFSENSE_USERNAME No admin API username
PFSENSE_PORT No 443 API port
PFSENSE_SCHEME No https http or https
PFSENSE_VERIFY_SSL No false Verify SSL certificate

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "pfsense": {
      "command": "uvx",
      "args": ["mcp-pfsense"],
      "env": {
        "PFSENSE_HOST": "10.10.10.1",
        "PFSENSE_PASSWORD": "your-password"
      }
    }
  }
}

Claude Code

claude mcp add pfsense -- uvx mcp-pfsense

Then set environment variables in your shell or .env file.

Usage Examples

Once connected, ask your AI assistant:

  • "What's the pfSense system status?"
  • "Show me all firewall rules on the LAN interface"
  • "List active DHCP leases"
  • "Add a DNS entry for nas.home.lan pointing to 10.10.10.50"
  • "What devices are connected to the network?" (ARP table)
  • "Show gateway health and latency"
  • "Create a firewall rule to allow TCP port 8080 on LAN"
  • "Reserve IP 10.10.10.60 for MAC aa:bb:cc:dd:ee:20"

API Compatibility

  • pfSense: 2.7.x and 2.8.x
  • pfrest: REST API v2 — any v2.x release, except list_dhcp_static_mappings, which needs v2.7.0 or later (it uses the /services/dhcp_server/static_mappings collection endpoint added in that release).
  • Python: 3.11+

The endpoint, parameters and encoding each tool uses are pinned by tests/test_client_endpoints.py and tests/test_wire_format.py, derived from the pfrest v2 endpoint definitions. Versions before 0.2.0 called several endpoints that do not exist in pfrest v2 (see Troubleshooting).

Note: pfrest runs on nginx (port 80 by default), separate from the pfSense WebGUI (lighttpd on port 443). If your pfrest is configured on a non-standard port, set PFSENSE_PORT and PFSENSE_SCHEME accordingly.

Troubleshooting

Only get_system_status and get_arp_table work; everything else returns 400/404

mcp-pfsense 0.1.1 and earlier called singular endpoints for listing (/interface, /firewall/rule, /firewall/alias) and legacy paths that pfrest v2 does not serve (/status/dhcp_leases, /services/dhcpd/static_mapping, /services/unbound/host_override, /status/gateway, /status/service for GET). Upgrade to 0.2.0 or later.

403 on list_services or other reads

pfrest checks the privileges of the API user per endpoint. Grant the user the api-v2-* privileges for the endpoints you need (or page-all for full access) under System → User Manager.

ModuleNotFoundError: No module named 'mcp.server.fastmcp'

The MCP Python SDK 2.0 removed the module that mcp-pfsense 0.1.1 and earlier import, so fresh installs (uvx mcp-pfsense, pip install) failed on startup. Upgrade to 0.2.0 or later, which pins mcp<2. If you must stay on an older mcp-pfsense: uvx --with "mcp<2" mcp-pfsense.

A rule / mapping / override was created but is not in effect

That is the default: writes are staged (see Safety). Check with get_pending_changes(subsystem) and activate with apply_changes(subsystem, confirm=true), or in the WebGUI. If a write returns 200 but nothing is stored at all, the pfrest read_only setting is on (System → REST API → Settings).

Development

git clone https://github.com/antonio-mello-ai/mcp-pfsense.git
cd mcp-pfsense
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# Run tests
pytest

# Lint and type check
ruff check .
mypy src/

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_pfsense-0.2.0.tar.gz (18.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_pfsense-0.2.0-py3-none-any.whl (16.2 kB view details)

Uploaded Python 3

File details

Details for the file mcp_pfsense-0.2.0.tar.gz.

File metadata

  • Download URL: mcp_pfsense-0.2.0.tar.gz
  • Upload date:
  • Size: 18.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mcp_pfsense-0.2.0.tar.gz
Algorithm Hash digest
SHA256 819a0cf75be4075eff944dbac5b868be9b489fecde5fe86b437d2610f62a8d08
MD5 519d0cc8f4fd56879438b252c1535985
BLAKE2b-256 b553a5ab5e8fccd118d49163bd30943810dae735cc2e56ace4d52d2b03b9158c

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_pfsense-0.2.0.tar.gz:

Publisher: publish.yml on antonio-mello-ai/mcp-pfsense

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcp_pfsense-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: mcp_pfsense-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 16.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mcp_pfsense-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2fbf703a400adb8f4136c91787a86780452a6d84ec34952b4d5afa849deb7c41
MD5 2efb60f99f2787f07a16399e3e950deb
BLAKE2b-256 a1aabe731bcc6c56985fcbaa858644855893853ca50d0f6e59c1acbaa405ed85

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_pfsense-0.2.0-py3-none-any.whl:

Publisher: publish.yml on antonio-mello-ai/mcp-pfsense

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page