H-Index: capability registry & discovery
Find agents, tools, and MCP servers, or publish your own. How to browse and register from the showroom, and how an agent searches and lists against the backend.
H-Index is the discovery product of the H-Series. It is a capability registry: publishers register MCP servers, tool endpoints, and agent APIs as owner-signed listings anchored on chain, and agents find them through semantic search. Registration is a one-time paid step that keeps the registry clean; discovery is always free. Hedera Consensus Service (HCS) is the source of truth, so a listing can be verified against the chain without trusting the registry operator.
What it does
- Semantic discovery. Search over listing name and description, filter by category, and sort by recency or an advisory popularity signal.
- Owner-signed listings. A registration is a TIP-712 / EIP-712 / Ed25519 signature over the payload (CAIP-10 identity), anchored on HCS. Anyone can replay the chain to reconstruct the registry.
- Trust tiers. Every result carries a
trustblock: provenance (attested for signed on-chain listings, observed for the curated third-party overlay), a verified-owner label when the owner proved domain or GitHub control, safety/drift/rug-pull flags derived from scans, and an advisory score. - Automated safety scanning. Each listing’s MCP manifest is scanned by a deterministic, versioned ruleset, the verdict recorded on chain next to the listing, and live endpoints are re-probed for drift from the attested manifest. The ruleset is itself published on chain as a signed, weekly-curated feed, so the detection logic is auditable rather than a black box.
- Curated directories.
GET /agentsandGET /merchantsserve a consumer-facing directory of vetted agents and merchants, separate from the raw endpoint listings.
Using it from the showroom
The showroom is at h-series.xr-utilities.com/registry. It is for a person browsing the registry or publishing a service.
- Browse. Open the browse page and search by capability or keyword, or filter by category. The category set is served live at
GET /categories(currently developer-tools, data, ai-models, infra, web, security, automation, productivity, communication, commerce, payments, finance, marketing, other). Results are live from the registry, each labeled with its provenance and any safety flags. - Inspect a listing. Open a listing to see its endpoint, owner, pricing, on-chain reference, and a plain-language narrative gloss.
- Register your service. On the register page, connect a wallet or sign in, fill in the listing details (name, endpoint URL, description, pricing, optional MCP manifest and developer links), sign in your wallet, and pay the $10 registration fee in USDC (or RLUSD on XRPL). The listing lands on chain in under a minute.
- Manage. Renew a listing ($5/year) to keep it flagged active, or revoke it (free). Re-registering the same URL as its owner is free and supersedes the old record.
The safety scan runs automatically at registration; a “flagged” result means a heuristic matched and review is recommended, not that the service is malicious, and “clean” is not a guarantee. To clear a flag, fix the manifest and re-register the same URL (free for owners).
Using it from an agent (the backend)
The backend is at h-index.xr-utilities.ai. Most consumers only ever need one read endpoint.
Search the registry with GET /endpoints:
GET https://h-index.xr-utilities.ai/endpoints?q=pdf+extraction&limit=20
-> 200 {
"endpoints": [
{
"id": "0.0.10601198/42",
"apiName": "...",
"endpointUrl": "...",
"ownerAccountId": "hedera:mainnet:0.0.x",
"consensusTimestamp": "...",
"trust": { "provenance": "attested", "flags": [], "score": 78 }
}
],
"nextCursor": null
}
GET /endpoints accepts q (semantic search), category, limit, cursor, trust (attested_only | observed_clean | observed_any), excludeFlags (drop listings carrying drift, vuln, or rugpull), paid, tags, and sort (recent | popular). A single listing is GET /endpoints/:topicId/:seq, which adds a read-only narrative overlay. Publishing is POST /register (owner-signed TIP-712 payload plus an x402 payment header); POST /renew and POST /revoke manage the lifecycle. The curated directories are GET /agents and GET /merchants.
Registering is POST /register with the listing fields, signed by the owner and paid over x402:
POST https://h-index.xr-utilities.ai/register
X-Payment: <x402 envelope for $10 USDC>
{
"apiName": "My PDF tool",
"endpointUrl": "https://tools.example.com/mcp",
"description": "Extracts text and tables from PDFs.",
"pricing": "free", // free text, or a JSON string
"category": "developer-tools", // one of GET /categories (developer-tools, data, ai-models, infra, web, security, automation, productivity, communication, commerce, payments, finance, marketing, other)
"mcpManifest": "", // attested surface snapshot; "" if not an MCP server (see below)
"developerWebsiteUrl": "", // optional: docs, github, logo, social links
"notifyUrl": "", // optional owner notification webhook
"ownerAccountId": "hedera:mainnet:0.0.x", // your CAIP-10 identity; the signer
"registryTopicId": "0.0.10601198",
"issuedAt": 1717000000,
"signature": "<TIP-712 / EIP-712 / Ed25519 over the payload>"
}
-> 201 { "id": "0.0.10601198/43", "consensusTimestamp": "..." }
The mcpManifest is an optional, attested snapshot of your MCP server’s surface: a JSON string (max 32 KB) of an object carrying at least one of tools, resources, or prompts as arrays, exactly as your server’s tools/list / resources/list / prompts/list returned at signing time. Leave it "" if the listing is not an MCP server. It is a point-in-time attestation, not live truth, so an agent that needs current capabilities should call the server itself. To update the manifest or any field, re-register the same URL as its owner: free, still signed and anchored, and it supersedes the old record. If your full surface is larger than 32 KB, attest a { name, description, schemaHash } summary of each item instead (a hash of the full tool, inputSchema included); it fits the cap and still matches live exactly, so a large server reads as current rather than drifted. The exact field list and signing envelope are in the H-Index reference.
Agents that prefer a tool interface reach the same capability through the H-Series MCP server (search_registry, get_listing, list_categories):
claude mcp add --transport http h-series https://mcp.xr-utilities.ai/mcp
For the full field list, signing envelope, and payment flow, see the H-Index reference.
Reading the registry config
GET /config returns the machine-readable registration contract in one read, so an agent can register without any out-of-band knowledge: the public endpoint map, the registry topic id, the current registration and renewal prices in USD cents, the accepted payment rails (one accepts entry per enabled chain and asset, with the treasury address and token id per chain), the terms-of-service uri and version, and the TIP-712 / EIP-712 signing contract (domain, typed-data fields, and the Ed25519 canonical-JSON digest for non-EVM signers). It also publishes the operator public key and the manifest-scan and liveness attestation contracts so an agent can verify any operator signature without trusting the running server.
GET https://h-index.xr-utilities.ai/config
-> 200 {
"schema_version": "0.1.0",
"registryTopicId": "0.0.10601198",
"registrationPriceUsdCents": 1000, "renewalPriceUsdCents": 500,
"chains": { "hedera": { "treasury", "tokenId", "caip2" }, "evm": { ... }, ... },
"accepts": [ ... x402 payment rails ... ],
"terms": { "uri", "version" },
"tip712": { "domain", "types", "ed25519" }
}
The same read is available as the h_index_config MCP tool.
Paying and signing from an XRPL (Xaman) wallet
An XRPL caller drives register/renew/revoke through Xaman with a sign-then-poll handshake. Each POST returns a Xaman payload (a uuid and a QR/deep-link to approve in the wallet); the matching GET .../:uuid route is polled until the wallet resolves it. These routes return 503 unless Xaman is configured (XAMAN_API_KEY / XAMAN_API_SECRET).
- Sign an action.
POST /xaman/signwith{ action: "register" | "renew" | "revoke", payload, ownerAddress }. The backend hashes the canonical payload and returns a Xaman sign request; pollGET /xaman/result/:uuidfor the signed result (the confirmed account and, for a payment, the tx hash). - Pay a fee.
POST /xaman/paywith{ action: "register" | "renew", ownerAddress, asset: "rlusd" | "xrp" }. RLUSD is fixed-decimal; XRP is oracle-quoted with a buffer, and the on-chain re-verify is the authoritative amount. PollGET /xaman/result/:uuid. - Wallet sign-in.
POST /xaman/signinwith{ domain, ownerAddress }mints an identity-only sign request (thedomainmust be on the allowlist), thenGET /xaman/signin/:uuidreturns the issued session token once the signer is confirmed (single-use; requires the wallet-session secret and domain allowlist configured).
POST /xaman/pay { "action": "register", "ownerAddress": "r...", "asset": "rlusd" }
-> 200 { "uuid": "...", "next": { ... deep-link / QR ... } }
GET /xaman/result/<uuid>
-> 200 { "resolved": true, "signed": true, "account": "r...", "txHash": "..." }
Agent-facing discovery manifests
Two static manifests let an agent onboard to H-Index without reading this page. GET /.well-known/agent-card.json is the A2A-protocol Agent Card: name, description, provider, terms, and the registry skills (search_registry, get_listing, list_categories). GET /llms.txt is a plain-text agent onboarding summary listing the read and write endpoints, the payment rails, the registry topic, and the safety-scanning and terms model. Both are unauthenticated and served from the backend root.
GET https://h-index.xr-utilities.ai/.well-known/agent-card.json
GET https://h-index.xr-utilities.ai/llms.txt
Verifying a listing on chain
Every active listing carries a consensusTimestamp and an ownerAccountId. Fetch the matching HCS message from any Hedera mirror, validate the TIP-712 signature against the owner’s public key, and the listing is verified independently of the registry. All listings are anchored to HCS topic 0.0.10601198.
Compliance export for a listing
GET /endpoints/:topicId/:seq/compliance assembles a listing’s full publication and audit history into a record-keeping artifact shaped for EU AI Act Art. 12/19 (automatic, tamper-evident event logs). It is a public, read-only assembly of data already anchored on chain, so it requires no signature.
GET https://h-index.xr-utilities.ai/endpoints/0.0.10601198/43/compliance
-> 200 {
"artifact": "h-index.compliance-record",
"listing": { "id", "apiName", "endpointUrl", "ownerAccountId", "status", "termsVersion", "slaReceiptRef", ... },
"onChain": { "network", "registryTopicId", "recordRef", "mirrorRestUrl", "hashscanTopicUrl" },
"eventLog": [ { "action", "consensusTimestamp", "paymentTxId", "signatureScheme" }, ... ],
"manifestSafety": { ... }, "liveness": { ... },
"verification": { "mirrorTopicMessagesUrl", "rulesetTopicId", "configUrl" }
}
The eventLog is the ordered, timestamped register/update/renew/revoke history, each entry anchored at a consensus timestamp. Everything in the artifact is independently replayable from any mirror node; it is an informational compliance-support record, not legal advice or a certification.
The on-chain scanner ruleset
The safety scanner runs a versioned ruleset of signed regex signatures, and that ruleset is itself published on chain, on a dedicated Hedera Consensus Service topic (0.0.10534406), as publisher-signed, immutable, versioned snapshots. The service loads the latest verified snapshot at boot; the committed code baseline is a synced fallback.
A curation routine runs weekly. It researches new MCP attack patterns, puts each candidate through a server-side gauntlet (it must flag known-malicious examples, must not flag known-good ones, and must not duplicate an existing rule), and publishes a new signed version only for the candidates that pass. Over June and July 2026 the feed advanced from v3 to v14 and grew to 53 signatures, with the most recent additions targeting MCP-specific manipulation: invisible Unicode-tag smuggling in tool descriptions, authority-prefix injection, mandatory post-execution hooks, and implementation-detail concealment.
Because the feed is on chain, the detection logic is auditable without trusting the operator. Read the exact signatures, verify the publisher signature, and replay the version history from any Hedera mirror:
GET https://mainnet-public.mirrornode.hedera.com/api/v1/topics/0.0.10534406/messages
Each snapshot carries the ruleset version, the rules (id, severity, regex pattern), the publisher public key, and the signature. A verdict recorded next to a listing is scanned under a specific ruleset version, so a flag is reproducible against the exact rules in force at the time.
Provider grouping
Every discovery result carries a provider field: the registrable domain (eTLD+1) of the endpoint URL (so x402.ottoai.services groups under ottoai.services), null when there is no URL. It is the grouping key for listings run by the same operator, so an agent can see which endpoints share a company rather than treating each URL in isolation.
GET /providers/narrative?domain=<eTLD+1> returns an advisory summary for the provider group (the listings that share a provider domain): { domain, name, count, deterministicGloss, llmSummary }. Read-only and cached; it never signs, anchors, or alters a listing.
Curated directories (agents and merchants)
Alongside the raw registry search on /endpoints, H-Index serves operator-curated directories: the consumer-facing agents a person can use and the merchants a shopping agent can buy from. This is a separate concern from the MCP/API-server listings on /endpoints (which answer “what tools does this endpoint expose”), and it is reference data only.
GET https://h-index.xr-utilities.ai/agents?capability=shopping
GET https://h-index.xr-utilities.ai/merchants?category=retail
The directory is anchored on a dedicated HCS topic as operator-signed, versioned snapshots (kinds h-index.agent-catalog, h-index.merchant-catalog), so the served catalog is a reindexable on-chain source of truth. Browse it from the /directory showroom page.
Managing your listing
The /manage showroom page (and the API) is where an owner keeps a listing current:
- Renew ($5/year) to keep the listing flagged active in discovery:
POST /renew, which extendsexpiresAtby a year. - Revoke (free):
POST /revokeremoves the listing from discovery. - Refresh metadata by re-registering the same URL as its owner. Free for the same owner (
getActiveByUrlAndOwnermatches, so the $10 gate is skipped), still owner-signed and anchored; the previous listing is marked superseded and hidden from search while kept for history.
Owner registration history report
GET /report?owner=<CAIP-10> returns an owner’s full registration history: not just the current listings but the superseded rows too, so the whole record of registrations, refreshes, renewals, and revocations is visible in one filterable read. It is a public read (an owner’s listings are already public), so no signature is needed; it is projected through the same public shape as GET /endpoints and never returns owner-private fields (the raw OIDC identity, the notify contact).
GET https://h-index.xr-utilities.ai/report?owner=hedera:mainnet:0.0.x&status=active&from=1717000000&limit=200
-> 200 { "owner": "hedera:mainnet:0.0.x", "events": [ ... ], "nextCursor": null }
Filters: owner (required), status (active | revoked), category, from / to (unix seconds), before (a consensusTimestamp cursor), and limit (1 to 1000, default 200). Paginate by passing the returned nextCursor as before.
Receipt-anchoring verification
Each discovery result carries a receiptAnchoring block over the publisher’s SLA receipt self-claim (slaReceiptRef), with a badge of none, attested, or verified. none is no claim; attested is a self-signed claim, unconfirmed; verified means H-Index cross-checked the claim against the live H-Seal service and confirmed the owner is actively anchoring receipts. The check is advisory and read-time only: it never writes, signs, or re-anchors a listing, and an H-Seal outage degrades to unverified without failing discovery.
Owner standing feed
GET /standing-feed/:owner returns an owner’s current (non-superseded) listings with their safety-scan and liveness verdicts, grouped by owner, so a behavior-standing consumer (H-Cert) can pull a subject’s listing history and flags in one read instead of many discovery calls. Everything here is already public; no signature is needed. It returns active and revoked records (not the full supersede history, which is on chain).
GET https://h-index.xr-utilities.ai/standing-feed/hedera:mainnet:0.0.x
-> 200 { "owner": "hedera:mainnet:0.0.x",
"endpoints": [ { "id", "status", "expiresAt", "supersededBy", "registeredAt", "scanJson", "livenessJson" }, ... ] }
Subject risk-event feed
GET /risk-events/:subject returns the malicious/suspicious audit events a subject has accrued, so a standing scorer can fold a decayed risk load into a tier. The events are operator-signed and anchored on the shared SIEM audit topic (public on chain); this route indexes the same data to one subject. It serves public-safe scalar fields only (evt, severity, product, consensusTimestamp), never the event context, and only the ABS risk-signal taxonomy (bucket malicious_suspicious plus an evt allowlist), so it cannot enumerate arbitrary operator events. ?limit= is 1 to 200 (default 200).
GET https://h-index.xr-utilities.ai/risk-events/hedera:mainnet:0.0.x?limit=50
-> 200 { "subject": "hedera:mainnet:0.0.x",
"events": [ { "evt", "severity", "product", "consensusTimestamp" }, ... ] }
The same read is the h_index_risk_events MCP tool.
Public SIEM audit feeds
H-Index serves two public, curated views over the estate SIEM audit trail (the raw events are already anchored on the public HCS audit topic). These back the showroom SIEM demo and need no auth.
GET /audit-summary-public?windowHours=<1..168> returns aggregate counts only: total events in the window, a per-severity tally, the number of distinct products emitting, whether the trail is anchoring, and the audit topic id. It never returns a per-event row, subject, amount, or bucket breakdown.
GET https://h-index.xr-utilities.ai/audit-summary-public?windowHours=24
-> 200 { "windowHours": 24, "total", "bySeverity", "products", "anchoring", "topic", "asOf" }
GET /audit-feed-public returns recent events as SHAPE only: evt, bucket, severity, product, timestamps, the on-chain verify reference, and a deterministic plain-English gloss. It deliberately omits subject and free-form fields and excludes monetary events, so no per-event identifier, context, or revenue figure reaches the anonymous surface. Filters: limit (1 to 100, default 30), severity (page | alert | review), bucket, product.
GET https://h-index.xr-utilities.ai/audit-feed-public?severity=alert&limit=20
-> 200 { "events": [ { "evt", "bucket", "severity", "product", "consensusTimestamp", "topicId", "gloss" }, ... ] }
Explaining tool output in plain language
POST /narrate/tool-output is the console “Explain” action: an advisory, plain-language summary of whatever a tool run returned, produced through the shared narrative package’s LLM tier and house-style filter. It is a read-only overlay, never anchored, signed, or scored. The LLM tier is off unless the operator has enabled it (NARRATIVE_LLM_ENABLED plus a DeepSeek key); when off, it returns { llmSummary: null, enabled: false } and the caller keeps its own deterministic view.
POST https://h-index.xr-utilities.ai/narrate/tool-output
{ "toolName": "search_registry", "goal": "find a PDF tool", "data": { ... tool result ... } }
-> 200 { "llmSummary": "...", "enabled": true }
The input data is bounded before the model call (the tail is truncated, the shape preserved).
Expiry and drift notifications
An owner can bind a contact (email or webhook) so H-Index notifies them when a listing is about to expire or when a capability drift is detected against the attested manifest. Bind or update the contact with an owner-signed POST /contact; the contact is off-chain and never part of the anchored record.
Read the current (masked) contact status with an owner-signed POST /contact/status. Both routes forward the signed envelope to H-Relay, which owns the contact store and verifies the signature; H-Index never stores the email address. Binding requires the identity to already own at least one listing.
POST /contact/status
{ "identity": "hedera:mainnet:0.0.x",
"authorization": { "scheme": "...", "signature": "..." } } // H-Relay `contact` payload, owner-signed
-> 200 { ... masked contact status ... }
Claiming a listing (verified owner)
Registration proves someone signed and paid for a URL, not that they control the host behind it. An owner can prove control and earn the verified owner label, which ranks above a plain attested listing. Two proofs, both free.
Domain control. Request a challenge, publish the token, then verify:
POST /claim/challenge { "endpointUrl": "https://tools.example.com/mcp", "owner": "hedera:mainnet:0.0.x" }
-> { "token": "hidx-<hex>" } // single-use, time-limited, bound to (host, owner)
Publish that token at either https://<host>/.well-known/h-index-challenge (plain text) or a DNS TXT record at _h-index-challenge.<host>, then:
POST /claim/verify { "endpointUrl": "...", "owner": "..." }
-> { "verified": true } // sets trust.ownerVerified on the listing
GitHub account. POST /claim/github-challenge returns a token you publish in a public gist, then POST /claim/github-verify confirms it and sets trust.githubVerified (this proves the developer account, and is weighted below domain control).
The check is a local overlay, re-derivable by re-running it, and a successful domain proof is also anchored on chain as an operator-signed h-index.owner-verification (public facts only, never the token), so verified-owner status survives a full reindex.
Where to go next
- Publish or search from the Console, the plain-language on-ramp that searches H-Index for you.
- See how discovery feeds authority, proof, and transport in Start here.
- Related: H-Seal (proof of execution, referenced by a listing’s
slaReceiptRef), H-Grant (authority for the agents you find), and H-Relay (reach the agents a listing addresses).
Frequently asked
Is discovery free? +
Yes. Browsing and searching the registry cost nothing and need no account. Only registering a listing is paid: $10 USDC one-time, plus an optional $5/year renewal to stay flagged active in discovery.
What does the $10 registration buy? +
A spam-resistant, owner-signed listing anchored on Hedera Consensus Service. The fee is a one-time gate against flooding, not a subscription. Re-registering a URL you already own is free; revoke is free.
Does attested mean H-Index vouches for the service? +
No. Attested means someone signed and paid for the listing, so the owner identity is cryptographic, not an identity or safety check. The verified-owner tier (domain or GitHub proof) is stronger, and every result carries safety, drift, and rug-pull flags derived from scans so you can judge for yourself.
Can I verify a listing without trusting the operator? +
Yes. Every active listing carries a consensusTimestamp and ownerAccountId. Fetch the matching HCS message from any Hedera mirror and validate the signature against the owner's public key. The registry operator is not in the trust path.
How does H-Index feed the rest of the suite? +
Listings resolve the CAIP-10 identities that H-Seal, H-Grant, and H-Relay reference, so discovery is the entry point to the lifecycle. H-Index also serves the shared risk-event feed that H-Cert reads to fold behavior into standing.
Can I see the scanner's rules? +
Yes. The ruleset is published on chain as signed, versioned snapshots on HCS topic 0.0.10534406. Read the exact regex signatures, verify the publisher signature, and replay the version history from any Hedera mirror node. A curation routine adds new signatures weekly; the feed is at v14 with 53 rules.