Abstract
This ERC introduces three new onchain metadata keys for an agent with an ERC-8004 profile. context is the agent's onchain entry point, the first thing read to understand what the agent is. endpoint keys give the agent's service endpoints a standard onchain form. address keys let a single agent identity hold a wallet on any number of chains.
Motivation
This ERC introduces three onchain metadata keys, each addressing a specific gap in an ERC-8004 profile:
- Context: An ERC-8004 profile's listing fields,
name,description, andimage, present the agent but do not capture its actual context: its makeup, knowledge, capabilities, and tools.contextadds a field for that. - Endpoints: An agent's service endpoints are optional entries in its registration file, and ERC-8004 defines no standard for keying them onchain.
endpointkeys add a standard onchain key for each endpoint. - Addresses: An ERC-8004 agent has a single
agentWallet, on its registration chain, with no standard way to associate addresses on other chains with the same identity.addresskeys add a per-chain address for one identity.
Specification
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Interface
The only requirement is that the registry expose ERC-8004's metadata functions:
function getMetadata(uint256 agentId, string memory metadataKey) external view returns (bytes memory)
function setMetadata(uint256 agentId, string memory metadataKey, bytes memory metadataValue) externalFull ERC-8004 compliance is NOT required. Any registry that exposes these two functions, including registries that are ERC-8004-like but not exactly ERC-8004, MAY use the keys defined in this ERC. All keys are read and written through these functions; this ERC does not define a new Solidity interface or events. Keys are case-sensitive and MUST use the canonical lowercase spelling defined below.
Reserved keys
| Key | Description | Value |
|---|---|---|
context | Freeform onchain context for the agent. | UTF-8 text. Markdown is RECOMMENDED; issuers MAY embed a fenced JSON code block for machine-readable fields (token lists, policy URIs, version, etc.). |
endpoint[<type>] | Endpoint URI for the protocol <type>. | UTF-8 URI. <type> is lowercase (e.g. mcp, a2a, web). For endpoint[web], an https URI is RECOMMENDED. |
address[<chainId>] | The agent's address on the chain identified by <chainId>. | The raw binary address for that chain per its CAIP-350 profile (e.g. the 20-byte address on an EVM chain); not text. |
An agent conforming to this ERC MUST set the context key to a non-empty value. The endpoint[<type>] and address[<chainId>] keys are OPTIONAL.
Endpoint types
<type> is a lowercase protocol name. This ERC does not fix a closed set; common values include mcp (Model Context Protocol), a2a (Agent-to-Agent), and web (a human-facing web page). Additional types MAY be used with the same endpoint[<type>] form; standards that reserve new types SHOULD define their canonical lowercase spelling.
Chain-keyed addresses
In address[<chainId>], <chainId> is the ERC-7930 Chain Identifier. The stored value is the raw binary address for that chain (for an EVM chain, the 20-byte address); ERC-7930 is used only to name the chain, not to encode the value.
For example, address[0x00010000010100] keys the agent's address on Ethereum mainnet, and the value is the 20 raw bytes of the EVM address.
Encoding
context and endpoint[...] values are UTF-8 bytes. address[...] values are raw binary addresses. In Solidity:
// context (UTF-8)
registry.setMetadata(agentId, "context", "I swap tokens on Ethereum mainnet.");
// endpoint (UTF-8 URI)
registry.setMetadata(agentId, "endpoint[mcp]", "https://mcp.agent.example/");
// address: store the raw 20 bytes of an EVM address, keyed by the Ethereum mainnet Chain Identifier
address agentAddr = 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045;
registry.setMetadata(agentId, "address[0x00010000010100]", abi.encodePacked(agentAddr));
// reading returns the 20 raw bytes, not a string
bytes memory stored = registry.getMetadata(agentId, "address[0x00010000010100]");An empty bytes return value (length 0) indicates the key has not been set.
Relationship to agentURI
Where the registry provides an agent or token URI (such as ERC-8004's agentURI), it remains the authoritative registration record and MAY be a base64 data: URI so that the full registration file is also stored onchain. The keys defined by this ERC are secondary: if the same value appears in both agentURI and one of these keys, the agentURI value takes precedence.
To avoid ambiguity, an implementation SHOULD NOT store the same data in both places. A given endpoint SHOULD appear either in agentURI or as an endpoint[<type>] key, not both. An address SHOULD NOT be stored as address[<chainId>] for a chain already covered by a non-zero agentWallet; address[<chainId>] is intended for the chains it does not cover. Because agentWallet can be zero (for example, ERC-8004 clears it when the agent is transferred), a client resolving the registration chain MAY fall back to address[<chainId>] for that chain when agentWallet is zero.
Rationale
- Small reserved set: Only the highest-value fields (
context, endpoints, and per-chain addresses) are promoted onchain; everything else stays inagentURI. This avoids mirroring the entire registration file onchain while still enabling cheap, contract-readable updates for the fields that benefit most. It mirrors the ERC-721T profile of ERC-8048. - Single
contextkey: One flexible key carries arbitrary agent context. UTF-8 Markdown is readable by humans and models, and an optional embedded JSON block lets clients parse machine-readable fields without additional keys. - Per-protocol and per-chain keys:
endpoint[<type>]andaddress[<chainId>]let an agent update one endpoint or one chain's address without rewriting the rest, and let contracts index a specific endpoint or chain directly. - Reuse of ERC-8004 primitives: The keys use the existing
getMetadata/setMetadatainterface, so no new Solidity interface or events are introduced.
Backwards Compatibility
This ERC is fully backwards compatible with ERC-8004. Agents that do not set any of these keys continue to function through agentURI.
Security Considerations
The keys defined here are values expressed by the agent's owner or operator and carry the same security level as the rest of the agent's profile; they are not a concern of the standard itself. The one consideration is that clients MUST follow this ERC's rules for how agentURI data is used and when the onchain values apply: agentURI takes precedence over these keys, and an address[<chainId>] value governs the registration chain only when agentWallet is zero.
Copyright
Copyright and related rights waived via CC0.
