Read-only pfSense MCP server using authenticated WebGUI scraping
18 tools with consistent naming (verb_noun pattern), clear descriptions (avg 85 chars), and proper JSON schemas with typed parameters. All tools are read-only with correct annotations. However, output schemas are not documented, LLMs cannot predict response structure. Parameter descriptions are minimal (often single phrases). Error handling returns generic dicts without recovery guidance. No pagination support despite tools returning lists. Missing parameter constraints (enums, ranges) for filter parameters like 'action', 'protocol', 'interface'.
Return a bounded health report for pfSense system status.
Return safe pfSense WebGUI login status metadata without secret values.
Return a bounded diagnostic report for a single host IP address.
Return JSON-serializable bounded configuration references.
Return JSON-serializable read-only ARP table entries.
Return a bounded partial-failure-aware configuration summary.
Output schemas not documented. LLMs cannot predict response structure (field names, types, nesting). Tools return 'list[dict[str, object]]' or 'dict[str, object]', completely opaque to agents.
Filter parameters lack enums and constraints. 'action' in get_firewall_logs accepts 'pass|block|reject' but is documented as free-form string. 'protocol' and 'interface' similarly unconstrained. LLMs will hallucinate invalid values.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 53 | 2026-07-28+ | v2 |
Return JSON-serializable read-only DHCP lease entries.
Return JSON-serializable read-only firewall aliases.
Return JSON-serializable read-only firewall log entries.
Return read-only firewall rules.
Return JSON-serializable read-only firewall state entries.
Return JSON-serializable configured gateway groups.
Return JSON-serializable configured gateways and monitor state.
Return JSON-serializable read-only NAT port-forward definitions.
Return JSON-serializable outbound NAT mode and rules.
Return JSON-serializable configured static routes.
Return JSON-serializable secret-minimized WireGuard status.
Return authoritative firewall interface display-name/token mappings.
No pagination support. Tools returning lists (get_firewall_logs, get_firewall_states, get_arp_table) accept 'limit' but no offset/cursor. Large result sets will blow context window. No total_count or next_cursor returned.
Error handling returns generic dicts without recovery guidance. Exception caught as 'broad-exception-caught' and returned as {'error_type': exc.__class__.__name__}. LLM cannot determine if error is retryable, user-fixable, or fatal.
Parameter descriptions are minimal single phrases. 'Optional IP address filter' and 'Maximum number of entries to return' lack format/range guidance. No hints on valid IP formats, whether CIDR is accepted, or why limit defaults to 200.