pfClaude
pfsense-mcp
A bidirectional AI agent for pfSense. Two components, one package: an MCP server for Claude Code control, and an emergency brain that activates when your network needs help.
Status: Planning Author: Claude (claude@arktechnwa.com) + Meldrey License: MIT Organization: ArktechNWA
Why?
Your AI assistant can help configure firewalls, but it's blind to your network's health. It can't see if your WAN is down, can't check DHCP leases, can't restart a stuck interface.
Worse: when your network breaks, you lose access to your AI assistant entirely.
pfclaude solves both problems:
Normal mode: Claude Code controls pfSense via MCP — full visibility, full capability
Emergency mode: When Claude Code is unreachable, pfSense's onboard brain activates — diagnostics, notifications, autonomous recovery
Philosophy
Maximum capability — Expose everything pfSense can do
User controls exposure — Checkbox permissions, not hardcoded limits
Maximum availability — Multiple transport channels, graceful fallbacks
Lightweight emergency brain — Minimal resource usage, adaptive monitoring
Bidirectional communication — Email commands work even when network is broken
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Claude Code (workstation) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ pfsense-mcp │ │
│ │ - Full pfSense API passthrough │ │
│ │ - All operations: firewall, NAT, DHCP, VPN, logs, etc. │ │
│ │ - Authenticated over HTTPS │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↕ HTTPS + API Key (primary)
↕ SSH (fallback)
┌─────────────────────────────────────────────────────────────────┐
│ pfSense Router │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ pfClaude Package │ │
│ │ │ │
│ │ NORMAL MODE │ EMERGENCY MODE │ │
│ │ ───────────── │ ────────────── │ │
│ │ API Server │ Watchdog Daemon │ │
│ │ ↕ MCP talks here │ ↳ Health monitors │ │
│ │ │ ↳ Trigger detection │ │
│ │ Full pfSense ops │ ↳ Decision engine │ │
│ │ Auth'd requests │ ↳ Autonomous actions │ │
│ │ │ ↳ Notification dispatch │ │
│ │ │ │ │
│ │ ───────────────────────────────────────────────────────── │ │
│ │ SHARED INFRASTRUCTURE │ │
│ │ • Permission matrix (checkboxes) │ │
│ │ • SMTP client (outbound alerts) │ │
│ │ • Email parser (inbound commands) │ │
│ │ • Cloud beacon (optional status sync) │ │
│ │ • Local knowledge base (patterns, history) │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘Authentication
API Authentication
Simple, proven security:
{
"auth": {
"api_key": "randomly-generated-64-char-key",
"require_https": true,
"ip_whitelist": ["192.168.1.0/24", "10.0.0.5"],
"rate_limit": 100,
"lockout_threshold": 5,
"lockout_duration": 900
}
}API key transmitted in header:
X-PfClaude-Key: <key>HTTPS required (uses pfSense's existing certificate)
Optional IP whitelist (only accept from known Claude IPs)
Rate limiting: 100 requests/min default
Failed auth lockout: 5 failures → 15 min ban
Email Authentication
For inbound email commands:
Subject: [PFCLAUDE:1234] statusSender must be in whitelist
PIN must match configured value
Timestamp validation (reject if >5min old)
Rate limit: 10 commands/hour
Trigger Conditions
Tiered detection with configurable thresholds:
Tier 1: Monitoring (always on, ultra-light)
Check | Description | Default |
Interface link state | Is the physical link up? | ✓ |
Heartbeat reception | Has Claude Code checked in? | ✓ |
Gateway reachability | Can we ping default gateway? | ✓ |
WAN connectivity | Can we reach external IPs? | ✓ |
Tier 2: Concern (triggers increased monitoring)
Check | Description | Default |
Packet loss > 10% | Network degraded | ✓ |
Latency spike > 3x | Something's congested | ✓ |
DNS resolution failing | Name lookups broken | ✓ |
DHCP not responding | Clients can't get IPs | ✓ |
Unusual traffic volume | 5x normal (attack? loop?) | ✓ |
Tier 3: Emergency (activates autonomous response)
Check | Description | Default |
LAN interface down | Physical link lost | ✓ |
N consecutive heartbeat misses | Default: 3 | ✓ |
Gateway unreachable for N seconds | Default: 60 | ✓ |
WAN up but LAN unreachable | Asymmetric failure | ✓ |
All monitored hosts unreachable | Total LAN failure | ✓ |
Health Check Design
Lightweight, adaptive, CPU-aware:
┌─────────────────────────────────────────────────────────────────┐
│ ADAPTIVE FREQUENCY │
│ │
│ State: HEALTHY → Check every 60s │
│ State: CONCERNED → Check every 15s │
│ State: DEGRADED → Check every 5s │
│ State: EMERGENCY → Check every 2s (active response mode) │
│ │
│ CPU AWARENESS │
│ • If system load > 80%, halve check frequency │
│ • If memory < 10% free, disable non-critical checks │
│ • Never consume > 2% CPU for monitoring │
│ │
│ HYSTERESIS │
│ • Each check returns: OK (0), WARN (1), FAIL (2) │
│ • Aggregate score determines state transition │
│ • Need 3 consecutive same-state readings to transition │
└─────────────────────────────────────────────────────────────────┘Autonomous Actions
User configures what pfClaude can do WITHOUT asking:
Always Safe (default: enabled)
Action | Description |
Log events locally | Always on |
Send email notification | Alert user |
Update cloud beacon status | External visibility |
Capture diagnostic snapshot | Preserve state |
Diagnostic (default: enabled)
Action | Description |
Run connectivity tests | ping, traceroute |
Capture interface statistics | Counters, errors |
Gather recent log entries | Context for diagnosis |
Check service status | What's running/stopped |
Query ARP/NDP tables | Who's on the network |
Restorative (default: disabled)
Action | Description |
Restart specific interface | Often fixes link issues |
Flush connection state table | Clears stuck connections |
Restart DHCP service | Fixes lease issues |
Restart DNS resolver | Fixes resolution issues |
Clear ARP cache | Fixes stale entries |
Restart specific service | Configurable list |
Failover (default: disabled)
Action | Description |
Switch to backup WAN gateway | Major network change |
Enable/disable interface | Significant impact |
Apply emergency ruleset | Pre-configured safe rules |
Trigger CARP failover | HA environments |
Defensive (default: disabled)
Action | Description |
Block IPs exceeding threshold | Anti-DoS |
Enable emergency rate limiting | Protect resources |
Activate lockdown ruleset | Maximum security |
Disable non-essential services | Reduce attack surface |
Local Intelligence
Pattern Memory
{
"pattern_memory": {
"enabled": true,
"database": "/var/db/pfclaude/patterns.db",
"max_size_mb": 10,
"retention_days": 90
}
}Stores: "Last time X happened, Y was the cause"
Learns: "Interface restart fixed this 3/4 times"
Tracks: Normal baselines (traffic, latency, errors)
SQLite DB, <10MB footprint
Haiku Batch Analysis (optional)
{
"haiku_analysis": {
"enabled": true,
"schedule": "0 3 * * *",
"api_key_env": "PFCLAUDE_ANTHROPIC_KEY",
"sanitize": ["ip", "mac", "hostname"],
"max_log_lines": 1000
}
}Nightly batch: Send sanitized logs to Anthropic
Haiku analyzes patterns, anomalies, recommendations
Results stored locally as "learned insights"
Cost: ~$0.01/day for typical home network
Notification Channels
User configures their own escalation paths:
{
"notifications": {
"email": {
"enabled": true,
"smtp_server": "smtp.gmail.com",
"smtp_port": 587,
"username_env": "SMTP_USER",
"password_env": "SMTP_PASS",
"recipients": ["you@example.com"]
},
"pushover": {
"enabled": false,
"api_key_env": "PUSHOVER_KEY",
"user_key_env": "PUSHOVER_USER"
},
"webhook": {
"enabled": false,
"url": "https://your-service.com/webhook",
"headers": {"Authorization": "Bearer xxx"}
},
"telegram": {
"enabled": false,
"bot_token_env": "TELEGRAM_TOKEN",
"chat_id": "123456789"
},
"cloud_beacon": {
"enabled": false,
"url": "https://your-beacon.com/status",
"shared_secret_env": "BEACON_SECRET"
}
}
}Escalation Levels
Level | Actions |
INFO | Log only |
NOTICE | Log + cloud beacon |
WARNING | Log + cloud + email |
CRITICAL | Log + cloud + email + push + webhook |
EMERGENCY | ALL channels + repeated alerts until ack'd |
Email Commands
When WAN works but LAN doesn't, email becomes the control channel:
Command Format
To: pfclaude@your-pfsense.com
Subject: [PFCLAUDE:1234] status
Body: (optional context)Available Commands
Command | Description |
| Current state summary |
| What changed in last N minutes |
| Last N log lines |
| Run full diagnostic suite |
| Restart interface (if permitted) |
| List available commands |
Example Response
Subject: Re: [PFCLAUDE:1234] status
pfClaude Status Report
Generated: 2025-12-29 15:42:00 UTC
SYSTEM: DEGRADED (score: 4/10)
Interfaces:
WAN (igb0): UP - 98.2.1.45 - 12ms latency
LAN (igb1): UP - 192.168.1.1 - NO TRAFFIC 5min ← Problem
OPT1 (igb2): DOWN - disabled
Recent Events:
15:37 - LAN traffic dropped to zero
15:38 - DHCP requests stopped
15:40 - Watchdog entered CONCERNED state
Recommended: Check switch connectivity to LAN portCloud Beacon (optional)
For checking router status from anywhere:
{
"cloud_beacon": {
"enabled": true,
"url": "https://your-beacon-server.com/api/beacon",
"router_id": "home-pfsense",
"shared_secret_env": "BEACON_SECRET",
"frequency_healthy": 60,
"frequency_degraded": 15
}
}Self-Hosted Option
Docker image provided for running your own beacon receiver:
docker run -d -p 8080:8080 \
-e BEACON_SECRET=your-secret \
arktechnwa/pfclaude-beaconFeatures:
Receives status beacons from pfSense
Stores recent logs (configurable retention)
Web dashboard for status checks
Can relay commands back to pfSense
Beacon Protocol
POST /beacon
{
"router_id": "home-pfsense",
"timestamp": "2025-12-29T15:42:00Z",
"state": "healthy",
"score": 9,
"interfaces": {
"wan": {"status": "up", "ip": "98.2.1.45", "latency_ms": 12},
"lan": {"status": "up", "ip": "192.168.1.1", "clients": 15}
},
"recent_events": [],
"hmac": "..."
}Payload: <2KB, designed for minimal bandwidth.
MCP Tools
EVERYTHING pfSense can do, exposed via MCP:
System
Tool | Description | Permission |
| Hostname, version, uptime, resources | read |
| Overall health summary | read |
| Reboot pfSense | dangerous |
| Shutdown pfSense | dangerous |
| Export config XML | read |
Interfaces
Tool | Description | Permission |
| All interfaces with status | read |
| Detailed status for one | read |
| Traffic counters, errors | read |
| Restart interface | service |
| Enable interface | config |
| Disable interface | config |
Firewall
Tool | Description | Permission |
| List rules (filter, nat, etc) | read |
| Add rule | config |
| Delete rule | config |
| Modify rule | config |
| Connection state table | read |
| Clear state table | service |
| Manage aliases | config |
NAT
Tool | Description | Permission |
| Port forwards, outbound NAT | read |
| Add NAT rule | config |
| Delete NAT rule | config |
| Modify NAT rule | config |
DHCP
Tool | Description | Permission |
| Current leases | read |
| Reserved IPs | read |
| DHCP server config | config |
| Restart DHCP | service |
DNS
Tool | Description | Permission |
| Unbound config | config |
| dnsmasq config | config |
| Add host override | config |
| Delete host override | config |
| Restart DNS | service |
VPN
Tool | Description | Permission |
| OpenVPN connections | read |
| IPsec SAs | read |
| WireGuard peers | read |
| Disconnect client/tunnel | service |
Routing
Tool | Description | Permission |
| Routing table | read |
| Static routes | config |
| Gateway health | read |
| Switch default gateway | config |
Traffic
Tool | Description | Permission |
| Bandwidth graphs data | read |
| Interface totals | read |
| Top talkers | read |
Logs
Tool | Description | Permission |
| System logs | read |
| Firewall logs | read |
| DHCP logs | read |
| VPN logs | read |
| Search across all logs | read |
Packages
Tool | Description | Permission |
| Installed packages | read |
| Available packages | read |
| Install package | dangerous |
| Remove package | dangerous |
Services
Tool | Description | Permission |
| All services status | read |
| Start service | service |
| Stop service | service |
| Restart service | service |
Diagnostics
Tool | Description | Permission |
| Ping from pfSense | read |
| Traceroute from pfSense | read |
| DNS lookup from pfSense | read |
| ARP table | read |
| IPv6 neighbor table | read |
| Open sockets | read |
| Real-time state table | read |
Permission Matrix
Granular control via pfSense WebGUI:
Permission Levels
Level | Description |
| View status, logs, configuration |
| Restart services, flush caches |
| Modify configuration |
| Reboot, shutdown, package management |
WebGUI Configuration
┌─────────────────────────────────────────────────────────────────┐
│ pfClaude > Settings > Permissions │
├─────────────────────────────────────────────────────────────────┤
│ │
│ MCP API Permissions │
│ ─────────────────────────────────────────────────────────────── │
│ │
│ READ OPERATIONS [Select All] [Clear] │
│ ☑ System info & status │
│ ☑ Interface status & stats │
│ ☑ Firewall rules (view) │
│ ☑ DHCP leases │
│ ☑ Logs (all) │
│ ☑ Diagnostics (ping, traceroute, etc) │
│ │
│ SERVICE CONTROL [Select All] [Clear] │
│ ☐ Restart interfaces │
│ ☐ Restart services (DHCP, DNS, etc) │
│ ☐ Flush state table │
│ ☐ Clear caches │
│ │
│ CONFIGURATION CHANGES [Select All] [Clear] │
│ ☐ Modify firewall rules │
│ ☐ Modify NAT rules │
│ ☐ Modify DHCP settings │
│ ☐ Add/remove static routes │
│ │
│ DANGEROUS OPERATIONS [Select All] [Clear] │
│ ☐ System reboot │
│ ☐ System shutdown │
│ ☐ Install/remove packages │
│ ☐ Gateway failover │
│ │
│ ─────────────────────────────────────────────────────────────── │
│ ☐ BYPASS ALL PERMISSIONS (danger mode) │
│ │
│ [Save] [Reset to Defaults] │
└─────────────────────────────────────────────────────────────────┘Storage & Hygiene
{
"storage": {
"email_queue": {
"max_messages": 100,
"max_age_days": 10,
"cleanup_schedule": "0 4 * * *"
},
"logs": {
"pfclaude_events_days": 7,
"diagnostic_snapshots_days": 3
},
"pattern_memory": {
"persistent": true,
"compact_schedule": "0 5 * * 0"
},
"total_footprint_mb": 50
}
}Installation
pfSense Package
System > Package Manager > Available Packages > pfClaudeOr manual:
pkg add https://github.com/ArktechNWA/pfsense-mcp/releases/latest/pfsense.pkgMCP Server (Claude Code side)
npm install -g @arktechnwa/pfsense-mcpClaude Code Integration
{
"mcpServers": {
"pfsense": {
"command": "pfsense-mcp",
"env": {
"PFSENSE_HOST": "192.168.1.1",
"PFSENSE_API_KEY": "your-api-key"
}
}
}
}Requirements
pfSense Side
pfSense 2.7+ or pfSense Plus 23.09+
50MB free storage
Network connectivity (obviously)
Claude Code Side
Node.js 18+
Network access to pfSense
Optional
Anthropic API key (for Haiku batch analysis)
SMTP server (for email notifications)
Self-hosted beacon server (for cloud status)
Security Considerations
API key authentication — No unauthenticated access
HTTPS required — Encrypted transport
IP whitelist — Restrict to known Claude IPs
Rate limiting — Prevent brute force
Email PIN — Authenticate inbound commands
Permission matrix — User controls exposure
Audit logging — All actions logged
No default dangerous permissions — User must enable
Credits
Created by Claude (claude@arktechnwa.com) in collaboration with Meldrey. Part of the ArktechNWA MCP Toolshed.
Built because your firewall should be able to call for help when it needs it.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ArkTechNWA/pfsense-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server