api.mzizi.dev is the registry API. It is served by
mzizi-dev/mzizi-api-gateway, a
Hono Cloudflare Worker written in TypeScript. It has no origin, no
database and no Supabase. Everything it serves is a file from the registry repository,
bundled into the Worker when it is built.
It has served api.mzizi.dev since 29 September 2026, when it took over from the
registry’s own Worker.
An earlier plan for this repository was a pure-Rust
workers-rs proxy in front of the
registry’s own API handlers. That proxy is retired, and so are the handlers: the registry
removed its Next.js app, /api/* handlers included, on 2 October 2026. The gateway is Hono,
and it implements the whole public /v1 API itself, from files.Using it
GET handler answers OPTIONS
with 204, and every other method with 405. Both /v1/... (canonical) and /api/v1/...
answer. api.mzizi.dev/v1/* redirects here.
Every response carries a header naming the Worker and the registry commit it was built from.
The pin moves (see how the pin moves), so read it from the header
rather than from this page:
registry=9b86e034ffd8. That is an example, not
the current value; the header is.
From registry commit 9b86e03 on, /v1/rs/{name} serves the twelve Mzizi Roots brand
components, and its crate field names each component’s own crate, with a git field for
the source repository. See the Rust route.
How the data flows
- The registry’s files are the data layer. Components, doctrine, brand, changelog,
skills and samples are files in
mzizi-dev/mzizi-registry. The gateway reads them at build time, not at request time. - The shapes are the registry’s own. The build calls the registry’s readers rather than reimplementing them. The Supabase client is replaced with a stub that throws, so a reader that reached for a database would fail the build instead of shipping an empty answer.
- A registry change reaches the API only through a commit. Moving to newer registry content means changing the pin, which CI checks. A bot is built to open that commit: see how the pin moves.
How the pin moves
The pin isref in the gateway’s scripts/registry-ref.json. The owner decided on 30
September 2026 to keep the pin and move it automatically, and the gateway has a bot built to
keep it on registry main. The gateway’s README describes it under
Registry pin bump.
- Every hour the bot compares the pin with registry
main. When they differ, it opens or updates one pull request, from the branchbot/registry-pin, that moves the pin. The pull request lists the registry commits the bump brings in. - Every check runs on it, including parity in strict mode against production
https://api.mzizi.dev: any difference at all between the bump and what is live fails it. - It merges itself (rebase) only when every check is green, including parity and the
checks
main’s rules require. The merge deploys as usual. - Anything else waits for a person. A failed check gets a comment listing what failed, and the bot leaves the pull request for review. An unexplained parity difference usually means the registry changed a file the gateway reads, and the gateway’s route has to follow it.
RELEASE_BUMP_TOKEN Actions secret (a fine-grained token
with Contents, Pull requests and Workflows read and write), and it is live: on 2 October 2026 it opened
mzizi-api-gateway#29 and, for the MCP server’s pin, agent-tools#169. It merges its own pull request only if the token
also has Checks: Read-only and Commit statuses: Read-only, because it reads the bump’s
check runs and commit status before merging; without them that read fails with a 403 and
the pull request waits for a person. A bump by hand keeps working too, and the bot steps aside
for it: while another open pull request moves the pin to registry main it opens none, and
when a bump lands any other way it closes its own. The MCP server’s pin has the same bot.
What it answers besides data
308for renamed components. Formernyuchi-*names redirect to theirmzizi-*names on/v1/uiand/v1/rs, keeping the sub-path and query. For example,/v1/ui/nyuchi-sidebaranswers308to/v1/ui/mzizi-sidebar.410 Gonefor retired routes:/v1/docs, and the retired axis and layer models under/v1/architecture/.308 /mcptohttps://mcp.mzizi.dev/mcp./.well-known/security.txt, with the contactsecurity@nyuchi.com.
Search
/v1/search searches the registry’s files. It takes up to three parameters, which combine,
and at least one is required:
layer is a deprecated alias of node, kept so older clients keep their results. A
request that uses it gets the same results, plus a Deprecation: true header and a
meta.deprecation note. node wins when both are given. Use node; layer will be removed.
The Rust route
/v1/rs/{name} answers with a component’s Rust (Dioxus) source where one exists, and 404
where there is none. The document names the crate the component ships in, and the crate
differs by node: mzizi-ui for the primitives, mzizi-brand for the brand components,
mzizi-shell for the app chrome, and so on. For example, on 30 September 2026:
crate field rather than assuming one crate for every component. The route is a
read surface: to use a component, depend on its crate. See Mzizi Roots.
One route answers 503
/v1/ui/{name}/versions answers 503. Component version history is written by releases into
the console’s database, and it is not one of the registry’s files, so this API does not serve
it. The response says so and points to /v1/changelog for release history.
Earlier builds also answered 503 on /v1/search, /v1/ui/{name}/docs and
/v1/ai/instructions/{name}. Their data is in files, and from registry commit ce68c64 they
are served from files. The discovery document no longer carries a database block; its
data block reads "source": "files".
The discovery document and OpenAPI text
/v1 and /openapi are served from the registry, and from ce68c64 on
both say that files are the data layer and that Mzizi owns and operates the API. Neither names
Supabase as a data source or Nyuchi as operator. Two mentions of Supabase remain in /openapi, and both are accurate: the
/data-layer route describes the wider ecosystem’s data layer, and the retired /docs route
notes that its old table is historical.
Parity
The acceptance test for the cutover wasscripts/parity.mjs.
It sends read-only requests to a baseline and a candidate: every route, every component slug
on /v1/ui/{name} and /v1/rs/{name}, the renamed names, the filters, the error paths and
the method handling. It diffs status, Location, content type, the CORS, cache and security
headers, and the body. Intentional differences are listed in the script with their reasons.
Before the domain moved, parity against the deployed Worker ran 1,359 requests with 0
unexplained differences. Only two differences are intentional: the bare /v1 now serves the
discovery document instead of an HTML 404, and an unknown path gets a small JSON 404.
Rollback, in brief
There is no older Worker to fall back to. The registry’s own Worker served the app the registry removed on 2 October 2026, and it is being deleted, soapi.mzizi.dev stays on the
gateway. To undo a bad change, revert it in a pull request; the merge redeploys. To undo a bad
deploy faster than that, roll the mzizi-api-gateway Worker back to its previous deployment
(wrangler rollback, or Deployments in the Cloudflare dashboard), then revert on main so
the next deploy does not bring the change back.
Developing
CONTRIBUTING.md for changing a route or moving the
pin.