Skip to content

Commit 2878cc8

Browse files
committed
fix(pluggable-widgets-mcp): fix property types, resource URIs, and add update-widget-prop tool
1 parent 3418bf6 commit 2878cc8

21 files changed

Lines changed: 566 additions & 2526 deletions

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/pluggable-widgets-mcp/AGENTS.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,13 @@ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3434
import { z } from "zod";
3535

3636
export function registerMyTools(server: McpServer): void {
37-
server.tool(
37+
server.registerTool(
3838
"my-tool",
39-
"Description shown to LLM",
40-
z.object({ param: z.string().describe("Parameter description") }),
39+
{
40+
title: "My Tool",
41+
description: "Description shown to LLM",
42+
inputSchema: z.object({ param: z.string().describe("Parameter description") })
43+
},
4144
async ({ param }) => ({
4245
content: [{ type: "text", text: "Success" }]
4346
})

packages/pluggable-widgets-mcp/README.md

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ A Model Context Protocol (MCP) server that enables AI assistants to scaffold Men
1010
pnpm install
1111
pnpm build # Build the server
1212
pnpm start # STDIO mode (default)
13-
pnpm start:stdio # HTTP mode
13+
pnpm start:stdio # STDIO mode
1414
```
1515

1616
## Global Installation
@@ -120,18 +120,24 @@ Generated widgets are placed in `generations/` directory within this package.
120120

121121
### File Operation Tools
122122

123-
| Tool | Description |
124-
| -------------------------- | ------------------------------------------------------------ |
125-
| `list-widget-files` | Lists all files in a widget directory, grouped by type |
126-
| `read-widget-file` | Reads the contents of a file from a widget directory |
127-
| `write-widget-file` | Writes content to a file (creates parent dirs automatically) |
128-
| `batch-write-widget-files` | Writes multiple files atomically |
123+
| Tool | Description |
124+
| ------------------- | ------------------------------------------------------------------------------------- |
125+
| `list-widget-files` | Lists all files in a widget directory, grouped by type |
126+
| `read-widget-file` | Reads the contents of a file from a widget directory |
127+
| `write-widget-file` | Writes content to a file (creates parent dirs). Supports single-file and batch modes. |
129128

130129
**Security:** All file operations are protected by `src/security/guardrails.ts`:
131130

132131
- Path traversal is blocked (no `..` escapes)
133132
- Extension whitelist: `.tsx`, `.ts`, `.xml`, `.scss`, `.css`, `.json`, `.md`
134133

134+
### Code Generation Tools
135+
136+
| Tool | Description |
137+
| -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
138+
| `generate-widget-code` | Generates widget XML + TSX + SCSS from property definitions. Saves a `.widget-definition.json` snapshot. |
139+
| `update-widget-properties` | Incrementally adds, removes, or modifies widget properties. Requires `generate-widget-code` to have been run first. |
140+
135141
### build-widget
136142

137143
Builds a widget using `pluggable-widgets-tools`, producing an `.mpk` file.
@@ -193,7 +199,7 @@ npx @modelcontextprotocol/inspector
193199
}
194200
```
195201
4. Click "Execute" and watch progress notifications as the widget is scaffolded
196-
5. Check `generations/testwidget/` for the created widget
202+
5. Check `generations/testWidget/` for the created widget
197203

198204
This is useful for verifying tool behavior without needing a full AI client integration.
199205

@@ -243,7 +249,7 @@ This means:
243249
**During widget scaffolding:**
244250

245251
- Chat shows: "Starting scaffolding..." → (wait) → "Widget created at `/path`"
246-
- Inspector shows: Step-by-step progress notifications for all 14 prompts
252+
- Inspector shows: Progress notifications (start → installing dependencies → complete)
247253

248254
**During widget building:**
249255

@@ -256,10 +262,13 @@ This means:
256262
- [x] HTTP transport
257263
- [x] STDIO transport
258264
- [x] Progress notifications
259-
- [x] File operations (list, read, write, batch-write)
265+
- [x] File operations (list, read, write)
260266
- [x] Build tool (`build-widget`)
261267
- [x] Guideline resources (property-types, widget-patterns)
262-
- [ ] Widget property editing (XML manipulation)
268+
- [x] Code generation (`generate-widget-code`)
269+
- [x] Incremental property update tool (`update-widget-properties`)
270+
- [ ] Batch widget generation
271+
- [ ] Widget testing helpers
263272
- [ ] TypeScript error recovery suggestions
264273

265274
## License

packages/pluggable-widgets-mcp/docs/property-types.md

Lines changed: 43 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
This document defines all available property types for Mendix pluggable widgets. Use this reference when defining properties in the JSON schema for XML generation.
44

5+
> **Note:** XML is generated automatically by the `generate-widget-code` tool. You only need to provide JSON property definitions — no XML knowledge required.
6+
57
## Property Definition Schema
68

79
When defining properties for the XML generator, use this JSON structure:
@@ -35,15 +37,6 @@ Simple text input.
3537
}
3638
```
3739

38-
**XML Output:**
39-
40-
```xml
41-
<property key="label" type="string" defaultValue="Click me">
42-
<caption>Label</caption>
43-
<description>Text label for the widget</description>
44-
</property>
45-
```
46-
4740
---
4841

4942
### boolean
@@ -60,15 +53,6 @@ True/false toggle.
6053
}
6154
```
6255

63-
**XML Output:**
64-
65-
```xml
66-
<property key="showIcon" type="boolean" defaultValue="true">
67-
<caption>Show icon</caption>
68-
<description>Display an icon next to the text</description>
69-
</property>
70-
```
71-
7256
---
7357

7458
### integer
@@ -85,15 +69,6 @@ Whole number input.
8569
}
8670
```
8771

88-
**XML Output:**
89-
90-
```xml
91-
<property key="maxItems" type="integer" defaultValue="10">
92-
<caption>Maximum items</caption>
93-
<description>Maximum number of items to display</description>
94-
</property>
95-
```
96-
9772
---
9873

9974
### decimal
@@ -128,15 +103,6 @@ Text with parameter substitution. Allows dynamic text with placeholders.
128103
}
129104
```
130105

131-
**XML Output:**
132-
133-
```xml
134-
<property key="legend" type="textTemplate" required="false">
135-
<caption>Legend</caption>
136-
<description>Text template with parameters</description>
137-
</property>
138-
```
139-
140106
---
141107

142108
### expression
@@ -164,15 +130,6 @@ Dynamic expression that can reference attributes and return computed values.
164130
}
165131
```
166132

167-
**XML Output (with returnType):**
168-
169-
```xml
170-
<property key="valueExpression" type="expression">
171-
<caption>Value</caption>
172-
<returnType type="String" />
173-
</property>
174-
```
175-
176133
---
177134

178135
## Action Types
@@ -191,15 +148,6 @@ Event handler that triggers actions (microflows, nanoflows, etc.).
191148
}
192149
```
193150

194-
**XML Output:**
195-
196-
```xml
197-
<property key="onClick" type="action" required="false">
198-
<caption>On click</caption>
199-
<description>Action to execute when clicked</description>
200-
</property>
201-
```
202-
203151
---
204152

205153
## Data Types
@@ -229,18 +177,6 @@ Links to an entity attribute. Must specify allowed attribute types.
229177
}
230178
```
231179

232-
**XML Output:**
233-
234-
```xml
235-
<property key="value" type="attribute" required="true">
236-
<caption>Value</caption>
237-
<description>Attribute to store the value</description>
238-
<attributeTypes>
239-
<attributeType name="String" />
240-
</attributeTypes>
241-
</property>
242-
```
243-
244180
**Valid attributeTypes:**
245181

246182
- `String`
@@ -271,15 +207,6 @@ Data source for list-based widgets.
271207
}
272208
```
273209

274-
**XML Output:**
275-
276-
```xml
277-
<property key="dataSource" type="datasource" isList="true" required="false">
278-
<caption>Data source</caption>
279-
<description>Source of items to display</description>
280-
</property>
281-
```
282-
283210
---
284211

285212
### association
@@ -297,15 +224,25 @@ Links to an entity association.
297224

298225
---
299226

300-
### entity
227+
### selection
301228

302-
Entity selector.
229+
Represents the selection mode for a widget (e.g., for data grids).
230+
231+
| Field | Type | Required | Description |
232+
| ----------- | ----------- | -------- | --------------------------- |
233+
| key | string || camelCase identifier |
234+
| type | "selection" || Must be "selection" |
235+
| caption | string || Display label in Studio Pro |
236+
| description | string | | Help text |
237+
| required | boolean | | Whether required |
238+
239+
**Example:**
303240

304241
```json
305242
{
306-
"key": "targetEntity",
307-
"type": "entity",
308-
"caption": "Target entity"
243+
"key": "selection",
244+
"type": "selection",
245+
"caption": "Selection"
309246
}
310247
```
311248

@@ -331,19 +268,6 @@ Dropdown with predefined options. Must include `enumValues` array.
331268
}
332269
```
333270

334-
**XML Output:**
335-
336-
```xml
337-
<property key="alignment" type="enumeration" defaultValue="left">
338-
<caption>Alignment</caption>
339-
<enumerationValues>
340-
<enumerationValue key="left">Left</enumerationValue>
341-
<enumerationValue key="center">Center</enumerationValue>
342-
<enumerationValue key="right">Right</enumerationValue>
343-
</enumerationValues>
344-
</property>
345-
```
346-
347271
---
348272

349273
### icon
@@ -416,15 +340,6 @@ Container for child widgets. Used to create widget slots.
416340
}
417341
```
418342

419-
**XML Output:**
420-
421-
```xml
422-
<property key="content" type="widgets">
423-
<caption>Content</caption>
424-
<description>Widgets to display inside</description>
425-
</property>
426-
```
427-
428343
---
429344

430345
### object
@@ -453,24 +368,6 @@ Complex nested property with sub-properties. Used for repeating structures.
453368
}
454369
```
455370

456-
**XML Output:**
457-
458-
```xml
459-
<property key="columns" type="object" isList="true">
460-
<caption>Columns</caption>
461-
<properties>
462-
<propertyGroup caption="Column">
463-
<property key="header" type="textTemplate">
464-
<caption>Header</caption>
465-
</property>
466-
<property key="width" type="integer" defaultValue="100">
467-
<caption>Width</caption>
468-
</property>
469-
</propertyGroup>
470-
</properties>
471-
</property>
472-
```
473-
474371
---
475372

476373
## System Properties
@@ -489,18 +386,6 @@ System properties are predefined by Mendix. Reference them by key only.
489386
- `TabIndex` - Tab order for accessibility
490387
- `Visibility` - Conditional visibility settings
491388

492-
**XML Output:**
493-
494-
```xml
495-
<propertyGroup caption="Common">
496-
<systemProperty key="Name" />
497-
<systemProperty key="TabIndex" />
498-
</propertyGroup>
499-
<propertyGroup caption="Visibility">
500-
<systemProperty key="Visibility" />
501-
</propertyGroup>
502-
```
503-
504389
---
505390

506391
## Property Groups
@@ -524,6 +409,31 @@ Properties can be organized into groups for better Studio Pro UI.
524409

525410
---
526411

412+
## Property Organization
413+
414+
### Auto-Grouping Behavior
415+
416+
If `propertyGroups` is omitted from the widget definition, the `generate-widget-code` tool applies automatic grouping:
417+
418+
- Non-action properties (all types except `action`) are placed in a **"General"** group.
419+
- Action properties (`type: "action"`) are placed in an **"Events"** group.
420+
421+
This means you rarely need to define `propertyGroups` explicitly for simple widgets. Only add it when you need custom group names or a specific ordering of groups.
422+
423+
### Incrementally Updating Properties
424+
425+
Once a widget has been generated with `generate-widget-code`, you do not need to regenerate all files to change the property list. Use the `update-widget-properties` tool to:
426+
427+
- **Add** new properties to an existing widget
428+
- **Remove** properties that are no longer needed
429+
- **Modify** property attributes (e.g., change a caption or default value)
430+
431+
The `update-widget-properties` tool reads the `.widget-definition.json` snapshot saved during `generate-widget-code` and applies only the requested delta, then regenerates the affected files.
432+
433+
> **Requirement:** `generate-widget-code` must have been run at least once before `update-widget-properties` can be used, because it depends on the `.widget-definition.json` snapshot.
434+
435+
---
436+
527437
## Full Widget Definition Example
528438

529439
```json
@@ -586,3 +496,4 @@ Properties can be organized into groups for better Studio Pro UI.
586496
| `icon` | Icon picker | - |
587497
| `image` | Image picker | - |
588498
| `association` | Entity relation | - |
499+
| `selection` | Selection mode | - |

0 commit comments

Comments
 (0)