@nyuchi/mzizi-mcp
v0.9.1
Published
Mzizi MCP — Model Context Protocol server for the Mzizi component registry. Reads the document-route store, one component per JSON document.
Downloads
1,797
Maintainers
Readme
@nyuchi/mzizi-mcp
Registry-driven Model Context Protocol server for the mzizi design system — the
drop-in replacement for the legacy design.nyuchi.com MCP.
The tool catalog is loaded at startup from the Supabase mcp_tool_registry table
(RLS public-read, anon role) and dispatched dynamically. Adding, renaming, or
retiring a tool is a registry edit, not a code change. The server is read-only on
the anonymous surface — write-kind tools are excluded.
Live at https://mcp.mzizi.dev/mcp (Cloudflare Worker mzizi-mcp, version
0.7.0 — MZIZI_MCP_VERSION in src/server.ts is what serverInfo.version
reports, and it moves in lockstep with package.json and server.json). A
free WorkOS signup gate fronts the endpoint — a WorkOS
Connect OAuth application (public client, PKCE; no client secret) — so sign up
once and read the whole registry at no cost. The worker advertises
/.well-known/oauth-protected-resource so MCP clients can run the OAuth discovery
dance automatically.
MCP Registry name: io.github.nyuchi/mzizi-mcp
Using it — MCP client config
Point any MCP client at the live HTTP endpoint:
{
"mcpServers": {
"mzizi": {
"type": "http",
"url": "https://mcp.mzizi.dev/mcp"
}
}
}The client will be redirected through the WorkOS Connect OAuth (PKCE) flow on first connect. After that, reads are free and unlimited.
stdio (local / offline)
Run the stdio bin via npx — useful for Claude Code, Cursor, or any assistant that
speaks stdio MCP. It is zero-config — the public mzizi registry URL + its
publishable (anon, RLS read-only) key are baked in, so no env is needed:
{
"mcpServers": {
"mzizi": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@nyuchi/mzizi-mcp"]
}
}
}This is the sanctioned headless path: the hosted mcp.mzizi.dev endpoint
sits behind an interactive, browser-only WorkOS signup gate that a headless agent
(Claude Code, CI, an offline client) can't complete, whereas the stdio bin reads
the same public registry directly with no login.
To point the bin at a fork or a self-hosted mirror, override the defaults with
SUPABASE_URL and SUPABASE_PUBLISHABLE_KEY (their NEXT_PUBLIC_ equivalents
are also accepted). Neither value is a secret — the publishable key only grants
the anon role, which RLS restricts to read-only reads of the public registry.
Registry-driven dispatch
| Registry kind | Dispatch |
| --------------- | ----------------------------------------- |
| sql_function | supabase.rpc(fn, args) |
| edge_function | supabase.functions.invoke(fn, { body }) |
| source_table | supabase.from(table).select() |
The registry currently holds 62 rows (60 enabled). After filtering out write-kind and first-party tools, ~55 tools are exposed on the anonymous public surface, spread across 17 categories.
Core tools (always present, defined in code)
| Tool | Backed by | Returns |
| --------------------- | -------------------------------------- | -------------------------------------------------------------- |
| list_collections | component_documents aggregate | Every collection + document counts + per-owner breakdown |
| get_database_status | component_documents count | Provider health + document-store row count + tool count |
| fundi_status | fundi /admin/whoami (M2M delegation) | fundi identity + granted scopes (only when FUNDI_URL is set) |
fundi_status is only registered on the server when FUNDI_URL is configured. It proxies to
the fundi worker using a WorkOS M2M token minted from WORKOS_M2M_CLIENT_ID /
WORKOS_M2M_CLIENT_SECRET, plus the authenticated user's token in X-Fundi-User-Token.
This makes mzizi-mcp the sanctioned fundi caller — the CLI reaches fundi through
mzizi-mcp, never by holding the M2M secret itself.
Tool categories (registry-driven)
| Category | Example tools |
| --------------- | --------------------------------------------------------------------------------- |
| component | get_component, list_components, search_components, get_component_links |
| architecture | get_node_documents |
| brand | get_brand_tokens, list_ecosystem_brands |
| skills | get_skill, list_skills |
| doctrine | doctrine-read tools |
| documents | read_documents, read_versions |
| release | list_changelog, get_changelog_entry, compute_release_diff |
| resolver | resolve_primitive, list_framework_descriptors |
| a11y | calculate_contrast_ratio, simulate_color_blindness, run_accessibility_audit |
| observability | list_observability_events, is_domain_allowed |
| fundi | get_healing_log, list_recent_fundi_issues |
| chaos | list_chaos_events |
| system | system-read tools |
| ai | get_ai_instructions, list_ai_instructions |
| governance | get_bundu_convention |
| meta | mcp_describe |
Call mcp_describe (with optional p_category filter) to enumerate the full live
catalog.
Resources
| URI | Content |
| --------------------- | ---------------------------------------------------- |
| mzizi://collections | Every collection + document counts + owner breakdown |
| mzizi://components | Lean index of the components collection |
Environment / secrets
HTTP Worker (Cloudflare)
Secrets (wrangler secret put):
| Secret | Required | Notes |
| -------------------------- | -------- | -------------------------------------------------------------- |
| SUPABASE_URL | yes | Public Supabase project URL |
| SUPABASE_PUBLISHABLE_KEY | yes | Anon (RLS public-read) key |
| SUPABASE_SECRET_KEY | no | Service-role key; placeholder is used if unset |
| COOKIE_ENCRYPTION_KEY | yes | HMAC key for the consent cookie (random bytes) |
| WORKOS_AUTHKIT_DOMAIN | no | AuthKit domain for /oauth2/* (https://accounts.mukoko.com) |
WORKOS_AUTHKIT_DOMAIN is a secret and not a [vars] entry, even though a hostname is not
confidential: a var wins on every deploy and silently discards a same-named remote value, so a
value that differs per environment cannot live in committed config. It is "not required" only
because src/identity.ts carries a working default — and it must move in lockstep with
fundi-tester, which binds the same issuer that this Worker's agent-card consumers are pointed
at. See AUTH.md.
Plain vars ([vars] in wrangler.toml, not secrets):
| Var | Notes |
| ---------------------- | -------------------------------------------------------------- |
| WORKOS_CLIENT_ID | Connect OAuth app client id (public client; PKCE) |
| WORKOS_M2M_CLIENT_ID | Fundi M2M app client id; required only when FUNDI_URL is set |
| FUNDI_URL | Base URL of the fundi worker; enables the fundi_status tool |
The Connect OAuth app is a public client (PKCE) — there is no
WORKOS_CLIENT_SECRETor WorkOS API key on the worker.
Optional: fundi-caller extras (only needed when mzizi-mcp is the fundi caller):
| Name | Kind | Purpose |
| -------------------------- | ------ | --------------------------------------------------- |
| WORKOS_M2M_CLIENT_SECRET | secret | Fundi M2M app secret (Worker secret; never in code) |
stdio / local dev (.dev.vars or environment)
| Variable | Required | Notes |
| -------------------------- | -------- | ----------------------------------- |
| SUPABASE_URL | no | Defaults to canonical mzizi project |
| SUPABASE_PUBLISHABLE_KEY | yes | Anon key |
Entrypoints
| Surface | Entry | Use |
| ------------- | ------------------- | ----------------------------------------------- |
| stdio | bin: mzizi-mcp | Local AI assistants (Claude Code, Cursor, etc.) |
| HTTP / Worker | mzizi-mcp/http | Cloudflare Workers + any fetch runtime |
| Library | @nyuchi/mzizi-mcp | Embed the server factory in your own host |
Source files:
src/server.ts—createMziziMcpServer(supabase)factorysrc/http.ts—createMziziHttpHandler()for any fetch runtimesrc/worker.ts— Cloudflare Worker bound toenv(the gated deployment)src/stdio.ts—bin: mzizi-mcpfor the MCP registry / local Claude Code
Build and deploy
# typecheck
pnpm --filter @nyuchi/mzizi-mcp typecheck
# build (tsc → dist/)
pnpm --filter @nyuchi/mzizi-mcp build
# local Worker dev
pnpm --filter @nyuchi/mzizi-mcp cf:dev
# deploy manually (CI handles pushes to main)
pnpm --filter @nyuchi/mzizi-mcp cf:deployCI deploys automatically on push to main touching mzizi-mcp/** via
.github/workflows/deploy-mzizi-mcp.yml.
License
Apache-2.0. Part of the mzizi tooling — an open-architecture project of the Bundu Foundation, operated by nyuchi.
