pfClaude
Enables bidirectional control and monitoring of pfSense firewalls through Claude, with full API access for configuration and diagnostics, plus autonomous emergency response capabilities when network connectivity is lost.
README
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] status
- Sender 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 |
|---|---|
status |
Current state summary |
changes <N>m |
What changed in last N minutes |
logs <N> |
Last N log lines |
diagnose |
Run full diagnostic suite |
restart <iface> |
Restart interface (if permitted) |
help |
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 port
Cloud 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-beacon
Features:
- 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 |
|---|---|---|
pf_system_info |
Hostname, version, uptime, resources | read |
pf_system_status |
Overall health summary | read |
pf_system_reboot |
Reboot pfSense | dangerous |
pf_system_shutdown |
Shutdown pfSense | dangerous |
pf_system_config_backup |
Export config XML | read |
Interfaces
| Tool | Description | Permission |
|---|---|---|
pf_interface_list |
All interfaces with status | read |
pf_interface_status |
Detailed status for one | read |
pf_interface_stats |
Traffic counters, errors | read |
pf_interface_restart |
Restart interface | service |
pf_interface_enable |
Enable interface | config |
pf_interface_disable |
Disable interface | config |
Firewall
| Tool | Description | Permission |
|---|---|---|
pf_firewall_rules |
List rules (filter, nat, etc) | read |
pf_firewall_rule_add |
Add rule | config |
pf_firewall_rule_delete |
Delete rule | config |
pf_firewall_rule_modify |
Modify rule | config |
pf_firewall_states |
Connection state table | read |
pf_firewall_states_flush |
Clear state table | service |
pf_firewall_aliases |
Manage aliases | config |
NAT
| Tool | Description | Permission |
|---|---|---|
pf_nat_rules |
Port forwards, outbound NAT | read |
pf_nat_rule_add |
Add NAT rule | config |
pf_nat_rule_delete |
Delete NAT rule | config |
pf_nat_rule_modify |
Modify NAT rule | config |
DHCP
| Tool | Description | Permission |
|---|---|---|
pf_dhcp_leases |
Current leases | read |
pf_dhcp_static_mappings |
Reserved IPs | read |
pf_dhcp_config |
DHCP server config | config |
pf_dhcp_service_restart |
Restart DHCP | service |
DNS
| Tool | Description | Permission |
|---|---|---|
pf_dns_resolver_config |
Unbound config | config |
pf_dns_forwarder_config |
dnsmasq config | config |
pf_dns_override_add |
Add host override | config |
pf_dns_override_delete |
Delete host override | config |
pf_dns_service_restart |
Restart DNS | service |
VPN
| Tool | Description | Permission |
|---|---|---|
pf_vpn_openvpn_status |
OpenVPN connections | read |
pf_vpn_ipsec_status |
IPsec SAs | read |
pf_vpn_wireguard_status |
WireGuard peers | read |
pf_vpn_disconnect |
Disconnect client/tunnel | service |
Routing
| Tool | Description | Permission |
|---|---|---|
pf_routes_table |
Routing table | read |
pf_routes_static |
Static routes | config |
pf_gateway_status |
Gateway health | read |
pf_gateway_switch |
Switch default gateway | config |
Traffic
| Tool | Description | Permission |
|---|---|---|
pf_traffic_graphs |
Bandwidth graphs data | read |
pf_traffic_totals |
Interface totals | read |
pf_traffic_top |
Top talkers | read |
Logs
| Tool | Description | Permission |
|---|---|---|
pf_logs_system |
System logs | read |
pf_logs_firewall |
Firewall logs | read |
pf_logs_dhcp |
DHCP logs | read |
pf_logs_vpn |
VPN logs | read |
pf_logs_search |
Search across all logs | read |
Packages
| Tool | Description | Permission |
|---|---|---|
pf_packages_installed |
Installed packages | read |
pf_packages_available |
Available packages | read |
pf_packages_install |
Install package | dangerous |
pf_packages_remove |
Remove package | dangerous |
Services
| Tool | Description | Permission |
|---|---|---|
pf_services_list |
All services status | read |
pf_services_start |
Start service | service |
pf_services_stop |
Stop service | service |
pf_services_restart |
Restart service | service |
Diagnostics
| Tool | Description | Permission |
|---|---|---|
pf_diag_ping |
Ping from pfSense | read |
pf_diag_traceroute |
Traceroute from pfSense | read |
pf_diag_dns_lookup |
DNS lookup from pfSense | read |
pf_diag_arp_table |
ARP table | read |
pf_diag_ndp_table |
IPv6 neighbor table | read |
pf_diag_sockets |
Open sockets | read |
pf_diag_pftop |
Real-time state table | read |
Permission Matrix
Granular control via pfSense WebGUI:
Permission Levels
| Level | Description |
|---|---|
read |
View status, logs, configuration |
service |
Restart services, flush caches |
config |
Modify configuration |
dangerous |
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 > pfClaude
Or manual:
pkg add https://github.com/ArktechNWA/pfsense-mcp/releases/latest/pfsense.pkg
MCP Server (Claude Code side)
npm install -g @arktechnwa/pfsense-mcp
Claude 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.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。