adguardctrl

Active

Tuning DNS filtering means the AdGuard Home dashboard, one box at a time, and hoping you clicked the right client. adguard-mcp hands the whole control surface to your agent: status, stats, query logs, filter lists, and gated changes, across every AdGuard Home instance you run, in plain language over stdio.

33 tools14 read-onlywrite-gatedmulti-instanceNode 20+MIT

See it work

one question, the tools it calls, the answer

representative session · claude + adguard-mcp
My kid says YouTube is blocked on the living-room tablet but the phone works. What is AdGuard actually doing, and can you block youtube.com for that one client?
adguard_check_host{ host: "youtube.com", client: "kid-tablet" }
filtered: false reason: NotFilteredNotFound resolved: 203.0.113.44, 203.0.113.45 matched rules: (none) instance: primary
adguard_add_user_rule{ rule: "||youtube.com^$client=kid-tablet", confirm: true }
ok rule added user rules: 41 -> 42 instance: primary
Nothing was blocking it, that is why the tablet still reached YouTube. I added a per-client rule scoped to kid-tablet, so YouTube is blocked there and the phone is untouched. That write needed confirm: true; I did not flip anything global.

Representative session. Illustrative values, RFC 5737 addresses. Credentials stay in memory and are redacted from logs; nothing leaves your box.

What it does

Point any MCP client at adguard-mcp and your self-hosted AdGuard Home becomes tools the agent can call: read status, stats, the DNS query log, filter lists, named clients, DNS config, and a check_host lookup that shows exactly what AdGuard would do with a hostname. The reason it exists is that the raw AdGuard Home API has no agent-safety layer, so every endpoint (including the ones that disable all blocking or wipe your rules) is one hallucinated call away. adguard-mcp differs by encoding those endpoints as typed tools behind a three-tier gate, keeping reads open, requiring confirm: true on writes, and requiring both confirm: true and destructive: true on destructive ops, while resolving any number of instances from env vars so one tool call can target a non-default box or drive AdGuardHome Sync.

Capabilities

33 tools across three gating tiers

Status & inspection6 read tools
Server status, stats window, DNS query-log slices, DNS config, and a check_host lookup that reports AdGuard's filter decision, matched rules, and resolved IPs.
Filter lists & rulesread + safe writes
List subscribed blocklists/allowlists and custom user rules; add, remove, toggle, or refresh lists and append/remove single user rules behind confirm: true.
Clients & blocked servicesread + safe writes
Enumerate named clients and the blocked-services catalog; add, update, or set per-client blocked services and schedules with confirm: true.
Protection & SafeSearchsafe + destructive
Toggle SafeSearch and SafeBrowsing (safe writes); toggle global protection or wholesale-replace the user-rules block (destructive, needs confirm + destructive).
Query log & stats maintenance3 destructive tools
Clear the DNS query log, reset the stats window, or delete a named client; each gated behind confirm: true and destructive: true.
AdGuardHome Sync4 tools
Origin/replica status, healthz check, and in-memory logs (reads), plus trigger a sync run; separate env prefix, tools stay listed but error clearly if Sync is unconfigured.
Full reference on GitHub →

Set it up

npm i -g @solomonneas/adguard-mcp

Set per-instance ADGUARD_PRIMARY_URL, ADGUARD_PRIMARY_USERNAME, ADGUARD_PRIMARY_PASSWORD (at least one instance required); add ADGUARD_<NAME>_* for more boxes and optional ADGUARDHOME_SYNC_URL for Sync.

MCP client config
{ "mcpServers": { "adguard": { "command": "npx", "args": ["-y", "@solomonneas/adguard-mcp"], "env": { "ADGUARD_PRIMARY_URL": "http://192.0.2.10", "ADGUARD_PRIMARY_USERNAME": "admin", "ADGUARD_PRIMARY_PASSWORD": "your-password" } } } }
[ shield ]

Three write-gate tiers: reads are open, safe writes require an explicit confirm: true, and destructive ops (toggle protection, replace the rules block, delete a client, wipe the query log) additionally require destructive: true, so an agent cannot disable filtering or wipe rules on a hallucinated call. Credentials live only in memory after env-load and are redacted from logs and error messages. It runs no daemon, stores no DNS traffic, and targets only self-hosted AdGuard Home boxes you run.

33
MCP tools
14
read-only
3
write-gate tiers
multi
instances + Sync
MIT
license