hetzner-dns-mcp
以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →
A Model Context Protocol (MCP) server for managing DNS zones and records via the Hetzner Cloud API.
Lets MCP clients like Claude Code, Claude Desktop or Codex manage your Hetzner DNS: list, create, update and delete zones and RRSets (record sets), import/export zone files, manage protection and TTLs, and track asynchronous zone actions.
Twenty-two tools is the ceiling, not the floor: HETZNER_ALLOW_TOOLS=essential
registers a curated eight instead, and a model picks the right tool far more
reliably from eight than from twenty-two — see
choosing which tools load.
> **Note:** This server targets the current DNS API that is part of the **Hetzner Cloud API** (api.hetzner.cloud). The legacy DNS API (dns.hetzner.com) was shut down in May 2026 and is not supported.
is resolved against the colour scheme of the page showing it, so GitHub
picks the variant that matches its own theme toggle. npm strips and
when it sanitises the README and keeps the , which is why that
fallback brings its own dark card instead of relying on a media query. -->
is resolved against the colour scheme of the page showing it, so GitHub
picks the variant that matches its own theme toggle. npm strips and
when it sanitises the README and keeps the , which is why that
fallback brings its own dark card instead of relying on a media query. -->
What makes it different
**Zones, record sets and the actions behind them.** Listing, creating, updating
and deleting zones and RRSets, importing and exporting BIND zone files, changing
TTLs and protection — and following the asynchronous zone actions Hetzner queues
behind a change, rather than reporting success and leaving you to guess.
**Nothing upstream is trusted.** Record values, comments and zone files come back
wrapped as untrusted data, secret-looking keys are redacted, oversized values are
truncated and HTML error pages are dropped instead of pasted into the context.
**Destructive calls ask a person.** Deleting a zone or replacing a record set
raises a real dialog through MCP elicitation. Where the client cannot show one,
the call is refused and carries a random single-use token that only ever appeared
in a previous tool result — so nothing hidden inside a DNS record can mint it.
Requirements
- Node.js ≥ 22
- A Hetzner Cloud API token for the project that holds your DNS zones — create one in the Hetzner Cloud Console under _your project → Security → API tokens_. Use a **read & write** token for full functionality (a read-only token limits you to the read tools).
Configuration
Configuration is provided via environment variables:
| Variable | Required | Description |
| ---------------------- | -------- | ---------------------------------------------------------------------------------- |
| HETZNER_API_TOKEN | yes | Hetzner Cloud API token (project-scoped) |
| HETZNER_READ_ONLY | no | true registers only the read tools; the write tools do not exist at all |
| HETZNER_ALLOW_TOOLS | no | Comma-separated tool names, list_* prefixes, or essential for a curated preset |
| HETZNER_DENY_TOOLS | no | Same syntax; removed from whatever HETZNER_ALLOW_TOOLS left |
| ELICITATION | no | false replaces the approval dialog with the two-call token. **Not prefixed** |
| HETZNER_API_BASE_URL | no | Base URL of the API (default: https://api.hetzner.cloud/v1) |
Without a token the server still starts and lists its tools (so registries and
inspectors can introspect it), but every tool call fails with setup
instructions instead of reaching the API.
HETZNER_API_TOKEN and HETZNER_API_BASE_URL are deleted from the process
environment once they have been read, so a later crash report or diagnostic
dump cannot expose the token.
Choosing which tools load
HETZNER_ALLOW_TOOLS and HETZNER_DENY_TOOLS take comma-separated tool names;
a trailing * matches a whole family. essential is a curated preset —
list_zones, get_zone, list_rrsets, get_rrset, create_rrset,
set_records, delete_rrset and export_zonefile — which covers reading a
zone and changing a record without the rare, catastrophic tools.
An entry that matches no tool aborts startup and names it, so a typo cannot