@agiflowai/scaffold-mcp 0.0.0 → 0.2.0

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.
Files changed (2) hide show
  1. package/dist/index.js +247 -20
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -519,11 +519,25 @@ boilerplateCommand.command("info <boilerplateName>").description("Show detailed
519
519
  //#endregion
520
520
  //#region src/cli/init.ts
521
521
  /**
522
+ * Find the workspace root by searching upwards for .git folder
523
+ */
524
+ async function findWorkspaceRoot(startPath = process.cwd()) {
525
+ let currentPath = path.resolve(startPath);
526
+ const rootPath = path.parse(currentPath).root;
527
+ while (true) {
528
+ const gitPath = path.join(currentPath, ".git");
529
+ if (await fs$1.pathExists(gitPath)) return currentPath;
530
+ if (currentPath === rootPath) return process.cwd();
531
+ currentPath = path.dirname(currentPath);
532
+ }
533
+ }
534
+ /**
522
535
  * Init command - initialize templates folder
523
536
  */
524
- const initCommand = new Command("init").description("Initialize templates folder structure").option("--path <path>", "Path to templates folder", "./templates").action(async (options) => {
537
+ const initCommand = new Command("init").description("Initialize templates folder structure at workspace root").action(async () => {
525
538
  try {
526
- const templatesPath = path.resolve(options.path);
539
+ const workspaceRoot = await findWorkspaceRoot();
540
+ const templatesPath = path.join(workspaceRoot, "templates");
527
541
  logger.info(`${icons.rocket} Initializing templates folder at: ${templatesPath}`);
528
542
  await fs$1.ensureDir(templatesPath);
529
543
  await fs$1.ensureDir(path.join(templatesPath, "boilerplates"));
@@ -790,6 +804,213 @@ Template File Content Guidelines:
790
804
  }
791
805
  };
792
806
 
807
+ //#endregion
808
+ //#region src/prompts/ScaffoldApplicationPrompt.ts
809
+ /**
810
+ * Prompt for scaffolding a new application using boilerplate templates
811
+ */
812
+ var ScaffoldApplicationPrompt = class ScaffoldApplicationPrompt {
813
+ static PROMPT_NAME = "scaffold-application";
814
+ /**
815
+ * Get the prompt definition for MCP
816
+ */
817
+ getDefinition() {
818
+ return {
819
+ name: ScaffoldApplicationPrompt.PROMPT_NAME,
820
+ description: "Scaffold a new application from a boilerplate template",
821
+ arguments: [{
822
+ name: "request",
823
+ description: "Describe the application you want to create (optional)",
824
+ required: false
825
+ }]
826
+ };
827
+ }
828
+ /**
829
+ * Get the prompt messages
830
+ */
831
+ getMessages(args) {
832
+ const userRequest = args?.request || "";
833
+ return [{
834
+ role: "user",
835
+ content: {
836
+ type: "text",
837
+ text: `You are helping create a new application using the scaffold-mcp MCP tools.
838
+
839
+ ${userRequest ? `User request: ${userRequest}\n` : ""}
840
+ Your task is to scaffold a new application by following this workflow:
841
+
842
+ ## Step 1: List Available Boilerplates
843
+ Use the \`list-boilerplates\` tool to see all available project templates.
844
+
845
+ **What to look for:**
846
+ - Boilerplate name (e.g., "scaffold-nextjs-app", "scaffold-vite-app")
847
+ - Description of what the boilerplate creates
848
+ - Target folder where projects will be created (e.g., "apps", "packages")
849
+ - Required and optional variables in the variables_schema
850
+
851
+ ## Step 2: Gather Required Information
852
+ Based on the selected boilerplate's variables_schema, collect:
853
+ - **Project name**: Must be kebab-case (e.g., "my-new-app", not "MyNewApp")
854
+ - **Required variables**: All variables marked as required: true
855
+ - **Optional variables**: Variables with required: false (ask user if needed)
856
+
857
+ Common variables:
858
+ - \`appName\` or \`packageName\`: The project name (kebab-case)
859
+ - \`description\`: Brief description of what the project does
860
+ - \`author\`: Author name
861
+
862
+ ## Step 3: Execute the Boilerplate
863
+ Use the \`use-boilerplate\` tool with:
864
+ - \`boilerplateName\`: Exact name from list-boilerplates response
865
+ - \`variables\`: Object matching the variables_schema exactly
866
+
867
+ **Example:**
868
+ \`\`\`json
869
+ {
870
+ "boilerplateName": "scaffold-nextjs-app",
871
+ "variables": {
872
+ "appName": "my-dashboard",
873
+ "description": "Admin dashboard for managing users",
874
+ "author": "John Doe"
875
+ }
876
+ }
877
+ \`\`\`
878
+
879
+ ## Important Guidelines:
880
+ - **Always call \`list-boilerplates\` first** to see available options and their schemas
881
+ - **Use exact variable names** from the schema (case-sensitive)
882
+ - **Provide all required variables** - the tool will fail if any are missing
883
+ - **Use kebab-case for project names** (e.g., "user-dashboard", not "UserDashboard")
884
+ - The tool will create the project in the appropriate directory automatically
885
+ - After creation, inform the user where the project was created
886
+
887
+ ## Example Workflow:
888
+ 1. Call \`list-boilerplates\` → See available templates
889
+ 2. Ask user which template to use (or infer from request)
890
+ 3. Collect required variables based on schema
891
+ 4. Call \`use-boilerplate\` with boilerplateName and variables
892
+ 5. Report success and next steps to the user`
893
+ }
894
+ }];
895
+ }
896
+ };
897
+
898
+ //#endregion
899
+ //#region src/prompts/ScaffoldFeaturePrompt.ts
900
+ /**
901
+ * Prompt for scaffolding a new feature in an existing project
902
+ */
903
+ var ScaffoldFeaturePrompt = class ScaffoldFeaturePrompt {
904
+ static PROMPT_NAME = "scaffold-feature";
905
+ /**
906
+ * Get the prompt definition for MCP
907
+ */
908
+ getDefinition() {
909
+ return {
910
+ name: ScaffoldFeaturePrompt.PROMPT_NAME,
911
+ description: "Scaffold a new feature (page, component, service, etc.) in an existing project",
912
+ arguments: [{
913
+ name: "request",
914
+ description: "Describe the feature you want to add (optional)",
915
+ required: false
916
+ }, {
917
+ name: "projectPath",
918
+ description: "Path to the project (e.g., \"apps/my-app\") - optional if can be inferred",
919
+ required: false
920
+ }]
921
+ };
922
+ }
923
+ /**
924
+ * Get the prompt messages
925
+ */
926
+ getMessages(args) {
927
+ const userRequest = args?.request || "";
928
+ const projectPath = args?.projectPath || "";
929
+ return [{
930
+ role: "user",
931
+ content: {
932
+ type: "text",
933
+ text: `You are helping add a new feature to an existing project using the scaffold-mcp MCP tools.
934
+
935
+ ${userRequest ? `User request: ${userRequest}\n` : ""}${projectPath ? `Project path: ${projectPath}\n` : ""}
936
+ Your task is to scaffold a new feature by following this workflow:
937
+
938
+ ## Step 1: Identify the Project
939
+ Determine the project path where the feature will be added:
940
+ - If projectPath is provided, use it
941
+ - Otherwise, ask the user or infer from context (e.g., "apps/my-app", "packages/my-lib")
942
+ - The path should point to a directory containing a \`project.json\` file
943
+
944
+ ## Step 2: List Available Scaffolding Methods
945
+ Use the \`list-scaffolding-methods\` tool with the projectPath.
946
+
947
+ **What to look for:**
948
+ - Feature name (e.g., "scaffold-nextjs-page", "scaffold-react-component")
949
+ - Description of what files/code it generates
950
+ - Required and optional variables in the variables_schema
951
+ - The template type (derived from project's sourceTemplate)
952
+
953
+ **Example:**
954
+ \`\`\`json
955
+ {
956
+ "projectPath": "apps/my-dashboard"
957
+ }
958
+ \`\`\`
959
+
960
+ ## Step 3: Gather Required Information
961
+ Based on the selected scaffolding method's variables_schema, collect:
962
+ - **Feature-specific variables**: Name, path, type, etc.
963
+ - **Required variables**: All variables marked as required: true
964
+ - **Optional variables**: Variables with required: false (ask user if needed)
965
+
966
+ Common variables:
967
+ - \`componentName\` / \`pageName\` / \`serviceName\`: Name in PascalCase
968
+ - \`componentPath\` / \`pagePath\`: Where to place the file (may use kebab-case)
969
+ - Boolean flags: \`withTests\`, \`withLayout\`, \`withStyles\`, etc.
970
+
971
+ ## Step 4: Execute the Scaffolding Method
972
+ Use the \`use-scaffold-method\` tool with:
973
+ - \`projectPath\`: Same path from step 1
974
+ - \`scaffold_feature_name\`: Exact name from list-scaffolding-methods response
975
+ - \`variables\`: Object matching the variables_schema exactly
976
+
977
+ **Example:**
978
+ \`\`\`json
979
+ {
980
+ "projectPath": "apps/my-dashboard",
981
+ "scaffold_feature_name": "scaffold-nextjs-page",
982
+ "variables": {
983
+ "pageName": "UserProfile",
984
+ "pagePath": "user/profile",
985
+ "withLayout": true,
986
+ "withTests": false
987
+ }
988
+ }
989
+ \`\`\`
990
+
991
+ ## Important Guidelines:
992
+ - **Always call \`list-scaffolding-methods\` first** with the projectPath
993
+ - **Use exact variable names** from the schema (case-sensitive)
994
+ - **Provide all required variables** - the tool will fail if any are missing
995
+ - **Follow naming conventions**:
996
+ - Component/Page/Service names: PascalCase (e.g., "UserProfile")
997
+ - File paths: kebab-case or as specified in schema (e.g., "user/profile")
998
+ - **Conditional files**: Files with \`?condition=true\` are only included when the variable is true
999
+ - The tool will create files in the appropriate locations automatically
1000
+ - After creation, inform the user what files were created
1001
+
1002
+ ## Example Workflow:
1003
+ 1. Identify project path (provided or ask user)
1004
+ 2. Call \`list-scaffolding-methods\` → See available features for this project
1005
+ 3. Ask user which feature to add (or infer from request)
1006
+ 4. Collect required variables based on schema
1007
+ 5. Call \`use-scaffold-method\` with projectPath, scaffold_feature_name, and variables
1008
+ 6. Report success and list created files`
1009
+ }
1010
+ }];
1011
+ }
1012
+ };
1013
+
793
1014
  //#endregion
794
1015
  //#region src/services/BoilerplateGeneratorService.ts
795
1016
  /**
@@ -2136,6 +2357,8 @@ function createServer(options = {}) {
2136
2357
  const generateFeatureScaffoldTool = adminEnabled ? new GenerateFeatureScaffoldTool(templatesPath) : null;
2137
2358
  const generateBoilerplatePrompt = adminEnabled ? new GenerateBoilerplatePrompt() : null;
2138
2359
  const generateFeatureScaffoldPrompt = adminEnabled ? new GenerateFeatureScaffoldPrompt() : null;
2360
+ const scaffoldApplicationPrompt = new ScaffoldApplicationPrompt();
2361
+ const scaffoldFeaturePrompt = new ScaffoldFeaturePrompt();
2139
2362
  const server = new Server({
2140
2363
  name: "scaffold-mcp",
2141
2364
  version: "1.0.0"
@@ -2241,26 +2464,30 @@ Example workflow for feature:
2241
2464
  }
2242
2465
  throw new Error(`Unknown tool: ${name}`);
2243
2466
  });
2244
- if (adminEnabled) {
2245
- server.setRequestHandler(ListPromptsRequestSchema, async () => {
2246
- const prompts = [];
2467
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
2468
+ const prompts = [];
2469
+ prompts.push(scaffoldApplicationPrompt.getDefinition());
2470
+ prompts.push(scaffoldFeaturePrompt.getDefinition());
2471
+ if (adminEnabled) {
2247
2472
  if (generateBoilerplatePrompt) prompts.push(generateBoilerplatePrompt.getDefinition());
2248
2473
  if (generateFeatureScaffoldPrompt) prompts.push(generateFeatureScaffoldPrompt.getDefinition());
2249
- return { prompts };
2250
- });
2251
- server.setRequestHandler(GetPromptRequestSchema, async (request) => {
2252
- const { name, arguments: args } = request.params;
2253
- if (name === GenerateBoilerplatePrompt.PROMPT_NAME) {
2254
- if (!generateBoilerplatePrompt) throw new Error("Prompt not available");
2255
- return { messages: generateBoilerplatePrompt.getMessages(args) };
2256
- }
2257
- if (name === GenerateFeatureScaffoldPrompt.PROMPT_NAME) {
2258
- if (!generateFeatureScaffoldPrompt) throw new Error("Prompt not available");
2259
- return { messages: generateFeatureScaffoldPrompt.getMessages(args) };
2260
- }
2261
- throw new Error(`Unknown prompt: ${name}`);
2262
- });
2263
- }
2474
+ }
2475
+ return { prompts };
2476
+ });
2477
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
2478
+ const { name, arguments: args } = request.params;
2479
+ if (name === ScaffoldApplicationPrompt.PROMPT_NAME) return { messages: scaffoldApplicationPrompt.getMessages(args) };
2480
+ if (name === ScaffoldFeaturePrompt.PROMPT_NAME) return { messages: scaffoldFeaturePrompt.getMessages(args) };
2481
+ if (name === GenerateBoilerplatePrompt.PROMPT_NAME) {
2482
+ if (!generateBoilerplatePrompt) throw new Error("Prompt not available");
2483
+ return { messages: generateBoilerplatePrompt.getMessages(args) };
2484
+ }
2485
+ if (name === GenerateFeatureScaffoldPrompt.PROMPT_NAME) {
2486
+ if (!generateFeatureScaffoldPrompt) throw new Error("Prompt not available");
2487
+ return { messages: generateFeatureScaffoldPrompt.getMessages(args) };
2488
+ }
2489
+ throw new Error(`Unknown prompt: ${name}`);
2490
+ });
2264
2491
  return server;
2265
2492
  }
2266
2493
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agiflowai/scaffold-mcp",
3
3
  "description": "MCP server for scaffolding applications with boilerplate templates",
4
- "version": "0.0.0",
4
+ "version": "0.2.0",
5
5
  "license": "AGPL-3.0",
6
6
  "author": "AgiflowIO",
7
7
  "repository": {
@@ -42,7 +42,7 @@
42
42
  "js-yaml": "4.1.0",
43
43
  "liquidjs": "10.21.1",
44
44
  "zod": "3.25.76",
45
- "@agiflowai/scaffold-generator": "0.0.0"
45
+ "@agiflowai/scaffold-generator": "0.2.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/express": "^5.0.0",