@nuwax-ai/openui-mcp
v0.3.13
Published
Durable file-based OpenUI artifacts over MCP for Nuwax.
Downloads
3,119
Readme
Nuwax OpenUI MCP
@nuwax-ai/openui-mcp provides OpenUI authoring guidance, schema resources,
validation, and durable artifact generation for Nuwax Agent sessions.
Architecture
The MCP server does not host pages. It writes OpenUI data into the active project and returns a lightweight reference:
nuwax_render_openui
-> validate OpenUI Lang
-> data/{artifactId}.openui.json
-> nuwax.openui-ref/v1Nuwax PC Web loads the data file and renders it with the frozen static runtime
at /openui-runtime/index.html. Inline, sidecar, and file preview all use that
same runtime.
Installation
Configure the server as a session-scoped stdio MCP so it inherits the current project directory:
{
"mcpServers": {
"nuwax-openui": {
"command": "npx",
"args": ["-y", "@nuwax-ai/[email protected]"]
}
}
}Do not configure it as a persistent/global MCP. If the host cannot provide the
project as the process working directory or an MCP Root, set
NUWAX_OPENUI_PROJECT_ROOT explicitly.
Environment
| Variable | Default | Effect |
| ---------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| NUWAX_OPENUI_PROJECT_ROOT | unset | Absolute project root when the host cannot expose MCP Roots / cwd. |
| NUWAX_OPENUI_TOOL_VERSION_SUFFIX | off | When 1 / true / yes / on, MCP tool names get a version fingerprint suffix (e.g. nuwax_render_openui_v0_3_12). When off (default), tools keep stable base names (nuwax_render_openui, …). Package version is still available via serverInfo.version, CLI --version, and artifact mcpVersion. |
Re-enable version-suffixed tool names (opt-in):
{
"mcpServers": {
"nuwax-openui": {
"command": "npx",
"args": ["-y", "@nuwax-ai/[email protected]"],
"env": {
"NUWAX_OPENUI_TOOL_VERSION_SUFFIX": "1"
}
}
}
}Check installed version
Print the npm package version without starting the MCP stdio server:
npx -y @nuwax-ai/openui-mcp@latest --version
# or, after a global / local install:
openui-mcp --version
nuwax-openui-mcp -VThe file repository is initialized lazily on the first render call. This avoids
creating a data/ directory when a client starts the server only to discover
its tool list.
Tools and resources
nuwax_render_openui: creates or updates an Artifact file (data/{artifactId}.openui.json). This is the only tool that publishes Host UI; it validates OpenUI Lang before writing. Do not claim the UI is open until this tool returns successfully.nuwax_get_openui_reference: returns the authoring guide or schema.nuwax_get_openui_update_guide: how to update an existing*.openui.json(reuseartifactIdwith render, or edit the file while keepingdocument.digestvalid).nuwax://openui/schema/v0.5: renderer-generated component schema.nuwax://openui/authoring-guide/v0.5: syntax and examples.nuwax_openui_authoring: reusable authoring prompt.
Call nuwax_get_openui_reference before producing complex forms, charts, or
dashboards. Always call nuwax_render_openui so the Host can show the UI (there
is no separate validate tool). Call nuwax_get_openui_update_guide before
modifying an existing OpenUI artifact.
Routing: what OpenUI is for (and what it is not)
During the MCP initialize handshake this server sends instructions that tell
the host how to route UI-producing requests. Routing is defined by capability
quadrant, not by keyword or skill name:
- Prefer OpenUI — a single, self-contained visual interface that presents or
collects structured information using standard components (KPI cards, charts,
tables, forms, text, images): data dashboards, monitoring panels, reports,
data-collection forms, status pages. Regardless of wording or language, these
MUST go to
nuwax_render_openui, because the resulting*.openui.jsonis the only UI payload the Nuwax Host can render inline or in a sidecar. - Do NOT use OpenUI — multi-page apps / websites / client-side routing; games or highly interactive bespoke experiences; free-form documents or long-form rich text; anything needing arbitrary JavaScript, external scripts, or raw HTML. OpenUI Lang is a restricted DSL (the model only composes standard components and never runs arbitrary code) and one artifact is one interface, so these are better served by writing ordinary code/files.
- Gray zone — ask: (1) is the deliverable ONE self-contained interface
rather than a navigable app? (2) can it be expressed with structured data +
standard components, without arbitrary JS or pixel-level custom layout? If
both are yes, use OpenUI; otherwise write ordinary code. When in doubt, prefer
the output the Host can actually render in-conversation—never silently fall
back to a bare
*.htmlfile.
Bare *.html files, SVG/PNG chart files, and any frontend / dataviz / charting
code-generation skill (frontend-design, dataviz, and similar) bypass the OpenUI
protocol and must not be used as a substitute for a "prefer" intent. The
exclusion is phrased as a class of output paths, not a closed list of skill
names, so newly added skills are covered too.
Reserved for future upstream alignment
Two extension points are pre-wired for upcoming parity with the official openui-lang spec; both are inert today:
presentation.density("compact" | "normal", optional): reserved for theme density. A compact density token set already ships in the runtime; the field is stored on the artifact so density-aware rendering can honor it later.customComponents(optional, must be empty): placeholder for official-style custom component registration (defineComponent+ Zod +createLibrary). No runtime registration mechanism exists yet, so only an absent/empty value is accepted.bindings.tools(optional, must stay empty): placeholder for live MCP-tool data bindings. The current runtime does NOT execute Query/Mutation tool bindings, so the authoring reference deliberately does not documentQuery(...)/Mutation(...)and agents should leavetoolsempty.
Creating an Artifact
{
"schemaVersion": "nuwax.openui/v1",
"title": "Deployment status",
"presentation": {
"mode": "inline",
"autoOpen": false
},
"document": {
"language": "openui-lang",
"specVersion": "0.5",
"source": "root = Stack([title])\ntitle = TextContent(\"Ready\", \"large-heavy\")"
},
"bindings": { "tools": [] },
"fallback": { "markdown": "Deployment is ready." }
}The response is a nuwax.openui-ref/v1 pointing to:
data/{artifactId}.openui.jsonPass the same artifactId on a later call to atomically replace the Artifact.
The original createdAt is retained while updatedAt and the document digest
are refreshed.
File contract
{
"type": "nuwax.openui-file",
"schemaVersion": "nuwax.openui-file/v1",
"artifactId": "550e8400-e29b-41d4-a716-446655440000",
"title": "Deployment status",
"presentation": { "mode": "inline", "autoOpen": false },
"document": {
"language": "openui-lang",
"specVersion": "0.5",
"source": "root = Stack([])",
"digest": "sha256:..."
},
"bindings": { "tools": [] },
"fallback": { "markdown": "" },
"createdAt": "2026-07-22T00:00:00.000Z",
"updatedAt": "2026-07-22T00:00:00.000Z"
}Artifacts have no TTL. Their lifetime follows the project files and they can be reviewed and versioned with Git.
Development
pnpm install
pnpm verifyThis is a pnpm workspace. The MCP server builds to dist/server/. The frozen
renderer runtime lives in the separate @nuwax-ai/openui-runtime workspace
package (packages/runtime), which builds runtime.js and runtime.css into
its own dist/. In the Nuwax repository, scripts/sync-openui-runtime.sh
resolves @nuwax-ai/openui-runtime and copies those assets into
public/static/openui-runtime/.
The server does not import the renderer at runtime: the component JSON Schema
and authoring reference are precomputed by pnpm gen:openui into
packages/server/src/generated/ and read as static files, keeping the stdio
process lean.
Publishing
Publish both workspace packages at the same version:
pnpm publish --filter @nuwax-ai/openui-mcp
pnpm publish --filter @nuwax-ai/openui-runtime