@@ -22,6 +22,8 @@ import {
2222 determineTestCommand ,
2323 formatCommandResult
2424} from "./helpers.js" ;
25+ import { getSampleForUri } from "./sampling.js" ;
26+ import { prompts } from "./prompts.js" ;
2527import { Guardrails , withGuardrails } from "./guardrails.js" ;
2628import { DiffEngine } from "./diff-engine.js" ;
2729import { PropertyEngine } from "./property-engine.js" ;
@@ -66,14 +68,8 @@ async function main(): Promise<void> {
6668 version : "0.1.0" ,
6769 title : "Mendix Widgets Copilot" ,
6870 capabilities : {
69- resources : {
70- "mendix:repo" : {
71- description : "The Mendix Pluggable Widgets repository" ,
72- icon : "https://www.mendix.com/favicon.ico" ,
73- url : REPO_ROOT
74- }
75- } ,
76- tools : { }
71+ resources : { } , // Resources will be registered dynamically
72+ tools : { } // Tools are registered below
7773 }
7874 } ) ;
7975
@@ -534,6 +530,9 @@ async function main(): Promise<void> {
534530 const diffResult = await diffEngine . createDiff ( result . changes ) ;
535531 const applyResult = await diffEngine . applyChanges ( diffResult , { dryRun : false , createBackup : true } ) ;
536532
533+ // After applying, regenerate typings via pluggable-widgets-tools
534+ const regen = await propertyEngine . regenerateTypings ( validatedPath ) ;
535+
537536 return {
538537 content : [
539538 {
@@ -546,7 +545,8 @@ async function main(): Promise<void> {
546545 errors : applyResult . errors ,
547546 rollbackToken : applyResult . rollbackInfo
548547 ? JSON . stringify ( applyResult . rollbackInfo )
549- : undefined
548+ : undefined ,
549+ typingsRegeneration : regen
550550 } ,
551551 null ,
552552 2
@@ -617,6 +617,9 @@ async function main(): Promise<void> {
617617 const diffResult = await diffEngine . createDiff ( result . changes ) ;
618618 const applyResult = await diffEngine . applyChanges ( diffResult , { dryRun : false , createBackup : true } ) ;
619619
620+ // After applying, regenerate typings via pluggable-widgets-tools
621+ const regen = await propertyEngine . regenerateTypings ( validatedPath ) ;
622+
620623 return {
621624 content : [
622625 {
@@ -629,7 +632,8 @@ async function main(): Promise<void> {
629632 errors : applyResult . errors ,
630633 rollbackToken : applyResult . rollbackInfo
631634 ? JSON . stringify ( applyResult . rollbackInfo )
632- : undefined
635+ : undefined ,
636+ typingsRegeneration : regen
633637 } ,
634638 null ,
635639 2
@@ -641,6 +645,142 @@ async function main(): Promise<void> {
641645 } )
642646 ) ;
643647
648+ // Register widget samples as resources for context
649+ // This provides a standard way for AI assistants to access widget context
650+ const packagesDir = join ( REPO_ROOT , "packages" ) ;
651+
652+ // Register a resource for the repository overview
653+ server . registerResource (
654+ "repository-list" ,
655+ "mendix-widget://repository/list" ,
656+ {
657+ title : "Widget Repository Overview" ,
658+ description : "Complete list of widgets in the repository with metadata" ,
659+ mimeType : "application/json"
660+ } ,
661+ async uri => {
662+ const packages = await scanPackages ( packagesDir ) ;
663+ return {
664+ contents : [
665+ {
666+ uri : uri . href ,
667+ text : JSON . stringify (
668+ {
669+ widget : "repository" ,
670+ type : "overview" ,
671+ timestamp : new Date ( ) . toISOString ( ) ,
672+ content : {
673+ metadata : {
674+ name : "Mendix Web Widgets Repository" ,
675+ version : "latest" ,
676+ path : REPO_ROOT ,
677+ description : "Complete list of widgets in the repository"
678+ } ,
679+ widgets : packages
680+ }
681+ } ,
682+ null ,
683+ 2
684+ ) ,
685+ mimeType : "application/json"
686+ }
687+ ]
688+ } ;
689+ }
690+ ) ;
691+
692+ // Register dynamic resources for widget contexts
693+ // We'll register a few key widgets as examples - in production, you might want to register all
694+ const registerWidgetResources = async ( ) => {
695+ const packages = await scanPackages ( packagesDir ) ;
696+
697+ // Register resources for the first 10 widgets as examples
698+ const widgetsToRegister = packages . filter ( pkg => pkg . kind === "pluggableWidget" ) . slice ( 0 , 10 ) ;
699+
700+ for ( const widget of widgetsToRegister ) {
701+ const widgetName = widget . name . replace ( "@mendix/" , "" ) ;
702+
703+ // Register overview resource
704+ server . registerResource (
705+ `${ widgetName } -overview` ,
706+ `mendix-widget://${ widgetName } /overview` ,
707+ {
708+ title : `${ widgetName } - Complete Overview` ,
709+ description : `Full context for ${ widgetName } widget including manifest, types, and configuration` ,
710+ mimeType : "application/json"
711+ } ,
712+ async uri => {
713+ const sampleContent = await getSampleForUri ( uri . href , REPO_ROOT ) ;
714+ if ( "error" in sampleContent ) {
715+ throw new Error ( sampleContent . error ) ;
716+ }
717+ return {
718+ contents : [
719+ {
720+ uri : uri . href ,
721+ text : JSON . stringify ( sampleContent , null , 2 ) ,
722+ mimeType : "application/json"
723+ }
724+ ]
725+ } ;
726+ }
727+ ) ;
728+
729+ // Register properties resource
730+ server . registerResource (
731+ `${ widgetName } -properties` ,
732+ `mendix-widget://${ widgetName } /properties` ,
733+ {
734+ title : `${ widgetName } - Properties` ,
735+ description : `Property definitions and structure for ${ widgetName } widget` ,
736+ mimeType : "application/json"
737+ } ,
738+ async uri => {
739+ const sampleContent = await getSampleForUri ( uri . href , REPO_ROOT ) ;
740+ if ( "error" in sampleContent ) {
741+ throw new Error ( sampleContent . error ) ;
742+ }
743+ return {
744+ contents : [
745+ {
746+ uri : uri . href ,
747+ text : JSON . stringify ( sampleContent , null , 2 ) ,
748+ mimeType : "application/json"
749+ }
750+ ]
751+ } ;
752+ }
753+ ) ;
754+ }
755+ } ;
756+
757+ // Register widget resources on startup
758+ await registerWidgetResources ( ) ;
759+
760+ // Register MCP Prompts for guided workflows
761+ for ( const prompt of prompts ) {
762+ // Build the argsSchema object from prompt arguments
763+ const argsSchema : Record < string , any > = { } ;
764+ for ( const arg of prompt . arguments ) {
765+ argsSchema [ arg . name ] = arg . schema || z . string ( ) ;
766+ if ( ! arg . required ) {
767+ argsSchema [ arg . name ] = argsSchema [ arg . name ] . optional ( ) ;
768+ }
769+ }
770+
771+ server . registerPrompt (
772+ prompt . name ,
773+ {
774+ title : prompt . title ,
775+ description : prompt . description ,
776+ argsSchema : argsSchema
777+ } ,
778+ prompt . handler
779+ ) ;
780+ }
781+
782+ console . error ( `Registered ${ prompts . length } prompt templates for guided workflows` ) ;
783+
644784 await server . connect ( new StdioServerTransport ( ) ) ;
645785}
646786
0 commit comments