Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c95bf46
feat(pluggable-widgets-mcp): introduce pluggable-widgets-mcp
rahmanunver Dec 5, 2025
480516b
refactor(pluggable-widgets-mcp): fix prompt timeout, refactor schema,…
rahmanunver Dec 17, 2025
a4dc687
feat(pluggable-widgets-mcp): wip
rahmanunver Dec 30, 2025
a6cf991
feat(pluggable-widgets-mcp): addition of resources and build tools, d…
rahmanunver Jan 14, 2026
dd5889b
feat(pluggable-widgets-mcp): refactor security guardrails into a sing…
rahmanunver Jan 15, 2026
9dda97d
feat(pluggable-widgets-mcp): introduce pluggable-widgets-mcp
rahmanunver Dec 5, 2025
63356d8
feat(pluggable-widgets-mcp): add code generation tool, handle working…
rahmanunver Jan 19, 2026
59ea5db
feat(pluggable-widgets-mcp): update readme and agents.md, add securit…
rahmanunver Jan 20, 2026
fcedc89
feat(pluggable-widgets-mcp): add changelog
rahmanunver Jan 20, 2026
ebae669
feat(pluggable-widgets-mcp): remove redundant prettier config
rahmanunver Jan 20, 2026
25364e2
fix(pluggable-widgets-mcp): fix property types, resource URIs, and ad…
rahmanunver Feb 23, 2026
ec1c760
feat(pluggable-widgets-mcp): use custom generator-widget with non-int…
rahmanunver Feb 25, 2026
01d5a53
feat(pluggable-widgets-mcp): add project tools, session state, and de…
rahmanunver Feb 27, 2026
853e5a9
refactor(pluggable-widgets-mcp): extract shared sandbox utility and a…
rahmanunver Feb 27, 2026
f2bfa2b
test(pluggable-widgets-mcp): add vitest infrastructure and unit tests
rahmanunver Feb 27, 2026
74fc30a
fix(pluggable-widgets-mcp): fix E2E pipeline — name passing, scaffold…
rahmanunver Feb 27, 2026
39031ef
fix(xml-generator): force required=true for primitive property types
rahmanunver Mar 4, 2026
2cae67f
fix(tsx-generator): use _props param in editorPreview when no label prop
rahmanunver Mar 4, 2026
f5821dd
fix(scaffolding): skip scaffold when widget directory already exists
rahmanunver Mar 4, 2026
c765680
feat(build): extract formatBuildSuccessResponse, chain build to deplo…
rahmanunver Mar 4, 2026
b24077c
feat(code-generation): add detectTemplateMismatch, reorder next steps…
rahmanunver Mar 4, 2026
4278d94
feat(server): add protocol logger and session lifecycle instrumentation
rahmanunver Mar 4, 2026
7c87232
test: add formatBuildSuccessResponse, detectTemplateMismatch, scenari…
rahmanunver Mar 4, 2026
aa765a7
chore: add mpk-analyzer utility, widget-patterns doc, update .gitignore
rahmanunver Mar 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"create-translation": "turbo run create-translation",
"include-oss-in-artifact": "pnpm --filter @mendix/automation-utils run include-oss-in-artifact",
"postinstall": "turbo run agent-rules",
"start:mcp": "pnpm --filter pluggable-widgets-mcp run start",
"lint": "turbo run lint --continue --concurrency 1",
"oss-clearance": "pnpm --filter @mendix/automation-utils run oss-clearance",
"prepare": "husky install",
Expand Down
4 changes: 4 additions & 0 deletions packages/pluggable-widgets-mcp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dist/
generations/
node_modules/
mcp-session-logs/
1 change: 1 addition & 0 deletions packages/pluggable-widgets-mcp/.prettierrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("@mendix/prettier-config-web-widgets");
116 changes: 116 additions & 0 deletions packages/pluggable-widgets-mcp/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Pluggable Widgets MCP Server

MCP server enabling AI assistants to scaffold and manage Mendix pluggable widgets via STDIO (default) or HTTP transport.

## Quick Reference

```bash
pnpm dev # Development with hot reload
pnpm build # TypeScript compilation + path alias resolution
pnpm start # Build and run (STDIO mode, default)
pnpm start:http # Build and run (HTTP mode, port 3100)
pnpm lint # ESLint check
```

## Project Structure

```
src/
├── index.ts # Entry point - transport mode selection
├── config.ts # Server configuration and constants
├── security/ # Path traversal & extension validation
├── server/ # HTTP and STDIO transport setup
├── resources/ # MCP resources (guidelines)
├── generators/ # XML and TSX code generators
└── tools/ # MCP tool implementations
```

## Adding Tools

1. Create `src/tools/my-feature.tools.ts`:

```typescript
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";

export function registerMyTools(server: McpServer): void {
server.registerTool(
"my-tool",
{
title: "My Tool",
description: "Description shown to LLM",
inputSchema: z.object({ param: z.string().describe("Parameter description") })
},
async ({ param }) => ({
content: [{ type: "text", text: "Success" }]
})
);
}
```

2. Register in `src/tools/index.ts`:

```typescript
import { registerMyTools } from "./my-feature.tools";

export function registerAllTools(server: McpServer): void {
// ... existing registrations
registerMyTools(server);
}
```

## Code Patterns

- **Imports**: Use `@/` path alias for absolute imports from `src/`
- **Schemas**: All tool inputs require Zod schemas
- **Errors**: Use `createErrorResponse()` from `@/tools/utils/response`
- **Long operations**: Use `ProgressTracker` from `@/tools/utils/progress-tracker`

## Notification Behavior (Important for AI Agents)

When using this MCP server, understand where different types of output appear:

| Output Type | Visibility | Purpose |
| -------------------------- | -------------------------- | ------------------------------------------------------- |
| **Tool Results** | ✅ Visible in conversation | Final outcomes, structured data, success/error messages |
| **Progress Notifications** | ❌ Not in conversation | Client UI indicators only (spinners, progress bars) |
| **Log Messages** | ❌ Not in conversation | Debug console/MCP Inspector only |

**Key Implications for AI Agents:**

1. **Don't expect intermediate progress in chat**: Long operations (scaffolding, building) will show results only when complete. The conversation won't contain step-by-step progress updates.

2. **Tool results are authoritative**: Only tool result content appears in the conversation history. Use this for:

- Success confirmations with file paths
- Structured error messages with suggestions
- Any information the AI needs to continue the workflow

3. **Progress tracking is for humans**: `sendProgress()` and `sendLogMessage()` are for human observers using MCP Inspector or UI indicators, not for AI decision-making.

4. **When debugging**:
- If operations seem to "hang", check MCP Inspector's Notifications/Logs panels
- Progress notifications confirm the server is working, even if the chat is quiet
- This is per MCP specification, not a bug

**Example Workflow:**

```typescript
// ❌ This progress won't appear in AI's context
await sendProgress(context, 50, "Scaffolding widget...");

// ✅ This result WILL appear in AI's context
return createToolResponse(`Widget created at ${widgetPath}`);
```

## Testing

```bash
npx @modelcontextprotocol/inspector node dist/index.js
```

## Security

**Read before implementing file operations**: [docs/agent/security.md](docs/agent/security.md)

All file operation tools must use `validateFilePath()` from `@/security` to prevent path traversal attacks.
11 changes: 11 additions & 0 deletions packages/pluggable-widgets-mcp/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changelog

All notable changes to this MCP server will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- We introduce pluggable-widgets-mcp.
Loading