--- eip: 8156 title: Agent Onchain Metadata description: Minimal onchain metadata keys (context, endpoints, and multichain addresses) for ERC-8004 agent registries author: Prem Makeig (@nxt3d) discussions-to: https://ethereum-magicians.org/t/agent-onchain-metadata/TBD status: Draft type: Standards Track category: ERC created: 2026-02-10 requires: 7930, 8004, 8048 --- ## Abstract This ERC introduces three new onchain metadata keys for an agent with an [ERC-8004](./eip-8004.md) 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](./eip-8004.md) profile: - **Context**: An [ERC-8004](./eip-8004.md) profile's listing fields, `name`, `description`, and `image`, present the agent but do not capture its actual context: its makeup, knowledge, capabilities, and tools. `context` adds a field for that. - **Endpoints**: An agent's service endpoints are optional entries in its registration file, and [ERC-8004](./eip-8004.md) defines no standard for keying them onchain. `endpoint` keys add a standard onchain key for each endpoint. - **Addresses**: An [ERC-8004](./eip-8004.md) agent has a single `agentWallet`, on its registration chain, with no standard way to associate addresses on other chains with the same identity. `address` keys 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](https://www.rfc-editor.org/rfc/rfc2119.html) and [RFC 8174](https://www.rfc-editor.org/rfc/rfc8174.html). ### Interface The only requirement is that the registry expose [ERC-8004](./eip-8004.md)'s metadata functions: ```solidity function getMetadata(uint256 agentId, string memory metadataKey) external view returns (bytes memory) function setMetadata(uint256 agentId, string memory metadataKey, bytes memory metadataValue) external ``` Full [ERC-8004](./eip-8004.md) compliance is NOT required. Any registry that exposes these two functions, including registries that are [ERC-8004](./eip-8004.md)-like but not exactly [ERC-8004](./eip-8004.md), 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[]` | Endpoint URI for the protocol ``. | UTF-8 URI. `` is lowercase (e.g. `mcp`, `a2a`, `web`). For `endpoint[web]`, an `https` URI is RECOMMENDED. | | `address[]` | The agent's address on the chain identified by ``. | 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[]` and `address[]` keys are OPTIONAL. #### Endpoint types `` 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[]` form; standards that reserve new types SHOULD define their canonical lowercase spelling. #### Chain-keyed addresses In `address[]`, `` is the [ERC-7930](./eip-7930.md) Chain Identifier. The stored value is the raw binary address for that chain (for an EVM chain, the 20-byte address); [ERC-7930](./eip-7930.md) 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: ```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](./eip-8004.md)'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[]` key, not both. An address SHOULD NOT be stored as `address[]` for a chain already covered by a non-zero `agentWallet`; `address[]` is intended for the chains it does not cover. Because `agentWallet` can be zero (for example, [ERC-8004](./eip-8004.md) clears it when the agent is transferred), a client resolving the registration chain MAY fall back to `address[]` 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 in `agentURI`. 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](./eip-8048.md). - **Single `context` key**: 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[]` and `address[]` 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](./eip-8004.md) primitives**: The keys use the existing `getMetadata`/`setMetadata` interface, so no new Solidity interface or events are introduced. ## Backwards Compatibility This ERC is fully backwards compatible with [ERC-8004](./eip-8004.md). 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[]` value governs the registration chain only when `agentWallet` is zero. ## Copyright Copyright and related rights waived via [CC0](../LICENSE.md).