Why Put Agent Discovery in DNS (Not Another Registry)
Agents and MCP servers are multiplying fast. Each one needs an endpoint, and right now most of us are wiring those endpoints by hand…
Why Put Agent Discovery in DNS (Not Another Registry)
Agents and MCP servers are multiplying fast. Each one needs an endpoint, and right now most of us are wiring those endpoints by hand: hardcoded URLs, env vars, a service mesh config that assumes everything sits still. That works until your agents stop sitting still. Ephemeral workloads spin up, move, and die. The orchestrator needs to find a capability, not memorize a host.
DNS already solves “find the thing by name” at planetary scale. So the question I kept circling was simpler than it sounds: what if DNS is only the pointer, never the schema?
That constraint became the whole project. It is called dns-agent-discovery, and the CLI is named dad. More on that at the end.
The problem, stated plainly
When you build agentic systems, three things fight you:
- Ephemeral agents. They come and go on timescales where static config is a liability, not a convenience.
- Moving endpoints. The thing you connected to yesterday is on a different pod today.
- Orchestrator-to-agent coupling. The moment your router knows deployment topology, you have welded orchestration to infrastructure.
I looked at the usual answers and turned each one down. Env vars and hardcoded URLs do not survive churn. Kubernetes-only service APIs lock you into one runtime and still do not carry capability metadata well. Consul and friends are heavyweight for what is really a pointer problem. A bespoke registry is one more service to run, secure, and explain, and it tends to absorb responsibilities it should not have.
The thing I most did not want: DNS holding MCP tool schemas, or auth living on the query plane. Name resolution should answer where and what, then get out of the way.
The idea
Give agents a sub-zone, agents.<cluster-domain>, and encode discovery in records DNS already supports:
- TXT carries
url,proto, andcaps(the capability tags). - SRV carries host and port.
- TTL defaults to 1 second, so short-lived agents expire on their own.
The flow is a clean handoff. DNS points. MCP connects.
db-reader.agents.cluster.local
TXT url=https://mcp.internal/v1/agents/db-reader proto=mcp caps=sql,crypto
SRV 0 5 443 mcp.internal

The schema exchange never touches the resolution plane. That separation is the entire point.
Architecture, in one breath
CoreDNS plus etcd, using the SkyDNS key format CoreDNS already understands. A Go library handles lookup and registration. The dad CLI wraps it for humans and scripts. A Helm chart deploys the whole thing on Kubernetes, and a Docker Compose demo runs it with no cluster at all.
Agent / Operator --register/deregister--> etcd (/skydns/...)
| ^
| lookup (DNS) | read
v |
agent-coredns (etcd plugin, TTL=1s) --------+
Tested on Colima and Talos. Current status is a v0.1.0 prototype, deployed and smoke-tested. Not a tagged release yet, so treat it as a working proof, not a dependency.
The five-second demo
The payoff is meant to fit in one breath:
cd demo
./try.sh
That spins up etcd and agent-coredns, registers a sample agent, and proves the lookup. The full lifecycle is the part worth watching: register, lookup, deregister, then a clean NXDOMAIN when the agent is gone. No tombstones, no stale pointers. The agent leaves and DNS forgets it, which is exactly what you want from an ephemeral system.
What we deliberately did not build
This is the section I care about most, because the restraint is the design.
- No MCP tool schema registry. Schemas belong at the application layer, after connect, via
tools/list. Putting them in DNS would recreate the registry I was trying to avoid. - No auth on the query plane. Lookups are open. The write path (registration) is where protection belongs, and that is coming, not bolted onto reads.
- No cross-cluster discovery yet. Federated lookup is a future ADR, not a v0.1.0 promise.
- No health signaling beyond TTL. A 1-second TTL is a blunt instrument. Real readiness is a later problem, and I would rather ship an honest blunt tool than a fake smart one.
One lesson worth passing on for anyone going down the SkyDNS path: the etcd record shape wants one TXT string per key (/txt0, /txt1, and so on), not a packed blob. I learned that the slow way so you do not have to.
The dad angle
The CLI is dad: DNS Agent Discovery. The name was too good to leave on the table, and yes, the weekend lab session that got it working happened to land on Father's Day. Discovery has a sense of humor. I will leave it there.
What is next
- Cluster DNS delegation, so kube-dns hands
agents.*to agent-coredns automatically. - Registration auth: etcd ACLs and NetworkPolicy first, mTLS on the write path after.
- A real v0.1.0 tag, with a published Go module and Helm chart.
Try it
Repo: github.com/raygj/dns-agent-discovery
Run the demo let me know if you could see it saving you time (and your santity) in you agentic SDLC. Improvements or ideas?
메타데이터
- post_id
- 4484e38bd82d
- slug
- why-put-agent-discovery-in-dns-not-another-registry-4484e38bd82d
- url
- https://medium.com/@ray.jim/why-put-agent-discovery-in-dns-not-another-registry-4484e38bd82d
- canonical_url
- https://medium.com/@ray.jim/why-put-agent-discovery-in-dns-not-another-registry-4484e38bd82d
- author_url
- https://medium.com/@ray.jim
- status
- ok
- fetched_at
- 2026-07-09 21:48:21