What HyperMap is, and what this page walks through
Two independently useful things meet on this page: a draft hypermedia format from All Purpose Machines, and a large fintech tool catalog that can be expressed in it.
HyperMap is an open-source project from allpurposemachines/hypermap. Its README defines it as "a JSON format for REST APIs built around a single reserved key, #, that carries hypermedia controls and executable scripts". The project also ships Mech, the reference client that speaks the format, available for the browser or as a POSIX daemon.
The idea behind the format is that a resource describes itself: instead of reading separate API documentation to learn which URLs exist, a client reads the payload, finds the controls, and follows them. Every relative link resolves against the URL the resource was fetched from, so a whole API becomes a tree a client can walk without out-of-band knowledge.
The AINumbers catalog lists 1,185 tools across 172 categories, plus 663 ChainGraph nodes joined into 368 named workflows (live counts from the suite's generated catalog, September 2026). That catalog can be projected into a static tree of HyperMap resources: the root points at category indexes, category resources point at individual tool pages on this site, and the workflow graph rides along as chain and node resources. The walkthrough below uses fragments from a generated sample of exactly that projection, and its final hop lands on a tool page you can open right now.
The reserved key and its three attributes
Everything normative below is quoted from the HyperMap specification (spec/index.bs in the upstream repository), with the section it comes from named alongside.
Media type. A HyperMap resource is JSON served under its own media type (spec, "Media Type"):
A HyperMap resource is served with the media type `application/vnd.hypermap+json`. Servers MUST use this media type for all HyperMap responses. Clients SHOULD use this media type in `Accept` headers when requesting HyperMap resources.
The top level is an object. The spec's "Top-Level Structure" section sets one hard structural rule:
The top level of a HyperMap resource MUST be a JSON object (not an array, string, number, boolean, or null).
The reserved key. The spec's "The # Key" section reserves a single member of each object for hypermedia; the three optional attributes are condensed below:
The key `#` is reserved in HyperMap's JSON serialization. When present on a
JSON object, its value MUST be a JSON object containing zero or more attributes.
An attributes object MAY contain the following members:
href a URL, absolute or relative to the resource's base URL; when
present, the containing object becomes a control
method an HTTP method; defaults to "GET" if omitted; MUST be uppercase
scripts an array of script URLs for the client to load, scoped to the
object that declares them
Controls. Any object whose # carries an href is a control, the format's unit of navigation (spec, "Controls"):
A control is a JSON object whose attributes include an `href` value. Controls represent navigable references to other resources or actions that can be triggered. A control's `method` defaults to `"GET"` if not specified. The child nodes of the control (excluding the `#` key) serve as form fields. For `GET` requests, form data is serialized as URL query parameters.
Base URL resolution. Relative references need no configuration; the spec's "URL Resolution" section anchors them to where the resource came from:
The base URL of a HyperMap resource is the URL from which the resource was fetched, after any redirects. All relative URLs in a resource — including `href` values in attributes and script URLs — are resolved against this base URL using the URL resolution algorithm defined in [URL].
A tiny example from the spec's own "Controls" section shows both shapes at once: a per-item link and a collection-level action. The sibling keys of a control act as its form fields:
{
"todos": [
{
"#": { "href": "5J0rwwsyh/" },
"title": "Learn HyperMap",
"completed": false
}
],
"newTodo": {
"#": { "href": "/todos/", "method": "POST" },
"title": ""
}
}
Each todo carries a GET control pointing at its own resource; the newTodo control is a POST whose title child is submitted as a JSON body. In read-only trees, every control is simply a GET link.
How the AINumbers catalog becomes a resource tree
The projection is a static set of JSON files, one resource per file, each conforming to the rules above: object at the top level, one # control, no scripts.
The root resource announces the suite and hands out three navigable controls, one per sub-tree, plus one control per category:
{
"#": { "href": "./index.json" },
"title": "AINumbers Fintech Intelligence Suite — HyperMap projection",
"catalog": { "#": { "href": "./catalog/index.json" }, "tool_count": 1167, "category_count": 167 },
"chains": { "#": { "href": "./chains/index.json" }, "chain_count": 369 },
"nodes": { "#": { "href": "./nodes/index.json" }, "node_count": 643 },
"categories": {
"aml-kyc": { "#": { "href": "./catalog/aml-kyc.json" }, "tool_count": 23 },
"agent-economy-runtime-aer": { "#": { "href": "./catalog/agent-economy-runtime-aer.json" }, "tool_count": 4 }
}
}
Abridged: two of the sample's 167 category entries are shown, with their real values. All hrefs are relative, so they resolve against wherever the tree is served from (spec, "URL Resolution"). The counts are the sample generation's; the live catalog has since grown to 1,185 tools.
Each part of the catalog lands in a specific place in the tree:
| Catalog concept | HyperMap surface |
|---|---|
| Category | A resource under catalog/<slug>.json; every category is also reachable as a control on the root. |
| Tool | An entry in its category's tools array whose # control holds the tool's absolute page URL on ainumbers.co. |
| Named workflow | A resource under chains/<name>.json, listed by a control in the chain index; its ordered steps and handoffs ride along as data. |
| ChainGraph node and its edges | A resource under nodes/<tool_id>.json carrying the node's consumes and feeds arrays, so the graph's edges are readable without leaving the tree. |
| Every page on this site | An absolute href, copied from the catalog's own URL metadata, so the last hop of any walk resolves to a real, live page. |
Why controls all the way down. A bare URL string would be valid JSON data, but it would not be a control, so a client could not activate it. The projection makes every navigable reference a control, and every control a plain GET: the tree is read-only, so no method member is needed anywhere (the spec default applies), and no scripts member appears in any resource. That is a deliberate shape for a catalog: links and data only, with execution left to the pages the links point at.
Three hops from the root to a live tool page
Each hop activates one control. The JSON is copied from the sample projection; hop 3's destination is a page on this site, linked relatively at the end of the step.
- 1
Follow the catalog control to the category index
Activating the root's catalog control is a GET of ./catalog/index.json, resolved against the root's base URL. The response is itself a HyperMap resource:
{ "#": { "href": "./catalog/index.json" }, "title": "Catalog categories", "category_count": 167, "categories": { "ai-agentic": { "#": { "href": "./catalog/ai-agentic.json" }, "tool_count": 13 } } }Abridged: one of the 167 category controls is shown.
Points at: one control per category, each carrying the category's tool count as plain data a client can rank or filter on before choosing a hop. - 2
Follow a category control into its tools
Activating categories.ai-agentic retrieves the category resource. Its tools array lists the category's 13 tools; each entry is a control whose href is the tool's absolute page URL:
{ "#": { "href": "./catalog/ai-agentic.json" }, "name": "ai-agentic", "slug": "ai-agentic", "tool_count": 13, "tools": [ { "#": { "href": "https://ainumbers.co/tools/rbe-02-a2a-exception-triage.html" }, "name": "a2a_exception_triage", "tool_id": "rbe-02-a2a-exception-triage", "version": "1.1.0", "tags": [], "href_status": "ok" } ] }Abridged: the first of the 13 tool entries is shown, verbatim.
Points at: the transition from the sample's relative links to an absolute one. Machine-readable facts (name, id, version) sit beside the link, so an agent can decide whether to hop without following it first. - 3
Follow the tool control to the live page
The first tool's control points at https://ainumbers.co/tools/rbe-02-a2a-exception-triage.html. That page is live on this site: A2A Exception Triage Console. The projection carried the URL verbatim from the catalog's own metadata, so a HyperMap client's third GET lands on a real page with the tool's full interface, and so does yours.
Points at: the working boundary of the tree. The projection is static JSON; the destination is the site's normal tool page, reached by an ordinary GET either way. - 4
Detour: read the workflow graph from the same tree
The chains and nodes controls expose the suite's multi-tool flows. A chain index entry is a control per named flow, and a node resource carries its edges as data:
{ "#": { "href": "./chains/index.json" }, "title": "Chaingraph chains", "chain_count": 369, "chains": [ { "#": { "href": "./chains/a2a-payment-rail-compliance.json" }, "name": "a2a-payment-rail-compliance", "title": "A2A Payment Rail Compliance", "domain": "Cross-Border & Instant Payments" } ] }{ "#": { "href": "https://ainumbers.co/tools/503-canton-tokenization-readiness-diagnostic.html" }, "tool_id": "503-canton-tokenization-readiness-diagnostic", "display_name": "Canton Tokenization Readiness Diagnostic", "status": "live", "consumes": [], "feeds": [ "504-settlement-risk-capital-optimizer" ] }Points at: both entries abridged with real values. The node's feeds edge names the next node in the graph, and each chain resource lists its ordered steps with the handoff between them, so a client can reason about a whole flow before opening any page.
How a client consumes the tree
Because the format is JSON over plain HTTP, three very different clients read the same resources without adaptation.
- 1
Any HTTP and JSON tooling
A resource is a static JSON object. Request it with the media type in the Accept header, parse it, and read the # member to find what to do next. Where the tree is hosted is a deployment choice; the command below shows the request shape against a placeholder host:
curl -s https://host/hypermap/index.json -H 'Accept: application/vnd.hypermap+json'Standard JSON tools such as jq work unchanged, because the hypermedia lives in an ordinary key.
- 2
Mech as the reference client
Mech parses a resource into a node tree and activates controls on request: open the root, then activate a control by its path in the tree. The three hops above correspond to activating catalog, then categories.ai-agentic, then the tool entry. The upstream repository's documentation is the authority on the CLI surface:
mech open https://host/hypermap/index.jsonFrom there, mech use follows a control and renders the response as a new tree. The repo also ships a browser shim and an example server, so the client side can be exercised entirely against public code.
- 3
An agent or script following hrefs
The traversal rules a program needs are short: GET the root; collect every object with a # containing an href; resolve relative values against the URL of the resource they came from; GET defaults when method is absent; stop at absolute URLs, which lead out of the tree and onto the site's own pages. The catalog projection adds plain data fields (counts, ids, tags, graph edges) next to the controls, which is what lets an agent choose a hop instead of crawling blind.
Where this fits in the suite: the same catalog is reachable as mcp/catalog.json and through the MCP server at mcp.html; the HyperMap tree is a third, link-first projection of the same tools. For the receipt side of agent integrations, see the Division Swarm receipt-chain demo.