关于 Pi-hole MCP Server
Pi-hole MCP Server 是用于通过 AI 客户端管理 Pi-hole v6 的 Go 服务,涵盖 DNS、域名、查询、DHCP 和系统管理,并支持只读范围控制及多实例比较与同步。
主要功能
- 01管理 DNS、域名和拦截列表
- 02分析查询日志与统计数据
- 03配置客户端和 DHCP
- 04通过只读模式限定工具
- 05比较并同步多个实例
适用场景
- 01检查被拦截的域名和查询活动
- 02管理本地 DNS 与 DHCP 设置
- 03将 AI 客户端限制为只读工具
- 04比较并协调多个 Pi-hole 实例
MCP 相关
它将 Pi-hole v6 操作作为 MCP 工具、提示词和资源提供给 AI 客户端。工具集和只读模式可控制可用操作。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
docker run -i --rm -e PIHOLE_URL -e PIHOLE_PASSWORD -e TZ -e PIHOLE_READ_ONLY -e PIHOLE_TLS_SKIP_VERIFY -e PIHOLE_REQUEST_TIMEOUT -e PIHOLE_MAX_RETRIES -e PIHOLE_RETRY_MAX_DELAY ghcr.io/hexamatic/pihole-mcp:0.9.0PIHOLE_URLBase URL of your Pi-hole web interface. For multiple Pi-holes use PIHOLE_1_URL, PIHOLE_2_URL, ... instead.PIHOLE_PASSWORD密钥Pi-hole admin password, or an application password (recommended — bypasses TOTP 2FA)TZIANA timezone for rendered timestamps, e.g. Australia/Adelaide. Defaults to UTC in the container.PIHOLE_READ_ONLYExpose only inspection tools. Every tool that can change Pi-hole is hidden and rejected if called.PIHOLE_TLS_SKIP_VERIFYSet to true only for a Pi-hole serving a self-signed HTTPS certificate. A trusted certificate is the better fix.PIHOLE_REQUEST_TIMEOUTHTTP request timeout as a Go duration, e.g. 30s or 1mPIHOLE_MAX_RETRIESRetries after a transient Pi-hole API failure; 0 disables retryingPIHOLE_RETRY_MAX_DELAYUpper bound on a single exponential-backoff wait, as a Go duration本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
ghcr.io/hexamatic/pihole-mcp:0.9.0stdio工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
pihole-mcp
82 个工具(配置第二个实例后为 84 个) | 9 个提示词 | 5 个资源 | 多实例 + 同步 | 只读模式 + 工具集 | 单个 Go 二进制文件
让 AI 助手全面控制你的 Pi-hole 实例:DNS 屏蔽、域名管理、查询分析、统计信息、网络设备、DHCP 和系统管理。兼容 Pi-hole v6 REST API。
为什么选择它
- 以严格受限的模式运行。
PIHOLE_READ_ONLY=true只开放不会更改任何内容的工具,并在每次调用时强制执行,而不只是限制客户端恰好缓存的工具列表。PIHOLE_TOOLSETS可进一步缩小范围,仅保留你需要的工具类别,因此客户端询问“我能用什么”时,得到的答复会更短、成本更低。 - 82 个工具(配置第二个 Pi-hole 后为 84 个),覆盖 Pi-hole v6 REST API 约 95% 的功能,包括域名、列表、组、客户端、DHCP、网络、查询日志、配置、本地 DNS 记录、Teleporter 备份与恢复,以及会话管理。
- 多实例差异比较与同步。 比较两个 Pi-hole 并准确查看差异,或将一个实例同步到另一个实例;执行写入前,可先查看试运行计划并使用确认令牌。
- 发布版本经过签名和证明,而不只是构建完成。 每个归档文件和容器镜像都附带无密钥 cosign 签名、SPDX SBOM 和 SLSA 构建来源证明;SECURITY.md 提供了检查每项内容的单行命令。
- 已列入官方 MCP Registry,名称为
io.github.hexamatic/pihole-mcp,支持 Registry 安装的客户端均可按名称安装。 - 上线五个月以来已发布九个版本,每个版本都附有真实的发布说明,讲清楚变更内容和原因,而不是只罗列提交哈希。
快速开始
大多数 MCP 客户端使用相同的配置格式。将以下内容添加到客户端配置中:
{
"mcpServers": {
"pihole": {
"command": "pihole-mcp",
"env": {
"PIHOLE_URL": "http://192.168.1.2",
"PIHOLE_PASSWORD": "your-password"
}
}
}
}
然后通过以下任一方式安装二进制文件。
可以询问什么
重点是使用自然语言,而不是工具名称。以下是一些可以实际输入的示例:
| 你询问 | 运行的工具 |
|---|---|
| “Pi-hole 现在正在拦截吗?已经拦截了多久?” | pihole_dns_get_blocking |
| “暂停拦截 10 分钟,我需要测试一下。” | pihole_dns_set_blocking |
| “为什么 reddit.com 被拦截了?检查它可能存在的所有列表。” | pihole_search_domains |
| “今天被拦截最多的域名有哪些?有没有看起来像误报的?” | pihole_stats_recent_blocked、review_top_blocked 提示词 |
| “将 nas.home 指向 192.168.1.50。” | pihole_local_dns_add |
| “我的哪些拦截列表超过 30 天没有更新?” | pihole_lists_list |
| “显示网络上 Pi-hole 无法识别的设备。” | pihole_network_devices、audit_network 提示词 |
| “比较我的两个 Pi-hole,并告诉我有什么不同。” | pihole_instance_diff |
| “在我更改任何内容之前,备份我的配置。” | pihole_teleporter_export |
| “哪个上游解析器最慢?值得切换吗?” | pihole_stats_upstreams、upstream_health 提示词 |
如果想提问而不冒任何内容被更改的风险,请先设置 PIHOLE_READ_ONLY=true。请参阅限定工具范围。
安装
MCP Registry
pihole-mcp 已列入官方 MCP Registry,名称如下:
io.github.hexamatic/pihole-mcp
支持从 Registry 安装的客户端可以按此名称添加,并会提示输入 PIHOLE_URL 和 PIHOLE_PASSWORD。该条目指向 ghcr.io 镜像,因此客户端需要能够正常使用 Docker。
Homebrew
brew install hexamatic/tap/pihole-mcp
可安装在 macOS 和 Linux 上(在 Linux 上使用 Homebrew)。在 macOS 上,cask 会在安装过程中清除隔离属性,因此运行二进制文件时不会出现 Gatekeeper 提示。
Scoop(Windows)
scoop bucket add hexamatic https://github.com/hexamatic/scoop-bucket
scoop install pihole-mcp
Go 安装
go install github.com/hexamatic/pihole-mcp/cmd/pihole-mcp@latest
Docker
docker pull ghcr.io/hexamatic/pihole-mcp:latest
Linux 软件包
面向基于 Debian(Ubuntu、Raspberry Pi OS)和基于 RPM(Fedora、RHEL)的发行版的 .deb 和 .rpm 软件包,可在 Releases 页面获取。
# Debian / Ubuntu / Raspberry Pi OS
sudo dpkg -i pihole-mcp_X.Y.Z_linux_amd64.deb
# Fedora / RHEL / CentOS
sudo rpm -i pihole-mcp_X.Y.Z_linux_amd64.rpm
下载二进制文件
适用于 Linux、macOS 和 Windows(amd64 和 arm64)的预构建二进制文件,可在 Releases 页面获取。
发布版本均提供校验和,使用无密钥 cosign 签名,并附带 SPDX SBOM 和 SLSA 构建来源证明。验证命令请参阅 SECURITY.md。
检查配置
安装并配置完成后,使用 -check 直接运行服务。它会加载配置、联系已配置的每个 Pi-hole,并按名称报告各实例的状态:
PIHOLE_URL=http://192.168.1.2 PIHOLE_PASSWORD=your-password pihole-mcp -check
pihole-mcp 0.9.0
PASS primary (http://192.168.1.2) core v6.1.4, FTL v6.7
All 1 instance(s) reachable and authenticated.
如果任何实例失败,它都会以非零状态码退出,并说明需要更改的内容。建议在将服务接入客户端之前运行此命令:大多数客户端会隐藏服务的输出,因此错误的 URL 或密码看起来与服务从未启动一样。
配置
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
PIHOLE_URL | 是 | - | Pi-hole 基础 URL(例如 http://192.168.1.2) |
PIHOLE_PASSWORD | 是 | - | 管理员密码或应用密码 |
PIHOLE_READ_ONLY | 否 | false | 仅公开无法更改 Pi-hole 的工具。参见限定工具范围。 |
PIHOLE_TOOLSETS | 否 | all | 要公开的工具集名称,以逗号分隔,例如 dashboard,domains。未设置或设为 all 时会公开所有工具。 |
PIHOLE_REQUEST_TIMEOUT | 否 | 30s | HTTP 请求超时时间 |
PIHOLE_MAX_RETRIES | 否 | 3 | Pi-hole API 调用失败后的重试次数。0 表示禁用。 |
PIHOLE_RETRY_MAX_DELAY | 否 | 8s | 单次退避等待的上限。 |
PIHOLE_HTTP_AUTH_TOKEN | 否 | - | 每个 HTTP/SSE 请求都必须提供的共享 bearer 令牌。至少 16 个字符。未设置表示不进行身份验证。 |
PIHOLE_HTTP_AUTH_TOKEN_FILE | 否 | - | 保存 bearer 令牌的文件路径,避免令牌出现在 ps 中。不能与 PIHOLE_HTTP_AUTH_TOKEN 同时使用。 |
PIHOLE_RATE_LIMIT | 否 | 120 | HTTP/SSE 传输每个会话每分钟的请求数上限;每个地址的上限为该值的 4 倍。0 表示禁用。 |
PIHOLE_ALLOWED_ORIGINS | 否 | localhost,127.0.0.1,[::1] | HTTP/SSE 传输的 Origin/Host 允许列表,以逗号分隔。字面值 * 会禁用强制检查(不安全)。这不是身份验证。 |
PIHOLE_TRUSTED_PROXIES | 否 | - | 可信代理的 IP 或 CIDR 网段列表,以逗号分隔;速率限制器会信任这些代理提供的 X-Forwarded-For。未设置时会忽略该标头。 |
PIHOLE_TLS_SKIP_VERIFY | 否 | false | 禁用 Pi-hole 连接的 TLS 证书验证。仅适用于使用自签名证书的实例。尽可能使用受信任的证书。 |
TZ | 否 | 系统时区(Docker 中为 UTC) | 用于渲染时间戳的 IANA 时区(例如 Australia/Adelaide)。时区数据已嵌入二进制文件,因此在 Docker 镜像中可直接使用。 |
OTEL_EXPORTER_OTLP_ENDPOINT | 否 | - | OpenTelemetry 收集器端点。设置后会启用追踪;精简构建中会忽略此项。 |
自动化场景建议使用应用密码:它们无需 TOTP 双重身份验证,且可单独撤销。
PIHOLE_HTTP_AUTH_TOKEN、PIHOLE_HTTP_AUTH_TOKEN_FILE、PIHOLE_RATE_LIMIT、PIHOLE_ALLOWED_ORIGINS 和 PIHOLE_TRUSTED_PROXIES 仅适用于 http 和 sse 传输;按定义,stdio 是单进程、单用户通道,不受这些限制。将任一传输公开到回环地址之外之前,请参阅安全性。
限定工具范围
默认情况下,服务会提供所有工具,其中有 34 个会更改 Pi-hole,27 个具有破坏性。可以通过两个变量缩小范围。
PIHOLE_READ_ONLY=true 只会公开无法更改任何内容的工具。写入工具不会出现在 tools/list 中,即使被调用也会遭到拒绝,因此使用缓存列表的客户端也无法调用这些工具。
PIHOLE_READ_ONLY=true # 49 tools instead of 82
PIHOLE_TOOLSETS 用于选择实际启用的工具系列。单独使用它也很有价值,因为每次对话都要为 tools/list 的开销付出代价:
PIHOLE_TOOLSETS=dashboard,domains,lists # blocklist curation, and nothing else
PIHOLE_TOOLSETS=all # the default, stated explicitly
两项设置会共同生效,且只读设置始终优先。将 PIHOLE_READ_ONLY=true 与 PIHOLE_TOOLSETS=dns,stats 配合使用,会得到这两个工具集中同时满足只读条件的 14 个工具。
工具集名称、每个工具集包含的内容及其工具数量见 docs/TOOLS.md;该文档由服务器用于筛选工具的同一张表生成。名称无效时,程序会在启动时失败并列出所有有效名称;运行 pihole-mcp -check 可查看这些名称,以及你的配置实际公开的工具数量:
scope: read-only=true, toolsets=dns,stats 14 of 82 tools exposed
已发布的工具集名称不会被移除、重命名或缩小范围。完整承诺见 CONTRIBUTING.md。
多个实例
要管理多个 Pi-hole,请配置带编号的实例,而不是使用 PIHOLE_URL/PIHOLE_PASSWORD:
| 变量 | 必填 | 说明 |
|---|---|---|
PIHOLE_1_URL、PIHOLE_2_URL,… | 是 | 每个实例的基础 URL(从 1 开始连续编号) |
PIHOLE_1_PASSWORD、PIHOLE_2_PASSWORD,… | 是 | 对应实例的密码 |
PIHOLE_1_NAME、PIHOLE_2_NAME,… | 否 | 友好名称(默认值为 instance-1、instance-2,…) |
{
"mcpServers": {
"pihole": {
"command": "pihole-mcp",
"env": {
"PIHOLE_1_URL": "http://192.168.1.2",
"PIHOLE_1_PASSWORD": "primary-password",
"PIHOLE_1_NAME": "downstairs",
"PIHOLE_2_URL": "http://192.168.1.3",
"PIHOLE_2_PASSWORD": "secondary-password",
"PIHOLE_2_NAME": "upstairs"
}
}
}
}
之后,每个工具都可接受可选的 instance 参数,每个结果都会标明其所属实例。省略该参数可指定第一个实例;传入名称可指定某个实例;对于只读工具(例如 pihole_padd、pihole_stats_summary),传入 instance=all 可并发查询所有实例,并返回单个结构化汇总(包含各实例的结果和成功/失败摘要,因此某个实例响应较慢或无法访问时,不会导致整个调用失败)。更改状态的工具必须指定单个实例名称。PIHOLE_URL 和 PIHOLE_1_URL 不能同时使用。
保持实例同步
运行多个 Pi-hole 时,会多出两个用于保持实例配置一致的工具:
pihole_instance_diff:比较两个实例,查看广告列表/允许列表、允许/拒绝规则(精确匹配和正则表达式)、分组、客户端、本地 DNS A/AAAA 记录以及 CNAME 记录之间的具体差异。此工具为只读工具,不会写入任何内容。pihole_instance_sync:将源实例的配置推送到目标实例。此工具会谨慎执行:- 仅单向同步。 指定作为准确信息来源的
source和target;只会写入目标实例。 - 先试运行。 默认返回计划和
confirm_token;只有使用mode=apply和该令牌重新运行后才会进行更改。如果规划和应用之间配置发生变化,令牌便不再匹配,应用操作将被拒绝。 - 默认添加/更新。 如果目标实例中存在源实例没有的条目,则会保留这些条目,除非传入
prune=true。 - 先备份。 在进行任何更改前,会创建目标实例的 teleporter 备份(使用
snapshot=false可禁用)。 - 省略即安全。 不会同步特定于主机和身份的信息(DHCP、接口绑定、密码、TLS 证书、会话、2FA)。也不会同步分组的成员关联,因为 Pi-hole 分组 ID 在每个实例中都是本地的。
- 仅单向同步。 指定作为准确信息来源的
示例:先预览 upstairs Pi-hole 相较于 downstairs 缺少哪些内容,然后再应用。
pihole_instance_diff { "source": "downstairs", "target": "upstairs" }
pihole_instance_sync { "source": "downstairs", "target": "upstairs" } → returns a plan + confirm_token
pihole_instance_sync { "source": "downstairs", "target": "upstairs",
"mode": "apply", "confirm_token": "<token from the plan>" }
客户端设置
上方的快速入门配置适用于大多数客户端。展开下面的部分,查看特定客户端的说明。
Claude Desktop
将以下内容添加到 Claude Desktop 配置文件:
| OS | 路径 |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
{
"mcpServers": {
"pihole": {
"command": "pihole-mcp",
"env": {
"PIHOLE_URL": "http://192.168.1.2",
"PIHOLE_PASSWORD": "your-password"
}
}
}
}
保存后重启 Claude Desktop。
如果没有显示该服务,请在终端中使用相同的环境变量运行 pihole-mcp -check,检查它能否连接到你的 Pi-hole。
Claude Code
claude mcp add pihole \
-e PIHOLE_URL=http://192.168.1.2 \
-e PIHOLE_PASSWORD=your-password \
-- pihole-mcp
使用以下命令验证:
claude mcp list
如果没有显示该服务,请在终端中使用相同的环境变量运行 pihole-mcp -check,检查它能否连接到你的 Pi-hole。
VS Code (GitHub Copilot)
将以下内容添加到工作区中的 .vscode/mcp.json:
{
"servers": {
"pihole": {
"type": "stdio",
"command": "pihole-mcp",
"env": {
"PIHOLE_URL": "http://192.168.1.2",
"PIHOLE_PASSWORD": "your-password"
}
}
}
}
或者通过命令面板添加:MCP: Add Server。
注意: VS Code 使用
"servers"作为顶层键(而不是"mcpServers"),并且要求"type": "stdio"。
如果没有显示该服务,请在终端中使用相同的环境变量运行 pihole-mcp -check,检查它能否连接到你的 Pi-hole。
Cursor
将以下内容添加到 ~/.cursor/mcp.json:
{
"mcpServers": {
"pihole": {
"command": "pihole-mcp",
"env": {
"PIHOLE_URL": "http://192.168.1.2",
"PIHOLE_PASSWORD": "your-password"
}
}
}
}
如果没有显示该服务,请在终端中使用相同的环境变量运行 pihole-mcp -check,检查它能否连接到你的 Pi-hole。
Windsurf
将以下内容添加到 ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"pihole": {
"command": "pihole-mcp",
"env": {
"PIHOLE_URL": "http://192.168.1.2",
"PIHOLE_PASSWORD": "your-password"
}
}
}
}
如果没有显示该服务,请在终端中使用相同的环境变量运行 pihole-mcp -check,检查它能否连接到你的 Pi-hole。
Cline
打开 Cline 设置 > MCP Servers > Configure,然后添加:
{
"mcpServers": {
"pihole": {
"command": "pihole-mcp",
"env": {
"PIHOLE_URL": "http://192.168.1.2",
"PIHOLE_PASSWORD": "your-password"
}
}
}
}
如果没有显示该服务,请在终端中使用相同的环境变量运行 pihole-mcp -check,检查它能否连接到你的 Pi-hole。
Docker (any client)
对于支持基于 Docker 的 MCP 服务的客户端:
{
"mcpServers": {
"pihole": {
"command": "docker",
"args": ["run", "-i", "--rm",
"-e", "PIHOLE_URL=http://192.168.1.2",
"-e", "PIHOLE_PASSWORD=your-password",
"-e", "TZ=Australia/Adelaide",
"-v", "/host/path/for/backups:/backups",
"ghcr.io/hexamatic/pihole-mcp:latest"]
}
}
}
适用于未安装 Go,或希望在远程主机上运行服务的情况。
-v 挂载用于 pihole_teleporter_export。没有它,备份会写入容器自身的文件系统,并在退出时 --rm 删除容器后消失。传入指向挂载目录内的 output_path(例如 /backups/pihole.zip),即可将备份保存在主机上。
若要检查容器能否连接到你的 Pi-hole,请使用相同镜像运行 -check。请记住,容器中的 localhost 指向容器自身,这是此处导致连接失败的常见原因:
docker run --rm \
-e PIHOLE_URL=http://192.168.1.2 \
-e PIHOLE_PASSWORD=your-password \
ghcr.io/hexamatic/pihole-mcp:latest -check
工具
单个 Pi-hole 会公开 82 个工具。配置多个实例会额外添加 pihole_instance_diff 和 pihole_instance_sync,共 84 个。这两个工具仅在存在第二个可供比较的实例时注册,因此单实例 Pi-hole 配置不会显示无法使用的工具。
如需公开更少的工具,请参阅限定工具范围。
下表为摘要;包含所有参数的完整生成参考文档见 docs/TOOLS.md。
仪表板
| 工具 | 描述 |
|---|---|
pihole_padd | 一次调用获取快照:查询、拦截、热门域名/客户端、缓存、版本、主机运行状况 |
DNS 控制
| 工具 | 描述 |
|---|---|
pihole_dns_get_blocking | 获取当前 DNS 拦截状态和计时器 |
pihole_dns_set_blocking | 启用/禁用拦截,可选设置计时器 |
本地 DNS
| 工具 | 描述 |
|---|---|
pihole_local_dns_list | 列出本地 A 和 AAAA 记录(dns.hosts) |
pihole_local_dns_add | 将主机名指向一个 IP 地址;记录类型由地址族决定 |
pihole_local_dns_delete | 按 IP 地址和主机名删除本地 A 或 AAAA 记录 |
pihole_local_cname_list | 列出本地 CNAME 记录(dns.cnameRecords) |
pihole_local_cname_add | 将别名指向另一个名称,可选设置 TTL |
pihole_local_cname_delete | 按别名删除本地 CNAME 记录 |
统计信息
| 工具 | 描述 |
|---|---|
pihole_stats_summary | 查询数、拦截率、客户端、gravity 大小 |
pihole_stats_top_domains | 查询量或拦截量最高的域名 |
pihole_stats_top_clients | 按查询数统计最活跃的客户端 |
pihole_stats_upstreams | 上游 DNS 服务器性能 |
pihole_stats_query_types | 查询类型分布(A、AAAA、MX 等) |
pihole_stats_recent_blocked | 最近拦截的域名 |
pihole_stats_database | 长期数据库统计信息 |
pihole_stats_database_top_domains/top_clients/upstreams/query_types | 上述四种工具对应的长期数据库数据,支持任意日期范围 |
域名管理
| 工具 | 描述 |
|---|---|
pihole_domains_list | 列出允许/拒绝的域名 |
pihole_domains_add | 添加域名(支持批量操作) |
pihole_domains_update | 更新域名条目 |
pihole_domains_delete | 删除域名 |
pihole_domains_batch_delete | 批量删除域名 |
分组、客户端、列表
| 工具 | 描述 |
|---|---|
pihole_groups_list/add/update/delete/batch_delete | 管理分组 |
pihole_clients_list/suggestions/add/update/delete/batch_delete | 管理客户端 |
pihole_lists_list/add/update/delete/batch_delete | 管理拦截列表/允许列表 |
查询日志
| 工具 | 描述 |
|---|---|
pihole_queries_search | 使用 12 个筛选条件和游标分页搜索查询 |
pihole_queries_suggestions | 可用的筛选值 |
系统
| 工具 | 描述 |
|---|---|
pihole_info_system | 主机、CPU、内存、磁盘、负载、温度 |
pihole_info_version | Pi-hole 组件版本 |
pihole_info_database | 数据库大小和查询数 |
pihole_info_messages | FTL 诊断消息 |
pihole_info_dismiss_message | 按 ID 忽略诊断消息 |
pihole_info_client | 发起请求的客户端自身的 IP 和连接信息 |
pihole_info_ftl | FTL 进程信息:PID、隐私级别、客户端/域名数量 |
pihole_info_metrics | 实时 DNS 和 DHCP 运行指标(缓存、插入、驱逐、租约) |
pihole_info_sensors | 硬件温度传感器 |
pihole_search_domains | 跨列表搜索域名 |
pihole_auth_sessions/revoke_session | 列出并撤销活跃的 API 会话 |
pihole_config_get/set | 读取/修改 Pi-hole 配置 |
pihole_config_get_value/add_value/remove_value | 通过点分路径进行细粒度配置访问 |
pihole_config_properties | 列出只读配置键(Pi-hole v6.6.1+) |
操作与网络
| 工具 | 描述 |
|---|---|
pihole_action_gravity_update | 重新下载屏蔽列表 |
pihole_action_restart_dns | 重启 FTL DNS 解析器 |
pihole_action_flush_logs | 清空查询日志 |
pihole_action_flush_network | 清空网络表(Pi-hole v6.3+) |
pihole_network_devices/gateway/info/routes/interfaces | 发现网络设备和接口 |
pihole_network_delete_device | 移除过时的网络设备记录 |
pihole_dhcp_leases/delete_lease | 管理 DHCP 租约 |
pihole_logs_dns/ftl/webserver | 获取日志 |
pihole_teleporter_export/import | 配置备份与恢复 |
pihole_history_graph/clients | 活动历史(内存中) |
pihole_history_database/database_clients | 活动历史(长期数据库,任意日期范围) |
多实例(仅在配置了多个 Pi-hole 时)
| 工具 | 描述 |
|---|---|
pihole_instance_diff | 比较两个实例之间的配置 |
pihole_instance_sync | 使目标实例与源实例保持一致(先生成试运行计划,再确认应用) |
响应选项
某些工具接受可选参数,用于控制输出:
detail(minimal|normal|full):控制响应深度。默认值:normal。使用minimal获取单行摘要,使用full获取完整 API 数据。适用于 15 个工具。format(text|csv):表格数据的输出格式。默认值:text。根据工具和行数,CSV 相比默认文本呈现可节省约 8–23% 的 token。适用于 22 个工具:pihole_domains_list、pihole_groups_list、pihole_lists_list、pihole_clients_list、pihole_queries_search、pihole_network_devices、pihole_dhcp_leases、pihole_config_properties、pihole_local_dns_list、pihole_local_cname_list、pihole_stats_top_domains、pihole_stats_top_clients、pihole_stats_upstreams、pihole_stats_query_types、pihole_stats_recent_blocked、pihole_stats_database_top_domains、pihole_stats_database_top_clients、pihole_stats_database_upstreams、pihole_history_graph、pihole_history_clients、pihole_history_database和pihole_history_database_clients。
提示词
用于常见任务的预构建多步骤工作流:
| 提示词 | 描述 |
|---|---|
diagnose_slow_dns | 分析上游性能并找出瓶颈 |
investigate_domain | 检查某个域名为何在所有列表中被屏蔽或允许 |
review_top_blocked | 识别热门被屏蔽域名中的误报 |
audit_network | 发现未知设备和未配置的客户端 |
optimise_blocklists | 建议合并和清理列表 |
daily_report | 全面的 Pi-hole 每日健康状况摘要 |
security_audit | 检查活动会话和身份验证配置,查找未授权访问 |
weekly_trends | 按周对比 DNS 统计数据 |
upstream_health | 深入分析上游解析器的性能 |
资源
MCP 客户端无需调用工具即可读取的只读上下文:
| URI | 描述 |
|---|---|
pihole://status | 屏蔽状态、版本、运行状况 |
pihole://summary | 查询统计数据 |
pihole://clients/{client} | 某个客户端的配置和分组 |
pihole://domains/{type}/{kind} | 列表中的域名,例如 deny/exact |
pihole://lists/{address} | 某个屏蔽列表或允许列表的详细信息 |
配置了多个 Pi-hole 时,也可以直接寻址每个实例:pihole://instances 会列出实例,pihole://<instance>/status 和 pihole://<instance>/summary 可读取指定实例。以上未添加前缀的 URI 始终读取第一个声明的实例。
高级配置
传输方式
默认情况下,pihole-mcp 使用 stdio(MCP 的标准方式)。此外也支持 HTTP 和 SSE 传输方式:
# Default stdio (for Claude Desktop, Cursor, etc.)
pihole-mcp
# HTTP transport (for web-based MCP clients)
pihole-mcp -transport http -address localhost:8080
# SSE transport (deprecated, see below)
pihole-mcp -transport sse -address localhost:8080
两个示例都绑定到环回地址,因此只有本机可以访问。在更改绑定地址前,请阅读下方的 安全性(HTTP 和 SSE 传输方式):在配置令牌之前,这两种传输方式都不会进行身份验证。
pihole-mcp 实现了 MCP 协议修订版 2025-11-25,并会为较旧的客户端协商降级版本 (2025-06-18、2025-03-26 和 2024-11-05 均受支持)。
SSE 已弃用。 HTTP+SSE 传输方式在 2025-03-26 修订版中被 Streamable HTTP 取代,并根据规范的功能生命周期政策正式重新归类为 已弃用 (SEP-2596),这意味着它仍属于规范的一部分,并会得到全面支持,至少十二个月后才可能提议移除。
-transport sse会继续保留,以支持较旧的客户端,并仍会接收安全修复,但新部署应使用-transport http。
安全性(HTTP 和 SSE 传输方式)
http 和 sse 传输方式在配置身份验证前均不进行身份验证。 stdio 不受影响:从定义上看,它是单进程、单用户的通道。
默认监听地址为 localhost:8080,因此默认情况下只有本机可以访问服务。更改绑定地址却不设置令牌后,任何能够访问该端口的人都可以控制你的 Pi-hole:停用屏蔽、重写屏蔽列表、读取网络上的所有 DNS 查询。
-
Bearer 身份验证(绑定地址不是环回地址时建议使用)。 设置共享令牌,并要求每个请求都在
Authorization: Bearer标头中携带该令牌。没有令牌的请求会在执行任何其他操作前收到401响应。令牌长度必须至少为 16 个字符。export PIHOLE_HTTP_AUTH_TOKEN="$(openssl rand -base64 32)" # A bind beyond loopback needs the allowlist extended too, or clients reach a # 403 from the Host check before the token is ever looked at. export PIHOLE_ALLOWED_ORIGINS="localhost,127.0.0.1,[::1],192.168.1.10" pihole-mcp -transport http -address 0.0.0.0:8080在命令行上设置的环境变量会显示在主机上所有用户都能查看的
ps输出中,因此也可以从文件读取令牌。容器平台挂载机密时也会采用这种形式:export PIHOLE_HTTP_AUTH_TOKEN_FILE=/run/secrets/pihole-mcp-token二选一,不要同时设置。令牌会以恒定时间进行比较,因此错误令牌不会泄露攻击者输入正确的部分有多少。被拒绝的请求会计入单独的身份验证失败额度:每个地址大约允许尝试 20 次,之后限制为每秒一次。这样既无法以全速尝试猜测令牌,也能防止大量错误令牌请求耗尽同一地址下持有有效令牌的客户端的额度,并且服务只会记录一次限流日志,而不是每次尝试都记录。
如果绑定到非环回地址却未设置令牌,启动时会记录错误并继续运行。服务不会拒绝启动,因为在前置的反向代理中进行身份验证是合理的部署方式。
-
Origin 和 Host 验证。 两个标头都必须解析为
PIHOLE_ALLOWED_ORIGINS中的主机(默认仅允许环回地址)。不匹配时返回403。允许缺少Origin,因为非浏览器 MCP 客户端不会发送该标头。这不是身份验证。 这是 DNS 重绑定防护,且只对浏览器有效:受害者访问的网页无法让其浏览器附带允许列表接受的
Origin。这两个标头都由调用方选择,因此任何非浏览器客户端都可以将它们设为允许列表中的值。请使用PIHOLE_HTTP_AUTH_TOKEN控制访问权限。export PIHOLE_ALLOWED_ORIGINS="localhost,127.0.0.1,[::1],pihole-mcp.lan"字面值
*会完全停用强制检查。在反向代理后方或已设置 Bearer 令牌时这样做是合理的,其他情况下则不合理。 -
速率限制。 按客户端地址设置令牌桶,并在其下方按 MCP 会话设置另一个令牌桶。
PIHOLE_RATE_LIMIT(默认值为120,突发上限为max(120/4, 30))是每个会话的速率;单个地址可发送四倍于此速率的请求。受限请求会返回429,并附带Retry-After: 1。设为0可停用速率限制。 地址上限才是真正限制调用方的机制,因为Mcp-Session-Id是由 客户端写入的请求头:如果没有上限,调用方每次请求都发送新的会话 ID,就永远不会受到限制。在 MCP 修订版2026-07-28中,这个请求头也将从传输层移除,届时上限就是唯一的限流机制。每个请求都会先计入 上限,即使随后被会话桶拒绝也不例外,因此已经受到限流的客户端仍会消耗其邻居共享的预算。IPv6 客户端按/64计数,因为单台主机通常会获得整个网段。# Tighter limit for a small fleet export PIHOLE_RATE_LIMIT=60 # Disable (only when running behind a proxy with its own rate limit) export PIHOLE_RATE_LIMIT=0 -
位于反向代理之后。 默认情况下,客户端地址是连接的对端地址;位于代理之后时,该地址就是代理本身,因此所有经过它的客户端都会共享一个上限。指定代理网络后,系统会改用
X-Forwarded-For,并从右向左取第一个不属于已列出代理的地址:export PIHOLE_TRUSTED_PROXIES="192.168.1.5"默认情况下不会信任任何内容,这是有意为之:
X-Forwarded-For由客户端提供,因此无条件信任它的服务端会让任意调用方自行选择限流桶。你列出的前缀内的每台主机都会获得这种权限,因此应尽可能指定单个代理,并将任何 CIDR 网段限制在部署所允许的最小范围内。10.0.0.0/8会信任你的整个网络。
OpenTelemetry
默认不启用追踪。设置 OTEL_EXPORTER_OTLP_ENDPOINT 即可启用:
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
pihole-mcp
所有工具调用都会自动追踪,并记录工具名称、耗时和错误状态。
如果不需要追踪,精简构建会完全移除 OpenTelemetry SDK、gRPC、protobuf 和 grpc-gateway 依赖。二进制文件体积会缩小 43%:
| 变体 | 二进制文件(linux/amd64) | 下载包(linux/amd64 .tar.gz) | Docker 镜像(linux/arm64) |
|---|---|---|---|
| 默认 | 17.9 MB | 6.8 MB | 19.0 MB |
| 精简 | 10.3 MB | 4.1 MB | 11.8 MB |
数据取自 v0.9.0 版本的发布资源。这里的 MB 表示一百万字节;镜像数据是 docker images 报告的 linux/arm64 镜像解压后大小,也就是 Raspberry Pi 拉取的镜像。
just build-slim
# or
go build -tags slim -o bin/pihole-mcp-slim ./cmd/pihole-mcp
# Docker
docker pull ghcr.io/hexamatic/pihole-mcp:latest-slim
除忽略 OTEL_EXPORTER_OTLP_ENDPOINT 外,精简版二进制文件的功能完全相同。
故障排除
“Pi-hole 拒绝了登录:API 会话池已满”
Pi-hole 允许的并发 API 会话数量有限(webserver.api.max_sessions,默认值为 16),每个登录的客户端都会占用一个名额:Web 界面、PADD、Home Assistant、其他任何集成,以及 pihole-mcp。名额全部占满时,Pi-hole 会返回 429,并拒绝后续登录,包括通过其自身 Web 界面发起的登录。
pihole-mcp 关闭时会释放名额,但如果进程被强制终止而非正常停止,遗留的会话会一直占用名额,直到过期。以下三种解决方法按优先顺序排列:
- 释放一个名额。 获取会话列表(
pihole_auth_sessions),并撤销一个处于空闲状态的会话(pihole_auth_revoke_session)。 - 提高上限。 对于运行了少量集成的机器,16 个名额偏少:
pihole-FTL --config webserver.api.max_sessions 32 - 等待。 名额会在
webserver.session.timeout后自动释放(默认 30 分钟)。
重试无济于事,因此 pihole-mcp 不会重试,而是直接报告问题,不会悄无声息地一直等待。
密码正确但身份验证失败
Pi-hole 会对反复失败的登录进行限流,而且限流机制无法区分“密码错误”和“你刚刚修正的密码”。请等待几秒后重试。如果问题仍然存在,请确认你使用的是管理员密码或应用密码,而不是 Web 界面的 TOTP 代码。
Docker:“连接被拒绝”,无法连接 Pi-hole
容器内的 localhost 指向容器本身,而不是宿主机。请将 PIHOLE_URL 指向宿主机的局域网地址(http://192.168.1.2)、Docker Desktop 上的 host.docker.internal,或将两个容器放入同一 Docker 网络并使用 Pi-hole 容器名称。
时间戳以 UTC 显示
工具输出中的每个时间戳都带有明确的时区标记(例如 19 Jul 2026, 9:41 AM UTC),因此无论使用哪个时区,响应都不会产生歧义。使用的时区取决于服务运行的位置:原生二进制文件使用系统时区,而 Docker 镜像默认使用 UTC。要在容器中获取本地时间,请在 pihole-mcp 容器上设置 TZ(而不只是 Pi-hole 容器)。时区数据已嵌入二进制文件,无需额外的软件包或卷挂载:
environment:
- TZ=Australia/Adelaide
无法识别的 TZ 值会在启动时记录警告,并回退到 UTC,而不是拒绝启动。
“x509: certificate signed by unknown authority”
你的 Pi-hole 正在使用自签名证书提供 HTTPS 服务,因此无法通过标准 TLS 验证。正确的解决办法是在 Pi-hole 上配置受信任的证书(例如通过其内置域名设置,或使用带有 Let's Encrypt 证书的反向代理)。如果这不现实,可以设置 PIHOLE_TLS_SKIP_VERIFY=true 来禁用验证。连接仍会加密,但服务器身份不再经过检查,因此只应在你控制的网络中使用此设置。
偶尔出现连接中断
Pi-hole 内置的 Web 服务器在负载较高时会关闭连接。pihole-mcp 会自动通过退避机制重试;如果仍然遇到失败,请提高 PIHOLE_MAX_RETRIES(默认值为 3)。
获取帮助
- 使用方面的问题? 请在 问答讨论 中提问;之后遇到相同问题的人也能在那里找到答案。
- 发现错误或想要某项功能? 请提交 issue。
- 发现安全漏洞? 请参阅 SECURITY.md。请不要公开提交 issue。
如需了解完整信息,包括从何处开始贡献,请参阅 SUPPORT.md。
开发
# Prerequisites: Go 1.26+, Docker, mise, just
# One-command setup
just setup
# Start local Pi-hole (http://localhost:8081, password: test)
# Port already taken? PIHOLE_DEV_PORT=8091 just dev-up
just dev-up
# Run quality checks (format + lint + test)
just check
# Run integration tests against local Pi-hole
just integration
# Build binary
just build
完整的开发指南请参阅 CONTRIBUTING.md。
Pi-hole 是 Pi-hole LLC 的注册商标。本项目由独立维护,与 Pi-hole LLC 无关联,也未获得其认可或赞助。
许可
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。