Conversation
Defines the schema for the agent card document that completes the discovery chain established in ENSIP-26. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move related spec links inline into Rationale section. The CI linter expects Security Considerations → Copyright with no intervening headings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Could the well-known endpoint be on an ENS name itself using the contenthash record? I think the question is how we have experimentation around new agent protocols, while at the same time not reserving a bunch of keywords that might conflict. Can you give your protocol a more unique name? For example, Also, if you can open a thread on the ENS forum, it can be helpful to get better visibility on your ENSIP. |
On the contenthash question: good direction for static agent cards, but our implementation relies on dynamic content, the card includes EIP-712 signed attestations and live endpoint URLs that change per execution. Contenthash (IPFS) is immutable once set; we use CCIP-Read precisely so the card can be served dynamically and signed by the gateway on each fetch. That said, a static variant pointing to a pinned card would be a valid subset of the same schema, the two aren't mutually exclusive. |
|
I would also recommend taking a look at #64, an in-progress ENSIP for attaching schemas for any type of entity (and especially agents). Here is an explanation of how it would work to attach an agent's metadata (including links to ERC-8004 and all other details that could be in an agent manifest) directly to their ENS name: 0xLighthouse/ens-metadata#46 |
|
Thanks @jmacwhyte — this is directly relevant and I should have caught #64 earlier. Reading through the Agent use case in 0xLighthouse/ens-metadata#46, there's significant overlap in intent and some differences in approach worth aligning on. Where we converge:
Where we differ:
The key naming divergence ( On CCIP-Read: ENSIP-27's primary use case is CCIP-Read resolution — the agent's ENS name resolves dynamically via an off-chain gateway, which enables private endpoints, runtime-computed metadata, and records that don't require on-chain writes. This is complementary to the static text record path rather than competing with it. An agent could publish stable fields as static records and serve dynamic ones via CCIP-Read. The The key naming ( Would it make sense to treat ENSIP-64 as the classification and metadata layer, and ENSIP-27 as the agent-card content spec that sits on top of it? The Open to that conversation here or wherever makes sense to the #64 working group. |
|
I have responded to your comment here: https://discuss.ens.domains/t/ensip-27-agent-card-schema-well-known-agent-json/22130/4 |
|
Reading this as someone who serves 1. Same path, near-identical shape, silently different semantics vs the A2A agent card.
The failure mode is the bad kind: everything parses, then the client speaks JSON-RPC to an MCP endpoint (or vice versa) and the error surfaces two layers away from its cause. Two cheap fixes, either works:
2. The design decision that matters here is the one already made: when there is no sanitization, the value MUST be the identity-sentinel URI rather than the field being absent. Absence claims nothing; identity claims identity — that asymmetry is what makes the commitment verifiable rather than vibes. As the 8299 side of this: happy to contribute a small conformance set for the "clients MUST fetch and verify" path — a valid pipeline spec, the identity sentinel, and a tampered pipeline that must fail — so independent implementations converge on bytes, not prose. Say the word and I'll PR them wherever fits (assets here, or a companion repo). 3. The card anchors who ( Right now a card can prove the agent's identity and its input handling, but a client acting on the agent's output still has nothing to check. An optional None of this blocks the ENSIP as written — (1) is the only one I'd call a must-settle, and fix (a) is a two-sentence edit. Good design overall; the ENSIP-25/26/27 + ERC-8004 chain is the right decomposition. |
… trustEndpoints; add babyblueviper1 as co-author Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Updated this PR with a substantial revision, co-authored with @babyblueviper1, whose review (above) was spec-level, not feedback, and folded in directly: A2A interoperability, made normative. /.well-known/agent.json is shared with A2A by design (the required fields are byte-compatible). The revision adds an explicit discrimination rule: schema_version is the ENSIP-27 discriminator, and a conforming client MUST check it before dereferencing url, which here is the MCP endpoint, vs A2A’s JSON-RPC. This closes the silent-protocol-mismatch failure mode. Grateful for the earlier input from @jmacwhyte and @nxt3d too, the ENSIP-25/26 + ERC-8004 decomposition this composes into is the right one. |
…c) — fix ensip linter Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Yes to co-authoring — thank you, @TMerlini. Recomputed
And I'm listed under Delivering the conformance vectors I offered, so the https://github.com/babyblueviper1/ensip27-sanitizationspec-vectors Three vectors, exactly the set the spec now names:
It's CIDv1-raw + sha2-256 on purpose: the CID is a pure Between your production gateway, the 8299 side, and a byte-level conformance set, this is the reference for verifiable agent discovery — the better outcome regardless of which ENSIP number it lands under. Let's build. |
…ec (valid/sentinel/tampered, CIDv1-raw+sha256) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Some outstanding questions:
|
|
On (1): checked rather than assumed — you're right, and thanks for catching it. A2A's well-known path moved from Concretely: our own production agent (api.babyblueviper.com) serves an A2A-conformant card, and we serve it at both paths for exactly this reason — (2) is @TMerlini's call as the spec's author — I'll let him speak to the ENS-specific rationale. My interest as a co-author is narrower: the |
A2A moved the agent-card well-known path from /.well-known/agent.json (v0.2.x) to /.well-known/agent-card.json (v0.3.0) per IANA feedback. The draft still specified the old path, so ENSIP-27 cards would not be discoverable by current A2A clients. Make agent-card.json canonical throughout; keep agent.json documented only as an optional byte-identical legacy alias (A2A <= v0.2.x). Preserves the deliberate path-sharing + schema_version discrimination design at the current A2A path. Caught by @jmacwhyte; fix per @babyblueviper1 review on PR ensdomains#75. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks both — two good catches, taking them in order. (1) The well-known path — you're right, fixed. A2A moved the card path from (2) Why an ENSIP, if agent cards are an AI concept? Fair question, and the honest answer is that the card schema isn't the ENS-specific part — you're right that that overlaps A2A, which is deliberate (byte-compatible, path-shared,
So: the AI/card-schema layer is A2A's and we align to it, not fork it; the ENS layer is the name→discovery resolution plus the on-chain-anchored extensions. It composes with A2A rather than competing with it. If the editors would rather sharpen that boundary further, I'm genuinely open to narrowing ENSIP-27 to reference A2A's base card and specify only the ENS-anchored extension fields + the resolution binding, instead of restating the shared required fields. That might be the cleaner shape given your point — happy to take it that direction if it's the preference. |
|
Renamed to drop the self-assigned "ENSIP-27." Per the repo README, ENSIP numbers are assigned by a maintainer at merge, so I've moved to the Add ENSIP: convention to clear the placeholder collision (a few open drafts are self-labeled 27). Scope is unchanged: this is the Agent Card Schema served under /.well-known/, already deployed and live on the dinamic.eth gateway, ERC-8004-anchored. Happy to let the editors assign the final number when it's picked up. |
Per the repo README, ENSIP numbers are assigned by a maintainer at merge. Rename ensips/27.md -> ensips/agent-card-schema.md and move the heading to the ENSIP-X placeholder (matching the Add-ENSIP convention, e.g. ensdomains#68) to clear the self-numbered collision. Content unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
Completes the agent discovery chain defined in ENSIP-26.
ENSIP-26 defines how to find an agent via ENS text records (
agent-endpoint[mcp],agent-endpoint[a2a]). This ENSIP defines what the agent card document at/.well-known/agent.jsoncontains./.well-known/agent.jsonschema (required + optional fields)erc8004identity anchor — bridges ENSIP-25 (verification) + ENSIP-26 (discovery) + ERC-8004 (on-chain identity)sanitizationSpecfor input provenance (WYRIWE)trustScopefor A2A depth limitingReference implementation
Live at
gateway.ensub.orgas of 2026-05-19:ERC-8004 factory (verified on Etherscan):
0xc2bb6502a7d8ee3cdb2f96508d6cdf426aa2858fThree live collection registries on Ethereum mainnet.
Relationship to existing ENSIPs
agent-endpoint[*]text recordsENSIP-26 explicitly states: "Future ENSIPs may define more specific formats." This is that future.
— dinamic.eth