关于 dns-aid
DNS-AID 是 IETF 草案 draft-mozleywilliams-dnsop-dnsaid-02 的参考实现,用于让 AI Agent 通过 DNS 中的 SVCB 记录相互发现与发布。它不依赖集中式注册表或硬编码 URL,面向需要在 DNS 上发布和解析 Agent 的开发者与运维人员。项目本身不定义规范,规范以 IETF 草案为准。
主要功能
- 01基于 SVCB 记录发布和解析 Agent
- 02提供 Python SDK、命令行和 MCP 服务工具
- 03Agent 索引记录与 HTTP 索引发现
- 04支持 DNS 域控制验证(DCV)
- 05可选的 OpenTelemetry 遥测与凭证回调
适用场景
- 01在自有域名下发布 MCP Agent 以便其他系统发现
- 02在 DNS 上解析指定域名的可用 Agent 及其端点
- 03通过 MCP 服务让 AI 客户端发布或发现 Agent
MCP 相关
该项目提供 MCP 服务(dns-aid-mcp),可通过 stdio 或 HTTP 传输向 MCP 客户端暴露 Agent 发布与发现相关的工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
DNS-AID
基于 DNS 的 Agent 标识与发现
IETF 草案 draft-mozleywilliams-dnsop-dnsaid-02 的参考实现。
DNS-AID 让 AI Agent 能够通过 DNS 发现彼此,利用互联网现有的命名基础设施,而不是依赖集中式注册表或硬编码 URL。
与 IETF 的关系
DNS-AID 规范正在 IETF 内制定:https://datatracker.ietf.org/doc/draft-mozleywilliams-dnsop-dnsaid/。
本仓库提供参考实现。
本项目不定义规范,IETF 草案具有权威性。
本仓库的范围
本项目专注于实现、工具和生态活动。
有关协议行为的变更应在 IETF 内讨论。
刚接触 DNS-AID? 请从入门指南开始,了解安装、首次发布 Agent 和后端设置。
文档
- 入门指南 — 安装、首次发布 Agent、后端设置
- API 参考 — Python SDK、CLI 和 MCP 服务工具参考
- ARD ai-catalog 发现 — 与 Agentic Resource Discovery 互操作:目录发现、host-anywhere DNS 指针和卡片解引用
- 架构 — 协议层、元数据解析、集成点
- 集成 — 特定后端的设置说明
- 演示指南 — 面向演讲和演示的端到端演练
- 路线图 — 项目近期、中期和长期的发展方向
- 隐私政策 | 安全政策 | 商标
生态与集成
DNS-AID 是一种基础层。本仓库中的库本身就足以独立使用——它可以针对任何 DNS 提供商发布和解析 Agent 记录,不依赖特定的目录、索引器或遥测后端。
当搜索、索引或遥测层有用时,SDK 可以指向任何实现了已记录接口的 HTTP 端点。我们鼓励运营者自行运行这些服务——索引器只是建立在此库发布和发现的同一批 DNS 记录之上的轻量层,SDK 遥测接收端可通过 DNS_AID_SDK_HTTP_PUSH_URL 配置(默认关闭)。生态中存在多种独立的目录实现;DNS-AID 的设计目标是与它们保持互操作,而非将某一种实现确立为标准。
快速开始
安装
# 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"
有关特定后端的额外功能(route53、cloudflare、ns1、cloud_dns、infoblox、akamai-edgedns、ddns),请参阅入门指南。
Python 库
import dns_aid
# Publish your agent to DNS
await 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")
路径 B:通过外部目录进行跨域搜索(v0.19.0+)
当调用方尚不知道目标 Agent 托管在哪个域时,SDK 可以查询任何实现了搜索端点的目录后端。目录层是可选的便利功能;DNS 底层仍是权威信任关卡。
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")
async with AgentClient(config=config) as client:
response = await client.search(q="payment processing", protocol="mcp")
for r in response.results:
print(r.agent.fqdn)
目录返回候选项后,通过路径 A 重新解析每个候选项,并在调用前验证签名 / DNSSEC。这就是“底层作为权威”的模式:目录提供排序和发现便利,但绝不会介入调用方与 Agent 之间的信任路径。
async with 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.
SDK 为能够计算并返回这些信号的目录提供了额外的筛选参数(capabilities、min_security_score、verified_only 等);完整参数请参阅 API 参考。这些值的语义由调用方选择的目录定义——DNS-AID 不会对其进行集中管理。
SDK:调用 Agent 并采集遥测数据(v0.6.0+)
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+):**安装 dns-aid[otel] 并设置
otel_enabled=True(或 DNS_AID_SDK_OTEL_ENABLED=true),即可为每次调用生成 span 和
指标,并将 W3C 跟踪上下文传播给下游 Agent。
请参阅 docs/integrations/opentelemetry.md。
如需了解进阶用法(连接复用、OpenTelemetry 导出、可插拔遥测接收器):
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",
)
async with 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
如果外部聚合器通过 HTTP 发布全社区排名,SDK 可以通过 client.fetch_rankings(...) 获取;端点由调用方配置,而非由库配置。
SDK:每次调用的凭据提供程序回调(v0.21.0+)
对于短期凭据(RFC 8693 令牌交换、AWS STS assume-role、HashiCorp Vault 动态密钥、由 HSM/KMS 支持的签名密钥),可向 invoke() 传入一个可选的异步 credential_provider 回调。SDK 会在调用时延迟等待该回调,并传入目标 AgentRecord,再使用返回的字典解析身份验证。此改动严格向后兼容——所有现有调用点无需修改源代码即可继续工作。
async def token_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)}
async with AgentClient(config=config) as client:
resp = await client.invoke(
agent,
method="tools/list",
credential_provider=token_exchange_provider,
)
优先级:auth_handler > credentials > credential_provider > no_auth。
请参阅 docs/security-credentials.md,了解各处理程序的安全矩阵、审计跟踪流程,以及
examples/integration_oauth2_token_exchange.py
和 examples/integration_aws_sts_assume_role.py
中的规范模式。
CLI 用法
# 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 索引记录
DNS-AID v0.3.0 会自动在 _index._agents.{domain} 维护索引记录,以便高效发现:
_index._agents.example.com. TXT "agents=chat:mcp,billing:a2a,support:https"
优点:
- 通过一次 DNS 查询即可发现域中的所有 Agent
- 爬虫可以高效地为域建立索引
- 明确列出已发布的 Agent(无需猜测)
当你 publish 或 delete Agent 时,索引会自动更新。对于内部 Agent,可使用 --no-update-index 选择不更新索引。
域控制验证(v0.20.0+)
DCV 允许一方通过短期 TXT 记录挑战,向另一方证明其控制某个 DNS 区域。适用于两种场景:匿名 Agent 声明所属组织,以及目录在将 Agent 列为组织已验证之前进行反冒充验证。
# 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
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)
完整详情请参阅 API 参考中的域控制验证。
HTTP 索引发现
DNS-AID 还支持基于 HTTP 的 Agent 发现,其索引格式的架构与 ANS 风格目录保持一致。它提供更丰富的元数据(描述、模型卡、能力、成本),同时仍通过 DNS 验证端点。
尝试的端点模式(按顺序):
https://index.aiagents.{domain}/index-wellknown(便于演示,无下划线)https://_index._aiagents.{domain}/index-wellknown(ANS 风格)https://{domain}/.well-known/agents-index.json(知名路径)
能力文档端点(v0.4.8+):
https://index.aiagents.{domain}/cap/{agent-name}— 返回每个 Agent 的能力文档 JSON
# 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 with HTTP index
agents = await dns_aid.discover("example.com", use_http_index=True)
| 发现方式 | 适用场景 |
|---|---|
| DNS(默认) | 最大程度的去中心化、离线缓存、最少的往返请求 |
| HTTP 索引 | 提前获取丰富的元数据、兼容 ANS、模型卡、能力、直接端点 |
以 FQDN 作为事实来源(v0.4.7): HTTP 索引只需提供每个 Agent 的 FQDN(例如 booking.example.com)。Agent 名称和协议会从 FQDN 中提取,无需单独的 protocols 字段。随后通过 DNS SVCB 查询解析权威端点。
发现透明度(v0.4.6+): 每个已发现的 Agent 都包含来源字段,用于说明数据的解析方式:
| 字段 | 值 | 说明 |
|---|---|---|
endpoint_source | dns_svcb、http_index_fallback、direct | 端点的解析方式 |
capability_source | cap_uri、txt_fallback、none | 能力的发现方式(v0.4.8+) |
能力解析(v0.4.8+): 能力按以下优先级解析:
- SVCB
capURI → 获取能力文档(包含能力、版本、描述的 JSON) - TXT 记录回退 → 从 DNS TXT 记录获取
capabilities=chat,support - HTTP 索引内嵌 → 能力嵌入在索引 JSON 响应中
MCP 服务
DNS-AID 包含一个 MCP(Model Context Protocol)服务,允许 Claude 等 AI Agent 发布和发现其他 Agent。
运行 MCP 服务
# Run with stdio transport (default - for Claude Desktop, etc.)
dns-aid-mcp
# Run with HTTP transport
dns-aid-mcp --transport http --port 8000
可用的 MCP 工具
| 工具 | 说明 |
|---|---|
publish_agent_to_dns | 将 AI Agent 发布到 DNS(自动更新索引) |
discover_agents_via_dns | 在域中发现 AI Agent(支持使用 use_http_index 通过 HTTP 索引发现) |
list_agent_tools | 列出已发现的 MCP Agent 上可用的工具 |
call_agent_tool | 调用已发现的 MCP Agent 上的工具(代理请求) |
verify_agent_dns | 验证 DNS-AID 记录和安全性 |
list_published_agents | 列出域中的所有 Agent |
delete_agent_from_dns | 从 DNS 中移除 Agent(自动更新索引) |
list_agent_index | 列出域索引记录中的 Agent |
sync_agent_index | 将索引与实际 DNS 记录同步 |
diagnose_environment | 运行环境诊断(依赖项、DNS、后端) |
Claude Desktop 集成
将以下内容添加到 Claude Desktop 配置中(~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"dns-aid": {
"command": "dns-aid-mcp"
}
}
}
随后 Claude 就可以发现并连接 AI Agent:
“查找 example.com 上可用的 Agent”
“将我的聊天 Agent 发布到 mycompany.com 的 DNS”
“发现 example.com 上的 Agent,并搜索从 SFO 到 JFK 的航班”
在线演示
通过 Claude Desktop 试用在线演示:
{
"mcpServers": {
"dns-aid": {
"command": "python",
"args": ["-m", "dns_aid.mcp.server"]
}
}
}
随后让 Claude 发现并使用预订 Agent:
“使用 HTTP 索引发现 example.com 上的 Agent,找到一个预订 Agent,并搜索 2026 年 3 月 15 日从 SFO 到 JFK 的航班”
Claude 将会:
- 调用
discover_agents_via_dns→ 找到位于https://booking.example.com/mcp的 booking-agent - 调用
list_agent_tools→ 查看 search_flights、get_flight_details、check_availability、create_reservation - 调用
call_agent_tool→ 搜索航班并返回结果
工作原理
DNS-AID 使用 SVCB 记录(RFC 9460)发布 AI Agent:
chat.example.com. 3600 IN SVCB 1 chat.example.com. alpn="a2a" port=443 mandatory="alpn,port"
chat.example.com. 3600 IN TXT "capabilities=chat,assistant" "version=1.0.0"
DNS-AID 自定义 SVCB 参数(v0.4.8+): 根据 IETF 草案,SVCB 记录可以携带额外的自定义参数,以提供更丰富的 Agent 元数据:
booking.example.com. SVCB 1 mcp.example.com. alpn="mcp" port=443 \
cap="https://mcp.example.com/.well-known/agent-cap.json" \
cap-sha256="dGVzdGhhc2g" bap="mcp/1,a2a/1" \
policy="https://example.com/agent-policy" realm="production"
| 参数 | 用途 |
|---|---|
cap | 指向能力文档的 URI(丰富的 JSON 元数据) |
cap-sha256 | 能力描述符的 SHA-256 摘要,用于完整性验证 |
bap | 支持的批量 Agent 协议及其版本 |
policy | 指向 Agent 策略文档的 URI |
realm | 多租户范围标识符 |
这样,任何 DNS 客户端都能发现 Agent,无需专有协议或中央注册表。
发现流程(与 DNS-AID 草案保持一致)
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 │
索引解析优先级: HTTP 索引端点 → TXT 索引记录 → 探测常见名称。
能力解析优先级: SVCB cap URI → 能力文档 → 回退到 TXT 记录。
每个发现的 Agent 都包含 endpoint_source 和 capability_source,用于标明所采用的路径。
Agent 元数据契约(v0.10.0+)
DNS 发现会告诉你 Agent 在哪里。Agent 元数据契约会告诉你如何连接、它能做什么,以及它是否仍处于活动状态。
每个 DNS-AID Agent 都可以提供 .well-known/agent.json 端点:
GET https://mcp.example.com/.well-known/agent.json
{
"aid_version": "1.0",
"identity": { "name": "billing", "version": "2.1.0", "deprecated": false },
"connection": { "protocol": "mcp", "transport": "streamable-http" },
"auth": { "type": "bearer", "header_name": "Authorization" },
"capabilities": {
"supports_streaming": true,
"actions": [
{ "name": "get_invoice", "intent": "query", "semantics": "read" },
{ "name": "process_payment", "intent": "transaction", "semantics": "write" }
]
}
}
这对编排器(LangGraph、CrewAI 等)为何重要:
| 字段 | 编排器决策 |
|---|---|
intent: query | 可安全并行调用,可缓存 |
intent: transaction | 需要原子执行,失败时回滚 |
semantics: read | 超时时可安全重试 |
semantics: write | 重试并不安全——可能重复产生副作用 |
auth.type: oauth2 | 调用前需要进行令牌交换 |
deprecated: true | 改为路由到 successor_fqdn |
A2A 兼容性: DNS-AID 和 Google A2A 都使用 /.well-known/agent.json。元数据获取器会自动检测格式——DNS-AID 原生格式(包含 aid_version 键)或 A2A Agent Card——并将两者规范化为相同的元数据字段。
架构
客户端:工具包
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐
│ AI Agents │ │ Developers │ │ Infrastructure Ops │
│ (Claude, etc.) │ │ │ │ │
└────────┬────────┘ └────────┬────────┘ └────────────┬────────────┘
│ │ │
│ MCP Protocol │ CLI │ CLI / API
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ DNS-AID TOOLKIT │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐ │
│ │ MCP Server │ │ CLI │ │ Python Library │ │
│ │ │ │ │ │ │ │
│ │ • publish_agent │ │ • dns-aid │ │ • dns_aid.publish() │ │
│ │ • discover_ │ │ publish │ │ • dns_aid.discover() │ │
│ │ agents │ │ • dns-aid │ │ • dns_aid.verify() │ │
│ │ • verify_agent │ │ discover │ │ • dns_aid.invoke() ◄── Tier 1 SDK
│ │ • list_agents │ │ • dns-aid │ │ • dns_aid.rank() │ │
│ │ • call_agent │ │ verify │ │ │ │
│ └────────┬────────┘ └────────┬────────┘ └────────────┬────────────┘ │
│ │ │ │ │
│ └────────────────────┴────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ CORE ENGINE │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │
│ │ │ Publisher │ │ Discoverer │ │ Validator │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ Create SVCB │ │ Query DNS │ │ • DNSSEC validation │ │ │
│ │ │ Create TXT │ │ Parse SVCB │ │ • DANE/TLSA check │ │ │
│ │ │ │ │ Return │ │ • Endpoint health │ │ │
│ │ │ │ │ endpoints │ │ │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ └────────────┬────────────┘ │ │
│ │ │ │ │ │ │
│ └─────────┴────────────────┴──────────────────────┴──────────────┘ │
│ │ │
└─────────────────────────────┼────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────────────────────────┐
│ DNS BACKEND ABSTRACTION │
│ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Route53 │ │ Infoblox │ │ DDNS │ │Cloudflare │ │ Akamai │ │ Mock │ │
│ │ (AWS) │ │ UDDI │ │ (RFC2136) │ │ │ │ Edge DNS │ │ (Testing) │ │
│ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
│ │ │ │ │ │ │ │
└────────┴──────────────┴──────────────┴──────────────┴──────────────┴──────────────┴──────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ DNS INFRASTRUCTURE │
│ │
│ Authoritative DNS servers hosting _agents.{domain} zones │
│ with SVCB, TXT, and TLSA records secured by DNSSEC │
└─────────────────────────────────────────────────────────────────────────┘
目录和索引层(外部)
基于 DNS-AID 构建的目录和索引服务——用于遍历公共 DNS 以查找 Agent 记录的爬虫、为 .well-known/agent.json 元数据编制索引的服务、搜索前端——不属于本仓库的范围。它们基于该底层基础构建,但独立运营。实现方可以自由制定自己的评分、排名和整理策略;DNS-AID 不会集中管理这些选择。
选择合适的接口
DNS-AID 提供三种接口。请根据你的使用场景进行选择:
Python 库
最适合: 将 Agent 发现功能集成到代码中的应用开发者。
import dns_aid
# Integrate directly into your Python application
agents = await dns_aid.discover("example.com", protocol="mcp")
| 使用场景 | 示例 |
|---|---|
| 构建能够发现其他 Agent 的 AI Agent | Agent 网状网络应用 |
| 将发现功能嵌入现有 Python 应用 | 将 DNS-AID 添加到 Flask/FastAPI 服务 |
| 自动化流水线和脚本 | CI/CD、定时发布 |
| 使用模拟后端进行单元测试 | 无需真实 DNS 即可测试 |
CLI 工具
最适合: 运维人员、DevOps 人员和需要快速手动操作的用户。
dns-aid discover example.com --protocol mcp
| 使用场景 | 示例 |
|---|---|
| 手动发布/发现 | 测试新的 Agent 部署 |
| Shell 脚本和自动化 | cron 作业、部署脚本 |
| 调试和故障排除 | 检查 DNS 记录是否存在 |
| 区域管理 | 列出 Agent、批量操作 |
MCP 服务
最适合: 需要 DNS-AID 功能的 AI 助手(Claude 等)。
dns-aid-mcp # Claude can now use DNS-AID tools
| 使用场景 | 示例 |
|---|---|
| Claude Desktop 集成 | “查找 salesforce.com 上的 Agent” |
| AI 驱动的基础设施 | Agent 自主注册和发现 |
| 自然语言 DNS 管理 | “将我的聊天 Agent 发布到 DNS” |
| 构建 Agent 工作流 | 多 Agent 编排 |
决策矩阵
| 你想要…… | 使用 |
|---|---|
| 在 Python 应用中集成发现功能 | Python Library |
| 从终端运行临时命令 | CLI |
| 使用 Shell 脚本自动化 | CLI |
| 让 Claude/AI 管理 DNS-AID | MCP Server |
| 无需真实 DNS 即可测试 | Python Library(搭配 MockBackend) |
| 调试 DNS 记录问题 | CLI(dns-aid verify) |
DNS 后端
有关各提供商的环境配置,请参阅 入门指南 中的后端章节。
DNS-AID 支持多个 DNS 后端:
| 后端 | 描述 | 安装扩展包 | 状态 |
|---|---|---|---|
| Akamai Edge DNS | Akamai Edge DNS | dns-aid[akamai-edgedns] | ✅ 生产环境 |
| Route 53 | AWS Route 53 | dns-aid[route53] | ✅ 生产环境 |
| Cloudflare | Cloudflare DNS | dns-aid[cloudflare] | ✅ 生产环境 |
| NS1 | NS1(现属 IBM)托管 DNS | dns-aid[ns1] | ✅ 生产环境 |
| Google Cloud DNS | GCP Cloud DNS | dns-aid[cloud-dns] | ✅ 生产环境 |
| Infoblox NIOS | Infoblox NIOS(本地部署的 WAPI) | dns-aid[nios] | ✅ 生产环境 |
| Infoblox UDDI | Infoblox Universal DDI(云端) | dns-aid[infoblox] | ✅ 生产环境 |
| DDNS | RFC 2136 动态 DNS(BIND 等) | dns-aid[ddns] | ✅ 生产环境 |
| Mock | 内存中运行(仅用于测试) | (内置) | ✅ 生产环境 |
Route 53 设置
-
配置 AWS 凭据:
export AWS_ACCESS_KEY_ID="your-access-key" export AWS_SECRET_ACCESS_KEY="your-secret-key" export AWS_DEFAULT_REGION="us-east-1" # Optional或使用 AWS CLI 配置文件:
aws configure # Or use a named profile export AWS_PROFILE="my-profile" -
验证区域访问权限:
dns-aid zones -
发布你的 Agent:
dns-aid publish -n my-agent -d myzone.com -p mcp -e mcp.myzone.com
Infoblox UDDI 设置
Infoblox UDDI(Universal DDI)是 Infoblox 的云原生 DDI 平台。DNS-AID 支持通过 Infoblox API 创建 SVCB 和 TXT 记录。
环境变量
| 变量 | 必填 | 默认值 | 描述 |
|---|---|---|---|
INFOBLOX_API_KEY | 是 | - | Infoblox Cloud Portal 中的 UDDI API 密钥 |
INFOBLOX_DNS_VIEW | 否 | default | DNS 视图名称(区域位于视图中) |
INFOBLOX_BASE_URL | 否 | https://csp.infoblox.com | API 基础 URL |
分步设置
-
从 Infoblox Cloud Portal 获取 API 密钥:
- 前往 Administration → API Keys
- 创建具有 DNS 权限的新 API 密钥
- 复制密钥(仅显示一次)
-
配置环境变量:
export INFOBLOX_API_KEY="your-api-key" export INFOBLOX_DNS_VIEW="default" # Or your specific view name -
确定你的区域和视图:
- 在 Infoblox Portal 中,前往 DNS → Authoritative Zones
- 记下区域名称(例如
example.com)及其所属视图
-
在 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 支持
Infoblox UDDI 支持完整的 ServiceMode SVCB(RFC 9460):priority > 0,并带有 svc_params,
包括标准键(alpn、port、mandatory、ipv4hint、ipv6hint 等)以及
专用范围 key65280–key65534。DNS-AID 的自定义参数(cap、cap-sha256、
bap、policy、realm、sig、connect-class、connect-meta、enroll-uri——编码为
key65400–key65405)会直接写入 SVCB 记录,而非降级为配套 TXT 记录。
| DNS-AID 要求 | Akamai Edge DNS | Route 53 | Infoblox UDDI |
|---|---|---|---|
| ServiceMode(priority > 0) | ✅ | ✅ | ✅ |
alpn / port / mandatory | ✅ | ✅ | ✅ |
| 专用键(cap/bap/policy/realm/sig/…) | ✅ | ✅ | ✅ |
Infoblox UDDI 和 Akamai Edge DNS 是完全符合 DNS-AID 要求的 ServiceMode SVCB 后端。
通过 API 验证记录
由于 Infoblox UDDI 区域可能无法通过公共 DNS 解析,请通过 API 验证记录:
async with InfobloxBloxOneBackend() as backend:
async for record in backend.list_records("example.com", name_pattern="my-agent"):
print(f"{record['type']}: {record['fqdn']}")
DDNS 设置(RFC 2136)
DDNS(动态 DNS)是一种通用后端,可与任何支持 RFC 2136 的 DNS 服务器配合使用,包括 BIND9、Windows DNS、PowerDNS 和 Knot DNS。对于没有特定供应商 API 的本地 DNS 基础设施,这是理想选择。
环境变量
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
DDNS_SERVER | 是 | - | DNS 服务器主机名或 IP |
DDNS_KEY_NAME | 是 | - | TSIG 密钥名称 |
DDNS_KEY_SECRET | 是 | - | TSIG 密钥密文(base64) |
DDNS_KEY_ALGORITHM | 否 | hmac-sha256 | TSIG 算法 |
DDNS_PORT | 否 | 53 | DNS 服务器端口 |
分步设置
-
在 DNS 服务器上创建 TSIG 密钥(BIND 示例):
tsig-keygen -a hmac-sha256 dns-aid-key > /etc/bind/dns-aid-key.conf -
配置区域,允许使用该密钥进行更新:
zone "example.com" { type master; file "/var/lib/bind/example.com.zone"; allow-update { key "dns-aid-key"; }; }; -
配置 DNS-AID:
export DDNS_SERVER="ns1.example.com" export DDNS_KEY_NAME="dns-aid-key" export DDNS_KEY_SECRET="your-base64-secret" -
在 Python 中使用:
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 优势
- 通用性强:适用于 BIND、Windows DNS、PowerDNS、Knot 及任何 RFC 2136 服务器
- 无供应商锁定:采用标准协议,不依赖专有 API
- 适用于本地部署:非常适合企业内部 DNS
- 完全符合 DNS-AID 规范:支持带有所有参数的 ServiceMode SVCB
Cloudflare 设置
Cloudflare DNS 凭借免费套餐和出色的 API 支持,非常适合演示、工作坊和快速原型开发。DNS-AID 完全支持 Cloudflare 的 SVCB 记录实现,包括原生私有用途 SVCB 键——DNS-AID 的自定义参数(cap、cap-sha256、bap、policy、realm 等)会直接写入 SVCB 记录(key65400–key65409),不会降级为 TXT 记录。
环境变量
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
CLOUDFLARE_API_TOKEN | 是 | - | 具有 DNS 编辑权限的 API 令牌 |
CLOUDFLARE_ZONE_ID | 否 | - | 区域 ID(未设置时自动发现) |
分步设置
-
在 Cloudflare 控制面板中创建 API 令牌:
- 前往 My Profile → API Tokens → Create Token
- 使用“Edit zone DNS”模板,或创建自定义令牌并设置:
- Permissions:Zone → DNS → Edit
- Zone Resources:Include → Specific zone → your-domain.com
- 复制令牌(仅显示一次)
-
配置环境变量:
export CLOUDFLARE_API_TOKEN="your-api-token" # Optional: specify zone ID (otherwise auto-discovered from domain) export CLOUDFLARE_ZONE_ID="your-zone-id" -
发布你的第一个 Agent:
dns-aid publish \ --name my-agent \ --domain your-domain.com \ --protocol mcp \ --endpoint agent.your-domain.com \ --backend cloudflare -
在 Python 中使用:
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 优势
- 免费套餐:DNS 托管免费,域名数量不限
- 支持 SVCB:完全符合 RFC 9460,支持 SVCB Type 64 记录
- 原生私有用途 SVCB 键:DNS-AID 自定义参数直接写入 SVCB 记录(
key65400–key65409)——不会降级为 TXT 记录,与 NS1 和 NIOS 一致 - 全球任播:在全球范围内快速解析 DNS
- 简单易用的 API:文档完善的 REST API v4
- 完全符合 DNS-AID 规范:支持带有所有参数的 ServiceMode SVCB
Akamai Edge DNS 设置
Akamai Edge DNS 支持具备完整私有用途键支持的 ServiceMode SVCB 记录,因此完全符合 DNS-AID 草案。所有 DNS-AID 自定义参数(cap、bap、realm 等)都会直接写入 SVCB,不会降级为 TXT 记录。
并发写入安全可靠:后端会按区域串行执行自身的写入操作,并在遇到 Akamai 的瞬时 409 concurrentZoneModification 响应时自动采用指数退避重试。
环境变量
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
AKAMAI_HOST | 否* | - | EdgeGrid API 主机名(例如 akab-xxxx.luna.akamaiapis.net) |
AKAMAI_CLIENT_TOKEN | 否* | - | EdgeGrid 客户端令牌 |
AKAMAI_CLIENT_SECRET | 否* | - | EdgeGrid 客户端密钥 |
AKAMAI_ACCESS_TOKEN | 否* | - | EdgeGrid 访问令牌 |
AKAMAI_EDGERC | 否 | ~/.edgerc | .edgerc 凭据文件的路径 |
AKAMAI_EDGERC_SECTION | 否 | default | 要使用的 .edgerc 配置节 |
* 如果不使用 .edgerc,则为必填。同时提供环境变量和 .edgerc 时,优先使用环境变量。
分步设置
-
在 Akamai Control Center 中创建 API 凭据:
- 前往 Identity & Access → Create API Client
- 授予 DNS—Zone Record Management 读写权限
- 下载
.edgerc文件,或记下四项凭据值
-
配置凭据(任选一种):
通过
.edgerc文件(Akamai 标准方式):# ~/.edgerc [default] host = akab-xxxx.luna.akamaiapis.net client_token = akab-xxxx client_secret = xxxx access_token = akab-xxxx通过环境变量:
export AKAMAI_HOST="akab-xxxx.luna.akamaiapis.net" export AKAMAI_CLIENT_TOKEN="akab-xxxx" export AKAMAI_CLIENT_SECRET="xxxx" export AKAMAI_ACCESS_TOKEN="akab-xxxx" -
发布第一个 Agent:
dns-aid publish \ --name my-agent \ --domain your-domain.com \ --protocol mcp \ --endpoint agent.your-domain.com \ --backend akamai-edgedns -
在 Python 中使用:
import asyncio from dns_aid.backends.akamai_edgedns import AkamaiEdgeDNSBackend from dns_aid import publish async def main(): # 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 功能
- 原生支持 SVCB:完全符合 RFC 9460,包括私有用途键
- 完全符合 DNS-AID:所有自定义参数(
cap、bap、realm等)均原生写入 SVCB 记录,不会降级为 TXT - DNSSEC:通过签名并提供服务的方式内置区域签名
- 灵活的凭据:同时支持
.edgerc文件和环境变量
DNS-AID 与其他方案的关系
Agent 发现是一个活跃的设计领域,多种提案在协议栈的不同层面发挥作用。DNS-AID 有意保持范围狭窄:它标准化发布者和解析器可依赖的 DNS 层基础,同时将目录、排序、支付和命名空间策略留给其他方案。以下摘要旨在帮助运营者了解 DNS-AID 的定位,而非将其与其他工作进行对比。
相关方案
- Agent Name Service(ANS) — 一种以目录为导向的方案,定义了 JSON 元数据架构和注册表接口。DNS-AID 的 HTTP Index 格式在两者重叠之处有意与 ANS 架构保持一致,因此 ANS 风格的目录可以使用 DNS-AID 发布者生成的同一份数据提供服务。
- A2A — 一种用于 Agent 间通信的协议。DNS-AID 与之互补:A2A 定义两个 Agent 如何通信,DNS-AID 定义一个 Agent 如何找到另一个 Agent 的通信端点。
- AgentDNS — 一项独立提案,在 DNS 原语之上构建 Agent 命名层。两项提案理念相近、机制不同;DNS-AID 选择遵循 RFC 9460 SVCB,从而让现有权威服务器和解析器无需修改即可使用。
- NANDA — 一种点对点覆盖网络方案。适用于偏好 DHT 式基础层的部署;DNS-AID 则面向组织已在运行的 DNS 基础设施。
- ai.txt / llms.txt — 放置在已知 URL 下的自由格式文本文件,适用于便于人类阅读的发现;DNS-AID 增加了结构化 SVCB 记录,以及可选的 DNSSEC 验证信任机制。
.agentgTLD — Agent Community 推动的 ICANN 新通用顶级域名(gTLD)项目,旨在创建专用命名空间(mycompany.agent)。它与 DNS-AID 互补:.agent域名开放后,DNS-AID 记录也能用于这些域名,就像用于其他区域一样。
DNS-AID 的范围
DNS-AID 标准化了发布/解析基础,包括 SVCB 记录布局、命名约定、能力和策略参数,以及以 DNSSEC 为锚点的验证路径。它不指定应采用哪种目录、排序算法、支付系统或信任机构。运营者可以自由将 DNS-AID 与上述任意方案结合使用,也可以独立运行。
背景与比较
有关 DNS-AID 与其他 Agent 发现方案(ANS、Google A2A+UCP、.agent gTLD、AgentDNS、NANDA、Web3、ai.txt)的比较,以及“主权问题”的背景信息,请参阅 docs/positioning.md。该内容不具规范性——协议定位由 IETF 决定。
示例
请参阅 examples/ 目录:
demo_route53.py- Route 53 发布/发现基础示例demo_full.py- 完整的端到端演示
# Run the full demo
export DNS_AID_TEST_ZONE="your-zone.com"
python examples/demo_full.py
开发
# 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
相关标准
- RFC 9460 - SVCB 和 HTTPS 资源记录
- RFC 4033-4035 - DNSSEC
- RFC 6698 - DANE TLSA
许可证
Apache 2.0
贡献
欢迎贡献!本项目支持一个计划由 Linux Foundation 托管的实现生态系统。DNS-AID 规范在 IETF 制定。
请参阅 CONTRIBUTING.md 了解指南。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。