@nano-ui-kit/a2ui-mcp
v0.0.1
Published
MCP server wrapping @nano-ui-kit/a2ui-compose. Exposes generation tools over MCP with an engine selector for monolithic + zettel strategies.
Downloads
165
Maintainers
Readme
@nano-ui-kit/a2ui-mcp
MCP server wrapping @nano-ui-kit/a2ui-compose. Exposes the generation
engine, component catalog, pattern library, validator, and training
feedback loop as stdio tools for Claude Desktop, Claude Code, and any
other MCP-speaking host.
Runtime only. Generation logic lives in
@nano-ui-kit/a2ui-compose; UI atoms in@nano-ui-kit/web-components; corpus in@nano-ui-kit/a2ui-corpus.
Quick start
node packages/a2ui/mcp/server.js
# or, if linked:
nanoui-mcpRegister with Claude Code (.claude/settings.json):
{
"mcpServers": {
"nano-ui": {
"command": "node",
"args": ["packages/a2ui/mcp/server.js"]
}
}
}API keys (at least one required for generate_ui):
export ANTHROPIC_API_KEY=sk-ant-…
export OPENAI_API_KEY=sk-…
export GEMINI_API_KEY=AIza…Tools
The server registers 21 tools. Shape is stable; argument schemas via Zod.
| Tool | What it does |
|------------------------|-----------------------------------------------------------|
| generate_ui | Intent → A2UI tree. Engine (monolithic/zettel) + mode. |
| validate_schema | Run the 15-check validator on an A2UI tree; returns 0-100. |
| classify_intent | Extract concepts, entities, implied components, steelman. |
| lookup_component | Resolve a component name (alias-aware) to its schema. |
| get_component_map | Full tag→class map including alias normalizations. |
| search_patterns | Keyword-rank the monolithic pattern corpus. |
| assemble_context | Build the system prompt context for a given intent. |
| check_anti_patterns | Scan a tree for canonical anti-patterns (chart-legend, …). |
| get_traits | List trait catalog + their host-binding rules. |
| convert_html | Raw HTML → best-effort A2UI tree (import path). |
| get_wiring_catalog | Declarative wiring-engine recipes. |
| import_pattern | Commit a generated result into the pattern library. |
| submit_feedback | Append a user-feedback event to the feedback store. |
| get_quality_metrics | Aggregate pass/fail scores over a window. |
| get_training_gaps | Intents that currently miss coverage. |
| run_eval | Run the held-out benchmark; return pass/fail per intent. |
| get_fragment | Fetch a single zettel fragment by id. |
| get_composition | Fetch a named multi-fragment composition. |
| resolve_composition | Expand a composition reference into its fragments. |
| get_graph | Dump the zettel fragment-dependency graph. |
| zettel_stats | Corpus counts (fragments, compositions, reuse ratio, …). |
Layout
a2ui-mcp/
├── server.js MCP bootstrap — registers all 21 tools inline
├── scripts/ Standalone runners (smoke tests, eval diffs, visual validate)
│ ├── generate.mjs CLI: `node scripts/generate.mjs "pricing page"`
│ ├── eval-diff.mjs diff held-out run vs baseline
│ ├── eval-fix.mjs re-run failing eval intents
│ ├── dogfood-test.mjs 20-intent dogfood + avg-score gate
│ ├── multi-turn-test.mjs session iteration smoke
│ ├── smoke-engine-registry.mjs registry + reserved-name checks
│ ├── smoke-register-engine.mjs plugin engine registration
│ ├── smoke-zettel.mjs zettel-specific smoke (corpus + composer)
│ ├── smoke-synthesis.mjs fragment-synthesis path
│ ├── smoke-merged.mjs cross-engine merge check
│ ├── smoke-searchable-select.mjs known-good composition regression
│ ├── test-a2ui.mjs A2UI message validator unit tests
│ ├── test-evals.mjs evals harness wrapper
│ └── visual-validate.mjs Playwright render + Vision-LLM critique
├── tools/ (reserved; tool code currently inlined in server.js)
└── personas/ persona presets (vocabulary + style hints for adapters)CLI usage
# One-shot generation from a prompt
node packages/a2ui/mcp/scripts/generate.mjs "pricing page with 3 tiers"
# Run the held-out eval
node packages/a2ui/mcp/scripts/test-evals.mjs
# Full verification sweep (invoked by /verification-sweep slash command)
npm run smoke:engines && \
npm run smoke:register-engine && \
npm run test:a2ui && \
npm run eval:diff -- --engine zettelHow it fits together
┌─────────────┐ MCP stdio
│ Claude Code │◀─────────────────▶ server.js
└─────────────┘ │
├── @nano-ui-kit/a2ui-compose (engines, validator, LLM bridge)
├── @nano-ui-kit/a2ui-corpus (catalog, fragments, feedback)
└── @nano-ui-kit/web-components (component schemas via .a2ui.json)On start, the server:
- Loads the component catalog (
a2ui-corpus/catalog-a2ui_0_9.json) - Lazy-initializes the zettel corpus on first
generate_ui/zettel_*call - Resolves LLM adapter from env vars
- Registers tools + opens stdio transport
Gotchas
- Corpus load is noisy. The zettel composer prints stats to stderr on first invocation. Callers expecting silent MCP should swallow stderr.
- API keys must be set before the server starts. Changing env vars mid-session doesn't hot-reload adapters.
- Engine selector is internal. Don't pass
engine: 'mcp'— the generator picksmonolithicvszettelfrom intent + mode. Reserved names in the registry guard against accidental shadowing. - Validator score < 70 is still returned. Consumers should gate on
the
passedboolean or rawscore— the tool doesn't auto-retry.
Evals + regression floors
The server enforces the same thresholds as the rest of the pipeline:
test:a2ui— 19/19 green (+1 skipped OK)smoke:register-engine— 11/11 greeneval:diff -- --engine zettel— coverage 100%, avgScore ≥ 88- Dogfood — 20/20 intents at avg ≥ 95
See repo-root AGENTS.md for the full verification sweep.
License
MIT
