Hetzner DNS について
Hetzner DNS は、Hetzner Cloud API を通じて DNS ゾーンとレコードセットを管理する MCP サーバーです。ゾーンファイルの入出力、TTL や保護設定に対応し、危険な変更には確認を求めます。
主な機能
- 01ゾーンとレコードセットの管理
- 02BIND ゾーンファイルの入出力
- 03TTL と保護設定の変更
- 04非同期ゾーン操作の追跡
- 05危険な変更時の確認
活用シーン
- 01Hetzner DNS レコードの確認と更新
- 02ゾーンファイルによるレコード移行
- 03用途に応じたツールの絞り込み
MCP 対応
Hetzner Cloud DNS のゾーンおよび RRSet 操作を MCP ツールとして公開します。クライアントは読み取り専用やツールの絞り込みを設定でき、重要な変更には MCP elicitation または単回の確認トークンが必要です。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y hetzner-dns-mcpHETZNER_API_TOKENシークレットHetzner Cloud API token (project-scoped, Cloud Console -> Security -> API tokens)HETZNER_READ_ONLYSet to true to register only the read-only tools (default: false)HETZNER_ALLOW_TOOLSComma-separated tool names or list_* prefixes to register; 'essential' selects a curated preset (default: all tools)HETZNER_DENY_TOOLSComma-separated tool names or list_* prefixes to remove from whatever HETZNER_ALLOW_TOOLS leftHETZNER_API_BASE_URLOverride the Hetzner Cloud API base URL (default: https://api.hetzner.cloud/v1)ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
22掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| mode | enum | いいえ | モードでゾーンを絞り込みますprimary | secondary |
| name | string | いいえ | 名前でゾーンを絞り込みます(完全一致) |
| page | integer | いいえ | 返すページ番号(ページネーション) |
| per_page | integer | いいえ | ページあたりの項目数(1-100、デフォルトは 25) |
| label_selector | string | いいえ | ラベルセレクターでゾーンを絞り込みます。例:"env=prod" |
詳細
hetzner-dns-mcp
Hetzner Cloud APIを通じてDNSゾーンとレコードを管理する、Model Context Protocol(MCP)サーバーです。
Claude Code、Claude Desktop、CodexなどのMCPクライアントを使ってHetzner DNSを管理できます。ゾーンとRRSet(レコードセット)の一覧表示、作成、更新、削除、ゾーンファイルのインポート/エクスポート、保護とTTLの管理、非同期のゾーン操作の追跡が可能です。
ツールは22個まで登録できますが、常にすべてを使う必要はありません。HETZNER_ALLOW_TOOLS=essential
を設定すると、厳選された8個だけが登録されます。22個の場合より8個の場合のほうが、モデルは適切なツールをはるかに確実に選べます。詳しくは
読み込むツールの選択を参照してください。
注記: このサーバーは、Hetzner Cloud API(
api.hetzner.cloud)に含まれる現在のDNS APIを対象としています。従来のDNS API(dns.hetzner.com)は2026年5月に停止されており、サポート対象外です。

ゾーン、レコードセット、それらを操作するアクション。 ゾーンや RRSet の一覧表示、作成、更新、削除、BIND ゾーンファイルのインポートとエクスポート、TTL や保護設定の変更に対応します。また、変更後に Hetzner がキューに登録する非同期のゾーンアクションを追跡するため、成功を報告するだけで後は推測に任せることはありません。
上流からのデータは一切信用しません。 レコード値、コメント、ゾーンファイルは信頼できないデータとして返されます。秘密情報に見えるキーはマスキングされ、サイズの大きすぎる値は切り詰められ、HTML のエラーページはコンテキストに貼り付けられないよう破棄されます。
破壊的な呼び出しには人による承認が必要です。 ゾーンの削除やレコードセットの置換では、MCP elicitation を通じて実際のダイアログが表示されます。クライアントがダイアログを表示できない場合、呼び出しは拒否され、以前のツール結果にのみ表示されたランダムな 1 回限りのトークンが付与されます。そのため、DNS レコード内に隠された内容からトークンが生成されることはありません。
要件
- Node.js ≥ 22
- DNS ゾーンがあるプロジェクトの Hetzner Cloud API トークン。Hetzner Cloud Console の your project → Security → API tokens から作成してください。すべての機能を使うには、読み取りと書き込みのトークンを使用してください。読み取り専用トークンでは、読み取りツールのみ使用できます。
設定
設定は環境変数で指定します。
| 変数 | 必須 | 説明 |
|---|---|---|
HETZNER_API_TOKEN | はい | Hetzner Cloud API トークン(プロジェクト単位) |
HETZNER_READ_ONLY | いいえ | true を指定すると読み取りツールのみ登録されます。書き込みツールは存在しません |
HETZNER_ALLOW_TOOLS | いいえ | カンマ区切りのツール名、list_* プレフィックス、または厳選プリセットの essential |
HETZNER_DENY_TOOLS | いいえ | 同じ構文です。HETZNER_ALLOW_TOOLS で残ったツールから除外されます |
ELICITATION | いいえ | false を指定すると、承認ダイアログが 2 回呼び出すトークンに置き換わります。プレフィックスは付きません |
HETZNER_API_BASE_URL | いいえ | API のベース URL(デフォルト:https://api.hetzner.cloud/v1) |
トークンがなくてもサーバーは起動し、ツールを一覧表示します(レジストリやインスペクターからのイントロスペクションが可能です)。ただし、すべてのツール呼び出しは API にアクセスせず、セットアップ手順を示して失敗します。
HETZNER_API_TOKEN と HETZNER_API_BASE_URL は読み取り後にプロセスの環境から削除されるため、後からクラッシュレポートや診断ダンプが作成されてもトークンが漏れることはありません。
読み込むツールの選択
HETZNER_ALLOW_TOOLS と HETZNER_DENY_TOOLS には、カンマ区切りのツール名を指定します。末尾の * はファミリー全体に一致します。essential は厳選されたプリセットで、list_zones、get_zone、list_rrsets、get_rrset、create_rrset、set_records、delete_rrset、export_zonefile が含まれます。ゾーンの読み取りとレコードの変更に必要なツールを網羅しつつ、使用頻度が低く重大な影響を及ぼすツールは含みません。
HETZNER_ALLOW_TOOLS=essential
HETZNER_ALLOW_TOOLS=list_*,get_zone,set_records
HETZNER_DENY_TOOLS=delete_zone,import_zonefile
どのツールにも一致しない項目があると、名前を示して起動が中止されます。そのため、入力ミスによってツールが気付かれないまま非表示になることはありません。ツールが見つからない理由を環境変数までさかのぼって調べる必要もありません。フィルタリングされたツールは登録されないため、tools/list にも表示されず、tools/call からも認識されません。これは HETZNER_READ_ONLY が有効な場合の書き込みツールと同様です。
これらのサーバーを複数同時に実行する場合は、mcp-hub という選択肢もあります。/hub エンドポイントを使うと、各サーバーのツールが 6 つのメタツールに置き換わります。
インストール
Claude Code
claude mcp add hetzner-dns -s user \
-e HETZNER_API_TOKEN=your-token \
-- npx -y hetzner-dns-mcp
Claude Desktop
claude_desktop_config.json に追加します。
{
"mcpServers": {
"hetzner-dns": {
"command": "npx",
"args": ["-y", "hetzner-dns-mcp"],
"env": {
"HETZNER_API_TOKEN": "your-token"
}
}
}
}
Codex
~/.codex/config.toml に追加します。
[mcp_servers.hetzner-dns]
command = "npx"
args = ["-y", "hetzner-dns-mcp"]
env = { HETZNER_API_TOKEN = "your-token" }
ソースから
git clone https://github.com/ni-c/hetzner-dns-mcp.git
cd hetzner-dns-mcp
npm install
npm run build
# then use `node /path/to/hetzner-dns-mcp/dist/index.js` as the command
Docker
マルチアーキテクチャイメージ(amd64/arm64)は、SBOM とビルド来歴とともに GHCR に公開されています。
docker run -i --rm -e HETZNER_API_TOKEN=your-token ghcr.io/ni-c/hetzner-dns-mcp
このイメージは stdio 経由で MCP と通信するため、クライアントでは docker run -i が必要です(ポートは公開されません)。
{
"mcpServers": {
"hetzner-dns": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"HETZNER_API_TOKEN",
"ghcr.io/ni-c/hetzner-dns-mcp"
],
"env": {
"HETZNER_API_TOKEN": "your-token"
}
}
}
}
mcp-hub 経由
ローカルプロセスを起動できないクライアント(ChatGPT コネクター、ウェブ版の Claude、Cursor、LibreChat など)は、mcp-hub 経由で hetzner-dns-mcp に接続します。1つのコンテナーで複数の stdio MCP サーバーを Streamable HTTP 経由で提供し、単一のパスワードによる OAuth 2.1 ログインと、OAuth を利用できないクライアント向けの長期間有効なトークンを備えています。/hub エンドポイントはすべてのサーバーを6つのメタツールの背後に配置するため、モデルのコンテキストに N×ツールスキーマを含めることなく、1つのコネクターからすべてのサーバーに接続できます。また、両方のプロトコルリビジョンに対応しており、このサーバーが質問すると、相手側のユーザーまで伝わります。
/config/mcp.json は Claude Code の形式を使用するため、追加する項目はすでにお持ちのものと同じです。
{
"mcpServers": {
"hetzner-dns": {
"command": "npx",
"args": ["-y", "hetzner-dns-mcp"],
"env": {
"HETZNER_API_TOKEN": "your-token",
"HETZNER_ALLOW_TOOLS": "essential"
},
"denyTools": ["delete_*"]
}
}
}
ここでの allowTools と denyTools は、サーバーごとに適用されるハブ独自のフィルターであり、env 内の *_ALLOW_TOOLS とは異なります。その違いと、そこで起こりがちな間違いについては、クライアントガイドをご覧ください。
ツール
すべてのツールは outputSchema を宣言し、テキストブロックとともに structuredContent を返すため、クライアントは文章を解析せずに結果を利用できます。<untrusted-data> の囲みはテキスト内に残ります。これは同じマーカーを読みやすく表示したものです。また、構造化データにはフィールドとして untrusted: true と source: "hetzner-cloud-api" が含まれます。すべてのツールがこれらを含みます。レコード値、コメント、ラベル、ゾーンファイルはゾーンを管理するユーザーが記述するものであり、このサーバーのツールがそれ以外のものを返すことはありません。
API ドキュメントは、仕様で保証されているトップレベルキーを持つオープンオブジェクトとして記述されています。API はこのサーバーが保証できるものではなく、SDK は結果を返す前に各結果をスキーマに照らして検証します。厳密な形式を指定すると、Hetzner がフィールドを追加した際にツールが完全に失敗してしまいます。
予算を超える結果は、現在エラーになります。以前はドキュメントの途中で切り詰めてその旨を伝えていましたが、テキストブロックなら問題ない一方、structuredContent では不可能です。2つのチャンネルで同じ値を返す必要があり、文字列の途中で切られたドキュメントは解析できません。
ゾーン
| ツール | 説明 |
|---|---|
list_zones | ステータス、モード、ネームサーバー、レコード数とともにゾーンを一覧表示します |
get_zone | 単一のゾーンの詳細をすべて取得します |
create_zone | プライマリまたはセカンダリゾーンを作成します。ゾーンファイルを指定することもできます |
update_zone | ゾーンのラベルを置き換えます |
delete_zone 👤 | ゾーンを完全に削除します |
export_zonefile | ゾーンを BIND ゾーンファイルとしてエクスポートします |
import_zonefile 👤 | BIND ゾーンファイルをインポートします(すべてのレコードを置き換えます) |
change_zone_ttl | ゾーンのデフォルト TTL を変更します |
change_zone_protection 👤 | 削除保護を有効/無効にします — 無効にする際は確認を求めます |
change_primary_nameservers 👤 | セカンダリゾーンのプライマリを置き換えます |
RRSets(レコードセット)
| ツール | 説明 |
|---|---|
list_rrsets | ゾーンのRRSetsを一覧表示します。名前/タイプ/ラベルで絞り込めます |
get_rrset | 名前とタイプを指定して、単一のRRSetを取得します |
create_rrset 👤 | レコードを含む新しいRRSetを作成します — 権威レコードを確認します |
update_rrset | RRSetのラベルを置き換えます |
delete_rrset 👤 | RRSetを完全に削除します |
set_records 👤 | RRSetのすべてのレコードを置き換えます |
add_records 👤 | RRSetにレコードを追加します(存在しない場合は作成します) — 権威レコードを確認します |
remove_records 👤 | RRSetから特定のレコードを削除します |
change_rrset_ttl | RRSetのTTLを変更します(またはnullでゾーンのデフォルトに戻します) |
change_rrset_protection 👤 | 変更保護を有効/無効にします — _無効にする_際に確認します |
👤 MCPのエリシテーションを通じて人に確認します · クライアントがダイアログを表示できない場合は、2回の呼び出しによる
confirm_tokenにフォールバックします。
アクション
| ツール | 説明 |
|---|---|
list_zone_actions | 非同期のゾーン操作(インポートなど)を一覧表示します。ステータスで絞り込めます |
get_zone_action | ステータスを確認するため、IDを指定して単一のアクションを取得します |
安全性
人に確認を求めます。指示するだけではありません。 delete_zone、
delete_rrset、import_zonefile、set_records、remove_records、
change_primary_nameservers、および保護を_解除する_場合の
change_zone_protection/change_rrset_protectionなど、取り消せない操作を行うすべてのツールは、クライアントが対応している場合、MCP エリシテーションを通じて実際のダイアログを表示します。モデルが人の代わりに回答することはできず、回答が返されるまで何も実行されません。
さらに3つのツールは、条件付きで確認を求めます。DNSでは、危険な操作は取り消すことではなく、何かを宣言することだからです。誰が応答するかを決定する名前またはタイプ(NS、DS、MX、CNAME、CAA、TLSA、SVCB、
HTTPS、SRV、ゾーン頂点の@、ワイルドカード)に対するcreate_rrsetとadd_records、およびprimary_nameserversまたはzonefileを含む呼び出しのcreate_zoneが対象です。これらは、change_primary_nameserversとimport_zonefileで保護されるものと同じペイロードです。確認はTTLやラベルを含め、呼び出しで書き込むすべてのフィールドに紐付けられるため、あるTTLに対して発行されたトークンで別のTTLを承認することはできません。
クライアントがダイアログを表示できない場合、ツールは最初の呼び出しを拒否し、5分間有効なランダムな使い捨てトークンを返します。2回目の呼び出しでは、同一の引数を再度指定し、そのトークンを渡す必要があります。
1. set_records(zone: "example.com", name: "www", type: "A", records: [{value: "198.51.100.1"}])
→ error: Refusing to replace the records … confirm_token: "3f9c…"
2. set_records(…same arguments…, confirm_token: "3f9c…")
→ executed
モデルが自分で設定できるブール値には意図的にしていません。トークンは_以前の_ツール結果にしか存在しないため、TXTレコードやゾーンファイルのコメントに隠された指示でトークンを捏造することはできません。ただし、これは同じ引数で呼び出しが2回行われたことだけを証明するもので、それ以上の意味はありません。フォールバック時の文言でも、誰かが承認したかのように誤解させず、その点を明示します。
どちらの場合も、承認は対象の内容に紐付けられます。set_records、remove_records、import_zonefileでは、これはペイロードそのもののハッシュです。["198.51.100.1"]に対する承認で、["198.51.100.66"]を書き込むことはできません。
ELICITATION=falseを設定すると、スケジュールされたジョブやテストハーネス向けに、意図的にフォールバック経路を使用します。ガードが解除されることはありません。人への確認を参照してください。
ダイアログは安全策であり、セキュリティ境界ではありません。境界となるのは、MCP ホストの権限確認です。これらのツールを自動承認しないでください。
信頼できない上流データ。 APIから返されるすべてのデータは<untrusted-data>エンベロープで囲まれます。レコード値、コメント、ラベル、ゾーンファイルは、ゾーンを管理する人が書き込むものだからです。確認メッセージでその内容を引用することはありません。件数とTTLのみを報告します。秘密情報のように見えるキー(tsig_key、token、secret、password)は結果から伏せられ、サイズの大きな値は切り詰められます。また、中間プロキシからのHTMLエラーページは、モデルのコンテキストに貼り付けるのではなく破棄されます。
最小権限。 HETZNER_READ_ONLY=trueを設定すると、読み取り専用の7つのツールだけが登録されます。書き込みツールは呼び出し時に失敗するのではなく、プロトコル上に存在しなくなります。読み取り専用のHetznerトークンと併用すれば、真に読み取り専用の構成になります。
その他の保証。
- ツールにはMCPアノテーション(
readOnlyHint、destructiveHint、idempotentHint)が付与されるため、ホストは適切な権限ポリシーを適用できます。 HETZNER_API_BASE_URLにはhttpsのURLを指定する必要があります(httpが許可されるのはlocalhostのみです)。また、認証情報を含めることはできません。APIトークンがそのホストに送信されるため、デフォルト以外のホストが設定されると警告が表示されます。- ゾーン識別子とRRSet名は厳格な文字セットで検証されます。スラッシュ、パーセント記号、単独の
.や..は使用できません。そのため、リクエストが意図したAPIパスから逸脱することはありません。リクエストでリダイレクトを追跡することもないため、Bearerヘッダーが別の場所で再利用されることはありません。 create_zone/change_primary_nameserversに渡されたTSIGキーは、会話のコンテキストやクライアントのトランスクリプトに含まれます。秘密情報として扱い、疑わしい場合はローテーションしてください。- Hetzner側のリソース保護が尊重されます。保護されたゾーン/RRSetではエラーが返され、対応する
change_*_protectionツールが案内されます。
意図的に公開していないもの
Hetzner Cloud DNS API のみです。 独立した dns.hetzner.com API は
2026 年 5 月に停止されており、実装されていません。今もこれを使用している
スクリプトは、このサーバーとは無関係の理由で動作しません。
HETZNER_API_BASE_URL はプロバイダーを切り替えるものではありません。 開発中に
ローカルのモックを指定するためのものであり、トークンが送信される先だからこそ、
HTTPS のみ、URL に認証情報を含めない、デフォルト以外のホストには警告を表示する、
という検証を行います。リクエストの形式は Hetzner のものです。
安全性
- DNS レコードはトークンを持つ人が編集できるため、上流からの値、コメント、
ゾーンファイルは信頼できないデータとして扱います。両方のチャネルで、また
データ自身が閉じられないフェンスの内側でも、報告する対象として扱い、決して
指示として実行しません。キーは正規化した名前の末尾(
password、secret、token、apikey、privatekey、passphrase、tsigkey)に基づいて伏せられ、 4 000 文字を超える値は切り詰められ、制御文字は取り除かれます。また、HTML の エラーページはコンテキストに貼り付けず破棄されます。 - ゾーンの削除やレコードセットの置き換えには、人による確認が必要です。MCP エリシテーションを通じて、対象を正確に指定した実際のダイアログを表示します。 クライアントがダイアログを表示できない場合、呼び出しは拒否され、以前のツール 結果にのみ含まれていたランダムな使い捨てトークンが付与されます。
HETZNER_READ_ONLY=trueを設定すると、7 つの読み取りツールのみが登録されます。 その場合、書き込みツールは呼び出し時に拒否されるのではなく、tools/listに 表示されません。- リクエストは信頼するのではなく、堅牢化されています。ゾーン識別子はパターン照合
され、パスが範囲外に逸脱するのを防ぎます。リダイレクトは拒否されるため、
Authorizationヘッダーがリダイレクト先に送られることはありません。すべての リクエストは 30 秒後にタイムアウトし、リクエスト本文は名前付きフィールドのみ から組み立てられます。また、トークンを送信する前にベース URL の検証(HTTPS、 認証情報なし)が行われます。トークン自体の形式も、エラーにそのまま引用される 可能性のある HTTP レイヤーに届く前にチェックされます。レスポンス本文は上限を 設けて読み取り、先にステータスを判定します。さらに、すべてのレスポンスは キャストするのではなく形式を検証するため、プロキシからの応答でも、原因の 分からないスキーマ違反ではなく、読みやすい結果が返されます。
ドキュメント
ガイド全文、ツールリファレンス、安全性に関する注意事項は
hetzner-dns-mcp.ni-c.de にあります(ソースは
docs/ にあります)。
開発
npm install
npm run build # compile TypeScript to dist/
npm test # run the vitest test suite
npm run lint # oxlint + prettier check
リリース
package.jsonのバージョンを更新します(npm version X.Y.Z --no-git-tag-version)。CHANGELOG.mdの[Unreleased]セクションを新しいバージョン名に変更します。- コミットし、タグを作成してプッシュします:
git tag -a vX.Y.Z -m "vX.Y.Z" && git push origin main vX.Y.Z。
その後、リリースワークフローがテストを実行し、
Trusted Publishing を使って npm に
公開し(プロビナンス付き)、CHANGELOG のリリースノートを含む GitHub リリースを
作成して、公式
MCP Registry
(io.github.ni-c/hetzner-dns-mcp、GitHub OIDC 経由)のエントリーを更新します。
リリース
リリースはタグによって実行されます。package.json のバージョンを更新し、
CHANGELOG.md の [Unreleased] の内容を新しいバージョンの下に移動してコミットし、
その後、次を実行します。
git tag -s vX.Y.Z -m "vX.Y.Z"
git push origin main vX.Y.Z
リリースワークフローでは、Trusted Publishing(OIDC、プロビナンス付き)を使って npm に公開し、マルチアーキテクチャのコンテナイメージを GHCR にプッシュし、 CHANGELOG の該当セクションから GitHub リリースを作成して、公式 MCP レジストリーのエントリーを更新します。
コントリビュート
イシュー、ディスカッション、プルリクエストを歓迎します。 CONTRIBUTING.md をご覧ください。脆弱性については、公開イシュー ではなく非公開での報告 をご利用ください。ポリシーは SECURITY.md に記載されています。
ライセンス
MIT © Willi Thiel
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。