Discover and publish AI agents via DNS using SVCB records (RFC 9460)
DNS-AID is a server that discovers and publishes AI agents via DNS using SVCB records (RFC 9460). It leverages DNS-based agent discovery and integrates with DNS security concepts to enable agent publication and retrieval.
π οΈ Key Features
Agent discovery through DNS using SVCB records (RFC 9460)
Publish AI agents via DNS infrastructure
Integration with DNSSEC-aware workflows
Open source repository style for collaboration
π Use Cases
Discover AI agents in a scalable, DNS-based namespace
Publish and distribute agent endpoints using standard DNS records
Enable automated agent lookup in cloud or on-prem environments
β‘ Developer Benefits
Clear MCP-aligned server description and repository signals
Topics include a2a, agent-discovery, ai-agents, dns-aid, and MCP
Readme excerpt provides CI, security, and project badges for quick health checks
β οΈ Limitations
Data in readme excerpt is partial; consult repository for full implementation details
May rely on RFC 9460 SVCB behavior and DNS infrastructure availability
DNS-AID enables AI agents to discover each other via DNS, using the internet's existing naming infrastructure instead of centralized registries or hardcoded URLs.
DNS-AID is a substrate. The library in this repository is sufficient on its own β it publishes and resolves agent records against any DNS provider, with no dependency on a particular directory, indexer, or telemetry backend.
When a search, indexing, or telemetry layer is useful, the SDK can point at any HTTP endpoint that implements the documented interfaces. Operators are encouraged to run their own β the indexer is a thin layer over the same DNS records this library publishes and discovers, and the SDK telemetry sink is configurable via DNS_AID_SDK_HTTP_PUSH_URL (off by default). Independent directory implementations exist across the ecosystem; DNS-AID is designed to remain interoperable with any of them rather than canonicalize a single one.
Quick Start
Install
bash
# Install from PyPI
pip install "dns-aid[cli,mcp]"# Or install the latest unreleased main from GitHub
pip install "dns-aid[cli,mcp] @ git+https://github.com/dns-aid/dns-aid-core.git"
For backend-specific extras (route53, cloudflare, ns1, cloud_dns, infoblox, akamai-edgedns, ddns), see the Getting Started Guide.
Python Library
python
import dns_aid
# Publish your agent to DNSawait dns_aid.publish(
name="my-agent",
domain="example.com",
protocol="mcp",
endpoint="agent.example.com",
capabilities=["chat", "code-review"]
)
# Discover agents at a domain (Path A: DNS substrate)
agents = await dns_aid.discover("example.com")
for agent in agents:
print(f"{agent.name}: {agent.endpoint_url}")
# Discover via HTTP index (richer metadata; format aligns with the ANS schema) β# also auto-detects and dereferences ARD ai-catalogs (see docs/ard-catalog.md)
agents = await dns_aid.discover("example.com", use_http_index=True)
# (0.26.3+) A catalog on your own domain needs nothing. An off-domain catalog# pointer is trusted only via per-record JWS (verify_signatures=True) or, opt-in,# a DNSSEC-validated pointer (trust_dnssec_pointers=True) β otherwise it is ignored# and discovery falls back to the on-domain catalog. The trust basis is surfaced as# AgentRecord.catalog_trust (tls_domain | dnssec | jws). See docs/ard-catalog.md.# (0.26.4+) Opt-in DNSSEC/DANE hardening (SDK/CLI/MCP; all default off β DNSSEC is# never required). require_dnssec / min_dnssec enforce the resolver AD flag on# DNS-plane agents (ARD / HTTP-catalog agents are exempt β they carry no DNS SVCB# record). verify_dane binds each agent endpoint's TLS cert to its DANE/TLSA record# (defense-in-depth, meaningful only under DNSSEC) β AgentRecord.dane_verified.# (0.26.5+) trust_dnssec_pointers (above) is exposed the same way β CLI# --trust-dnssec-pointers / MCP β so all four opt-in trust controls have SDK/CLI/MCP parity.# Filtered discovery β pure-Python predicates over the in-memory result (v0.19.0+)
result = await dns_aid.discover(
"example.com",
capabilities=["payment-processing"],
auth_type="oauth2",
realm="prod",
require_signed=True,
require_signature_algorithm=["ES256", "Ed25519"],
)
# Verify an agent's DNS records
result = await dns_aid.verify("my-agent.example.com")
print(f"Security Score: {result.security_score}/100")
Path B: cross-domain search via an external directory (v0.19.0+)
When the caller does not yet know which domain hosts the agent it wants, the SDK can query any directory backend that implements the search endpoint. The directory layer is opt-in convenience; the DNS substrate remains the authoritative trust gate.
python
from dns_aid.sdk import AgentClient, SDKConfig
# Point at whichever directory the caller has chosen to trust.# Can also be set via DNS_AID_SDK_DIRECTORY_API_URL.
config = SDKConfig(directory_api_url="https://your-directory.example.com")
asyncwith AgentClient(config=config) as client:
response = await client.search(q="payment processing", protocol="mcp")
for r in response.results:
print(r.agent.fqdn)
After the directory returns candidates, re-resolve each one through Path A and validate signatures / DNSSEC before invoking. This is the substrate-as-authority pattern: the directory provides ranking and discovery convenience, but never sits in the trust path between the caller and the agent.
python
asyncwith AgentClient(config=config) as client:
response = await client.search(q="fraud detection")
for candidate in response.results:
verified = await dns_aid.discover(
candidate.agent.domain,
name=candidate.agent.name,
require_signed=True,
)
# Invoke only when DNS substrate confirms the directory's claim.
The SDK exposes additional filter parameters (capabilities, min_security_score, verified_only, etc.) for directories that compute and return those signals; see API Reference for the full surface. The semantics of those values are defined by whichever directory the caller has chosen β DNS-AID does not centralize them.
SDK: Invoke Agents & Capture Telemetry (v0.6.0+)
python
import dns_aid
# Discover + invoke in one line β telemetry captured automatically
result = await dns_aid.discover("example.com", protocol="mcp")
agent = result.agents[0]
resp = await dns_aid.invoke(agent, method="tools/list")
print(f"Latency: {resp.signal.invocation_latency_ms}ms")
print(f"Status: {resp.signal.status}")
print(f"Tools: {resp.data}")
# Rank multiple agents by your own local telemetry signals
ranked = await dns_aid.rank(result.agents, method="tools/list")
for r in ranked:
print(f"{r.agent_fqdn}: score={r.composite_score:.1f}")
OpenTelemetry (v0.23.0+): install dns-aid[otel] and set
otel_enabled=True (or DNS_AID_SDK_OTEL_ENABLED=true) to emit spans +
metrics per invoke and propagate W3C trace context to downstream agents.
See docs/integrations/opentelemetry.md.
For advanced usage (connection reuse, OpenTelemetry export, pluggable telemetry sink):
python
from dns_aid.sdk import AgentClient, SDKConfig
config = SDKConfig(
otel_enabled=True, # Export to any OpenTelemetry collector
caller_id="my-app",
# Optional: push telemetry to any HTTP endpoint the caller controls# http_push_url="https://your-telemetry.example.com/v1/signals",
)
asyncwith AgentClient(config=config) as client:
resp = await client.invoke(agent, method="tools/call", arguments={...})
fqdns = [a.fqdn for a in agents]
ranked = client.rank(fqdns) # Rank by the caller's own observed telemetry
If an external aggregator publishes community-wide rankings over HTTP, the SDK can fetch them via client.fetch_rankings(...); the endpoint is configured by the caller, not by the library.
For short-lived credentials (RFC 8693 token exchange, AWS STS assume-role,
HashiCorp Vault dynamic secrets, HSM/KMS-backed signing keys), pass an opt-in
async credential_provider callback to invoke(). The SDK awaits the callback
lazily at invoke time with the target AgentRecord and uses the returned dict
for auth resolution. Strictly additive β every existing call site continues to
work without source change.
python
asyncdeftoken_exchange_provider(agent: AgentRecord) -> dict[str, str]:
# Mint a fresh delegation token per call β e.g., RFC 8693 token exchange# against Keycloak / Okta / Auth0 / Microsoft Entra ID.return {"token": await my_idp.exchange_token(subject_token, agent.fqdn)}
asyncwith AgentClient(config=config) as client:
resp = await client.invoke(
agent,
method="tools/list",
credential_provider=token_exchange_provider,
)
# Publish an agent to DNS
dns-aid publish \
--name my-agent \
--domain example.com \
--protocol mcp \
--endpoint agent.example.com \
--capability chat \
--capability code-review
# Publish with transport and auth metadata (v0.10.0+)
dns-aid publish \
--name billing \
--domain example.com \
--protocol mcp \
--endpoint mcp.example.com \
--capability billing --capability invoicing \
--transport streamable-http \
--auth-type bearer
# Publish with DNS-AID custom SVCB parameters (v0.4.8+)
dns-aid publish \
--name booking \
--domain example.com \
--protocol mcp \
--endpoint mcp.example.com \
--capability travel --capability booking \
--cap-uri https://mcp.example.com/.well-known/agent-cap.json \
--cap-sha256 dGVzdGhhc2g \
--bap "mcp/1,a2a/1" \
--policy-uri https://example.com/agent-policy \
--realm production
# Discover agents at a domain (pure DNS - default)
dns-aid discover example.com
# Discover with substrate filters
dns-aid discover example.com --protocol mcp --name chat
# Discover with in-memory filters (v0.19.0+)
dns-aid discover example.com \
--capabilities payment-processing --capabilities fraud-detection \
--auth-type oauth2 --realm prod \
--require-signed --require-signature-algorithm ES256
# Cross-domain search via a directory the caller has chosen (v0.19.0+)export DNS_AID_SDK_DIRECTORY_API_URL=https://your-directory.example.com
dns-aid search "payment processing" --protocol mcp
# Discover via HTTP index (richer metadata; format aligns with the ANS schema)
dns-aid discover example.com --use-http-index
# Output as JSON
dns-aid discover example.com --json
# Verify DNS records
dns-aid verify my-agent.example.com
# List DNS-AID records in a zone
dns-aid list example.com
# List available zones (Route 53)
dns-aid zones
# Delete an agent
dns-aid delete --name my-agent --domain example.com --protocol mcp
# Index Management (v0.3.0+)# List agents in a domain's index record
dns-aid index list example.com
# Sync index with actual DNS records (useful for repair)
dns-aid index sync example.com
# Advertise an ARD ai-catalog via DNS pointer (host-anywhere; v0.26.0+)# Publishes _catalog._agents + _index._agents SVCB β the catalog host.
dns-aid index publish-catalog example.com catalogue.example.com
# Publish without updating the index (for internal agents)
dns-aid publish --name internal-bot --domain example.com --protocol mcp --no-update-index
# Domain Submission to a Directory (v0.4.0+)# Submit your domain to a directory of your choice for indexing.# The --to flag (or DNS_AID_SDK_DIRECTORY_API_URL) selects which directory.
dns-aid submit example.com --to https://your-directory.example.com
# Submit with company metadata
dns-aid submit example.com \
--to https://your-directory.example.com \
--company-name "Example Corp" \
--company-website "https://example.com" \
--company-description "We build AI agents"
Agent Index Records
DNS-AID v0.3.0 automatically maintains an index record at _index._agents.{domain} for efficient discovery:
The index is updated automatically when you publish or delete agents. Use --no-update-index to opt out for internal agents.
Domain Control Validation (v0.20.0+)
DCV lets one party prove to another that they control a DNS zone, using a short-lived
TXT record challenge. Two use cases: anonymous agents asserting org affiliation, and
directory anti-impersonation before listing an agent as org-verified.
bash
# Challenger: issue a challenge for a domain
CHALLENGE=$(dns-aid dcv issue orgb.example.com --agent assistant --issuer orga.example.com --json)
TOKEN=$(echo$CHALLENGE | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")
# Claimant: place the challenge TXT record in the zone (using their own DNS credentials)
dns-aid dcv place orgb.example.com $TOKEN# Challenger: verify the record is present and unexpired
dns-aid dcv verify orgb.example.com $TOKEN# Claimant: revoke after successful verification
dns-aid dcv revoke orgb.example.com $TOKEN
python
from dns_aid.core import dcv
# Challenger
challenge = dcv.issue("orgb.example.com", agent_name="assistant", issuer_domain="orga.example.com")
# ... deliver challenge out-of-band to claimant ...# Claimant (different process, different credentials)await dcv.place(challenge.domain, challenge.token, bnd_req=challenge.bnd_req)
# Challenger
result = await dcv.verify(challenge.domain, challenge.token, expected_bnd_req=challenge.bnd_req)
if result.verified:
await dcv.revoke(challenge.domain, token=challenge.token)
DNS-AID also supports HTTP-based agent discovery, with an index format whose schema aligns with ANS-style directories. This provides richer metadata (descriptions, model cards, capabilities, costs) while still validating endpoints via DNS.
Endpoint patterns tried (in order):
https://index.aiagents.{domain}/index-wellknown (demo-friendly, no underscores)
https://index.aiagents.{domain}/cap/{agent-name} β returns a capability document JSON per agent
bash
# Fetch HTTP index directly
curl https://index.aiagents.example.com/index-wellknown
# Fetch capability document for a specific agent
curl https://index.aiagents.example.com/cap/booking-agent
# CLI with HTTP index
dns-aid discover example.com --use-http-index
python
# Python with HTTP index
agents = await dns_aid.discover("example.com", use_http_index=True)
Discovery Method
When to Use
DNS (default)
Maximum decentralization, offline caching, minimal round trips
HTTP Index
Rich metadata upfront, ANS compatibility, model cards, capabilities, direct endpoints
FQDN as Source of Truth (v0.4.7): The HTTP index only needs to provide each agent's FQDN (e.g., booking.example.com). Agent name and protocol are extracted from the FQDN β no separate protocols field needed. DNS SVCB lookup then resolves the authoritative endpoint.
Discovery Transparency (v0.4.6+): Each discovered agent includes source fields showing how data was resolved:
Field
Values
Description
endpoint_source
dns_svcb, http_index_fallback, direct
How the endpoint was resolved
capability_source
cap_uri, txt_fallback, none
How capabilities were discovered (v0.4.8+)
Capability Resolution (v0.4.8+): Capabilities are resolved with the following priority:
SVCB cap URI β fetch capability document (JSON with capabilities, version, description)
TXT record fallback β capabilities=chat,support from DNS TXT record
HTTP Index inline β capabilities embedded in the index JSON response
MCP Server
DNS-AID includes an MCP (Model Context Protocol) server that allows AI agents like Claude to publish and discover other agents.
Running the MCP Server
bash
# Run with stdio transport (default - for Claude Desktop, etc.)
dns-aid-mcp
# Run with HTTP transport
dns-aid-mcp --transport http --port 8000
Available MCP Tools
Tool
Description
publish_agent_to_dns
Publish an AI agent to DNS (auto-updates index)
discover_agents_via_dns
Discover AI agents at a domain (supports use_http_index for HTTP-index discovery)
list_agent_tools
List available tools on a discovered MCP agent
call_agent_tool
Call a tool on a discovered MCP agent (proxy requests)
verify_agent_dns
Verify DNS-AID records and security
list_published_agents
List all agents in a domain
delete_agent_from_dns
Remove an agent from DNS (auto-updates index)
list_agent_index
List agents in domain's index record
sync_agent_index
Sync index with actual DNS records
diagnose_environment
Run environment diagnostics (deps, DNS, backends)
Claude Desktop Integration
Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
SHA-256 digest of capability descriptor for integrity verification
bap
Supported bulk agent protocols with versioning
policy
URI to agent policy document
realm
Multi-tenant scope identifier
This allows any DNS client to discover agents without proprietary protocols or central registries.
Discovery Flow (DNS-AID Draft Aligned)
code
Agent A DNS Agent B
β β β
β "Find agents at β β
β salesforce.com" β β
β β β
ββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Step 1: Fetch HTTP Index (primary) β
β ββββββββββββββββββββββββββββββββββ β
β GET https://index.aiagents.salesforce.com/index-wellknown β
β Response: [{"fqdn":"chat.salesforce.com",...}] β
β β
β Fallback: Query TXT Index via DNS β
β Query: _index._agents.salesforce.com TXT β
β Response: "agents=chat:a2a,billing:mcp" β
ββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
ββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Step 2: Query SVCB per agent β
β ββββββββββββββββββββββββββββ β
β Query: chat.salesforce.com SVCB β
β Response: SVCB 1 chat.salesforce.com. alpn="a2a" port=443 β
β cap="https://chat.salesforce.com/.well-known/cap.json"β
β (DNSSEC validated) β
ββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
ββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Step 2b: Fetch Capability Document (if cap URI present) β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β GET https://chat.salesforce.com/.well-known/cap.json β
β Response: {"capabilities":["chat","support"],"version":"1.0"} β
β (cap_sha256 integrity verified) β
ββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
ββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Step 3: TXT Capabilities (fallback if no cap document) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββ β
β Query: chat.salesforce.com TXT β
β Response: "capabilities=chat,support" "version=1.0.0" β
ββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββΊβ
β Connect to https://chat.salesforce.com:443 β
Index Resolution Priority: HTTP index endpoint β TXT index record β common name probing.
Capability Resolution Priority: SVCB cap URI β capability document β TXT record fallback.
Each discovered agent includes endpoint_source and capability_source showing which path was used.
Agent Metadata Contract (v0.10.0+)
DNS discovery tells you WHERE an agent is. The Agent Metadata Contract tells you HOW to connect, WHAT it can do, and WHETHER it's still active.
Every DNS-AID agent can serve a .well-known/agent.json endpoint:
Why this matters for orchestrators (LangGraph, CrewAI, etc.):
Field
Orchestrator Decision
intent: query
Safe to call in parallel, cacheable
intent: transaction
Needs atomic execution, rollback on failure
semantics: read
Safe to retry on timeout
semantics: write
NOT safe to retry β may duplicate side effects
auth.type: oauth2
Needs token exchange before calling
deprecated: true
Route to successor_fqdn instead
A2A Compatibility: Both DNS-AID and Google A2A use /.well-known/agent.json. The metadata fetcher auto-detects the format β DNS-AID native (has aid_version key) or A2A Agent Card β and normalizes both into the same metadata fields.
Directory and indexing services that build on top of DNS-AID β crawlers that walk public DNS for agent records, services that index .well-known/agent.json metadata, search frontends β are out of scope for this repository. They build on the substrate but are operated independently. Implementations are free to define their own scoring, ranking, and curation policy; DNS-AID does not centralize those choices.
Choosing the Right Interface
DNS-AID provides three interfaces. Choose based on your use case:
Python Library
Best for: Application developers building agent discovery into their code.
python
import dns_aid
# Integrate directly into your Python application
agents = await dns_aid.discover("example.com", protocol="mcp")
Use Case
Example
Building an AI agent that discovers other agents
Agent mesh applications
Embedding discovery into existing Python apps
Adding DNS-AID to a Flask/FastAPI service
Automated pipelines and scripts
CI/CD, scheduled publishing
Unit testing with mock backend
Testing without real DNS
CLI Tool
Best for: Operators, DevOps, and quick manual operations.
bash
dns-aid discover example.com --protocol mcp
Use Case
Example
Manual publishing/discovery
Testing a new agent deployment
Shell scripts and automation
cron jobs, deployment scripts
Debugging and troubleshooting
Checking DNS records exist
Zone management
Listing agents, bulk operations
MCP Server
Best for: AI assistants (Claude, etc.) that need DNS-AID capabilities.
bash
dns-aid-mcp # Claude can now use DNS-AID tools
Use Case
Example
Claude Desktop integration
"Find agents at salesforce.com"
AI-driven infrastructure
Agent self-registration and discovery
Natural language DNS management
"Publish my chat agent to DNS"
Building agentic workflows
Multi-agent orchestration
Decision Matrix
You want to...
Use
Build discovery into your Python app
Python Library
Run ad-hoc commands from terminal
CLI
Automate with shell scripts
CLI
Enable Claude/AI to manage DNS-AID
MCP Server
Test without real DNS
Python Library (with MockBackend)
Debug DNS record issues
CLI (dns-aid verify)
DNS Backends
For per-provider environment configuration, see the Getting Started Guide backend sections.
export INFOBLOX_API_KEY="your-api-key"export INFOBLOX_DNS_VIEW="default"# Or your specific view name
Identify your zone and view:
In Infoblox Portal, go to DNS β Authoritative Zones
Note the zone name (e.g., example.com) and which view it belongs to
Use in Python:
python
from dns_aid.backends.infoblox import InfobloxBloxOneBackend
from dns_aid.core.publisher import set_default_backend
from dns_aid import publish
# Initialize backend (reads from environment variables)
backend = InfobloxBloxOneBackend()
# Or with explicit configuration
backend = InfobloxBloxOneBackend(
api_key="your-api-key",
dns_view="default", # Your DNS view name
)
set_default_backend(backend)
await publish(
name="my-agent",
domain="example.com",
protocol="mcp",
endpoint="agent.example.com",
capabilities=["chat", "code-review"]
)
Infoblox UDDI SVCB Support
Infoblox UDDI supports full ServiceMode SVCB (RFC 9460): priority > 0 with svc_params,
including the standard keys (alpn, port, mandatory, ipv4hint, ipv6hint, ...) and the
private-use range key65280βkey65534. DNS-AID's custom parameters (cap, cap-sha256,
bap, policy, realm, sig, connect-class, connect-meta, enroll-uri β encoded as
key65400βkey65405) are written natively on the SVCB record, not demoted to a TXT
companion.
DNS-AID Requirement
Akamai Edge DNS
Route 53
Infoblox UDDI
ServiceMode (priority > 0)
β
β
β
alpn / port / mandatory
β
β
β
Private-use keys (cap/bap/policy/realm/sig/...)
β
β
β
Infoblox UDDI and Akamai Edge DNS are fully DNS-AID-compliant ServiceMode SVCB backends.
Verify Records via API
Since Infoblox UDDI zones may not be publicly resolvable, verify records via the API:
python
asyncwith InfobloxBloxOneBackend() as backend:
asyncfor record in backend.list_records("example.com", name_pattern="my-agent"):
print(f"{record['type']}: {record['fqdn']}")
DDNS Setup (RFC 2136)
DDNS (Dynamic DNS) is a universal backend that works with any DNS server supporting RFC 2136, including BIND9, Windows DNS, PowerDNS, and Knot DNS. This is ideal for on-premise DNS infrastructure without vendor-specific APIs.
Environment Variables
Variable
Required
Default
Description
DDNS_SERVER
Yes
-
DNS server hostname or IP
DDNS_KEY_NAME
Yes
-
TSIG key name
DDNS_KEY_SECRET
Yes
-
TSIG key secret (base64)
DDNS_KEY_ALGORITHM
No
hmac-sha256
TSIG algorithm
DDNS_PORT
No
53
DNS server port
Step-by-Step Setup
Create a TSIG key on your DNS server (BIND example):
bash
tsig-keygen -a hmac-sha256 dns-aid-key > /etc/bind/dns-aid-key.conf
Configure your zone to allow updates with the key:
code
zone "example.com" {
type master;
file "/var/lib/bind/example.com.zone";
allow-update { key "dns-aid-key"; };
};
from dns_aid.backends.ddns import DDNSBackend
from dns_aid import publish
backend = DDNSBackend()
# Or with explicit configuration
backend = DDNSBackend(
server="ns1.example.com",
key_name="dns-aid-key",
key_secret="base64secret==",
key_algorithm="hmac-sha256"
)
await publish(
name="my-agent",
domain="example.com",
protocol="mcp",
endpoint="agent.example.com",
backend=backend
)
DDNS Advantages
Universal: Works with BIND, Windows DNS, PowerDNS, Knot, and any RFC 2136 server
No vendor lock-in: Standard protocol, no proprietary APIs
On-premise friendly: Perfect for enterprise internal DNS
Full DNS-AID compliance: Supports ServiceMode SVCB with all parameters
Cloudflare Setup
Cloudflare DNS is ideal for demos, workshops, and quick prototyping thanks to its free tier and excellent API support. DNS-AID fully supports Cloudflare's SVCB record implementation, including native private-use SVCB keys β DNS-AID's custom parameters (cap, cap-sha256, bap, policy, realm, ...) are written directly to the SVCB record (key65400βkey65409), with no TXT demotion.
Environment Variables
Variable
Required
Default
Description
CLOUDFLARE_API_TOKEN
Yes
-
API token with DNS edit permissions
CLOUDFLARE_ZONE_ID
No
-
Zone ID (auto-discovered if not set)
Step-by-Step Setup
Create an API token in Cloudflare Dashboard:
Go to My Profile β API Tokens β Create Token
Use the "Edit zone DNS" template or create custom with:
Permissions: Zone β DNS β Edit
Zone Resources: Include β Specific zone β your-domain.com
Copy the token (shown only once)
Configure environment variables:
bash
export CLOUDFLARE_API_TOKEN="your-api-token"# Optional: specify zone ID (otherwise auto-discovered from domain)export CLOUDFLARE_ZONE_ID="your-zone-id"
from dns_aid.backends.cloudflare import CloudflareBackend
from dns_aid import publish
# Initialize backend (reads from environment variables)
backend = CloudflareBackend()
# Or with explicit configuration
backend = CloudflareBackend(
api_token="your-api-token",
zone_id="optional-zone-id", # Auto-discovered if not provided
)
await publish(
name="my-agent",
domain="your-domain.com",
protocol="mcp",
endpoint="agent.your-domain.com",
backend=backend
)
Cloudflare Advantages
Free tier: DNS hosting is free for unlimited domains
SVCB support: Full RFC 9460 compliance with SVCB Type 64 records
Native private-use SVCB keys: DNS-AID custom params go straight into the SVCB record (key65400βkey65409) β no TXT demotion, matching NS1 and NIOS
Global anycast: Fast DNS resolution worldwide
Simple API: Well-documented REST API v4
Full DNS-AID compliance: Supports ServiceMode SVCB with all parameters
Akamai Edge DNS Setup
Akamai Edge DNS supports ServiceMode SVCB records with full private-use key support, making it fully compliant with the DNS-AID draft. All custom DNS-AID parameters (cap, bap, realm, etc.) are written directly into SVCB β no TXT demotion.
Writes are safe under concurrency: the backend serializes its own writes per zone and automatically retries Akamai's transient 409 concurrentZoneModification responses with exponential backoff.
Environment Variables
Variable
Required
Default
Description
AKAMAI_HOST
No*
-
EdgeGrid API hostname (e.g., akab-xxxx.luna.akamaiapis.net)
AKAMAI_CLIENT_TOKEN
No*
-
EdgeGrid client token
AKAMAI_CLIENT_SECRET
No*
-
EdgeGrid client secret
AKAMAI_ACCESS_TOKEN
No*
-
EdgeGrid access token
AKAMAI_EDGERC
No
~/.edgerc
Path to .edgerc credentials file
AKAMAI_EDGERC_SECTION
No
default
Section within .edgerc to use
* Required if not using .edgerc. Environment variables take precedence over .edgerc when both are present.
Step-by-Step Setup
Create API credentials in Akamai Control Center:
Go to Identity & Access β Create API Client
Grant DNSβZone Record Management read-write permission
Download the .edgerc file or note the four credential values
import asyncio
from dns_aid.backends.akamai_edgedns import AkamaiEdgeDNSBackend
from dns_aid import publish
asyncdefmain():
# Initialize backend (reads from ~/.edgerc or environment variables)
backend = AkamaiEdgeDNSBackend()
await publish(
name="my-agent",
domain="your-domain.com",
protocol="mcp",
endpoint="agent.your-domain.com",
backend=backend,
)
asyncio.run(main())
Akamai Edge DNS Features
Native SVCB support: Full RFC 9460 compliance including private-use keys
Full DNS-AID compliance: All custom params (cap, bap, realm, etc.) written natively on the SVCB record β no demotion to TXT
DNSSEC: Built-in zone signing via sign-and-serve
Flexible credentials: Supports both .edgerc file and environment variables
How DNS-AID Relates to Other Efforts
Agent discovery is an active design space, with multiple proposals working at different layers of the stack. DNS-AID is intentionally narrow: it standardizes a DNS-layer substrate that publishers and resolvers can rely on, leaving directory, ranking, payments, and namespace policy to other efforts. The summary below is meant to help operators understand where DNS-AID fits β not to position it against other work.
Adjacent efforts
Agent Name Service (ANS) β A directory-oriented approach defining a JSON metadata schema and registry interfaces. DNS-AID's HTTP Index format is intentionally aligned with the ANS schema where it overlaps, so an ANS-style directory can be served from the same data a DNS-AID publisher produces.
A2A β A communication protocol for agent-to-agent messaging. DNS-AID is complementary: A2A defines how two agents talk, DNS-AID defines how one agent finds the other's endpoint to talk to.
AgentDNS β A separate proposal that builds an agent-naming layer on top of DNS primitives. The two proposals overlap in spirit and differ in mechanism; DNS-AID's choice is to stay inside RFC 9460 SVCB so existing authoritative servers and resolvers work unchanged.
NANDA β A peer-to-peer overlay approach. Useful in deployments where a DHT-style substrate is preferred; DNS-AID instead targets the DNS infrastructure organizations already operate.
ai.txt / llms.txt β Free-form text files at well-known URLs. Useful for human-readable discovery; DNS-AID adds structured SVCB records and optional DNSSEC-validated trust.
.agent gTLD β An ICANN new-gTLD effort by the Agent Community to create a dedicated namespace (mycompany.agent). Complementary to DNS-AID β when .agent domains become available, DNS-AID records will work on them too, the same way they work on any other zone.
Where DNS-AID is scoped
DNS-AID standardizes the publish/resolve substrate: SVCB record layout, naming convention, capability and policy parameters, and a DNSSEC-anchored verification path. It does not pick a winning directory, ranking algorithm, payment system, or trust authority. Operators are free to combine DNS-AID with any of the efforts above, or to run it standalone.
Background and Comparison
For background on how DNS-AID compares to other agent-discovery approaches (ANS, Google A2A+UCP, .agent gTLD, AgentDNS, NANDA, Web3, ai.txt) and "The Sovereignty Question", see docs/positioning.md. That content is non-normative β protocol positioning is determined at the IETF.
Examples
See the examples/ directory:
demo_route53.py - Basic Route 53 publish/discover
demo_full.py - Complete end-to-end demonstration
bash
# Run the full demoexport DNS_AID_TEST_ZONE="your-zone.com"
python examples/demo_full.py
Development
bash
# Clone the repo
git clone https://github.com/dns-aid/dns-aid-core.git
cd DNS-AID
# Install all workspace packages (requires uv)
uv sync# Run all tests
uv run pytest
# Run tests for a specific package
uv run pytest packages/dns-aid-directory/tests/
uv run pytest packages/dns-aid-crawlers/tests/
uv run pytest packages/dns-aid-k8s/tests/
# Run with coverage
uv run pytest --cov=dns_aid_directory --cov=dns_aid_crawlers --cov=dns_aid_k8s
Contributions welcome! This project supports an implementation ecosystem with planned hosting in the Linux Foundation. The DNS-AID specification is developed in the IETF.