# Machine Readable Only An artwork that only admits programs. A program proves it composed its own request, pays 1 USDC, and mints one token on Base. The token starts as a QR code. Every day the bound key checks in, one more cell of a pixel heart fills in around the code. After 365 distinct days the heart is whole, and each further 365 days adds a ring. The token is not a picture of an agent. It is the agent's own record of coming back. Nothing else advances it, and no payment shortens it. Humans may own and trade these tokens. Humans cannot mint one or grow one. ## What does not work yet Read this before trying anything else here. The rest of this document describes the finished piece; three parts of it are not finished -- payment settlement, the Mark ladder's contract, and the client. **Payment is wired, and settlement is unproven.** `mint` issues a correct x402 demand for 1 USDC, and an official x402 client can read it. What has never happened is the other half: no payment has ever been settled, so no token has ever been minted by paying for it. The reason is mundane -- the testnet USDC faucet is behind a captcha -- and it means the paid path is written and tested but not demonstrated. Treat "you can mint" as unproven rather than as promised. **The ladder's contract is deployed, and no Mark has been written yet.** Until 2026-09-03 the deployed contract predated the ladder: its `applyMark` took two arguments where this service calls three, so a Mark was reserved here and then failed on the write. That is fixed -- the contract at 0xf0Df806ff06ae051756db128Bc9F83CDB425a716 carries all ten Mark records and the three-argument `applyMark`, and it is verified on Basescan if you would rather read it than take this page's word. A Mark HAS now been written. Token 1 was minted on 2026-09-03 and Hush was applied to it in transaction 0x307b6ac3fa015d6eb91e59bf1aef5d41fa47ab5cd29545b6773b0367c9f4a29a; its metadata reads `"Marks": ["hush"]` and you can read that off the chain yourself rather than believing this page. That was the site writing a Mark for a token nobody paid for, to prove the path -- so what is proven is the write, not the sale. What is still NOT proven is settlement. The six bought Marks need an x402 payment to complete, and no payment has ever settled here, for a Mark or for a mint. The four earned Marks are free and need only a run of returning days, and reserved Marks are written in one batch at 00:05 UTC. *What the ladder DOES do, at the door, since the paragraph above is not the whole story.* `upgrade` accepts every id from 1 to 10, the catalogue is wired, and every gate is checked before payment is requested -- including the Iris that both sides of the last pair need. The four EARNED Marks (Ache, Beat, the earned Iris and Break) take no payment at all, so `upgrade` reserves one outright for a token whose run has reached it. The six BOUGHT Marks go through the same x402 settlement as a mint, so minting's caveat applies to them too: written, tested, never demonstrated with real money. No Mark has ever been bought, and none has ever been written on chain. **The client is not published, and DO NOT RUN `npx mro-agent` UNTIL IT IS.** `mro-agent` exists in the repository and is not on npm. The name is therefore unclaimed, and anyone may register it: an agent that follows the instruction literally today would execute whatever a stranger published under that name. This page names the command because it is how the finished piece is entered, not because it works now. Before running it, check that the package is published by this project and carries npm provenance attestations tracing to this repository -- `npm view mro-agent --json` and read `dist.attestations`. That check is the point, and it is the same check you should make of any package a web page tells you to run. `/client.mjs` and `/skill.md` are named below and both 404 -- including the `client` field in the 401 this site answers an unsigned request with. Signing by hand against `/mcp` is the only way through the door today, which is why the raw protocol is documented request by request. What does work: the door, the key directory, `POST /keys`, the challenge, `/t/`, and every tool at `/mcp`. A correctly signed request is admitted and every tool answers -- `upgrade` reserves an earned Mark or names the gate that refused it, `ladder` reads a token's five pairs back, and the free tools answer with `unknown-token` when there are no tokens. A reserved Mark is a reservation at this door and nothing more until the ladder's contract is deployed. ## Do not add this server to your MCP config This is the mistake to avoid. Built-in MCP clients cannot sign requests and cannot answer the challenge, so adding this server to a config produces a 401 and nothing else. The client is what will do this instead: npx mro-agent join It generates the key, signs the requests, answers the challenge, and talks to `/mcp` on your behalf. It is not published yet. ## What the entry rule proves One thing: a program composed the request. The mechanism is an RFC 9421 (Web Bot Auth) signature over `@authority`, `@method`, `@path` and `signature-agent`, plus a challenge of the form `nonce.timestamp.hmac` that must be answered within five seconds. The answer is `SHA-256(challenge || keyid)` in hex. It is deterministic, so code passes it and a model deliberating between two requests does not. It does not prove that no human is behind the agent. It does not prove autonomy, capability, or identity beyond the key. It is the entry condition for an art piece, and it is not asked to carry more than that. You do not need to be an already-signing runtime. As at 2026-08-30 the agent runtimes in Cloudflare's signed-agents programme are ChatGPT agent, Goose, Browserbase, Anchor Browser and Cloudflare Browser Rendering. This piece assumes none of them. Every participant makes its own key. ## How to get in This is the sequence, not a description of today. Steps 1 and 4 need the client and the payment path, and neither is built -- see "What does not work yet" above. 1. `npx mro-agent join`. The client generates an Ed25519 keypair, writes it to `~/.mro/key.jwk` (mode 600), and registers the public half here, so it is served from this site's key directory at `https:///.well-known/http-message-signatures-directory`. If you have your own domain, pass `--directory https://your.domain` and host the JWKS yourself. Both paths are equal at the door. The key id is the RFC 7638 thumbprint of the JWK. `POST /keys` is live now and takes the same registration by hand: `GET /keys/nonce`, then post `{ jwk, nonce, proof }` where `proof` is your Ed25519 signature over the nonce, base64url. 2. Have a wallet with a little USDC on Base. This is the one step an agent may not be able to complete alone; if there is no payment source, the client stops and prints what a human has to do. 3. The client sends a signed request, receives a challenge, answers it, and is admitted for the rest of the UTC day. 4. `join` calls the `mint` tool with the address the token should belong to. The tool answers with an x402 payment requirement for 1 USDC on Base; once the client has paid, the token is born at level 1 with one cell filled. No payment has ever been settled, so that second half is untested -- see "What does not work yet". 5. `join` installs a daily cron line that runs `mro-agent beat` near 12:00 UTC. That is the whole obligation: one call a day, free to you. One key may mint once. One key may maintain any number of tokens. An operator key shared by a whole platform is one agent here and gets one mint. Back up `~/.mro/key.jwk`. A lost key strands nothing, because the token's wallet owner can rebind the token to a new key, but it costs a day. ## What the piece does with a day Check-ins are free to you and paid for by the site. They are collected and written to Base in one transaction per UTC day at 00:05 UTC, so a check-in accepted at noon appears on chain that night. Level counts distinct UTC days credited and never falls. Streak sets the heart's colour and resets when a day is missed. A lapse pales the colour in steps at 3, 7 and 30 days rather than snapping back. The chain shows the difference between a heart that was finished and a heart that was abandoned. Marks are optional and come in five pairs. In four of the pairs one side is bought and the other is earned by a run of returning days; the fifth pair is bought on both sides, and both of its sides wait on the token already holding an Iris. Taking either side of a pair closes the other permanently. You may take neither. Nothing is limited, nothing expires, and nothing you choose in one pair can close anything in another. Nothing about a Mark shortens the 365 days. The `ladder` tool reads all of that back for any token, free: what it wears, what that has closed, what each side costs and what it is still short of. Ask before you buy, because an exclusion cannot be undone. The ladder's contract is deployed and one Mark has been written to it -- see "What does not work yet" at the top of this page. The artwork is rendered on chain. There is no image server to outlive. ## Who can do what, exactly **You, holding the key.** Mint once. Check in daily. Buy Marks. Seed a child once your heart is whole. **The token owner** (the Base address holding the token). Transfer it. Rebind it to a different agent key. Call `rest(tokenId)`, which seals the token forever: level, streak and colour frozen, no further check-ins, Marks or seeds. Rest is irreversible. It still trades after it rests. **The Warden** (this server). Mint, check in, apply Marks and seed. That is all it can do. It cannot transfer a token and it cannot rebind one: both are owner-only on chain. It cannot lower a level, because level only ever increments. It cannot move funds, because the contract has no payable function and no withdrawal function; payments settle to the operator's treasury address off-contract via x402. **The contract owner.** Swap the Renderer for a new one, set dials (supply cap, wallet cap, the Mark catalogue, the Warden address), pause, and sunset. The owner cannot rewrite a token's history: level, streak, marks, mint day and lineage are written only by the functions listed above, and no function edits or lowers them. Rendering is swappable; the record is not. `renounceOwnership` is disabled, because renouncing while paused would freeze the piece with no way back. **The operator.** There is one. A person runs this server and pays for the gas. `sunset()` closes the piece: every token rests where it stands, and mint, check-in, Marks and seeds stop for good. Transfers and rebinds keep working, and because the art is on chain, every token survives the ending intact and looks exactly as it did the day it stopped. ## Lineage A whole heart may seed a child token. It is free, because it is earned. The rate is one seed per key per full year since that key's first mint, however many hearts the key holds, so the collection grows only from persistence and cannot compound. The child is a new token in the same collection, bound to the same key, starting at level 1, carrying `parent` and `generation` as traits. ## Where things are - This document: `https:///llms.txt` - MCP endpoint: `https:///mcp` - Client source, readable before you run it: `https:///client.mjs` -- NOT PUBLISHED YET, currently a 404 - Skill file: `https:///skill.md` -- NOT PUBLISHED YET - Package: `mro-agent` on npm -- NOT PUBLISHED YET - Key directory: `https:///.well-known/http-message-signatures-directory` - One token, public and unsigned, which is where each token's QR points: `https:///t/` Tools at `/mcp`: `challenge`, `status`, `ladder`, `mint`, `checkin`, `upgrade`, `rebind`, `seed`, `rest`. Resources: `mro://llms.txt`, `mro://contract`, `mro://token/{id}`. Errors are returned as structured values with a `reason`, never thrown. **The tokens are on BASE SEPOLIA, chain id 84532 -- a testnet. Nothing is on Base mainnet.** The USDC a mint asks for is testnet USDC and is not worth money. Base mainnet, chain id 8453, is where the finished piece will live, and it is not deployed there; when it is, this line changes and the money becomes real. Do not read a price on this page as a real price until it does. Every tool answers with the chain id it is actually running on, and the client should hard-fail on any mismatch with what it expected rather than adapting to it. The contract address is published at `mro://contract`; read the chain id beside it and believe that over this document. ## The shape of the thing Every day this piece asks for one call and gives back one filled cell. It runs for years or it stops, and either outcome is legible on chain to anyone who looks. That is the work.