Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
AI Agents – ENS Organizational Registry
Skip to content

Setting up metadata for your AI agent

This guide explains how to publish your AI agent's identity and capabilities as ENS metadata, turning an ENS name into a permissionless, registry-free discovery point for your agent. It complements ERC-8004, and the on-chain records described here can stand alone or point at an existing ERC-8004 registration file via agent-uri.

Step 1: Choose the right ENS node

Agent records should live on the ENS name you want to be your agent's canonical identity. Indexers find agents by scanning ENS text records on-chain, so the name you choose here is the address consumers will resolve when they look your agent up.

Two distinct addresses are involved in this step, and it's worth being clear about both before proceeding.

  1. The address the ENS name resolves to should be the address controlled by the agent. This is the agent's on-chain identity: any transaction or signature coming from this address is understood to originate from the agent itself. The ETH address record on the node should be set to this address.
  2. The owner or manager of the ENS name controls who can update records and create subnames. This can be set to either the agent's own address (giving the agent the ability to update its own records autonomously) or to a user's address (so the operator retains control and can update the agent's records on its behalf).

With those two decisions made, you can proceed:

  1. Pick the ENS name (or subname) the agent will be known by. This might be a top-level name like myagent.eth, or a dedicated subname like agent.alice.eth. Subnames are recommended when an operator runs multiple agents, since each subname gets its own independent set of records.

Step 2: Add your agent information

  1. Open ensmetadata.app, connect the wallet that controls the ENS name you want to use, and navigate to the node you chose in Step 1.
  2. Under Schema, select Agent. This automatically sets the class and schema records and reveals the recommended fields.
  3. Fill in your agent's information. The most common fields appear automatically; to add additional fields, choose "+ Add Optional Field" and select from the list.
Record keyWhat to put
nameThe display name shown in agent directories and clients
descriptionA short natural-language description of what the agent does
avatarURI pointing to the agent's avatar image
agent-uri(Optional) URI pointing to an ERC-8004 registration file, if the agent has one
agent-walletThe address where the agent receives payments (corresponds to the agentWallet reserved key in the ERC-8004 Identity Registry)
x402-support"true" if the agent accepts x402 payments
active"true" or "false" — whether the agent is currently operational

The agent schema follows a layering principle: stable, important metadata lives directly on the ENS name where it's always available and costs nothing to read; verbose or frequently-changing data lives in the registration file pointed to by agent-uri. As a rule of thumb, publish name, description, avatar, agent-wallet, and x402-support directly on the ENS name, and leave large service catalogues, evolving capability details, and frequently-flipped status flags to the registration file.

A minimal agent record after this step looks like:

myagent.eth
  ├── class        = "Agent"
  ├── schema       = "<agent schema URI>"
  ├── name         = "My Agent"
  ├── description  = "A natural-language description of what this agent does"
  ├── avatar       = "https://example.com/avatar.png"
  ├── agent-wallet = "0x..."
  └── x402-support = "true"

Consumers can now resolve all of these with a standard ENS text record lookup.

Step 3: Advertise services

Services are how clients discover what your agent actually does and where to call it. The agent schema supports two approaches that can coexist.

As a single index URI using the services field, pointing to a JSON payload that enumerates all services. This mirrors the services array in an ERC-8004 registration file and is convenient when services change frequently or are too verbose to publish individually:

myagent.eth
  └── services = "https://example.com/services.json"

As individual parametrised records using services[name], where each entry maps a service name to its endpoint. This keeps service data on-chain and directly readable without fetching an external file:

myagent.eth
  ├── services[web] = "https://web.agentxyz.com/"
  ├── services[mcp] = "https://mcp.agentxyz.com/"
  └── services[a2a] = "https://agent.example/.well-known/agent-card.json"

Each value can be a direct endpoint URI, or it can point to a JSON descriptor if the service requires more detail (authentication schemes, input/output formats, etc.). The data: and cbor: URI prefixes are also supported for embedding descriptors inline rather than hosting them externally.

For now, adding parametrised entries is a manual process in ensmetadata.app:

  1. With the node selected, click the "+ Record" button at the bottom of the metadata editing drawer.
  2. Enter the parametrised key exactly as shown (for example, services[mcp]), with the service name in square brackets.
  3. Paste the endpoint URI as the value, and save the changes.
  4. Repeat for each service the agent exposes, then broadcast the transaction.

Clients should treat the bare services record as a fallback value that gets queried when they can't find a direct services[name] entry on the ENS name.

Step 4: Cross-registry references and trust models

These two array fields are optional but recommended for agents that participate in on-chain registries or advertise verification mechanisms. Both are added through the same "+ Record" flow as parametrised services in Step 3.

Cross-registry references. Agents registered with ERC-8004 or other on-chain registries can advertise those registrations using the registrations[*] array field. Each entry follows CAIP-19 format, since ERC-8004 identities are modelled as ERC-721 tokens ({namespace}:{chainId}/{tokenStandard}:{identityRegistry}/{agentId}):

myagent.eth
  ├── registrations[0] = "eip155:1/erc721:0x742.../22"
  └── registrations[1] = "eip155:8453/erc721:0x.../7"

This makes the ENS name a single place to find every registration the agent holds, regardless of which chains or contracts they span.

Trust models. The supported-trust[*] array advertises which trust verification mechanisms the agent supports — corresponding to the supportedTrust field in an ERC-8004 registration file:

myagent.eth
  ├── supported-trust[0] = "reputation"
  └── supported-trust[1] = "tee-attestation"

How agents are discovered

Once your records are live, any consumer can find and read them without a central directory. The discovery flow looks like this:

  1. Index TextChanged events on the ENS Public Resolver, filtering for records where the key is class and the value is "Agent". Alternatively, index all nodes that set a schema record pointing to a recognised agent schema.
  2. Resolve the agent's records on each matching node. Read the text records listed in the schema — or all text records if you want the full picture — including name, description, agent-wallet, parametrised services[*] entries, and registrations[*].
  3. Fall back to the registration file only when needed. If the data the consumer wants isn't published directly on the ENS name, fetch the JSON file at agent-uri and read it from there.

This gives any consumer a live, permissionless view of every agent that has opted in to on-chain discoverability.

Related