Talk to your DNS
A built-in MCP server lets Claude Code, Codex, Cursor or any MCP client manage zones and records from a prompt, under the same RBAC, validation and audit log as the UI.
PowerDNS-AuthAdmin is a modern, self-hosted web interface for PowerDNS Authoritative. Scoped RBAC, SSO with OIDC, SAML and LDAP, passkeys, diff-before-apply zone editing and an append-only audit log. Now with a built-in MCP server, so Claude Code or any AI assistant can change records under the same rules. One Docker image. No telemetry.
New in 1.9 · Model Context Protocol
A built-in MCP server lets Claude Code, Codex, Cursor or any MCP client manage zones and records from a prompt. The assistant never gets more power than the token you give it, and every change lands in the audit log.
Point www on example.com at 192.0.2.10 and add an AAAA for 2001:db8::10.
Done. www.example.com now answers A 192.0.2.10 and AAAA 2001:db8::10, TTL 300. Both changes went through review and are in the audit log under your name.
zone.read alone for questions, add record.* for edits, or a single per-zone grant for a bot that should only ever touch one zone./api/mcp over Streamable HTTP with the token as a Bearer header. Pick your client below.# Claude Code: one command, then just ask
claude mcp add --transport http powerdns https://dns.example.com/api/mcp \
--header "Authorization: Bearer pda_pat_xxxxxxxx"
# /mcp inside Claude Code shows the connection{
"mcpServers": {
"powerdns": {
"type": "http",
"url": "https://dns.example.com/api/mcp",
"headers": {
"Authorization": "Bearer ${PDNS_AUTHADMIN_TOKEN}"
}
}
}
}# ~/.codex/config.toml
[mcp_servers.powerdns]
url = "https://dns.example.com/api/mcp"
bearer_token_env_var = "PDNS_AUTHADMIN_TOKEN"
# then: export PDNS_AUTHADMIN_TOKEN=pda_pat_xxxxxxxx{
"mcpServers": {
"powerdns": {
"url": "https://dns.example.com/api/mcp",
"headers": {
"Authorization": "Bearer pda_pat_xxxxxxxx"
}
}
}
}Features
Designed for teams that operate real, multi-backend PowerDNS infrastructure, from a homelab to a hosting provider.
A built-in MCP server lets Claude Code, Codex, Cursor or any MCP client manage zones and records from a prompt, under the same RBAC, validation and audit log as the UI.
Five system roles plus your own custom roles across ~60 permissions, each assignment scoped to global, team, zone or server.
OIDC with PKCE, SAML 2.0 and LDAP / Active Directory, all with group → role mapping. Local accounts use Argon2id.
Passkeys and hardware security keys (WebAuthn) or TOTP. Any role can require MFA before it takes effect.
Edit records inline or in the full editor, drive it all from the keyboard, and review every change as a BIND-style diff before it is written.
Standalone primaries, primary + secondaries and multi-primary clusters in one zone list, with NOTIFY-aware probes that compare every secondary's serial.
Enable, disable and rectify DNSSEC per zone, publish the right DS set, manage cryptokeys, TSIG keys and autoprimaries without pdnsutil.
Every write, including what an AI assistant does, is recorded with redacted before / after snapshots, the PowerDNS HTTP trail and per-zone history.
A single Docker image on SQLite or Postgres. A provisioning.yaml brings up roles, teams, backends and SSO on first boot.
A closer look
Every screen reflows down to a phone. Pick a screen, switch device, or flip the theme: the screenshots follow.
Quickstart
One image, ghcr.io/powerdns-authadmin/powerdns-authadmin. Runs on SQLite or Postgres, and migrations plus the role seed run automatically on boot.
mkdir powerdns-authadmin && cd powerdns-authadmin
# 1. Generate secrets once. Back this file up and never change them.
{
echo "APP_SECRET_KEY=$(openssl rand -base64 32)"
echo "APP_ENCRYPTION_KEY=$(openssl rand -base64 32)"
echo "BOOTSTRAP_ADMIN_EMAIL=admin@example.com"
echo "BOOTSTRAP_ADMIN_PASSWORD=$(openssl rand -base64 18)"
echo "APP_URL=https://dns.example.com" # the exact URL your browser uses
} > .env
chmod 600 .env
# 2. Save compose.yml (next tab), then start it
docker compose up -d# compose.yml: single instance on SQLite
services:
app:
image: ghcr.io/powerdns-authadmin/powerdns-authadmin:latest
restart: unless-stopped
ports: ["3000:3000"]
environment:
APP_URL: ${APP_URL}
DATABASE_URL: file:/data/powerdns_authadmin.db
APP_SECRET_KEY: ${APP_SECRET_KEY}
APP_ENCRYPTION_KEY: ${APP_ENCRYPTION_KEY}
BOOTSTRAP_ADMIN_EMAIL: ${BOOTSTRAP_ADMIN_EMAIL}
BOOTSTRAP_ADMIN_PASSWORD: ${BOOTSTRAP_ADMIN_PASSWORD}
# Optional: apply provisioning.yaml once on first boot
# PROVISION_ON_BOOT: "true"
# PROVISIONING_FILE: /etc/pda/provisioning.yaml
volumes:
- app-data:/data
# - ./provisioning.yaml:/etc/pda/provisioning.yaml:ro
volumes:
app-data:# provisioning.yaml: applied once on first boot, then the UI
# is the source of truth. Every block is optional.
settings:
site_name: "ACME DNS"
default_record_ttl: 300
# Register your PowerDNS Authoritative backend(s)
pdns_servers:
- slug: primary
name: "Primary PowerDNS"
base_url: "https://pdns.internal:8081/api/v1"
server_id: localhost
api_key: "change-me-pdns-api-key" # encrypted at rest
is_default: true.env. A regenerated APP_ENCRYPTION_KEY makes stored API keys and MFA secrets unreadable, so back it up.APP_URL to the exact URL your browser uses, scheme and host included.docker compose up -d and sign in with the bootstrap admin.provisioning.yaml to register backends, roles, teams and SSO on first boot.Running more than one replica? Use Postgres plus Redis behind a load balancer. Just evaluating? The live demo is one click away.
Coming from PowerDNS-Admin?
PowerDNS-AuthAdmin is a separate project written in TypeScript for teams with several backends, an identity provider and an auditor to answer to. Your zones already live in PowerDNS, so pointing it at your API is all it takes to see them.
How it compares and how to switchFAQ
PowerDNS-AuthAdmin is a free, open-source web interface for managing PowerDNS Authoritative servers. It adds role-based access control, single sign-on (OIDC, SAML and LDAP), passkeys and MFA, a diff-before-apply record editor, DNSSEC and TSIG management, multi-backend cluster support, an append-only audit log and a built-in MCP server for AI assistants on top of the PowerDNS HTTP API. It ships as one Docker image and is MIT licensed.
Yes. Since version 1.9.0, PowerDNS-AuthAdmin includes a Model Context Protocol (MCP) server at /api/mcp. Connect Claude Code, Codex, Cursor, Windsurf or any MCP client over Streamable HTTP with a personal access token as the Bearer header, then ask in plain language: point www at an address, replace a zone's MX records, create a staging zone. The assistant gets nine tools for listing backends and zones, reading records, replacing, appending and deleting records, and creating or deleting zones. See the MCP guide for each client's configuration.
PowerDNS-AuthAdmin is tested in CI against PowerDNS Authoritative 4.6 to 5.0 (4.6, 4.7, 4.8, 4.9 and 5.0). It talks to PowerDNS through the Authoritative server's built-in HTTP API, so the API and an API key must be enabled.
Any OpenID Connect provider (with PKCE, group → role mapping and RP-initiated logout), any SAML 2.0 identity provider such as AD FS, Authentik, Keycloak, Okta, Microsoft Entra ID, PingFederate or Shibboleth, and LDAP against Active Directory or OpenLDAP. Local email and password accounts are also available.
PowerDNS-AuthAdmin is a separate project written from scratch in TypeScript on Node.js. Its focus is teams running multiple backends: scoped RBAC, OIDC / SAML / LDAP with group mapping, passkeys, diff-before-apply editing, cluster and secondary sync probes, an append-only audit log and a built-in MCP server for AI assistants. See the comparison page for details.
Community driven
PowerDNS-AuthAdmin is MIT licensed and developed in public. Star the repo, start a discussion, report a bug or send a pull request. Contributions of every size are welcome.