pfSense MCP Server

by gensecaihq

Not rated
GitHub

About

Enables natural language interaction with pfSense firewalls through GenAI applications.

Details

Author
gensecaihq
Categories
Developer Tools, Infrastructure, Security

Setup

Install pfSense MCP Server in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/gensecaihq/pfsense-mcp-server

Follow the installation instructions in the repository README, then restart your MCP client.

Manage your pfSense firewall in plain English — from Claude Desktop, Claude Code, or any MCP client.

333 toolsacross every subsystem ·wire-format verifiedagainst the pfSense REST API ·safety guardrailson every change

You: Block all traffic from 203.0.113.5 on WAN Claude: ✓ created block rule → ✓ applied changes → rollback: restore_config_backup(revision_id=42) You: Why can't 192.168.1.50 reach the internet? Claude: ran diagnostics → gateway WAN_DHCP is down, and a block rule on LAN matches this host You: Add a WireGuard peer for my laptop and show me the config Claude: ✓ created peer on tun_wg0 → here's the client config to import

pfSense MCP ServerconnectsClaude Desktop,Claude Code, and any otherMCPclient to your pfSense firewall. Ask questions, diagnose issues, and change configuration through conversation — with a confirmation gate, config backup, and rollback on every destructive action.

Letting an AI touch a production firewall is only safe if the plumbing is right, so that's where the work went: every tool's wire format is verified against the pfSense REST API schema by a contract-test layer, and every change runs through a guardrail pipeline. 572 tests plus a wire-protocol E2E suite in CI on Python 3.11–3.13.

[!TIP] Jump to theQuick Start— about two minutes withuvx, no clone required. And if this saves you a trip through the pfSense web UI, a ⭐ helps others find it.

Why this exists·Quick start·What you can do·Safety·Supported versions·Authentication·Deployment·Configuration·Testing·MCP compliance·Architecture·Contributing

Managing a pfSense firewall means clicking through web UI tabs, remembering field names, and hoping you don't fat-finger a rule that locks you out. With this MCP server, you describe what you want in plain English and the AI handles the REST API calls, validates inputs, and warns you before anything destructive happens.

- Every destructive operation requires explicit confirmation and shows you exactly what will happen
- Config backup before every delete/reboot — with a one-line rollback command (and an explicit warning if a backup point can't be captured)
- Rate limiting on every mutating tool prevents runaway AI loops from flooding your firewall
- Positive input validation (IP/port/MAC/CIDR) plus path-traversal/XSS screening, and secrets redacted from logsandAPI error responses
- Wire-format verified against the pfSense REST API v2.10.0 schema by a contract-test layer, so tools send exactly what the API expects

Prerequisites:Python 3.11+, pfSense withREST API v2 packageinstalled

uvx --from git+https://github.com/gensecaihq/pfsense-mcp-server pfsense-mcp-server
git clone https://github.com/gensecaihq/pfsense-mcp-server.git cd pfsense-mcp-server pip install -r requirements.txt cp .env.example .env # Edit .env: set PFSENSE_URL, AUTH_METHOD, and credentials

Connect to Claude Desktop— add to~/Library/Application Support/Claude/claude_desktop_config.json.

Using the installed entry point (Option A):

{ "mcpServers": { "pfsense": { "command": "uvx", "args": ["--from", "git+https://github.com/gensecaihq/pfsense-mcp-server", "pfsense-mcp-server"], "env": { "PFSENSE_URL": "https://192.168.1.1", "AUTH_METHOD": "basic", "PFSENSE_USERNAME": "admin", "PFSENSE_PASSWORD": "your-password", "PFSENSE_VERSION": "CE_2_8_1", "PFSENSE_CA_FILE": "/path/to/pfsense-ca.pem" } } } }
{ "mcpServers": { "pfsense": { "command": "python3.11", "args": ["-m", "src.main"], "cwd": "/path/to/pfsense-mcp-server", "env": { "PFSENSE_URL": "https://192.168.1.1", "AUTH_METHOD": "basic", "PFSENSE_USERNAME": "admin", "PFSENSE_PASSWORD": "your-password", "PFSENSE_VERSION": "CE_2_8_1", "PFSENSE_CA_FILE": "/path/to/pfsense-ca.pem" } } } }

About that CA file.pfSense ships with a self-signed certificate from its own CA, and Python does not read your OS trust store — so verification fails out of the box. Export the CA atSystem > Cert. Manager > CAs(the export-certificate icon), save the PEM anywhere readable, and pointPFSENSE_CA_FILEat it. A missing or unparseable file is a startup error, never a silent downgrade.

VERIFY_SSL=falsealso connects, and is fine for a throwaway lab. Understand what it costs: nothing authenticates the firewall, so anything that can intercept the connection can read the API key and act as the firewall. This tool changes firewall rules — treat that credential accordingly.

Start talking to your firewall.Open Claude Desktop and ask:

- "Show me all blocked traffic in the last hour"
- "What services are running?"
- "Create a port forward for port 443 to 192.168.1.50"
- "Run a full system health check"

333 tools across every major pfSense subsystem:

AI managing a production firewall needs guardrails. This server has 9 layers:

"Delete firewall rule 5" 1. CLASSIFY → HIGH risk (destructive) 2. ALLOWLIST → tool is permitted 3. SANITIZE → parameters clean (no injection) 4. RATE LIMIT → under 10 deletes/minute 5. DRY RUN? → user can preview first 6. CONFIRM → blocked until confirm=True 7. BACKUP → config revision captured 8. EXECUTE → API call made 9. AUDIT LOG → action recorded with redacted params Response includes: "config_backup": { "pre_change_revision_id": 42, "rollback_instruction": "restore_config_backup(revision_id=42, confirm=True)" }

Every one of the 202 mutating tools carries a guardrail, enforced at registration by a meta-test so a new tool can't ship ungated: the 52 destructive (delete/reboot/halt) tools requireconfirm=True, and the other 150 (create/update/apply/manage/export/service-control) are rate-limited, audited, and allowlist-checked. Sensitive parameters (passwords, keys, PSKs, bind passwords, tokens) are redacted in the audit logandin echoed API error responses.

- Passdry_run=Trueto preview any destructive operation without executing
- Passverify_descr="Allow HTTPS"to verify you're deleting the right rule (guards against ID shifts)
- SetMCP_READ_ONLY=trueto expose only the 131 read-only tools (search, get, diagnose)
- SetMCP_ALLOWED_TOOLS=search_firewall_rules,get_firewall_logto restrict to specific tools

SeeSECURITY.mdfor the vulnerability-disclosure policy and deployment-hardening guidance.

Requires thepfSense REST API v2 packagebyjaredhendrickson13. Package v2.8.x+ ships builds only for CE 2.8.1 and Plus 25.11.1/26.03/26.03.1; v2.7.3 is the last release with builds for CE 2.8.0 and Plus 24.11/25.11.

Security note:run REST API packagev2.10.0+. It fixes a command-injection flaw in the interface-group endpoints (GHSA-w3w4-mvcc-vmgr) and adds core command auto-escaping; v2.9.0 fixed an earlier settings-sync privilege escalation ([GHSA-8q8g-9f77-8g8g).

v2.10.0 also marksOpenVPNClient.auth_pass,User.ipsecpsk, andWireGuardPeer.presharedkeyassensitive, so the API no longer returns them by default. This server stillsetsthem normally; if a workflow needs to read one back, add a sensitive-field override in the REST API settings.

Three methods supported (configure in.env):

stdio(default) — for Claude Desktop and Claude Code:

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.