pihole-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| PIHOLE_URL | Yes | The URL of the Pi-hole server | |
| PIHOLE_PASSWORD | Yes | The application password for Pi-hole API authentication, created in the Pi-hole Web UI under Settings > Web Interface > 'Application password' > Generate |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_statsA | Summary statistics (total/blocked queries, percentage, unique domains, clients). Pass from_ts and until_ts (Unix timestamps) to query the long-term database for any range. |
| get_top_blockedB | Top blocked domains by query count. from_ts/until_ts switch to the long-term database. |
| get_top_permittedB | Top allowed domains by query count. from_ts/until_ts switch to the long-term database. |
| get_top_clientsB | Top clients by query count (blocked=true ranks by blocked queries). from_ts/until_ts use the long-term database. |
| get_query_typesB | Breakdown of DNS query types (A, AAAA, PTR, SRV, etc). from_ts/until_ts use the long-term database. |
| get_forward_destinationsB | Upstream DNS server stats (which forwarders served how many queries). from_ts/until_ts use the long-term database. |
| get_recent_blockedC | Recently blocked domains. |
| get_historyC | Time-series activity: allowed/blocked/other counts per bucket. from_ts/until_ts use the long-term database. |
| get_client_historyA | Per-client query time series for the top from_ts/until_ts query the long-term database instead (count is then ignored). |
| get_query_logA | Fetch DNS queries with optional filters (wildcards * supported on text filters). Filters:
|
| get_query_suggestionsA | Get available filter values for the query log (domains, clients, upstreams, types, statuses). |
| get_blocking_statusA | Check if Pi-hole DNS blocking is enabled. Returns status and any active timer. |
| enable_blockingA | Enable DNS blocking immediately. |
| disable_blockingA | Disable DNS blocking. If duration_seconds is given, re-enables after that timer; otherwise indefinite. |
| get_whitelistA | List all exact-match allowed domains. |
| get_blacklistA | List all exact-match blocked domains. |
| add_to_whitelistC | Add a domain to the allow list (whitelist). |
| add_to_blacklistC | Add a domain to the deny list (blacklist). |
| remove_from_whitelistB | Remove a domain from the allow list. |
| remove_from_blacklistB | Remove a domain from the deny list. |
| list_domainsA | List domain-list entries, optionally narrowed to allow/deny and exact/regex. kind requires domain_type. |
| add_domainC | Add an exact domain or a regex to the allow or deny list. groups are group IDs (default group 0). |
| update_domainC | Update a domain-list entry: move it between lists, change comment, groups, or enabled state. |
| remove_domainC | Remove an exact domain or regex from the allow or deny list. |
| list_local_dnsA | List local DNS entries (hosts and CNAME records). |
| add_local_a_recordA | Add a local A record (host -> IP). Replaces any existing entry for the same host. |
| remove_local_a_recordB | Remove any local A record matching the given host. |
| add_local_cname_recordA | Add a local CNAME record (host -> target). Replaces any existing CNAME for the same host. |
| remove_local_cname_recordB | Remove any local CNAME record for the given host. |
| update_gravityA | Refresh Pi-hole gravity (download adlists). Takes a minute or more. Returns the last output_lines lines of the gravity run. Reports cleanly if a run is already in progress. |
| flush_cacheA | Flush the DNS cache. Pi-hole v6 has no separate cache-flush endpoint, so this restarts the DNS resolver. |
| restart_dnsA | Restart the DNS resolver (brief DNS outage, clears cache). Preview unless confirm=true. |
| flush_logsA | Clear the Pi-hole query log. |
| flush_arpA | Flush the ARP cache of the Pi-hole host. Preview unless confirm=true. |
| flush_networkA | Clear Pi-hole's network device table (device history is lost). Preview unless confirm=true. |
| get_tail_logA | Get the last Pass next_id from a previous response to get only newer entries. |
| export_teleporterA | Download a Teleporter backup zip of all Pi-hole settings and lists into output_dir. The archive contains the password hash, so store it securely. Existing files are never overwritten. |
| search_domainA | Explain why a domain is blocked or allowed: shows matching domain-list entries, regexes, and adlists (gravity), with the groups each applies to. partial=true also matches substrings. max_results caps results per category. |
| list_adlistsB | List subscribed adlists (block lists and allow lists) with status and domain counts. |
| add_adlistA | Subscribe to an adlist URL. Run update_gravity afterwards to download it. |
| update_adlistB | Change an adlist's comment, groups, or enabled state. Run update_gravity to apply. |
| remove_adlistA | Unsubscribe from an adlist. Preview unless confirm=true. Run update_gravity afterwards. |
| list_groupsB | List groups. Groups tie clients to domain lists and adlists for per-device policy. |
| add_groupC | Create a group. |
| update_groupC | Rename a group or change its comment or enabled state. |
| remove_groupA | Delete a group. Preview unless confirm=true. |
| list_clientsA | List configured clients (IP, MAC, hostname, CIDR, or interface) and their groups. |
| get_client_suggestionsB | Clients seen on the network that are not yet configured, as candidates for add_client. |
| add_clientC | Configure a client by IP, MAC, hostname, CIDR subnet, or :interface, and assign group IDs. |
| update_clientC | Change a configured client's comment or group IDs. |
| remove_clientB | Remove a configured client (it falls back to the default group). |
| get_versionA | Installed and latest available versions of Pi-hole core, web, FTL, and Docker tag. |
| get_system_infoB | Host uptime, memory, swap, CPU load, and process count. |
| get_host_infoB | Host hardware model, kernel, and OS details. |
| get_sensorsA | Temperature sensor readings and the configured hot limit. |
| get_ftl_infoB | FTL process status: PID, uptime, privacy level, client and gravity counts, query frequency. |
| get_database_infoB | Long-term query database size, query count, and SQLite version. |
| get_metricsB | DNS cache and DHCP metrics (cache size, insertions, evictions, reply types). |
| get_messagesB | Pi-hole diagnostic warnings (rate limiting, load, DNSMASQ errors, list issues). |
| delete_messageB | Dismiss one diagnostic message by ID. |
| get_paddB | Compact dashboard in one call (PADD data): blocking, stats, top items, system, versions. |
| list_network_devicesC | Pi-hole's network table: MAC address, vendor, IPs, hostnames, first/last seen, query count. |
| delete_network_deviceA | Remove one device from the network table by its ID. Preview unless confirm=true. |
| get_gatewayA | Default gateway address and interface (detailed=true includes routes and interfaces). |
| get_routesC | Routing table of the Pi-hole host. |
| get_interfacesC | Network interfaces of the Pi-hole host with addresses and traffic counters. |
| list_dhcp_leasesA | Active DHCP leases (only populated when Pi-hole's DHCP server is enabled). |
| remove_dhcp_leaseA | Remove a DHCP lease by IP. Preview unless confirm=true. |
| get_configA | Read Pi-hole settings. element narrows to a section or key, e.g. 'dns', 'dns.upstreams', 'dhcp'. detailed=true adds descriptions, allowed values, and defaults. Password hashes and the TOTP secret are redacted. |
| update_configA | Set a Pi-hole setting, e.g. element='dns.upstreams', value=['9.9.9.9']. Preview (current value) unless confirm=true. Some settings restart FTL; restart=false defers that. Authentication settings (webserver.api.*) are refused. |
| add_config_itemB | Append one value to an array setting, e.g. element='dns.upstreams', value='1.1.1.1'. Preview unless confirm=true. |
| remove_config_itemA | Remove one value from an array setting. Preview unless confirm=true. |
| server_infoA | Return chris2ao-pihole-mcp server version, configured Pi-hole URL, and tool count. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 73 tools
Most tools have distinct resource/action purposes, but there is substantial overlap between the legacy whitelist/blacklist tools (get_whitelist, add_to_whitelist, remove_from_whitelist, etc.) and the newer domain-list tools (list_domains, add_domain, remove_domain). Descriptions clarify each individually, but do not guide which set to prefer, creating real misselection risk.
The set overwhelmingly follows a verb_noun convention (get_*, list_*, add_*, update_*, remove_*, delete_*, flush_*), making names predictable. Minor deviations exist: server_info lacks a verb, and add_to_whitelist/remove_from_whitelist use a different preposition pattern than add_domain/remove_domain.
73 tools is far beyond the typical 3-15 range and is extreme for a single Pi-hole instance. The count is inflated by fine-grained maintenance operations (flush_arp, flush_network, flush_cache, restart_dns) and duplicate whitelist/domain-list management surfaces.
The surface is very comprehensive, covering stats, query logs, adlists, groups, clients, DHCP, network, config, local DNS, system info, and maintenance. Minor gaps remain, such as no Teleporter import (only export) and no dedicated update for local A/CNAME records (add replaces instead).