Automation toolkit for HE.net Free DNS. It provides:
- A reusable Node.js core library for DNS zone parsing, record normalization, diffs, and safety checks.
- A guarded Playwright-backed HE.net web adapter for logged-in
dns.he.networkflows. - A CLI for planning, applying, verifying, and reporting DNS changes.
- An Ansible collection scaffold at
optdyn.he_net. - An MCP server so agents can inspect, plan, and apply DNS changes with explicit confirmations.
HE.net does not publish a general full CRUD DNS management API for Free DNS. This project treats the web UI as an adapter and keeps desired state, validation, exact-domain matching, and reporting in local code.
- Dry-run by default.
- Destructive operations require exact zone equality and confirmation tokens.
- No wildcard, substring, prefix, or fuzzy matching for zone selection.
- Credentials are read from environment variables or ignored files and are never written to reports.
- Reports are redacted before persistence.
- Live DNS verification queries authoritative nameservers directly.
- Mutation commands write local archive snapshots and operation history under
.local/he-net-archivesby default.
The CLI create path supports the record types published by HE.net Hosted DNS:
A, AAAA, AFSDB, ALIAS, CAA, CNAME, HINFO, LOC, MX,
NAPTR, NS, PTR, RP, SPF, SRV, SSHFP, and TXT.
Unsupported record types are rejected before a live form submission.
Supported credential sources:
HE_NET_USERNAMEandHE_NET_PASSWORDHE_NET_CREDS=/path/to/file./he-net-creds.txt
Credential files may be JSON, key/value, netrc, username:password, or two-line username/password text.
Parse a raw HE.net AXFR capture:
he-net zone parse --origin example.com. --input example-zone.txt --records-json records/example.com.json --zone-file zones/example.com.zoneInspect a zone in the logged-in HE.net account:
he-net he inspect-zone --zone example.com --report reports/example.com.mdPlan a record change:
he-net he plan-records --zone example.com --desired records/example.com.desired.json --report reports/example.com-plan.mdApply a record change:
he-net he apply-records --zone example.com --desired records/example.com.desired.json --execute --confirm-zone example.com --confirm-apply APPLY_RECORDSList archived snapshots:
he-net archive list --zone example.comPlan rollback to a historical snapshot:
he-net he rollback-plan --zone example.com --snapshot SNAPSHOT_ID --report reports/example.com-rollback.mdApply rollback:
he-net he rollback-records --zone example.com --snapshot SNAPSHOT_ID --execute --confirm-zone example.com --confirm-rollback ROLLBACK_RECORDSVerify authoritative answers:
he-net dns verify --records records/example.com.desired.json --nameserver ns1.he.net --nameserver ns2.he.netThe collection lives under ansible_collections/optdyn/he_net.
Example:
- name: Plan HE.net records
optdyn.he_net.he_net_record:
zone: example.com
desired:
- owner: www.example.com.
type: A
ttl: 300
rdata: 203.0.113.10
state: present
execute: falseRun:
he-net-mcpTools exposed:
parse_zoneworkflow_recordscompare_recordsverify_recordslist_zonesinspect_zoneplan_recordsapply_recordsdelete_recordsrollback_planrollback_recordsinspect_slave_conversionconvert_slavearchive_list_snapshotsarchive_show_snapshotarchive_list_operationsarchive_show_operation
Mutation tools are dry-run by default and require exact zone, execute=true,
and operation-specific confirmation tokens such as APPLY_RECORDS,
DELETE_RECORDS, ROLLBACK_RECORDS, or CONVERT.
Install the local MCP server into the current Linux user's VS Code MCP configuration:
npm run install:vscode-mcpDry-run first:
npm run install:vscode-mcp -- --dry-runInstall to a workspace-local .vscode/mcp.json instead:
npm run install:vscode-mcp -- --scope workspaceAdd a credentials file path to the VS Code MCP server environment:
npm run install:vscode-mcp -- --creds-path "$PWD/he-net-creds.txt"The installer preserves existing MCP server entries, backs up an existing
mcp.json to mcp.json.bak, installs npm dependencies, installs Playwright
Chromium, and writes a VS Code servers.heNetDns stdio entry.
Live test domains are local operator configuration. Copy
test-domains.example.txt to ./test-domains.txt, or symlink
./test-domains.txt to a private file with one domain name per line. Inspect it
with:
he-net test-domains listNo live mutation is performed by automated tests.
Run read-only live integration tests against configured test domains:
HE_NET_LIVE_READ_TESTS=1 npm testRun guarded live mutation rollback tests against configured test domains:
HE_NET_LIVE_MUTATION_TESTS=1 \
HE_NET_CONFIRM_LIVE_MUTATION=ROLLBACK_TEST_DOMAINS \
npm testThe mutation rollback test snapshots each configured test domain, adds a
temporary TXT record, and rolls the zone back to the original snapshot in a
finally block.