Enables control of Pi-hole v6 ad blocking and real-time statistics retrieval.
Pi-hole MCP Server
WARNING!!: Currently works only when this MCP server and AI client are on the same machine. Need to figure out why it doesn't approve request from other machines in local network.
An MCP (Model Context Protocol) server for controlling Pi-hole ad blocking.
Note: This server is configured for Pi-hole v6 with REST API authentication using app passwords.
Configuration
The server uses a config.json file for configuration. Create this file in the project root:
{
"server": {
"mode": "stdio",
"port": 5000
},
"pihole": {
"base_url": "http://192.168.68.59:8081/api"
}
}
Configuration Options
server.mode: Server mode -"stdio"(default) or"port"server.port: Port number when using port mode (default: 5000)pihole.base_url: Pi-hole API base URL (default: "http://192.168.68.59:8081/api")
Setup
- Ensure your Pi-hole has an app password configured (Settings > API > App Password)
- Set the environment variable with your app password:
export PIHOLE_APP_PASSWORD=your_app_password_here - Configure the server mode in
config.json
Running
Stdio Mode (Default)
Run the server in stdio mode (for MCP clients):
python main.py
Port Mode
Set "mode": "port" in config.json and run:
python main.py
The server will start on the configured port (default: 5000) using Server-Sent Events (SSE).
Or use the VS Code task: Ctrl+Shift+P > Tasks: Run Task > Run Python Script
Running with Docker
Prerequisites
- Docker and Docker Compose installed
- Pi-hole app password configured
Setup
- Ensure your
config.jsonis configured for your environment - Set the Pi-hole app password as an environment variable:
export PIHOLE_APP_PASSWORD=your_app_password_here
Running
# Build and start the container
docker-compose up --build
# Or run in background
docker-compose up -d --build
Configuration
The container uses the config.json file mounted as a volume. You can modify the configuration file and restart the container:
docker-compose restart
Logs
# View logs
docker-compose logs -f
# View logs for specific service
docker-compose logs -f pihole-mcp
Cleanup
# Stop and remove containers
docker-compose down
# Remove containers and volumes
docker-compose down -v
# Remove images
docker-compose down --rmi all
Tools
get_pihole_status: Get current Pi-hole blocking status (enabled/disabled)get_pihole_summary: Get Pi-hole statistics summary (queries, blocked domains, etc.)enable_pihole: Enable ad blocking permanentlydisable_pihole: Disable ad blocking (optional duration in seconds)
API Details
This implementation uses Pi-hole v6 REST API with session-based authentication:
- Authentication: POST to
/api/authwith app password - Status: GET
/api/dns/blocking - Summary: GET
/api/stats/summary - Control: POST to
/api/dns/blockingwith JSON payload
Testing
Run unit tests (mocked):
python -m pytest test_main.py::TestPiHoleMCP -v
Run configuration tests:
python -m pytest test_main.py::TestConfiguration -v
Run integration tests (requires PIHOLE_APP_PASSWORD and will actually control Pi-hole):
export PIHOLE_APP_PASSWORD=your_app_password
python -m pytest test_main.py::TestPiHoleIntegration -v -s
Warning: Integration tests will enable/disable Pi-hole blocking. Use with caution!
Debugging
Open main.py, press F5 or use the Run and Debug panel.
Tools (4)
get_pihole_statusGet current Pi-hole blocking status (enabled/disabled)get_pihole_summaryGet Pi-hole statistics summary (queries, blocked domains, etc.)enable_piholeEnable ad blocking permanentlydisable_piholeDisable ad blocking (optional duration in seconds)Environment Variables
PIHOLE_APP_PASSWORDrequiredApp password configured in Pi-hole Settings > API > App PasswordConfiguration
{
"mcpServers": {
"pihole": {
"command": "python",
"args": ["/path/to/pihole-mcp/main.py"],
"env": {
"PIHOLE_APP_PASSWORD": "your_app_password_here"
}
}
}
}