Mzizi tools overview
The Mzizi tooling — @nyuchi/mzizi-mcp, @nyuchi/mzizi-cli (the fundi agent
SDK + CLI), and @nyuchi/mzizi-skills — is governed by the Bundu Foundation,
operated by Nyuchi as part of the open Mzizi project, and consumed by every
Nyuchi codebase. It all lives in one monorepo,
nyuchi/mzizi-tools.
This section documents how Nyuchi uses them. Upstream product reference lives in bundu-docs.
| Also in this section | Covers |
|---|---|
| The DNA double helix | The architecture model Mzizi actually serves — nodes, strands, rungs |
| Registry health | Which of the 64 registry tools work, which serve retired data |
| A2A | How long-running runs will be delegated to fundi. Design, not shipped |
The packages
Section titled “The packages”| Package | Version | Ships as |
|---|---|---|
@nyuchi/mzizi-mcp |
0.5.0-beta.6 |
Cloudflare Worker at mcp.mzizi.dev + an npm stdio bin |
@nyuchi/mzizi-cli |
0.4.0-beta.1 (last stable 0.3.0) |
npm — SDK + the fundi bin |
@nyuchi/mzizi-skills |
0.5.0 |
npm — 9 skills, data only |
@nyuchi/fundi-tester |
0.2.0 |
Cloudflare Worker only. private: true — never published to npm |
@nyuchi/bushtrade-mcp |
0.2.0 |
Cloudflare Worker + stdio bin. Not on npm yet; ships manually |
@nyuchi/mzizi-console-app |
0.2.0-beta.1 |
Svelte mini-app for the Console. Not on npm yet; ships manually |
Versions read from the npm registry and the monorepo on 2026-07-31. Per-package
semver: every commit touching a tool is a patch, every merged PR lands a minor,
and an open PR carries an X.Y.0-beta.N pre-release of that next minor — which
is why the two live tools currently report betas.
mzizi-mcp — the registry MCP
Section titled “mzizi-mcp — the registry MCP”Two live MCP surfaces read the same Mzizi document store, and the difference matters:
| Endpoint | What it is | Auth |
|---|---|---|
https://mcp.mzizi.dev/mcp |
The standalone mzizi-mcp Cloudflare Worker. 64 tools, built at startup from the mcp_tool_registry table |
WorkOS Connect OAuth PKCE — free signup |
https://mzizi.dev/mcp |
The portal’s canonical document-route MCP — components, collections, database status | none (anon read) |
The worker is registry-driven: it reads the tool catalogue from the database
at startup and dispatches each tool by its kind — a SQL function, an edge
function, or a table select. Adding a tool is a database edit, not a code change.
Two CORE tools are defined in code rather than the registry
(list_collections, get_database_status), plus fundi_status when the fundi
worker is configured.
Connect a client:
{ "mcpServers": { "mzizi": { "type": "http", "url": "https://mcp.mzizi.dev/mcp" } }}An unauthenticated tools/list against mcp.mzizi.dev/mcp returns
401 invalid_token — that is the gate working, not an outage. It also means
production is not a usable target for scripted inspection; point the official
inspector at the local stdio bin or a wrangler dev instance instead.
The server is listed on the public MCP registry as
io.github.nyuchi/mzizi-mcp.
mzizi-cli — the fundi agent
Section titled “mzizi-cli — the fundi agent”One npm package, @nyuchi/mzizi-cli, containing both the SDK and a CLI whose bin
is named fundi.
pnpm add -D @nyuchi/mzizi-cliThree verbs, plus session commands:
| Command | Needs | Does |
|---|---|---|
fundi explore |
nothing — offline | Reads a small set of disk markers (package.json, tsconfig.json, app/globals.css, tailwind.config.*, components.json) and prints a project snapshot. No model call. |
fundi plan <goal...> |
ANTHROPIC_API_KEY + sign-in |
Plans the minimal Mzizi-aligned edits. Read-only — prints the steps as a dry run and writes nothing. |
fundi chat <message...> |
ANTHROPIC_API_KEY + sign-in |
One-shot chat scoped to Mzizi doctrine. |
fundi login [--token <jwt>] |
— | Saves a WorkOS access token for the gated mzizi-mcp. |
fundi logout / fundi whoami |
— | Clears, or reports, the saved identity. |
Environment the CLI reads (the SDK itself is deliberately env-agnostic — wiring env into options is the caller’s job):
| Variable | Default |
|---|---|
ANTHROPIC_API_KEY |
required for plan and chat |
MZIZI_MCP_URL |
https://mcp.mzizi.dev/mcp |
MZIZI_MODEL |
claude-sonnet-4-6 |
WORKOS_ACCESS_TOKEN |
alternative to fundi login |
As a library:
import { createFundi } from '@nyuchi/mzizi-cli';
const fundi = await createFundi({ projectRoot: process.cwd(), anthropicApiKey: process.env.ANTHROPIC_API_KEY!, mcpUrl: process.env.MZIZI_MCP_URL, // optional model: process.env.MZIZI_MODEL, // optional});
const snapshot = await fundi.explore();const plan = await fundi.plan('add the Mzizi token layer and a button', snapshot);await plan.apply({ dryRun: true });Two safety properties worth knowing before you point it at a repo:
- Planning is read-only. The agent has six tools;
write_fileandrun_shellare blocked during planning and only reachable throughplan.apply({ dryRun: false }). - Everything is sandboxed to
projectRoot. Any path that escapes it is rejected — neither the planner nor the apply phase can read or write outside the project.
Agent skills
Section titled “Agent skills”The design-system and engineering doctrine ships as a public npm package of agent skills. Install it into any repo so Claude Code (or Cursor, Copilot, Cline, Windsurf) has the doctrine on hand instead of guessing:
npx skills add @nyuchi/mzizi-skillsOr take the whole toolchain as a Claude Code plugin — the skills, the fundi
agent, the registry MCP, and the /mzizi:* commands in one step:
/plugin marketplace add nyuchi/mzizi-tools/plugin install mzizi@mzizi-toolsNine skills ship in 0.5.0:
| Skill | Reach for it when |
|---|---|
nyuchi-design |
Generating any branded interface — minerals, radius, type |
bundu-design |
Cross-brand materials and brand-voice decisions |
mukoko-design |
Producing or exporting mukoko visual identity |
simplify |
Before adding a component or style, and during any refactor |
discoverability |
A shared link shows no preview, or you’re adding a route/site |
scaffold-component |
Authoring a new component into the Mzizi registry |
ecosystem-app-setup |
Bootstrapping a new ecosystem app against the registry |
cloudflare-worker-rust |
Building a Worker in Rust with workers-rs |
mcp-server-cloudflare |
Adding or changing an MCP Worker |
The last four were migrated out of the database and out of the nyuchi/mzizi
repo during the 0.5.0 cycle, so git is now the single home for every Mzizi
skill. Their retired references were corrected on the way in.
Git is the source of truth
Section titled “Git is the source of truth”Skills are authored in nyuchi/mzizi-tools as
mzizi-skills/skills/<name>/SKILL.md — YAML frontmatter carrying name and
description, then the body — and listed in mzizi-skills/index.json. That
bundle is the single home for skill content: mzizi-tools projects it into
the Mzizi skills collection (pnpm skills:sync, disk → DB), and the portal
serves what it finds there via /api/v1/skills* and MCP get_skill.
The sync writes through RLS, as authenticated
Section titled “The sync writes through RLS, as authenticated”This is the part people get wrong, so it is worth stating plainly.
skills:sync authenticates as the authenticated role by minting a short-lived
JWT via OAuth 2.0 client_credentials against the WorkOS M2M application —
the same issuer Supabase Third-Party Auth trusts. Row-level policies then decide
what the sync may write.
There is deliberately no service-role path. The earlier implementation used a service-role key and bypassed RLS entirely; that was removed on purpose. No key outranks the policies.
Two headers do two different jobs, and conflating them is the classic failure:
| Header | Carries | Determines |
|---|---|---|
apikey |
the publishable (anon) key | which project |
Authorization |
Bearer <M2M JWT> |
which role RLS evaluates |
Sending the anon key as both can only ever be the anon role, which is read-only
here. A 401 or 403 on write is RLS declining — fix the policy, do not reach
for a service-role key to get around it.
Changing a skill
Section titled “Changing a skill”- Open a PR against
nyuchi/mzizi-toolseditingmzizi-skills/skills/<name>/SKILL.md. - Adding a skill? Also add an
index.jsonentry (name,file,description) — consumers read the index, so an unlisted skill is invisible. - Bump the version in both
mzizi-skills/package.jsonandindex.json; they move in lockstep. - Run
pnpm skills:validatefrom the repo root. It is offline and needs no credentials — which is exactly why it, and not the drift check, gates the publish workflow: a missing secret must never be the reason a broken bundle ships. It catches version drift between the two files, an index entry pointing at a missing file, frontmatternamedisagreeing with the index, an unlisted skill directory, and anexportsmap that would make consumers silently fall back to built-in defaults. - Merge to
main.publish-mzizi-skills.ymlvalidates and publishes to npm. The workflow checks the registry first, so a merge without a version bump publishes nothing — bump the version or nothing ships. - An operator runs
pnpm skills:syncto project the change into the registry surface. That step needs the WorkOS M2M credentials, not a service-role key.
Auth by audience
Section titled “Auth by audience”Every gated surface in the toolchain answers two separate questions, and the answers come from different systems. Getting this split right is the difference between a design that scales and one that quietly leaks a secret into a CLI.
Authentication — how the caller proves identity:
| Surface kind | Mechanism | Examples |
|---|---|---|
| Public / customer | WorkOS Connect OAuth PKCE — public client, no secret. Always a Worker; each public MCP has its own Connect app | mzizi-mcp, bushtrade-mcp |
| Internal staff / machine | WorkOS M2M (client credentials). Only Workers hold the secret | fundi /admin/* |
Entitlement — what the caller may do:
- Public / customer → a UCP commerce subscription. Per-user tags do not scale to public consumption.
- Internal → scopes on the M2M token (
fundi:admin, and the plannedfundi:security/fundi:chaos). These are token scopes, not per-user tags.
The fundi worker is a resource server with no interactive login at all. It
validates two things on /admin/*: an inbound M2M token, and a forwarded
end-user token in X-Fundi-User-Token so it only ever acts for a real signed-in
user. Cron, queue, webhook, and health routes bypass that gate because they are
not user-triggered.
When you add a gated surface, ask one question: staff/machine (→ M2M + a claim scope) or public/customer (→ Connect OAuth PKCE + a UCP subscription)? Never gate a public or paid surface with a per-user tag, and never ship an M2M secret in a CLI.
The component registry
Section titled “The component registry”Mzizi ships UI through a shadcn-compatible registry at mzizi.dev, consumed
under the @mzizi namespace — mzizi.dev/api/v1/ui/{name}. The fundi CLI and
the Mzizi MCP resolver both resolve the same source, so a component pulled by the
CLI, by an agent, or by a raw shadcn add all come from one place.
npx shadcn@latest add https://mzizi.dev/api/v1/ui/buttonComponent naming is a deliberate mix: plain shadcn names for
framework-standard primitives (button, dialog, card, …) alongside custom
components prefixed by brand — nyuchi-, bundu-, or mzizi-. The prefix
signals a brand-specific composite; an unprefixed name is a stock shadcn
primitive re-served through the registry.
Still unwritten
Section titled “Still unwritten”Honest gaps rather than a promise:
- Nyuchi-specific workflows against
mzizi-mcp— scaffolding a new mini-app, validating component back-links, running the registry health check as part of a release. - How to exercise a skill locally before publishing, beyond
pnpm skills:validate’s structural checks. - Whether Nyuchi-specific skills (ones no external consumer would want) belong in
the shared bundle or in a per-repo
.claude/skills/. @nyuchi/mzizi-console-appintegration from the Console side — it is still pre-1.0 and ships manually.
Cross-links
Section titled “Cross-links”nyuchi/mzizi-tools— the monorepo.@nyuchi/mzizi-skills— the published skills bundle; source undermzizi-skills/skills/.- Nyuchi tools directory — every skill, CLI, and MCP server across the Nyuchi and Bundu repos.
- bundu-docs › Mzizi architecture — the upstream architecture reference.
- bundu-docs › Mzizi registry — the self-healing component registry the tools talk to.