# 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:
```json
{
"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
1. Ensure your Pi-hole has an app password configured (Settings > API > App Password)
2. Set the environment variable with your app password:
```bash
export PIHOLE_APP_PASSWORD=your_app_password_here
```
3. Configure the server mode in `config.json`
## Running
### Stdio Mode (Default)
Run the server in stdio mode (for MCP clients):
```bash
python main.py
```
### Port Mode
Set `"mode": "port"` in `config.json` and run:
```bash
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
1. Ensure your `config.json` is configured for your environment
2. Set the Pi-hole app password as an environment variable:
```bash
export PIHOLE_APP_PASSWORD=your_app_password_here
```
### Running
```bash
# 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:
```bash
docker-compose restart
```
### Logs
```bash
# View logs
docker-compose logs -f
# View logs for specific service
docker-compose logs -f pihole-mcp
```
### Cleanup
```bash
# 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 permanently
- `disable_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/auth` with app password
- Status: GET `/api/dns/blocking`
- Summary: GET `/api/stats/summary`
- Control: POST to `/api/dns/blocking` with JSON payload
## Testing
Run unit tests (mocked):
```bash
python -m pytest test_main.py::TestPiHoleMCP -v
```
Run configuration tests:
```bash
python -m pytest test_main.py::TestConfiguration -v
```
Run integration tests (requires PIHOLE_APP_PASSWORD and will actually control Pi-hole):
```bash
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.