Skip to content

Commit a31349f

Browse files
committed
feat(pluggable-widgets-mcp): introduce pluggable-widgets-mcp
1 parent dac41c5 commit a31349f

26 files changed

Lines changed: 3682 additions & 101 deletions
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dist/
2+
generations/
3+
node_modules/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require("@mendix/prettier-config-web-widgets");
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require("@mendix/prettier-config-web-widgets");
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# Pluggable Widgets MCP Server - AI Agent Guide
2+
3+
This document provides context for AI development assistants working on the MCP (Model Context Protocol) server for Mendix pluggable widgets.
4+
5+
## Overview
6+
7+
This package implements an MCP server that enables AI assistants to scaffold and manage Mendix pluggable widgets programmatically. It supports both HTTP and STDIO transports for flexible integration with various MCP clients.
8+
9+
### Key Characteristics
10+
11+
- **MCP SDK**: Built on `@modelcontextprotocol/sdk` for standardized AI tool integration
12+
- **Dual Transport**: HTTP (Express) for web clients, STDIO for CLI clients (Claude Desktop, etc.)
13+
- **TypeScript**: Fully typed with Zod schemas for runtime validation
14+
- **Widget Generator**: Wraps `@mendix/generator-widget` via PTY for interactive scaffolding
15+
16+
## Project Structure
17+
18+
```
19+
src/
20+
├── index.ts # Entry point - transport mode selection
21+
├── config.ts # Server configuration and constants
22+
├── server/
23+
│ ├── server.ts # MCP server factory and tool registration
24+
│ ├── http.ts # HTTP transport setup (Express)
25+
│ ├── stdio.ts # STDIO transport setup
26+
│ ├── routes.ts # Express route handlers
27+
│ └── session.ts # HTTP session management
28+
└── tools/
29+
├── index.ts # Tool aggregation
30+
├── types.ts # MCP tool type definitions
31+
├── scaffolding.tools.ts # Widget creation tool
32+
└── utils/
33+
├── generator.ts # Widget generator PTY wrapper
34+
├── progress-tracker.ts # Progress/logging helper
35+
├── notifications.ts # MCP notification utilities
36+
└── response.ts # Tool response helpers
37+
```
38+
39+
## Architecture
40+
41+
### Transport Layer
42+
43+
The server supports two transport modes selected via CLI argument:
44+
45+
- **HTTP** (default): Multi-session Express server on port 3100
46+
- **STDIO**: Single-session stdin/stdout for CLI integration
47+
48+
### Tool Registration
49+
50+
Tools are defined using the `ToolDefinition<T>` interface:
51+
52+
```typescript
53+
interface ToolDefinition<T> {
54+
name: string; // Tool identifier
55+
title: string; // Human-readable name
56+
description: string; // LLM-facing description
57+
inputSchema: ZodType<T>; // Zod schema for validation
58+
handler: ToolHandler<T>; // Async handler function
59+
}
60+
```
61+
62+
New tools should be:
63+
64+
1. Created in `src/tools/` with a `*.tools.ts` suffix
65+
2. Export a `get*Tools()` function returning `ToolDefinition[]`
66+
3. Registered in `src/tools/index.ts`
67+
68+
### Widget Generator Integration
69+
70+
The `create-widget` tool uses `node-pty` to interact with the Mendix widget generator CLI. Key implementation details:
71+
72+
- **PTY Simulation**: Required because the generator uses interactive prompts
73+
- **Prompt Detection**: Matches expected prompts in terminal output
74+
- **Answer Automation**: Sends pre-configured answers based on user input
75+
- **Progress Tracking**: Reports progress via MCP notifications
76+
77+
## Development Commands
78+
79+
```bash
80+
pnpm dev # Development mode with hot reload (tsx watch)
81+
pnpm build # TypeScript compilation + path alias resolution
82+
pnpm start # Build and run (HTTP mode)
83+
pnpm start:stdio # Build and run (STDIO mode)
84+
pnpm lint # ESLint + Prettier check
85+
```
86+
87+
## Adding New Tools
88+
89+
1. **Create tool file**: `src/tools/my-feature.tools.ts`
90+
91+
```typescript
92+
import { z } from "zod";
93+
import type { ToolDefinition, ToolResponse } from "@/tools/types";
94+
import { createToolResponse, createErrorResponse } from "@/tools/utils/response";
95+
96+
const mySchema = z.object({
97+
param: z.string().describe("Parameter description for LLM")
98+
});
99+
100+
type MyInput = z.infer<typeof mySchema>;
101+
102+
export function getMyTools(): ToolDefinition<MyInput>[] {
103+
return [
104+
{
105+
name: "my-tool",
106+
title: "My Tool",
107+
description: "What this tool does (shown to LLM)",
108+
inputSchema: mySchema,
109+
handler: async (args, context) => {
110+
// Implementation
111+
return createToolResponse("Success message");
112+
}
113+
}
114+
];
115+
}
116+
```
117+
118+
2. **Register in index**: Update `src/tools/index.ts`
119+
120+
```typescript
121+
import { getMyTools } from "./my-feature.tools";
122+
123+
export function getAllTools(): AnyToolDefinition[] {
124+
return [
125+
...getScaffoldingTools(),
126+
...getMyTools() // Add here
127+
];
128+
}
129+
```
130+
131+
## Code Conventions
132+
133+
### Imports
134+
135+
- Use `@/` path alias for absolute imports from `src/`
136+
- Prefer specific file imports over barrel exports when dealing with circular dependencies
137+
- Group imports: node builtins → external packages → internal modules
138+
139+
### Error Handling
140+
141+
- Use `createErrorResponse()` for user-facing errors
142+
- Log to `console.error` (not stdout) in STDIO mode
143+
- Use `ProgressTracker` for long-running operations
144+
145+
### Type Safety
146+
147+
- All tool inputs must have Zod schemas
148+
- Use `ToolContext` for MCP-provided context (notifications, progress)
149+
- Avoid `any` except in `AnyToolDefinition` (required for heterogeneous tool arrays)
150+
151+
## Testing
152+
153+
Use MCP Inspector for interactive testing:
154+
155+
```bash
156+
# STDIO mode
157+
npx @modelcontextprotocol/inspector node dist/index.js stdio
158+
159+
# HTTP mode
160+
pnpm start
161+
npx @modelcontextprotocol/inspector
162+
# Connect to http://localhost:3100/mcp
163+
```
164+
165+
## Key Files Reference
166+
167+
| File | Purpose |
168+
| -------------------------- | -------------------------------------- |
169+
| `config.ts` | All constants (ports, timeouts, paths) |
170+
| `tools/types.ts` | MCP tool type definitions |
171+
| `tools/utils/generator.ts` | Widget generator prompts and defaults |
172+
| `server/session.ts` | HTTP session lifecycle management |
173+
174+
## Common Patterns
175+
176+
### Progress Notifications
177+
178+
```typescript
179+
const tracker = new ProgressTracker({
180+
context,
181+
logger: "my-tool",
182+
totalSteps: 5
183+
});
184+
185+
tracker.start("initializing");
186+
await tracker.progress(25, "Step 1 complete");
187+
await tracker.info("Detailed log message", { key: "value" });
188+
tracker.stop();
189+
```
190+
191+
### Long-Running Operations
192+
193+
- Use `ProgressTracker` for heartbeat and stuck detection
194+
- Set appropriate timeouts (see `SCAFFOLD_TIMEOUT_MS`)
195+
- Call `tracker.markComplete()` before expected long waits (e.g., npm install)
196+
197+
## Roadmap Context
198+
199+
Current focus is widget scaffolding. Planned additions:
200+
201+
- Widget property editing
202+
- XML configuration management
203+
- Build and deployment automation
204+
205+
When adding features, maintain the existing patterns for tool registration, progress tracking, and transport-agnostic design.
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# Mendix Pluggable Widgets MCP Server
2+
3+
> **Work in Progress** - This is an MVP focused on widget scaffolding. Widget editing capabilities coming soon.
4+
5+
A Model Context Protocol (MCP) server that enables AI assistants to scaffold Mendix pluggable widgets programmatically.
6+
7+
## Quick Start
8+
9+
```bash
10+
pnpm install
11+
pnpm start # HTTP mode (default)
12+
pnpm start:stdio # STDIO mode
13+
```
14+
15+
## Transport Modes
16+
17+
### HTTP Mode (default)
18+
19+
Runs an HTTP server for web-based MCP clients.
20+
21+
```bash
22+
pnpm start
23+
pnpm start:http
24+
```
25+
26+
- Server runs on `http://localhost:3100` (override with `PORT` env var)
27+
- Health check: `GET /health`
28+
- MCP endpoint: `POST /mcp`
29+
30+
### STDIO Mode
31+
32+
Runs via stdin/stdout for CLI-based MCP clients (Claude Desktop, etc.).
33+
34+
```bash
35+
pnpm start:stdio
36+
```
37+
38+
## MCP Client Configuration
39+
40+
### HTTP
41+
42+
```json
43+
{
44+
"mcpServers": {
45+
"pluggable-widgets-mcp": {
46+
"url": "http://localhost:3100/mcp"
47+
}
48+
}
49+
}
50+
```
51+
52+
### STDIO
53+
54+
**_Some client setups like Claude Desktop support STDIO only (for now)_**
55+
56+
```json
57+
{
58+
"mcpServers": {
59+
"pluggable-widgets-mcp": {
60+
"command": "node",
61+
"args": ["/path/to/pluggable-widgets-mcp/dist/index.js", "stdio"]
62+
}
63+
}
64+
}
65+
```
66+
67+
## Available Tools
68+
69+
### create-widget
70+
71+
Scaffolds a new Mendix pluggable widget using `@mendix/generator-widget`.
72+
73+
| Parameter | Required | Default | Description |
74+
| --------------------- | -------- | ------------ | ------------------------------------ |
75+
| `name` | Yes | - | Widget name (PascalCase recommended) |
76+
| `description` | Yes | - | Brief description of the widget |
77+
| `version` | No | `1.0.0` | Initial version (semver) |
78+
| `author` | No | `Mendix` | Author name |
79+
| `license` | No | `Apache-2.0` | License type |
80+
| `organization` | No | `Mendix` | Organization namespace |
81+
| `template` | No | `empty` | `full` (sample code) or `empty` |
82+
| `programmingLanguage` | No | `typescript` | `typescript` or `javascript` |
83+
| `unitTests` | No | `true` | Include unit test setup (Jest/TS) |
84+
| `e2eTests` | No | `false` | Include E2E test setup (Playwright) |
85+
86+
Generated widgets are placed in `generations/` directory within this package.
87+
88+
## Development
89+
90+
```bash
91+
pnpm dev # Development mode with hot reload
92+
pnpm build # Build for production
93+
pnpm start # Build and run
94+
```
95+
96+
## Testing with MCP Inspector
97+
98+
The [MCP Inspector](https://github.com/modelcontextprotocol/inspector) is an interactive debugging tool for testing MCP servers. It provides a web UI to connect to your server, explore available tools, and execute them with custom inputs.
99+
100+
### Quick Start
101+
102+
```bash
103+
# Run Inspector against this server (STDIO mode)
104+
npx @modelcontextprotocol/inspector node dist/index.js stdio
105+
106+
# Or for HTTP mode, start the server first then connect via Inspector
107+
pnpm start
108+
npx @modelcontextprotocol/inspector
109+
# Then enter http://localhost:3100/mcp as the server URL
110+
```
111+
112+
### Using the Inspector
113+
114+
1. **Connect** - The Inspector will automatically connect to your MCP server
115+
2. **Explore Tools** - View all registered tools (`create-widget`, etc.) with their schemas
116+
3. **Execute Tools** - Fill in parameters and run tools to test behavior
117+
4. **View Responses** - See JSON responses, progress notifications, and logs in real-time
118+
119+
### Example: Testing `create-widget`
120+
121+
1. Start the Inspector: `npx @modelcontextprotocol/inspector node dist/index.js stdio`
122+
2. Select the `create-widget` tool from the tools list
123+
3. Fill in required parameters:
124+
```json
125+
{
126+
"name": "TestWidget",
127+
"description": "A test widget",
128+
... // Defaults for other optional values if not entered
129+
}
130+
```
131+
4. Click "Execute" and watch progress notifications as the widget is scaffolded
132+
5. Check `generations/testwidget/` for the created widget
133+
134+
This is useful for verifying tool behavior without needing a full AI client integration.
135+
136+
## Roadmap
137+
138+
- [x] Widget scaffolding
139+
- [x] HTTP transport
140+
- [x] STDIO transport
141+
- [x] Progress notifications
142+
- [ ] Widget editing and modification
143+
- [ ] Property management
144+
- [ ] Build and deployment tools
145+
146+
## License
147+
148+
Apache-2.0 - Mendix Technology BV 2025
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import config from "@mendix/eslint-config-web-widgets/widget-ts.mjs";
2+
3+
export default config;

0 commit comments

Comments
 (0)