mcp-new 1.2.1 → 1.2.2

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.
package/README.md CHANGED
@@ -124,6 +124,18 @@ mcp-new init
124
124
 
125
125
  # Add a new tool to existing project
126
126
  mcp-new add-tool
127
+
128
+ # List all available presets
129
+ mcp-new list-presets
130
+
131
+ # Validate current MCP server project
132
+ mcp-new validate
133
+
134
+ # Upgrade MCP SDK to latest version
135
+ mcp-new upgrade
136
+
137
+ # Check for updates without installing
138
+ mcp-new upgrade --check
127
139
  ```
128
140
 
129
141
  ---
@@ -151,6 +163,9 @@ Options:
151
163
  Commands:
152
164
  init Initialize in current directory
153
165
  add-tool Add tool to existing project
166
+ list-presets List all available preset templates
167
+ validate Validate current MCP server project
168
+ upgrade Upgrade MCP SDK to latest version
154
169
  ```
155
170
 
156
171
  ### Generated Project Structure
@@ -2219,6 +2219,7 @@ export {
2219
2219
  promptResourceConfig,
2220
2220
  promptMultipleResources,
2221
2221
  promptGenerationMethod,
2222
+ PRESETS,
2222
2223
  promptPreset,
2223
2224
  runWizard,
2224
2225
  runQuickWizard,
package/dist/cli.js CHANGED
@@ -1,84 +1,531 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ PRESETS,
3
4
  addToolCommand,
4
5
  createCommand,
5
- initCommand
6
- } from "./chunk-BHGUGEHE.js";
6
+ createSpinner,
7
+ initCommand,
8
+ logger
9
+ } from "./chunk-3JG4FVS2.js";
7
10
 
8
11
  // src/cli.ts
9
12
  import { Command } from "commander";
13
+ import chalk4 from "chalk";
14
+
15
+ // src/commands/list-presets.ts
10
16
  import chalk from "chalk";
17
+ async function listPresetsCommand() {
18
+ console.log();
19
+ console.log(chalk.bold.white("Available Presets"));
20
+ console.log(chalk.gray("\u2500".repeat(60)));
21
+ console.log();
22
+ for (const [id, preset] of Object.entries(PRESETS)) {
23
+ console.log(chalk.yellow.bold(` ${id}`));
24
+ console.log(chalk.gray(` ${preset.description}`));
25
+ console.log();
26
+ console.log(chalk.white(" Tools:"));
27
+ for (const tool of preset.tools) {
28
+ const paramCount = tool.parameters.length;
29
+ const paramText = paramCount === 0 ? chalk.gray("no params") : chalk.gray(`${paramCount} param${paramCount > 1 ? "s" : ""}`);
30
+ console.log(` ${chalk.cyan("\u2022")} ${chalk.white(tool.name)} ${paramText}`);
31
+ console.log(` ${chalk.gray(tool.description)}`);
32
+ }
33
+ console.log();
34
+ console.log(chalk.gray(" " + "\u2500".repeat(56)));
35
+ console.log();
36
+ }
37
+ console.log(chalk.bold.white("Usage:"));
38
+ console.log();
39
+ console.log(chalk.gray(" $"), chalk.cyan("mcp-new my-project --preset database"));
40
+ console.log(chalk.gray(" $"), chalk.cyan("mcp-new my-api --preset rest-api -t"));
41
+ console.log(chalk.gray(" $"), chalk.cyan("mcp-new my-fs --preset filesystem -p"));
42
+ console.log();
43
+ }
44
+
45
+ // src/commands/validate.ts
46
+ import path from "path";
47
+ import fs from "fs-extra";
48
+ import chalk2 from "chalk";
49
+ async function validateCommand() {
50
+ const currentDir = process.cwd();
51
+ logger.title("Validating MCP Server");
52
+ const result = await validateProject(currentDir);
53
+ console.log();
54
+ if (result.language) {
55
+ console.log(chalk2.blue("i"), `Detected language: ${chalk2.cyan(result.language)}`);
56
+ }
57
+ for (const info of result.info) {
58
+ console.log(chalk2.blue("i"), info);
59
+ }
60
+ for (const warning of result.warnings) {
61
+ console.log(chalk2.yellow("\u26A0"), warning);
62
+ }
63
+ for (const error of result.errors) {
64
+ console.log(chalk2.red("\u2717"), error);
65
+ }
66
+ console.log();
67
+ if (result.valid) {
68
+ logger.success("MCP server is valid!");
69
+ } else {
70
+ logger.error("Validation failed. Please fix the issues above.");
71
+ process.exit(1);
72
+ }
73
+ }
74
+ async function validateProject(projectDir) {
75
+ const result = {
76
+ valid: true,
77
+ language: null,
78
+ errors: [],
79
+ warnings: [],
80
+ info: []
81
+ };
82
+ const hasPackageJson = await fs.pathExists(path.join(projectDir, "package.json"));
83
+ const hasPyproject = await fs.pathExists(path.join(projectDir, "pyproject.toml"));
84
+ const hasGoMod = await fs.pathExists(path.join(projectDir, "go.mod"));
85
+ const hasCargoToml = await fs.pathExists(path.join(projectDir, "Cargo.toml"));
86
+ if (!hasPackageJson && !hasPyproject && !hasGoMod && !hasCargoToml) {
87
+ result.errors.push("No project configuration found (package.json, pyproject.toml, go.mod, or Cargo.toml)");
88
+ result.valid = false;
89
+ return result;
90
+ }
91
+ if (hasPackageJson) {
92
+ result.language = "typescript";
93
+ await validateTypeScriptProject(projectDir, result);
94
+ }
95
+ if (hasPyproject) {
96
+ result.language = "python";
97
+ await validatePythonProject(projectDir, result);
98
+ }
99
+ if (hasGoMod) {
100
+ result.language = "go";
101
+ await validateGoProject(projectDir, result);
102
+ }
103
+ if (hasCargoToml) {
104
+ result.language = "rust";
105
+ await validateRustProject(projectDir, result);
106
+ }
107
+ return result;
108
+ }
109
+ async function validateTypeScriptProject(projectDir, result) {
110
+ try {
111
+ const packageJsonPath = path.join(projectDir, "package.json");
112
+ const packageJson = await fs.readJson(packageJsonPath);
113
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
114
+ if (deps["@modelcontextprotocol/sdk"]) {
115
+ result.info.push(`MCP SDK version: ${chalk2.green(deps["@modelcontextprotocol/sdk"])}`);
116
+ } else {
117
+ result.errors.push("Missing @modelcontextprotocol/sdk dependency");
118
+ result.valid = false;
119
+ }
120
+ const srcIndex = path.join(projectDir, "src", "index.ts");
121
+ const srcIndexJs = path.join(projectDir, "src", "index.js");
122
+ const distIndex = path.join(projectDir, "dist", "index.js");
123
+ if (await fs.pathExists(srcIndex)) {
124
+ result.info.push("Entry point: src/index.ts");
125
+ await validateTypeScriptEntryPoint(srcIndex, result);
126
+ } else if (await fs.pathExists(srcIndexJs)) {
127
+ result.info.push("Entry point: src/index.js");
128
+ } else if (await fs.pathExists(distIndex)) {
129
+ result.info.push("Entry point: dist/index.js (built)");
130
+ } else {
131
+ result.warnings.push("No entry point found (expected src/index.ts or src/index.js)");
132
+ }
133
+ if (await fs.pathExists(path.join(projectDir, "tsconfig.json"))) {
134
+ result.info.push("TypeScript config: tsconfig.json");
135
+ } else {
136
+ result.warnings.push("No tsconfig.json found");
137
+ }
138
+ if (packageJson.scripts?.build) {
139
+ result.info.push(`Build script: ${chalk2.gray(packageJson.scripts.build)}`);
140
+ } else {
141
+ result.warnings.push("No build script found in package.json");
142
+ }
143
+ } catch (error) {
144
+ result.errors.push("Failed to parse package.json");
145
+ result.valid = false;
146
+ }
147
+ }
148
+ async function validateTypeScriptEntryPoint(filePath, result) {
149
+ try {
150
+ const content = await fs.readFile(filePath, "utf-8");
151
+ if (content.includes("@modelcontextprotocol/sdk")) {
152
+ result.info.push("MCP SDK import found");
153
+ } else {
154
+ result.warnings.push("No MCP SDK import found in entry point");
155
+ }
156
+ if (content.includes("McpServer") || content.includes("Server")) {
157
+ result.info.push("MCP Server class usage found");
158
+ } else {
159
+ result.warnings.push("No MCP Server class found");
160
+ }
161
+ const toolMatches = content.match(/\.tool\s*\(/g) || content.match(/setRequestHandler.*CallToolRequest/g);
162
+ if (toolMatches) {
163
+ result.info.push(`Tools defined: ${chalk2.green(toolMatches.length)}`);
164
+ }
165
+ } catch {
166
+ result.warnings.push("Could not analyze entry point file");
167
+ }
168
+ }
169
+ async function validatePythonProject(projectDir, result) {
170
+ try {
171
+ const pyprojectPath = path.join(projectDir, "pyproject.toml");
172
+ const content = await fs.readFile(pyprojectPath, "utf-8");
173
+ if (content.includes("mcp") || content.includes("modelcontextprotocol")) {
174
+ result.info.push("MCP dependency found in pyproject.toml");
175
+ } else {
176
+ const requirementsPath = path.join(projectDir, "requirements.txt");
177
+ if (await fs.pathExists(requirementsPath)) {
178
+ const requirements = await fs.readFile(requirementsPath, "utf-8");
179
+ if (requirements.includes("mcp")) {
180
+ result.info.push("MCP dependency found in requirements.txt");
181
+ } else {
182
+ result.errors.push("Missing MCP dependency");
183
+ result.valid = false;
184
+ }
185
+ } else {
186
+ result.warnings.push("No requirements.txt found");
187
+ }
188
+ }
189
+ const serverPath = path.join(projectDir, "src", "server.py");
190
+ if (await fs.pathExists(serverPath)) {
191
+ result.info.push("Server file: src/server.py");
192
+ } else {
193
+ result.warnings.push("No server.py found in src/");
194
+ }
195
+ } catch (error) {
196
+ result.errors.push("Failed to parse pyproject.toml");
197
+ result.valid = false;
198
+ }
199
+ }
200
+ async function validateGoProject(projectDir, result) {
201
+ try {
202
+ const goModPath = path.join(projectDir, "go.mod");
203
+ const content = await fs.readFile(goModPath, "utf-8");
204
+ if (content.includes("mcp-go") || content.includes("modelcontextprotocol")) {
205
+ result.info.push("MCP Go SDK found in go.mod");
206
+ } else {
207
+ result.errors.push("Missing MCP Go SDK dependency");
208
+ result.valid = false;
209
+ }
210
+ const mainPath = path.join(projectDir, "cmd", "server", "main.go");
211
+ const altMainPath = path.join(projectDir, "main.go");
212
+ if (await fs.pathExists(mainPath)) {
213
+ result.info.push("Entry point: cmd/server/main.go");
214
+ } else if (await fs.pathExists(altMainPath)) {
215
+ result.info.push("Entry point: main.go");
216
+ } else {
217
+ result.warnings.push("No main.go found");
218
+ }
219
+ } catch (error) {
220
+ result.errors.push("Failed to parse go.mod");
221
+ result.valid = false;
222
+ }
223
+ }
224
+ async function validateRustProject(projectDir, result) {
225
+ try {
226
+ const cargoPath = path.join(projectDir, "Cargo.toml");
227
+ const content = await fs.readFile(cargoPath, "utf-8");
228
+ if (content.includes("rmcp") || content.includes("mcp")) {
229
+ result.info.push("MCP Rust SDK found in Cargo.toml");
230
+ } else {
231
+ result.errors.push("Missing MCP Rust SDK dependency");
232
+ result.valid = false;
233
+ }
234
+ const mainPath = path.join(projectDir, "src", "main.rs");
235
+ if (await fs.pathExists(mainPath)) {
236
+ result.info.push("Entry point: src/main.rs");
237
+ } else {
238
+ result.warnings.push("No main.rs found");
239
+ }
240
+ } catch (error) {
241
+ result.errors.push("Failed to parse Cargo.toml");
242
+ result.valid = false;
243
+ }
244
+ }
245
+
246
+ // src/commands/upgrade.ts
247
+ import path2 from "path";
248
+ import fs2 from "fs-extra";
249
+ import chalk3 from "chalk";
250
+ import { execa } from "execa";
251
+ async function upgradeCommand(options) {
252
+ const currentDir = process.cwd();
253
+ logger.title("MCP SDK Upgrade");
254
+ const hasPackageJson = await fs2.pathExists(path2.join(currentDir, "package.json"));
255
+ const hasPyproject = await fs2.pathExists(path2.join(currentDir, "pyproject.toml"));
256
+ const hasGoMod = await fs2.pathExists(path2.join(currentDir, "go.mod"));
257
+ const hasCargoToml = await fs2.pathExists(path2.join(currentDir, "Cargo.toml"));
258
+ if (!hasPackageJson && !hasPyproject && !hasGoMod && !hasCargoToml) {
259
+ logger.error("No project configuration found.");
260
+ logger.info("Run this command from the root of your MCP server project.");
261
+ process.exit(1);
262
+ }
263
+ let info = null;
264
+ if (hasPackageJson) {
265
+ info = await checkNodePackage(currentDir);
266
+ } else if (hasPyproject) {
267
+ info = await checkPythonPackage(currentDir);
268
+ } else if (hasGoMod) {
269
+ info = await checkGoPackage(currentDir);
270
+ } else if (hasCargoToml) {
271
+ info = await checkRustPackage(currentDir);
272
+ }
273
+ if (!info) {
274
+ logger.error("Could not detect MCP SDK version.");
275
+ process.exit(1);
276
+ }
277
+ console.log();
278
+ console.log(chalk3.blue("i"), `Package: ${chalk3.cyan(info.packageName)}`);
279
+ console.log(chalk3.blue("i"), `Current version: ${info.current ? chalk3.yellow(info.current) : chalk3.gray("not installed")}`);
280
+ console.log(chalk3.blue("i"), `Latest version: ${info.latest ? chalk3.green(info.latest) : chalk3.gray("unknown")}`);
281
+ console.log();
282
+ if (options.check) {
283
+ if (info.current === info.latest) {
284
+ logger.success("Already up to date!");
285
+ } else if (info.latest) {
286
+ logger.info(`Update available: ${info.current} \u2192 ${info.latest}`);
287
+ logger.code(`mcp-new upgrade`);
288
+ }
289
+ return;
290
+ }
291
+ if (info.current === info.latest) {
292
+ logger.success("Already up to date!");
293
+ return;
294
+ }
295
+ if (!info.latest) {
296
+ logger.error("Could not fetch latest version.");
297
+ process.exit(1);
298
+ }
299
+ const spinner = createSpinner(`Upgrading ${info.packageName}...`);
300
+ spinner.start();
301
+ try {
302
+ if (hasPackageJson) {
303
+ await upgradeNodePackage(currentDir, info);
304
+ } else if (hasPyproject) {
305
+ await upgradePythonPackage(currentDir, info);
306
+ } else if (hasGoMod) {
307
+ await upgradeGoPackage(currentDir, info);
308
+ } else if (hasCargoToml) {
309
+ await upgradeRustPackage(currentDir, info);
310
+ }
311
+ spinner.succeed(`Upgraded to ${info.packageName}@${info.latest}`);
312
+ logger.blank();
313
+ logger.success("MCP SDK upgraded successfully!");
314
+ } catch (error) {
315
+ spinner.fail("Upgrade failed");
316
+ if (error instanceof Error) {
317
+ logger.error(error.message);
318
+ }
319
+ process.exit(1);
320
+ }
321
+ }
322
+ async function checkNodePackage(projectDir) {
323
+ const packageName = "@modelcontextprotocol/sdk";
324
+ let current = null;
325
+ let latest = null;
326
+ try {
327
+ const packageJson = await fs2.readJson(path2.join(projectDir, "package.json"));
328
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
329
+ current = deps[packageName]?.replace(/[\^~]/, "") || null;
330
+ } catch {
331
+ }
332
+ try {
333
+ const { stdout } = await execa("npm", ["view", packageName, "version"]);
334
+ latest = stdout.trim();
335
+ } catch {
336
+ }
337
+ return { current, latest, packageManager: "npm", packageName };
338
+ }
339
+ async function upgradeNodePackage(projectDir, info) {
340
+ const packageJsonPath = path2.join(projectDir, "package.json");
341
+ const packageJson = await fs2.readJson(packageJsonPath);
342
+ if (packageJson.dependencies?.[info.packageName]) {
343
+ packageJson.dependencies[info.packageName] = `^${info.latest}`;
344
+ } else if (packageJson.devDependencies?.[info.packageName]) {
345
+ packageJson.devDependencies[info.packageName] = `^${info.latest}`;
346
+ }
347
+ await fs2.writeJson(packageJsonPath, packageJson, { spaces: 2 });
348
+ await execa("npm", ["install"], { cwd: projectDir });
349
+ }
350
+ async function checkPythonPackage(projectDir) {
351
+ const packageName = "mcp";
352
+ let current = null;
353
+ let latest = null;
354
+ try {
355
+ const { stdout } = await execa("pip", ["show", packageName]);
356
+ const versionMatch = stdout.match(/Version:\s*(\S+)/);
357
+ current = versionMatch?.[1] || null;
358
+ } catch {
359
+ }
360
+ try {
361
+ const { stdout } = await execa("pip", ["index", "versions", packageName]);
362
+ const match = stdout.match(/Available versions:\s*([^\s,]+)/);
363
+ latest = match?.[1] || null;
364
+ } catch {
365
+ try {
366
+ const { stdout } = await execa("pip", ["install", `${packageName}==`, "--dry-run"], { reject: false });
367
+ const match = stdout.match(/from versions:\s*([^)]+)\)/);
368
+ if (match) {
369
+ const versions = match[1].split(",").map((v) => v.trim());
370
+ latest = versions[versions.length - 1] || null;
371
+ }
372
+ } catch {
373
+ }
374
+ }
375
+ return { current, latest, packageManager: "pip", packageName };
376
+ }
377
+ async function upgradePythonPackage(_projectDir, info) {
378
+ await execa("pip", ["install", "--upgrade", info.packageName]);
379
+ }
380
+ async function checkGoPackage(projectDir) {
381
+ const packageName = "github.com/mark3labs/mcp-go";
382
+ let current = null;
383
+ let latest = null;
384
+ try {
385
+ const goModContent = await fs2.readFile(path2.join(projectDir, "go.mod"), "utf-8");
386
+ const match = goModContent.match(new RegExp(`${packageName.replace(/\//g, "\\/")}\\s+v([\\d.]+)`));
387
+ current = match?.[1] || null;
388
+ } catch {
389
+ }
390
+ try {
391
+ const { stdout } = await execa("go", ["list", "-m", "-versions", packageName]);
392
+ const versions = stdout.split(" ").slice(1);
393
+ latest = versions[versions.length - 1]?.replace("v", "") || null;
394
+ } catch {
395
+ }
396
+ return { current, latest, packageManager: "go", packageName };
397
+ }
398
+ async function upgradeGoPackage(projectDir, info) {
399
+ await execa("go", ["get", "-u", `${info.packageName}@latest`], { cwd: projectDir });
400
+ await execa("go", ["mod", "tidy"], { cwd: projectDir });
401
+ }
402
+ async function checkRustPackage(projectDir) {
403
+ const packageName = "rmcp";
404
+ let current = null;
405
+ let latest = null;
406
+ try {
407
+ const cargoContent = await fs2.readFile(path2.join(projectDir, "Cargo.toml"), "utf-8");
408
+ const match = cargoContent.match(/rmcp\s*=\s*["']([^"']+)["']/);
409
+ current = match?.[1] || null;
410
+ } catch {
411
+ }
412
+ try {
413
+ const { stdout } = await execa("cargo", ["search", packageName, "--limit", "1"]);
414
+ const match = stdout.match(/rmcp\s*=\s*"([^"]+)"/);
415
+ latest = match?.[1] || null;
416
+ } catch {
417
+ }
418
+ return { current, latest, packageManager: "cargo", packageName };
419
+ }
420
+ async function upgradeRustPackage(projectDir, info) {
421
+ await execa("cargo", ["update", "-p", info.packageName], { cwd: projectDir });
422
+ }
423
+
424
+ // src/cli.ts
11
425
  var program = new Command();
12
426
  var logo = `
13
- ${chalk.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")}
14
- ${chalk.cyan("\u2551")} ${chalk.bold.white("mcp-new")} ${chalk.cyan("\u2551")}
15
- ${chalk.cyan("\u2551")} ${chalk.gray("Generate MCP servers in seconds")} ${chalk.cyan("\u2551")}
16
- ${chalk.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")}
427
+ ${chalk4.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")}
428
+ ${chalk4.cyan("\u2551")} ${chalk4.bold.white("mcp-new")} ${chalk4.cyan("\u2551")}
429
+ ${chalk4.cyan("\u2551")} ${chalk4.gray("Generate MCP servers in seconds")} ${chalk4.cyan("\u2551")}
430
+ ${chalk4.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")}
17
431
  `;
18
432
  var examples = `
19
- ${chalk.bold("Examples:")}
433
+ ${chalk4.bold("Examples:")}
20
434
 
21
- ${chalk.gray("# Create a new MCP server with interactive wizard")}
22
- ${chalk.cyan("$")} mcp-new my-server
435
+ ${chalk4.gray("# Create a new MCP server with interactive wizard")}
436
+ ${chalk4.cyan("$")} mcp-new my-server
23
437
 
24
- ${chalk.gray("# Create TypeScript server with defaults")}
25
- ${chalk.cyan("$")} mcp-new my-server -t -y
438
+ ${chalk4.gray("# Create TypeScript server with defaults")}
439
+ ${chalk4.cyan("$")} mcp-new my-server -t -y
26
440
 
27
- ${chalk.gray("# Create Python server")}
28
- ${chalk.cyan("$")} mcp-new my-server -p
441
+ ${chalk4.gray("# Create Python server")}
442
+ ${chalk4.cyan("$")} mcp-new my-server -p
29
443
 
30
- ${chalk.gray("# Create from preset template")}
31
- ${chalk.cyan("$")} mcp-new my-db --preset database
32
- ${chalk.cyan("$")} mcp-new my-api --preset rest-api
33
- ${chalk.cyan("$")} mcp-new my-fs --preset filesystem
444
+ ${chalk4.gray("# Create from preset template")}
445
+ ${chalk4.cyan("$")} mcp-new my-db --preset database
446
+ ${chalk4.cyan("$")} mcp-new my-api --preset rest-api
447
+ ${chalk4.cyan("$")} mcp-new my-fs --preset filesystem
34
448
 
35
- ${chalk.gray("# Create from OpenAPI specification")}
36
- ${chalk.cyan("$")} mcp-new my-api --from-openapi ./openapi.yaml
449
+ ${chalk4.gray("# Create from OpenAPI specification")}
450
+ ${chalk4.cyan("$")} mcp-new my-api --from-openapi ./openapi.yaml
37
451
 
38
- ${chalk.gray("# Create using AI (requires ANTHROPIC_API_KEY)")}
39
- ${chalk.cyan("$")} mcp-new my-server --from-prompt
452
+ ${chalk4.gray("# Create using AI (requires ANTHROPIC_API_KEY)")}
453
+ ${chalk4.cyan("$")} mcp-new my-server --from-prompt
40
454
 
41
- ${chalk.bold("Available Presets:")}
455
+ ${chalk4.bold("Available Presets:")}
42
456
 
43
- ${chalk.yellow("database")} Database CRUD tools (query, insert, update, delete, list_tables)
44
- ${chalk.yellow("rest-api")} REST API tools (http_get, http_post, http_put, http_delete, set_base_url)
45
- ${chalk.yellow("filesystem")} File system tools (read_file, write_file, list_directory, search_files, file_info)
457
+ ${chalk4.yellow("database")} Database CRUD tools (query, insert, update, delete, list_tables)
458
+ ${chalk4.yellow("rest-api")} REST API tools (http_get, http_post, http_put, http_delete, set_base_url)
459
+ ${chalk4.yellow("filesystem")} File system tools (read_file, write_file, list_directory, search_files, file_info)
46
460
 
47
- ${chalk.bold("Supported Languages:")}
461
+ ${chalk4.bold("Supported Languages:")}
48
462
 
49
- ${chalk.green("-t, --typescript")} TypeScript with npm
50
- ${chalk.green("-p, --python")} Python with pip
51
- ${chalk.green("-g, --go")} Go with go modules
52
- ${chalk.green("-r, --rust")} Rust with cargo
463
+ ${chalk4.green("-t, --typescript")} TypeScript with npm
464
+ ${chalk4.green("-p, --python")} Python with pip
465
+ ${chalk4.green("-g, --go")} Go with go modules
466
+ ${chalk4.green("-r, --rust")} Rust with cargo
53
467
 
54
- ${chalk.bold("Learn More:")}
468
+ ${chalk4.bold("Learn More:")}
55
469
 
56
- Documentation: ${chalk.underline("https://github.com/d1maash/mcp-new")}
57
- MCP Spec: ${chalk.underline("https://spec.modelcontextprotocol.io")}
470
+ Documentation: ${chalk4.underline("https://github.com/d1maash/mcp-new")}
471
+ MCP Spec: ${chalk4.underline("https://spec.modelcontextprotocol.io")}
58
472
  `;
59
- program.name("mcp-new").description("CLI tool for generating MCP (Model Context Protocol) servers").version("1.2.1").addHelpText("beforeAll", logo).addHelpText("after", examples);
473
+ program.name("mcp-new").description("CLI tool for generating MCP (Model Context Protocol) servers").version("1.2.2").addHelpText("beforeAll", logo).addHelpText("after", examples);
60
474
  program.argument("[project-name]", "Name of the project to create").option("-t, --typescript", "Use TypeScript template").option("-p, --python", "Use Python template").option("-g, --go", "Use Go template").option("-r, --rust", "Use Rust template").option("--skip-install", "Skip dependency installation").option("--from-openapi <path>", "Generate from OpenAPI/Swagger specification").option("--from-prompt", "Generate tools using AI from text description").option("--preset <name>", "Use a preset template (database, rest-api, filesystem)").option("-y, --yes", "Skip prompts and use defaults").action(createCommand);
61
475
  program.command("init").description("Initialize MCP server in the current directory").option("-t, --typescript", "Use TypeScript template").option("-p, --python", "Use Python template").option("-g, --go", "Use Go template").option("-r, --rust", "Use Rust template").option("--skip-install", "Skip dependency installation").option("-f, --force", "Initialize even if directory contains files").addHelpText("after", `
62
- ${chalk.bold("Examples:")}
476
+ ${chalk4.bold("Examples:")}
63
477
 
64
- ${chalk.gray("# Initialize in current directory")}
65
- ${chalk.cyan("$")} mcp-new init
478
+ ${chalk4.gray("# Initialize in current directory")}
479
+ ${chalk4.cyan("$")} mcp-new init
66
480
 
67
- ${chalk.gray("# Initialize with TypeScript")}
68
- ${chalk.cyan("$")} mcp-new init -t
481
+ ${chalk4.gray("# Initialize with TypeScript")}
482
+ ${chalk4.cyan("$")} mcp-new init -t
69
483
 
70
- ${chalk.gray("# Force initialize (overwrite existing files)")}
71
- ${chalk.cyan("$")} mcp-new init -f
484
+ ${chalk4.gray("# Force initialize (overwrite existing files)")}
485
+ ${chalk4.cyan("$")} mcp-new init -f
72
486
  `).action(initCommand);
73
487
  program.command("add-tool").description("Add a new tool to an existing MCP server").option("-n, --name <name>", "Tool name (snake_case)").addHelpText("after", `
74
- ${chalk.bold("Examples:")}
488
+ ${chalk4.bold("Examples:")}
75
489
 
76
- ${chalk.gray("# Add tool interactively")}
77
- ${chalk.cyan("$")} mcp-new add-tool
490
+ ${chalk4.gray("# Add tool interactively")}
491
+ ${chalk4.cyan("$")} mcp-new add-tool
78
492
 
79
- ${chalk.gray("# Add tool with name")}
80
- ${chalk.cyan("$")} mcp-new add-tool -n my_new_tool
493
+ ${chalk4.gray("# Add tool with name")}
494
+ ${chalk4.cyan("$")} mcp-new add-tool -n my_new_tool
81
495
  `).action(addToolCommand);
496
+ program.command("list-presets").description("List all available preset templates").addHelpText("after", `
497
+ ${chalk4.bold("Examples:")}
498
+
499
+ ${chalk4.gray("# Show all presets with their tools")}
500
+ ${chalk4.cyan("$")} mcp-new list-presets
501
+ `).action(listPresetsCommand);
502
+ program.command("validate").description("Validate the current MCP server project").addHelpText("after", `
503
+ ${chalk4.bold("Examples:")}
504
+
505
+ ${chalk4.gray("# Validate current project")}
506
+ ${chalk4.cyan("$")} mcp-new validate
507
+
508
+ ${chalk4.bold("Checks:")}
509
+ \u2022 Project configuration (package.json, pyproject.toml, etc.)
510
+ \u2022 MCP SDK dependency presence and version
511
+ \u2022 Entry point file existence
512
+ \u2022 Basic project structure
513
+ `).action(validateCommand);
514
+ program.command("upgrade").description("Upgrade MCP SDK to the latest version").option("-c, --check", "Check for updates without installing").addHelpText("after", `
515
+ ${chalk4.bold("Examples:")}
516
+
517
+ ${chalk4.gray("# Upgrade MCP SDK to latest version")}
518
+ ${chalk4.cyan("$")} mcp-new upgrade
519
+
520
+ ${chalk4.gray("# Check for updates without installing")}
521
+ ${chalk4.cyan("$")} mcp-new upgrade --check
522
+
523
+ ${chalk4.bold("Supported languages:")}
524
+ \u2022 TypeScript/JavaScript (npm)
525
+ \u2022 Python (pip)
526
+ \u2022 Go (go modules)
527
+ \u2022 Rust (cargo)
528
+ `).action(upgradeCommand);
82
529
  program.parse();
83
530
  if (process.argv.length === 2) {
84
531
  program.help();
package/dist/index.js CHANGED
@@ -60,7 +60,7 @@ import {
60
60
  walkDir,
61
61
  withSpinner,
62
62
  writeFile
63
- } from "./chunk-BHGUGEHE.js";
63
+ } from "./chunk-3JG4FVS2.js";
64
64
 
65
65
  // src/types/config.ts
66
66
  import { z } from "zod";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-new",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "CLI generator for MCP servers. Like create-react-app, but for MCP.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",