create-mcp-use-app 0.7.4-canary.0 → 0.7.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":""}
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/index.ts
3
+ // src/index.tsx
4
4
  import chalk from "chalk";
5
5
  import { Command } from "commander";
6
- import inquirer from "inquirer";
6
+ import { render } from "ink";
7
+ import SelectInput from "ink-select-input";
8
+ import TextInput from "ink-text-input";
7
9
  import { execSync, spawn } from "child_process";
8
10
  import {
9
11
  copyFileSync,
@@ -17,6 +19,8 @@ import {
17
19
  import { dirname, join, resolve } from "path";
18
20
  import { fileURLToPath } from "url";
19
21
  import ora from "ora";
22
+ import React, { useState } from "react";
23
+ import { Box, Text } from "ink";
20
24
  var __filename = fileURLToPath(import.meta.url);
21
25
  var __dirname = dirname(__filename);
22
26
  function runPackageManager(packageManager, args, cwd) {
@@ -231,9 +235,48 @@ function processTemplateFile(filePath, versions, isDevelopment = false, useCanar
231
235
  }
232
236
  return processedContent;
233
237
  }
234
- program.name("create-mcp-use-app").description("Create a new MCP server project").version(packageJson.version).argument("[project-name]", "Name of the MCP server project").option("-t, --template <template>", "Template to use", "starter").option("--install", "Install dependencies after creating project").option("--no-git", "Skip initializing a git repository").option("--dev", "Use workspace dependencies for development").option("--canary", "Use canary versions of packages").option("--yarn", "Use yarn as package manager").option("--npm", "Use npm as package manager").option("--pnpm", "Use pnpm as package manager").action(
238
+ function getAvailableTemplates() {
239
+ const templatesDir = join(__dirname, "templates");
240
+ if (!existsSync(templatesDir)) {
241
+ return [];
242
+ }
243
+ return readdirSync(templatesDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name).sort();
244
+ }
245
+ function listTemplates() {
246
+ console.log("");
247
+ renderLogo();
248
+ console.log("");
249
+ console.log(chalk.bold("Available Templates:"));
250
+ console.log("");
251
+ const templatesDir = join(__dirname, "templates");
252
+ const availableTemplates = getAvailableTemplates();
253
+ if (availableTemplates.length === 0) {
254
+ console.log(chalk.red("\u274C No templates found!"));
255
+ return;
256
+ }
257
+ for (const template of availableTemplates) {
258
+ const packageJsonPath = join(templatesDir, template, "package.json");
259
+ let description = "MCP server template";
260
+ if (existsSync(packageJsonPath)) {
261
+ try {
262
+ const packageJson2 = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
263
+ description = packageJson2.description || description;
264
+ } catch (error) {
265
+ }
266
+ }
267
+ console.log(chalk.cyan(` ${template.padEnd(15)}`), chalk.gray(description));
268
+ }
269
+ console.log("");
270
+ console.log(chalk.gray("\u{1F4A1} Use with: npx create-mcp-use-app my-project --template <template>"));
271
+ console.log("");
272
+ }
273
+ program.name("create-mcp-use-app").description("Create a new MCP server project").version(packageJson.version).argument("[project-name]", "Name of the MCP server project").option("-t, --template <template>", "Template to use (starter, mcp-ui, apps-sdk)", "starter").option("--list-templates", "List all available templates").option("--install", "Install dependencies after creating project").option("--no-git", "Skip initializing a git repository").option("--dev", "Use workspace dependencies for development").option("--canary", "Use canary versions of packages").option("--yarn", "Use yarn as package manager").option("--npm", "Use npm as package manager").option("--pnpm", "Use pnpm as package manager").action(
235
274
  async (projectName, options) => {
236
275
  try {
276
+ if (options.listTemplates) {
277
+ listTemplates();
278
+ process.exit(0);
279
+ }
237
280
  let selectedTemplate = options.template;
238
281
  if (!projectName) {
239
282
  console.log("");
@@ -581,58 +624,94 @@ function updatePackageJson(projectPath, projectName) {
581
624
  packageJsonContent.description = `MCP server: ${projectName}`;
582
625
  writeFileSync(packageJsonPath, JSON.stringify(packageJsonContent, null, 2));
583
626
  }
584
- async function promptForProjectName() {
585
- const { projectName } = await inquirer.prompt([
627
+ function ProjectNameInput({ onSubmit }) {
628
+ const [value, setValue] = useState("");
629
+ const [error, setError] = useState("");
630
+ const handleSubmit = (val) => {
631
+ const trimmed = val.trim();
632
+ if (!trimmed) {
633
+ setError("Project name is required");
634
+ return;
635
+ }
636
+ if (!/^[a-zA-Z0-9-_]+$/.test(trimmed)) {
637
+ setError("Project name can only contain letters, numbers, hyphens, and underscores");
638
+ return;
639
+ }
640
+ if (existsSync(join(process.cwd(), trimmed))) {
641
+ setError(`Directory "${trimmed}" already exists! Please choose a different name.`);
642
+ return;
643
+ }
644
+ onSubmit(trimmed);
645
+ };
646
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "What is your project name?")), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "cyan" }, "\u276F "), /* @__PURE__ */ React.createElement(
647
+ TextInput,
586
648
  {
587
- type: "input",
588
- name: "projectName",
589
- message: "What is your project name?",
590
- validate: (input) => {
591
- const trimmed = input.trim();
592
- if (!trimmed) {
593
- return "Project name is required";
594
- }
595
- if (!/^[a-zA-Z0-9-_]+$/.test(trimmed)) {
596
- return "Project name can only contain letters, numbers, hyphens, and underscores";
597
- }
598
- if (existsSync(join(process.cwd(), trimmed))) {
599
- return `Directory "${trimmed}" already exists! Please choose a different name.`;
600
- }
601
- return true;
602
- }
649
+ value,
650
+ onChange: setValue,
651
+ onSubmit: handleSubmit
603
652
  }
604
- ]);
605
- return projectName;
653
+ )), error && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "red" }, "\u2716 ", error)));
606
654
  }
607
- async function promptForTemplate() {
655
+ async function promptForProjectName() {
656
+ return new Promise((resolve2) => {
657
+ const { unmount } = render(
658
+ /* @__PURE__ */ React.createElement(
659
+ ProjectNameInput,
660
+ {
661
+ onSubmit: (name) => {
662
+ unmount();
663
+ resolve2(name);
664
+ }
665
+ }
666
+ )
667
+ );
668
+ });
669
+ }
670
+ function TemplateSelector({ onSelect }) {
608
671
  const templatesDir = join(__dirname, "templates");
672
+ if (!existsSync(templatesDir)) {
673
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: "red" }, "\u274C Templates directory not found at: ", templatesDir), /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, " __dirname: ", __dirname));
674
+ }
609
675
  const availableTemplates = readdirSync(templatesDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name).sort();
610
- const templateDescriptions = {};
611
- for (const template2 of availableTemplates) {
612
- const packageJsonPath = join(templatesDir, template2, "package.json");
676
+ if (availableTemplates.length === 0) {
677
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: "red" }, "\u274C No templates found in: ", templatesDir));
678
+ }
679
+ const items = availableTemplates.map((template) => {
680
+ const packageJsonPath = join(templatesDir, template, "package.json");
681
+ let description = "MCP server template";
613
682
  if (existsSync(packageJsonPath)) {
614
683
  try {
615
684
  const packageJson2 = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
616
- templateDescriptions[template2] = packageJson2.description || "MCP server template";
685
+ description = packageJson2.description || description;
617
686
  } catch (error) {
618
- templateDescriptions[template2] = "MCP server template";
619
687
  }
620
- } else {
621
- templateDescriptions[template2] = "MCP server template";
622
688
  }
623
- }
624
- const { template } = await inquirer.prompt([
689
+ return {
690
+ label: `${template} - ${description}`,
691
+ value: template
692
+ };
693
+ });
694
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Select a template:")), /* @__PURE__ */ React.createElement(
695
+ SelectInput,
625
696
  {
626
- type: "list",
627
- name: "template",
628
- message: "Select a template:",
629
- default: "starter",
630
- choices: availableTemplates.map((template2) => ({
631
- name: `${template2} - ${templateDescriptions[template2] || "MCP server template"}`,
632
- value: template2
633
- }))
697
+ items,
698
+ onSelect: (item) => onSelect(item.value)
634
699
  }
635
- ]);
636
- return template;
700
+ ));
701
+ }
702
+ async function promptForTemplate() {
703
+ return new Promise((resolve2) => {
704
+ const { unmount } = render(
705
+ /* @__PURE__ */ React.createElement(
706
+ TemplateSelector,
707
+ {
708
+ onSelect: (template) => {
709
+ unmount();
710
+ resolve2(template);
711
+ }
712
+ }
713
+ )
714
+ );
715
+ });
637
716
  }
638
717
  program.parse();
@@ -27,12 +27,15 @@
27
27
  "deploy": "mcp-use deploy"
28
28
  },
29
29
  "dependencies": {
30
+ "@openai/apps-sdk-ui": "^0.2.0",
31
+ "@tanstack/react-query": "^5.90.11",
30
32
  "cors": "^2.8.5",
31
33
  "express": "^5.2.0",
32
34
  "mcp-use": "workspace:*",
33
35
  "node-mocks-http": "^1.17.2",
34
36
  "react": "^19.2.0",
35
37
  "react-dom": "^19.2.0",
38
+ "react-router": "^7.9.6",
36
39
  "react-router-dom": "^7.9.6",
37
40
  "tailwindcss": "^4.1.17",
38
41
  "zod": "^4.1.13"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mcp-use-app",
3
- "version": "0.7.4-canary.0",
3
+ "version": "0.7.4",
4
4
  "type": "module",
5
5
  "description": "Create MCP-Use apps with one command",
6
6
  "author": "mcp-use, Inc.",
@@ -39,13 +39,16 @@
39
39
  "chalk": "^5.6.2",
40
40
  "commander": "^14.0.2",
41
41
  "fs-extra": "^11.3.2",
42
- "inquirer": "^13.0.1",
43
- "ora": "^9.0.0"
42
+ "ink": "^6.5.1",
43
+ "ink-select-input": "^6.2.0",
44
+ "ink-text-input": "^6.0.0",
45
+ "ora": "^9.0.0",
46
+ "react": "^19.2.0"
44
47
  },
45
48
  "devDependencies": {
46
49
  "@types/fs-extra": "^11.0.4",
47
- "@types/inquirer": "^9.0.9",
48
50
  "@types/node": "^24.10.1",
51
+ "@types/react": "^19.2.7",
49
52
  "typescript": "^5.9.3",
50
53
  "vitest": "^4.0.14"
51
54
  },
@@ -53,7 +56,7 @@
53
56
  "access": "public"
54
57
  },
55
58
  "scripts": {
56
- "build": "npm run clean && tsup src/index.ts --format esm && tsc --emitDeclarationOnly --declaration && npm run copy-templates",
59
+ "build": "npm run clean && tsup src/index.tsx --format esm && tsc --emitDeclarationOnly --declaration && npm run copy-templates",
57
60
  "clean": "rm -rf dist tsconfig.tsbuildinfo",
58
61
  "copy-templates": "node scripts/copy-templates.js",
59
62
  "dev": "tsc --build --watch",