← Back to list

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…

Jim Ray · 2026-06-21 01:01 · 0 claps · 3.3 min read
#agents #dns #kubernetes #devops
Open on Medium ↗
Wiki topics: AGT · AI Agents FT · Fine-tuning & Adaptation ☁️ · DevOps & Cloud

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, and caps (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