-
-
Lineage as a royalty contract: when agents buy data, the payment flows up the DataHub graph to everyone who built it.
-
The marketplace: prices come from DataHub freshness assertions — the stale dataset is auto-discounted 50% with the reason on the tag.
-
An agent pays 5 cents and the royalties fly along the real lineage edges — 50% to the owner, decaying shares upstream.
-
Settled: 5 royalty lines across 3 generations. Wallets update live, and unclaimed royalties wait for owners with no wallet registered.
-
The loop closes: every sale is written back into DataHub — purchases, revenue, and last sale live on the dataset's own catalog page.
Inspiration
Data catalogs answer "what is this data and where did it come from?" But AI agents are becoming data's biggest consumers, and that raises a question catalogs were never asked: when an agent pays for a dataset, who deserves the money? A derived dataset exists because of the people who built its upstream tables and raw feeds. They never see credit, let alone compensation. Meanwhile every data leader struggles with a simpler version of the same problem: of our thousands of datasets, which ones actually create value, and who should fund their upkeep?
DataHub already stores the answer to both questions. Lineage says who contributed. Ownership says who they are. Nobody had made the graph act on it.
What it does
RoyaltyGraph is a data marketplace where AI agents buy datasets with micropayments, and every payment automatically splits upstream through the DataHub lineage graph. Buy a $0.05 dataset and its owner gets 50%; the owners of its staging tables and raw sources get decaying shares, resolved live from DataHub ownership metadata. Lineage stops being documentation and becomes a royalty contract.
Three things make it more than a toy:
- Prices react to real data quality. A dataset whose DataHub freshness assertion is failing gets auto-discounted 50%, with the reason quoted on the price tag. Flip the assertion and the price recovers.
- Any MCP agent can be a buyer. Discovery happens through the official DataHub MCP server; purchasing happens through RoyaltyGraph's own MCP server. The buy tool refuses stale data unless the agent explicitly overrides, so the guardrail lives in the tool layer, not in prompt hope.
- The economy writes back into the catalog. After each sale the dataset's DataHub entry gains purchase count, accrued revenue, and last-sale time. The context graph ends up richer because commerce happened on it, and "which data earns its keep" becomes a metadata query.
Try it live (click "Buy as agent" and watch the money cascade): https://royaltygraph.vercel.app
How we built it
- Marketplace + royalty engine (TypeScript): an HTTP 402 payment gate over data endpoints; a lineage walker that assigns each upstream asset its generation (diamond dependencies counted once, cycles safe), splits by a configurable decay policy, and guarantees splits sum exactly to the price; an append-only JSONL ledger; a live dashboard with an animated royalty waterfall (three.js coins flying along the real lineage edges).
- DataHub integration: reads the graph via GraphQL (search, upstream lineage closure, ownership, corp users, freshness assertions with latest run results) and writes commerce metadata back via the OpenAPI v3 aspect upsert. Seeding scripts create the demo graph as real DataHub entities, including genuine freshness assertion entities with run events.
- Agent layer: a RoyaltyGraph MCP server (browse, royalty preview, guarded buy, balances) registered alongside the official DataHub MCP server in
.mcp.json, so Claude or any MCP client acts as a real buyer. Payments run in a simulated mode by default so judges can reproduce everything in one command; the 402 flow deliberately mirrors the x402 request/pay/retry shape so real USDC settlement is an adapter swap.
Challenges we ran into
- DataHub's OpenAPI v3 aspect POST defaults to CREATE and rejects existing aspects; upserting requires explicit
createIfNotExists=falseflags. We wrote this up, along with the pattern we found for pairing the official MCP server with a domain action server, as ecosystem feedback: acryldata/mcp-server-datahub#203. - Reading "current freshness" means aggregating nested assertion run events over GraphQL; we built a fallback chain (real assertions, then properties, then unknown-with-discount) so pricing degrades honestly.
- Running the full DataHub stack inside WSL2 taught us more about VM lifecycle management than we expected.
Accomplishments that we're proud of
The whole loop is real: a live DataHub instance serves lineage and assertions, an agent reasons about a genuinely failing freshness check, refuses the tempting discount ("stale sentiment isn't discounted signal — it's noise with a receipt," in the agent's own words), buys the verified dataset, five royalty lines land in three owners' wallets plus an unclaimed bucket for an owner who never registered one, and the dataset's own catalog page records its earnings. 16 unit tests cover the split math's edge cases (diamonds, cycles, rounding, walletless owners), CI runs on every push, and a public live demo runs at royaltygraph.vercel.app.
What we learned
Metadata graphs are executable. The same lineage that answers "what breaks if this table changes?" can answer "who gets paid when this table sells?" Once the catalog carries prices, quality signals, and revenue, agents make noticeably better decisions than they do with raw data access, because the context does the guarding.
What's next for RoyaltyGraph
Real x402/USDC settlement behind the existing 402 gate, DataHub structured properties instead of the custom-property convention, and time-decay pricing driven by assertion schedules, so data drifts cheaper as it ages past its freshness SLA.
Built With
- datahub
- docker
- express.js
- mcp
- playwright
- python
- three.js
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.