@golemui/gui-mcp 0.16.0 → 0.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ## 0.16.1 (2026-05-30)
2
+
3
+ ### 🚀 Features
4
+
5
+ - **mcp:** expose tool functions as an importable library alongside the CLI ([#146](https://github.com/golemui/golemui/pull/146))
6
+
7
+ ### ❤️ Thank You
8
+
9
+ - Mud Scientist
10
+
11
+ ## 0.16.0 (2026-05-30)
12
+
13
+ ### 🚀 Features
14
+
15
+ - **core:** improved string interpolation with full expression support ([#143](https://github.com/golemui/golemui/pull/143))
16
+ - **mcp:** add get_concept tool and fix reactive-expression lint ([#138](https://github.com/golemui/golemui/pull/138))
17
+
18
+ ### 🩹 Fixes
19
+
20
+ - **schemas:** clean up and enrich JSON schema definitions ([#145](https://github.com/golemui/golemui/pull/145))
21
+
22
+ ### ❤️ Thank You
23
+
24
+ - mudscientist
25
+ - Raúl Jiménez @Elecash
26
+
1
27
  ## 0.15.1 (2026-05-27)
2
28
 
3
29
  This was a version bump only for gui-mcp to align it with other projects, there were no code changes.
package/README.md CHANGED
@@ -82,6 +82,50 @@ single GolemUI widget. Cheaper than dumping the whole API into the model's conte
82
82
  **Input:** `{ widgetType }` (one of the widget `type` constants — `textinput`,
83
83
  `dropdown`, `repeater`, `flex`, etc.)
84
84
 
85
+ ### `get_concept`
86
+
87
+ Returns a detailed guide for a cross-cutting concept - things that span multiple widgets
88
+ and affect the whole form. Use it when you need state-suffixed props
89
+ (`"label.stateName": "..."`) or to reuse a condition across multiple widgets via
90
+ `include`/`exclude`. Currently supported: `"states"`, `"string-interpolation"`.
91
+
92
+ **Input:** `{ concept }` - one of `"states"`, `"string-interpolation"`
93
+
94
+ ## Library usage
95
+
96
+ The package also exports all tools as plain functions, so you can call them directly
97
+ from Node.js apps, scripts, or other libraries without running an MCP server.
98
+
99
+ ```bash
100
+ npm install @golemui/gui-mcp
101
+ ```
102
+
103
+ ```ts
104
+ import {
105
+ validateFormDefinition,
106
+ generateFromJsonSchema,
107
+ generateFromOpenapi,
108
+ getWidgetSpec,
109
+ getConcept,
110
+ } from '@golemui/gui-mcp';
111
+
112
+ // Validate a form definition
113
+ const result = validateFormDefinition({ formDefinition: myForm });
114
+ if (!result.valid) console.error(result.errors);
115
+
116
+ // Generate a form from a JSON Schema
117
+ const { form, unmapped } = generateFromJsonSchema({ jsonSchema: mySchema });
118
+
119
+ // Generate a form from an OpenAPI spec
120
+ const { form } = await generateFromOpenapi({
121
+ documentUrl: 'https://example.com/openapi.json',
122
+ operation: 'POST /users',
123
+ });
124
+ ```
125
+
126
+ The tool descriptor objects (`VALIDATE_FORM_DEFINITION_TOOL`, `GENERATE_FROM_JSON_SCHEMA_TOOL`, ...)
127
+ are also exported if you want to register the tools in your own MCP server.
128
+
85
129
  ## How it stays accurate
86
130
 
87
131
  The server ships a frozen snapshot of the GolemUI JSON Schemas inside its npm package,
@@ -97,7 +141,7 @@ _grounding layer_ the host IDE's model calls into.
97
141
 
98
142
  ### Interactive testing with MCP Inspector
99
143
 
100
- Start the MCP server and open a local web UI at http://localhost:5173
144
+ Start the MCP server and open a local web UI at <http://localhost:5173>
101
145
 
102
146
  ```bash
103
147
  npm run start:mcp
@@ -105,17 +149,17 @@ npm run start:mcp
105
149
 
106
150
  To use the server from within Claude Code conversations, register with local Claude Code:
107
151
 
108
- #### With the Calude code CLI
152
+ #### With the Claude code CLI
109
153
 
110
154
  ```bash
111
- claude mcp add golemui-local -- node /Users/{USER}/{...}/golem/golemui/dist/libs/gui/mcp/index.js
155
+ claude mcp add golemui-local -- node /Users/{USER}/{...}/golem/golemui/dist/libs/gui/mcp/cli.js
112
156
  ```
113
157
 
114
158
  Then restart or reload the session. The tools appear in Claude's tool list.
115
159
 
116
160
  Remove with claude mcp remove golemui-local when done.
117
161
 
118
- #### With the Calude code extension
162
+ #### With the Claude code extension
119
163
 
120
164
  Create or edit the project-level MCP config at .mcp.json in the workspace root:
121
165
 
@@ -124,7 +168,7 @@ Create or edit the project-level MCP config at .mcp.json in the workspace root:
124
168
  "mcpServers": {
125
169
  "golemui-local": {
126
170
  "command": "node",
127
- "args": ["/Users/{USER}/{...}/golem/golemui/dist/libs/gui/mcp/index.js"]
171
+ "args": ["/Users/{USER}/{...}/golem/golemui/dist/libs/gui/mcp/cli.js"]
128
172
  }
129
173
  }
130
174
  }
package/cli.js ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
6
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
+ import { ListToolsRequestSchema, CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js";
8
+ import { V as VALIDATE_FORM_DEFINITION_TOOL, G as GENERATE_FROM_JSON_SCHEMA_TOOL, b as GENERATE_FROM_OPENAPI_TOOL, d as GET_WIDGET_SPEC_TOOL, f as GET_CONCEPT_TOOL, e as getConcept, c as getWidgetSpec, a as generateFromOpenapi, g as generateFromJsonSchema, v as validateFormDefinition } from "./get-concept-CHgtnDXr.js";
9
+ function readPackageMeta() {
10
+ const here = dirname(fileURLToPath(import.meta.url));
11
+ for (const candidate of [join(here, "package.json"), join(here, "..", "package.json")]) {
12
+ try {
13
+ const pkg = JSON.parse(readFileSync(candidate, "utf-8"));
14
+ if (pkg.name && pkg.version) return { name: pkg.name, version: pkg.version };
15
+ } catch {
16
+ }
17
+ }
18
+ return { name: "@golemui/gui-mcp", version: "0.0.0" };
19
+ }
20
+ const { name: PKG_NAME, version: PKG_VERSION } = readPackageMeta();
21
+ const TOOLS = [
22
+ VALIDATE_FORM_DEFINITION_TOOL,
23
+ GENERATE_FROM_JSON_SCHEMA_TOOL,
24
+ GENERATE_FROM_OPENAPI_TOOL,
25
+ GET_WIDGET_SPEC_TOOL,
26
+ GET_CONCEPT_TOOL
27
+ ];
28
+ const SERVER_INSTRUCTIONS = 'This server builds and validates GolemUI form definitions — declarative, JSON-serializable forms shaped as `{ form: [...widgets], states?: {...} }`. Its job is to help you produce a form definition that is guaranteed correct before the user pastes it into their codebase.\n\nRecommended workflow:\n1. Starting from an existing schema? Use a generator — both return a pre-validated definition, so check the returned `unmapped` list and surface anything left over to the user. For a raw JSON Schema (e.g. an API request body), call `generate_from_json_schema`. For an OpenAPI 3.x spec, call `generate_from_openapi`: pass `operation` as "METHOD /path" (e.g. "POST /users") or an exact operationId, plus the spec as a parsed `document` or a `documentUrl` to fetch — it resolves the operation\'s request body, dereferences `$ref`s, and falls back to the operation\'s parameters when there is no request body.\n2. Building or editing by hand? Look up a single widget with `get_widget_spec` (its `kind`, `props`, and `validator` shape), and cross-cutting behavior that spans widgets — conditional rendering, per-state prop overrides — with `get_concept`.\n3. ALWAYS finish by calling `validate_form_definition`. It checks the definition against the bundled JSON Schemas and returns `{ valid, errors, warnings, expressionWarnings }`. Treat `errors` as blocking: fix them and re-validate until `valid` is true. `warnings` (likely-custom widgets) and `expressionWarnings` (linted reactive expressions) are advisory — surface them, but they do not flip `valid`.\n\nDo not hand a form definition to the user until `validate_form_definition` reports `valid: true`.';
29
+ const server = new Server(
30
+ { name: PKG_NAME, version: PKG_VERSION },
31
+ { capabilities: { tools: {} }, instructions: SERVER_INSTRUCTIONS }
32
+ );
33
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
34
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
35
+ const { name, arguments: args } = request.params;
36
+ try {
37
+ switch (name) {
38
+ case "validate_form_definition":
39
+ return ok(validateFormDefinition(args));
40
+ case "generate_from_json_schema":
41
+ return ok(generateFromJsonSchema(args));
42
+ case "generate_from_openapi":
43
+ return ok(await generateFromOpenapi(args));
44
+ case "get_widget_spec":
45
+ return ok(getWidgetSpec(args));
46
+ case "get_concept":
47
+ return ok(getConcept(args));
48
+ default:
49
+ return err(`Unknown tool: ${name}`);
50
+ }
51
+ } catch (e) {
52
+ return err(e.message);
53
+ }
54
+ });
55
+ function ok(payload) {
56
+ return {
57
+ content: [{ type: "text", text: JSON.stringify(payload, null, 2) }]
58
+ };
59
+ }
60
+ function err(message) {
61
+ return {
62
+ isError: true,
63
+ content: [{ type: "text", text: message }]
64
+ };
65
+ }
66
+ async function main() {
67
+ const transport = new StdioServerTransport();
68
+ await server.connect(transport);
69
+ process.stderr.write(`${PKG_NAME} v${PKG_VERSION} ready on stdio
70
+ `);
71
+ }
72
+ main().catch((e) => {
73
+ process.stderr.write(`${PKG_NAME} failed to start: ${e.stack ?? e}
74
+ `);
75
+ process.exit(1);
76
+ });