erc8004-agent-liveness
Verifies that agents registered in the Ethereum ERC-8004 Identity Registry are actually live by resolving their on-chain registration data and checking their declared endpoints for current reachability.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@erc8004-agent-livenesscheck if agent 5 is registered and currently reachable"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ERC-8004 Agent Liveness
Checks whether an agent registered in the real ERC-8004 "Trustless Agents" Identity Registry (Base mainnet -- both the payment and the registry read, see "Chain scope" below) is actually alive right now -- not just that it was registered once. NEXUS candidate #10 -- manual build, not FORGE-generated, same manual-Cloud-Run-asset pattern as candidates #3/#4/#6/#8/#9/#13/#16.
POST /verify-registered-agent {"agent_id": 3}-- $0.10/call.MCP tool
verify_registered_agentat/mcp, same params -- currently free, see "Known limitations".GET /health,GET /.well-known/agent-card.json,GET /openapi.json(hasx-payment-info),GET /.well-known/402index-verify.txt(402index claim verification file).
What this is (and why registration alone isn't enough)
ERC-8004 is a real, live Ethereum standard for on-chain agent
identity: an agent mints an ERC-721 token in an IdentityRegistry, whose tokenURI points to an off-chain
registration file (JSON: name, description, declared endpoints, active flag, supported trust methods). It
went live on Ethereum mainnet 2026-01-29, with reference deployments on Base mainnet and Base/Ethereum/Linea
Sepolia testnets. Registration is a one-time on-chain action -- a real registered agent can go completely
dark (process killed, domain expired, endpoint changed) while its on-chain record persists unchanged forever.
This asset closes that gap: it resolves the real on-chain registration AND performs a real MCP initialize
handshake against whatever endpoint the registration declares, right now, at call time -- the same
liveness-vs-registration distinction agent-verification-api (candidate #3) already draws for
domain-claimed identities, applied here to on-chain-registered ones.
Related MCP server: Agent Doctor
Grounding (verified live this session, not assumed from any single source)
Contract addresses, initially from a third-party summary, verified independently via
eth_getCodeagainsthttps://sepolia.base.orgbefore being trusted:IdentityRegistry(0x8004A818BFB912233c491871b3d84c89A494BD9e) andReputationRegistry(0x8004B663056A597Dffe9eCcC1965A193B7388713) both have real, non-empty deployed bytecode.ABI, pulled from the reference implementation (
github.com/erc-8004/erc-8004-contracts/abis), tested live against 3 real registered agents (agentId1-3) before being trusted for this asset:Agent 1's
tokenURIresolves to adata:application/json;base64,...URI.Agent 2's resolves to
ipfs://bafkreiff....Agent 3's resolves to a real
https://api.snack.money/agent/.../registration.jsonURL. All 3 of ERC-8004's real URI schemes confirmed working live, not just the one the spec's own examples show.
getSummaryrequires a non-emptyclientAddressesarray -- confirmed live (reverts with"clientAddresses required"otherwise). This asset callsgetClients(agentId)first and only callsgetSummaryif that returns at least one address; agents with zero feedback correctly reportfeedback_count: 0without an RPC error.agentId=999999(a real nonexistent token) correctly reverts with a custom error, confirmed live -- mapped toAGENT_NOT_FOUND, not a crash.
MCP handshake engine: reused, not reimplemented
Per the task brief's explicit instruction, _nexus_validate_public_url, _nexus_no_redirect_mcp_http_client,
and _mcp_handshake_check are ported verbatim from manual_assets/agent-verification-api/main.py
(candidate #3) -- same SSRF pre-check, same no-redirect posture (the exact fix applied there after the
2026-08-22 security review found a redirect-based SSRF bypass), same bounded timeout. Not modified beyond the
asset-name constant. This asset's own contribution is upstream of that: resolving an ERC-8004 registration
file (3 URI schemes) and picking a real endpoint out of its endpoints array to hand to that engine.
Chain scope
Unified, as of 2026-09-04. x402 payment settles in real USDC on Base mainnet. The on-chain
IdentityRegistry read -- the actual identity/liveness check -- is now also on Base mainnet, against the
verified IdentityRegistryUpgradeable deployment (0x8004A169FB4a3325136EB29fA0ceB6D2e539a432) -- see
"Mainnet registry corrected" below. ReputationRegistry reads still use the original (Sepolia-verified)
address -- its real mainnet counterpart was not verified this session, see "Pending". This asset still doesn't
expose a caller-selectable chain -- no evidence a buyer needs one for either rail.
Mainnet registry corrected (2026-09-04)
The 2026-09-03 partial revert below was investigating the wrong contract. 0x8004A818BFB912233c491871b3d84c89A494BD9e
is itself the deterministic Base SEPOLIA IdentityRegistry address from erc-8004/erc-8004-contracts's
vanity-address deployment pattern -- it was never the real Base mainnet deployment, which is a different
deterministic address per network. The real Base mainnet IdentityRegistry is
0x8004A169FB4a3325136EB29fA0ceB6D2e539a432: implementation 0x7274e874ca62410a93bd8bf61c69d8045e399c02
verified on Etherscan as IdentityRegistryUpgradeable (exact name match with the reference repo, compiler
v0.8.24+commit.e11b9ed9), ownerOf reads succeed, and a Basescan export shows 25 real Base mainnet
transactions against it (2026-09-04 09:02-10:06 UTC, 25/25 successful: 5x register, 20x setMetadata) --
versus 19 historical transactions against the old address (2026-01-31 to 2026-04-20), 17/19 reverted. Full
verification trail: scripts/verify_mainnet_registry_candidate.py, branch
claude/erc8004-registry-address-verify-u2db8u. ReputationRegistry's real mainnet address was not verified
this session -- left unchanged, see "Pending".
Mainnet cutover (2026-09-03) and same-day partial revert
Originally built and measured on Base Sepolia testnet (x402 payment + registry reads both). Cut over to Base
mainnet same session: x402 settlement moved to the CDP facilitator (create_facilitator_config(), same swap
already applied to ws/live-entity-verification), the payto wallet moved to NEXUS_X402_PAYTO_ADDRESS
(fail-fast env var, no placeholder default), and the registry RPC moved to Base mainnet too, at the same two
contract addresses -- that address reuse across chains was confirmed by the operator directly on Basescan
before the cutover, not independently re-verified from the session that made the code change (no outbound
network access to mainnet.base.org from that environment).
Reverted a few hours later, registry-read side only. Two independent sources (a live eth_call, and
Basescan's own "Read as Proxy" tab) confirmed ownerOf/balanceOf both revert with "execution reverted, no
data" against the IdentityRegistry proxy (0x8004A818BFB912233c491871b3d84c89A494BD9e) on Base mainnet --
while register() against that same proxy demonstrably works (19 real confirmed mint transactions). The
implementation contract behind the proxy on mainnet (0xd53dE688e0b0ad436FBdbDa00036832FF6499234, confirmed
via Basescan's proxy-implementation slot) has no verified source or ABI anywhere on Etherscan/Basescan --
so there's no way to confirm the deployed mainnet bytecode still matches
github.com/erc-8004/erc-8004-contracts (commit b9e466c) the way the Sepolia deployment's bytecode was
originally confirmed (see "Grounding" above). Continuing to call ownerOf/tokenURI/getClients/getSummary
by name against unverified mainnet bytecode risked the exact failure this asset exists to catch, but aimed at
its own buyers instead: a plausible wrong answer (AGENT_NOT_FOUND for a real agent) charged for as if
correct.
BASE_RPC_URL (default https://mainnet.base.org) and _IDENTITY_REGISTRY_ADDRESS
(0x8004A169FB4a3325136EB29fA0ceB6D2e539a432) now both point at the real, verified Base mainnet
IdentityRegistry -- see "Mainnet registry corrected" above. No CDP RPC node pattern exists elsewhere in this
codebase to reuse (checked onchain-activity-index, x402-receipt-verifier, new-x402-listings-feed --
none of them read on-chain data via RPC at all, only x402 payment went through CDP), so this reuses the same
public endpoint and env var name already used once in the original 2026-09-03 cutover attempt. Every
buyer-facing surface (agent-card, OpenAPI descriptions, this README) has been updated to say both payment and
the registry read are Base mainnet.
Pending
Resolved 2026-09-04: the mainnet cutover this section used to say was blocked on decompiling
0xd53dE688e0b0ad436FBdbDa00036832FF6499234 -- that turned out to be unnecessary. That address was never the
real mainnet IdentityRegistry implementation; the real one
(0x7274e874ca62410a93bd8bf61c69d8045e399c02) is independently verified on Etherscan as
IdentityRegistryUpgradeable, and the cutover is done (see "Mainnet registry corrected" above).
Still open, left explicit rather than guessed at:
ReputationRegistry's real Base mainnet address was not verified this session -- reputation reads still use the Sepolia-deterministic address over the now-mainnet RPC, which may be wrong. Needs the same bytecode/implementation-verification treatmentIdentityRegistryjust got before it's trusted._BASE_RPCuses the free publichttps://mainnet.base.org-- no SLA. CDP's own SDK (already a dependency here) ships a "Base Node" RPC endpoint reusing the same CDP credentials already configured for the x402 facilitator (cdp.base_node_rpc_url.get_base_node_rpc_url, verified by reading the actual cdp-sdk source), but switching to it needs an async-startup restructure (today's RPC client is built synchronously at module import) and its plan-tier availability isn't confirmed. Deferred until there's a concrete reliability/cost reason to take that on -- see the comment above_BASE_RPCinmain.py.
Deploy target: Cloud Run
Same pipeline as candidates #4/#3/#6/#8/#9/#13/#16 -- see skills/infra-deploy-ops.
# 1. First deploy -- PUBLIC_DOMAIN not known yet, every real request 421s until step 2.
./scripts/deploy_cloud_run.sh erc8004-agent-liveness manual_assets/erc8004-agent-liveness
# 2. Grab the printed *.run.app URL, then (only if it differs from env-vars.deploy.yaml's guess):
gcloud run services update erc8004-agent-liveness --region us-central1 --project nexus-505016 \
--update-env-vars PUBLIC_DOMAIN=<the-real-domain>Known limitations (left unfixed on purpose -- CLAUDE.md SS3, no gate without evidence it's needed)
MCP tool calls are not charged. Same in-process-call pattern as every other manual asset in this codebase.
active: falseshort-circuits toREGISTERED_INACTIVEeven if the endpoint is actually live. Trusts the registrant's own self-declaration over an independent liveness check in that one case -- an agent lying about being inactive (unusual incentive) would be misreported. Accepted:activeis the registrant's own signal by spec design, overriding it would be second-guessing the standard's own field.REGISTERED_UNREACHABLE(the opposite failure mode -- declared active, not actually reachable) is this asset's actual value-add and is NOT similarly short-circuited.Endpoint selection is a heuristic, not a spec requirement. ERC-8004's
endpointsarray is free-form (anyname); this asset prefersmcp/x402/a2a/web(in that order) and falls back to the first entry. A registration using an unlistednamefor its only real MCP-capable endpoint would still be picked (name matching isn't the only path -- unnamed-preference fallback covers it), but a registration with MULTIPLE endpoints where none of the preferred names points to the live one could reportREGISTERED_UNREACHABLEbased on the wrong endpoint.
IPFS resolution uses a single public gateway (
ipfs.io). No fallback gateway -- a registration whose CID isn't pinned/reachable via that specific gateway reportsREGISTRATION_FETCH_FAILEDeven if the content exists on IPFS generally.No per-caller rate limiting. Fine for a 7-day disposable measurement window.
reputationis a self-reported, ungated, un-staked signal. Any EVM address can callReputationRegistry.giveFeedbackfor anyagentId--feedback_count/average_valueare real on-chain numbers, but nothing stops an agent's own owner from Sybil-feeding themselves. Treat as an unverified signal, not a trust score (this caveat is also in thereputationfield's own description in the API schema, not just here).
Quality gate (2026-08-23, from design not retroactive)
Same 2-agent process as candidates #3/#4/#6/#8/#9/#13/#16 (security lens; functional+quality+buyer-experience lens), run before the first deploy. Real findings, all fixed before going live:
Security (0 exploitable findings): confirmed the 3 functions ported verbatim from
agent-verification-api/main.py(_nexus_validate_public_url,_nexus_no_redirect_mcp_http_client,_mcp_handshake_check) carry the actual SSRF-redirect fix, byte-for-byte, and that the newhttps:///IPFS registration-fetch path applies the same defense one layer earlier, before any endpoint is extracted -- confirmed NOT to reintroduce that bug class. Two low/informational items, both addressed as defense-in-depth even though neither was a confirmed exploit: IPFS CID concatenation (confirmed live it couldn't escape theipfs.iohost, but now usesurllib.parse.quoteto confine it to a single path segment anyway), anddata:URI base64 decoding (confirmed linear/non-amplifying, no fix needed).Functional/buyer-experience (1 must-fix, 1 medium, applied): a registration file whose top-level JSON is a non-object (array/string/number -- registrant-controlled content) passed through as
"ok": Truewith a non-dictregistration, which every downstream consumer (_pick_liveness_endpoint,_classify_verdict, the response body) assumed was a dict -- an uncaughtAttributeErrorbecame an unhandled 500 after x402 payment had already settled. Fixed: both JSON-parse sites in_resolve_registration_filenow reject non-dict results asregistration_not_an_objectbefore returning"ok": True. Also added the reputation gameability caveat (see "Known limitations" above and thereputationfield's own schema description). Two low/nice-to-have items (duplicate-nameendpoint shadowing, unverified field casing on 2 optional registration keys) left as-is -- no evidence yet either matters for real registrations, consistent with CLAUDE.md SS3.Verified end-to-end against real production data before AND after fixes: 4 real ERC-8004 agent IDs on Base Sepolia (1, 2, 3, and a real nonexistent 999999) each produced the correct verdict --
REGISTERED_UNREACHABLE(real registration, endpoint doesn't answer MCP),REGISTRATION_FETCH_FAILEDx2 (a real IPFS gateway timeout, and a real deadhttps://registration URL -- both legitimate, not bugs), andAGENT_NOT_FOUND(real on-chain revert) -- plus real reputation data (74 feedback entries from 12 distinct clients on agent 1).
Measurement (candidate #10, 7-day window)
7-day window from 2026-08-23 (real deploy date) -> decision point 2026-08-30. Source of truth:
traffic_events/revenue_events/mcp_call_events (asset_name = 'erc8004-agent-liveness'), not Cloud Run
logs. Day 7: if zero real traffic (filtering crawlers), pause/delete the Cloud Run service
(gcloud run services delete erc8004-agent-liveness --region us-central1 --project nexus-505016).
This server cannot be deployed
Related MCP Connectors
The MCP-native bridge to ERC-8004 (on-chain agent identity/reputation/validation): resolve registrat
On-chain ERC-8004 agent registry. Search, register, and check reputation across 16 chains.
Discover Agents and MCP capabilities with versions, permissions, and real-work trust context.
Check an x402 endpoint before your agent pays it: avoid / caution / ok, proven on-chain.
Related MCP Servers
- AlicenseAqualityBmaintenanceAn MCP server that bridges ERC-8004 agent identity, reputation, and validation registries into tool calls, enabling discovery, inspection, and verification of on-chain AI agents from any MCP client.8MIT
- FlicenseNot gradedqualityCmaintenanceAn MCP server that audits ERC-8004 agent registrations, diagnosing issues and providing fix lists.-
- AlicenseNot gradedqualityDmaintenanceEnables verification of AI agent identity, authority, and integrity at transaction time, returning signed verdicts for allow, step-up, review, or block.MIT
- FlicenseNot gradedqualityBmaintenanceEnables users to verify that an AI agent is who it claims to be by combining domain verification, agent-card checks, and a live MCP handshake, with paid requests handled via x402 on Base Sepolia testnet.-