Unified Pi-hole v6 MCP server consolidating tools from three upstream MCPs
Strong naming conventions (verb_noun pattern across all 29 tools). Descriptions present and actionable (avg ~80 chars, well within 10-1024 range). Input schemas fully visible with proper JSON Schema types and descriptions. Output schemas not documented, a significant gap for agent planning. Error handling minimal; no recovery guidance or categorization. Security: credentials injected server-side via PiholeConfig (good), but no permission gates or audit logging. Composition is clean, each tool has single responsibility, though some read-only tools could batch (e.g., get_top_blocked + get_top_permitted as one call with filters).
Add a local A record (host -> IP). Replaces any existing entry for the same host.
Add a local CNAME record (host -> target). Replaces any existing CNAME for the same host.
Add a domain to the deny list (blacklist).
Add a domain to the allow list (whitelist).
Disable DNS blocking. If duration_seconds is given, re-enables after that timer; otherwise indefinite.
Enable DNS blocking immediately.
Output schemas not documented. LLMs cannot plan downstream tool calls or extract required fields (e.g., what fields does get_query_log return? Does it include pagination cursors?). Agents must guess structure.
No error handling or recovery guidance. Tools return raw API responses without categorizing errors as retryable, user-fixable, or fatal. E.g., if add_to_whitelist fails, the LLM has no guidance on whether to retry or ask the user.
Destructive operations (flush_logs, flush_cache, disable_blocking) lack confirmation or dry-run support. Agents can irreversibly delete query logs without a safety gate.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | 2026-07-28+ | v2 |
Flush the Pi-hole DNS cache.
Clear the Pi-hole query log.
List all exact-match blocked domains.
Check if Pi-hole DNS blocking is enabled. Returns status and any active timer.
Upstream DNS server stats (which forwarders served how many queries).
Time-series activity graph: timestamps, allowed/blocked/other counts per bucket.
Fetch recent DNS queries with optional filters. Filters: - length: number of queries (default 100) - from_ts / until_ts: Unix timestamps - domain: exact or wildcard (*) domain match - client_ip: exact or wildcard (*) client IP match - upstream: one of 'cache', 'blocklist', 'permitted' - cursor: pagination cursor from previous response
Get available filter values for the query log (domains, clients, upstreams, types, statuses).
Breakdown of DNS query types (A, AAAA, PTR, SRV, etc).
Recently blocked domains.
Get summary statistics (total queries, blocked queries, blocking percentage, unique domains, clients).
Get the tail of a Pi-hole log file. log must be one of 'dnsmasq', 'ftl', 'webserver'.
Get top blocked domains by query count.
Get top clients by query count. Set blocked=true for top clients by blocked query count.
Get top allowed (permitted) domains by query count.
List all exact-match allowed domains.
List local DNS entries (hosts and CNAME records).
Remove a domain from the deny list.
Remove a domain from the allow list.
Remove any local A record matching the given host.
Remove any local CNAME record for the given host.
Return chris2ao-pihole-mcp server version, configured Pi-hole URL, and tool count.
Refresh Pi-hole gravity (adlist database). Takes a minute or more to complete.
No permission gates or audit logging. Any agent with access to this server can modify DNS, disable blocking, or clear logs. No trace of who called what or when.
Pagination not implemented for list tools. get_whitelist, get_blacklist, list_local_dns return all results without limit or cursor. Large lists will blow context windows.