add_local_a_record
Add a local A record to map a hostname to an IP address. Existing entries for the same host are automatically replaced.
Instructions
Add a local A record (host -> IP). Replaces any existing entry for the same host.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| host | Yes | ||
| ip | Yes |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/pihole_mcp/tools/local_dns.py:25-30 (handler)The `add_local_a_record` tool handler: fetches current DNS config, filters out any existing entry for the same host, appends the new `ip host` record, and PATCHes the config.
async def add_local_a_record(host: str, ip: str) -> dict: """Add a local A record (host -> IP). Replaces any existing entry for the same host.""" dns = await _current_dns_config(client) hosts = [h for h in dns.get("hosts", []) if not h.endswith(f" {host}")] hosts.append(f"{ip} {host}") return await _patch_dns(client, {"hosts": hosts}) - src/pihole_mcp/tools/local_dns.py:17-54 (registration)The `register` function uses `@mcp.tool()` decorator to register `add_local_a_record` (and 4 other tools) on the FastMCP instance.
def register(mcp: FastMCP, client: PiholeClient) -> int: @mcp.tool() async def list_local_dns() -> dict: """List local DNS entries (hosts and CNAME records).""" dns = await _current_dns_config(client) return {"hosts": dns.get("hosts", []), "cnameRecords": dns.get("cnameRecords", [])} @mcp.tool() async def add_local_a_record(host: str, ip: str) -> dict: """Add a local A record (host -> IP). Replaces any existing entry for the same host.""" dns = await _current_dns_config(client) hosts = [h for h in dns.get("hosts", []) if not h.endswith(f" {host}")] hosts.append(f"{ip} {host}") return await _patch_dns(client, {"hosts": hosts}) @mcp.tool() async def remove_local_a_record(host: str) -> dict: """Remove any local A record matching the given host.""" dns = await _current_dns_config(client) hosts = [h for h in dns.get("hosts", []) if not h.endswith(f" {host}")] return await _patch_dns(client, {"hosts": hosts}) @mcp.tool() async def add_local_cname_record(host: str, target: str, ttl: int = 300) -> dict: """Add a local CNAME record (host -> target). Replaces any existing CNAME for the same host.""" dns = await _current_dns_config(client) records = [r for r in dns.get("cnameRecords", []) if not r.startswith(f"{host},")] records.append(f"{host},{target},{ttl}") return await _patch_dns(client, {"cnameRecords": records}) @mcp.tool() async def remove_local_cname_record(host: str) -> dict: """Remove any local CNAME record for the given host.""" dns = await _current_dns_config(client) records = [r for r in dns.get("cnameRecords", []) if not r.startswith(f"{host},")] return await _patch_dns(client, {"cnameRecords": records}) return 5 - Helper `_current_dns_config` fetches the current DNS config from Pi-hole API.
async def _current_dns_config(client: PiholeClient) -> dict: payload = await client.get("/config/dns") config = payload.get("config") or {} dns = config.get("dns") or {} return dns - Helper `_patch_dns` sends a PATCH request to update DNS config.
async def _patch_dns(client: PiholeClient, dns_delta: dict) -> dict: return await client.patch("/config/dns", json={"config": {"dns": dns_delta}}) - src/pihole_mcp/tools/__init__.py:14-19 (registration)`register_all` iterates all tool modules (including `local_dns`) and calls their `register` function, wiring tools to the MCP server.
def register_all(mcp: FastMCP, client: PiholeClient) -> int: """Register every tool module against the FastMCP instance. Returns tool count.""" count = 0 for module in (stats, queries, blocking, domains, local_dns, maintenance): count += module.register(mcp, client) return count