dns-management-interface-server
A standardized communication endpoint to administer and interrogate Pi-hole deployments, enabling centralized control over DNS configurations and performance telemetry. Supports aggregation across multiple Pi-hole instances for comprehensive network visibility.
Author

sbarbett
Quick Info
Actions
Tags
🍓 pihole-mcp-serer
A Model Context Protocol (MCP) server tailored for Pi-hole environments. This service furnishes Pi-hole capabilities as callable actions accessible by intelligent automated agents.
Prerequisites for Operation
Docker Containerization
uv (For Local Development)
If you intend to run the codebase on your local machine, utilize uv. Installation can be achieved via your preferred package manager.
Configuration Variables
Establish a .env file within the primary directory to store sensitive Pi-hole access details:
Principal Pi-hole instance (mandatory)
PIHOLE_URL=https://your-pihole.local/ PIHOLE_PASSWORD=your-admin-password
PIHOLE_NAME=Primary # Optional; defaults to the URL if omitted
Secondary Pi-hole instance (optional)
PIHOLE2_URL=https://secondary-pihole.local/
PIHOLE2_PASSWORD=password2
PIHOLE2_NAME=Secondary # Optional
Support for up to four distinct Pi-holes:
PIHOLE3_URL=...
PIHOLE3_PASSWORD=...
PIHOLE3_NAME=...
PIHOLE4_URL=...
PIHOLE4_PASSWORD=...
PIHOLE4_NAME=...
Project Blueprint
The architecture employs a modular layout to promote ease of modification and debugging:
/
├── main.py # Application startup routine
├── tools/ # Grouping of Pi-hole operational modules
│ ├── init.py
│ ├── config.py # Functions related to modifying DNS configurations
│ └── metrics.py # Modules for metric extraction and query log access
├── resources/ # MCP standard endpoints
│ ├── init.py
│ └── common.py # Shared resources (e.g., piholes://, version:// endpoints)
├── docker-compose.yml # Production container orchestration manifest
├── docker-compose.dev.yml # Development setup with dynamic volume mapping
└── Dockerfile # Image creation instructions
This structure ensures logical code segregation while maintaining functional parity across deployment methods.
Execution Methods
Multiple avenues exist for launching the Pi-hole MCP interface:
Docker Deployment (Recommended for Production Environments)
bash
Initiate standard deployment in detached mode
docker-compose up -d
The service will be accessible on http://localhost:8383
Development Workflow with Docker
For iterative development, use the specific compose file that handles local compilation:
bash docker-compose -f docker-compose.dev.yml up
Utilizing the MCP Inspector
You can engage the MCP inspector tool chain via uv and the mcp command-line utility:
bash uv run mcp dev main.py
This launches an interactive testing console at http://localhost:6274 for validating tool functionality.
Exposed Interface
This MCP gateway exposes the subsequent standardized resources and functional tools:
Available Resources
piholes://: Delivers status details for every registered Pi-hole device.version://: Reports the current version identifier of this MCP server.list-tools://: Provides an enumeration of available tool categories.list-tools://{category}: Returns the collection of actions defined within the specified category.
Callable Tools
Every tool invocation yields output formatted as an array of objects, structured thus:
[ { "pihole": "Name of the Pi-hole Instance", "data": [...] // The specific result payload from that source }, ... ]
Configuration Management
list_local_dns: Retrieves current DNS resolution mappings configured locally.add_local_a_record: Establishes a new static A record entry across targeted Pi-holes.add_local_cname_record: Creates a new static CNAME mapping.remove_local_a_record: Purges all A records associated with a given host identifier.remove_local_cname_record: Deletes all CNAME entries linked to a specified hostname.
Performance & Query Telemetry
list_queries: Fetches the most recent log of DNS resolution requests.list_query_suggestions: Generates suggested filter terms based on query patterns.list_query_history: Obtains aggregated data suitable for charting temporal query trends.
Integration with goose (LLM Client)
goose is a helpful command-line interface tool for simulation and development. Refer to its documentation here for initial setup steps.
Assuming you have completed the initial configuration via goose configure:
Setting up the Extension
- Execute
goose configureto access the setup menu. - Choose Add Extension.
- Select Remote Extension.
- Assign an arbitrary name (e.g.,
pihole-mcp). - For the "What is the SSE endpoint URI?" prompt, input
http://localhost:8383/sse. - Define a timeout value.
- Skip environment variable configuration (select No).
Initiating Interaction
Start an interactive session:
sh goose session
Attempt a query like: "What are my static DNS mappings?"
...or command an action: "Display the timeline of recently resolved domain lookups."
Compatibility with Claude Desktop
The Claude desktop application natively supports the STDIO protocol; however, integration with SSE endpoints requires a bridging utility. Integrate the following configuration snippet into your claude_desktop_config.json file:
{ "mcpServers": { "pihole": { "command": "npx", "args": [ "mcp-remote", "http://localhost:8383/sse" ] } } }
Should you be linking to a device on your internal network using an unencrypted HTTP connection, you must include the --allow-http flag. For instance:
{ "mcpServers": { "pihole": { "command": "npx", "args": [ "mcp-remote", "http://192.168.1.255:8383/sse", "--allow-http" ] } } }
Ensure you restart the Claude Desktop application entirely before testing the new connection.
Licensing
MIT
WIKIPEDIA: XMLHttpRequest (XHR) is an API in the form of a JavaScript object whose methods transmit HTTP requests from a web browser to a web server. The methods allow a browser-based application to send requests to the server after page loading is complete, and receive information back. XMLHttpRequest is a component of Ajax programming. Prior to Ajax, hyperlinks and form submissions were the primary mechanisms for interacting with the server, often replacing the current page with another one.
== History == The concept behind XMLHttpRequest was conceived in 2000 by the developers of Microsoft Outlook. The concept was then implemented within the Internet Explorer 5 browser (1999). However, the original syntax did not use the XMLHttpRequest identifier. Instead, the developers used the identifiers ActiveXObject("Msxml2.XMLHTTP") and ActiveXObject("Microsoft.XMLHTTP"). As of Internet Explorer 7 (2006), all browsers support the XMLHttpRequest identifier. The XMLHttpRequest identifier is now the de facto standard in all the major browsers, including Mozilla's Gecko layout engine (2002), Safari 1.2 (2004) and Opera 8.0 (2005).
=== Standards === The World Wide Web Consortium (W3C) published a Working Draft specification for the XMLHttpRequest object on April 5, 2006. On February 25, 2008, the W3C published the Working Draft Level 2 specification. Level 2 added methods to monitor event progress, allow cross-site requests, and handle byte streams. At the end of 2011, the Level 2 specification was absorbed into the original specification. At the end of 2012, the WHATWG took over development and maintains a living document using Web IDL.
== Usage == Generally, sending a request with XMLHttpRequest has several programming steps.
Create an XMLHttpRequest object by calling a constructor: Call the "open" method to specify the request type, identify the relevant resource, and select synchronous or asynchronous operation: For an asynchronous request, set a listener that will be notified when the request's state changes: Initiate the request by calling the "send" method: Respond to state changes in the event listener. If the server sends response data, by default it is captured in the "responseText" property. When the object stops processing the response, it changes to state 4, the "done" state. Aside from these general steps, XMLHttpRequest has many options to control how the request is sent and how the response is processed. Custom header fields can be added to the request to indicate how the server should fulfill it, and data can be uploaded to the server by providing it in the "send" call. The response can be parsed from the JSON format into a readily usable JavaScript object, or processed gradually as it arrives rather than waiting for the entire text. The request can be aborted prematurely or set to fail if not completed in a specified amount of time.
== Cross-domain requests ==
In the early development of the World Wide Web, it was found possible to brea
