mcp-new 1.1.0 → 1.2.1
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 +205 -121
- package/dist/{chunk-K3TOM22I.js → chunk-BHGUGEHE.js} +498 -9
- package/dist/cli.js +66 -6
- package/dist/index.d.ts +26 -1
- package/dist/index.js +13 -1
- package/package.json +2 -2
- package/templates/go/README.md.ejs +67 -4
- package/templates/python/README.md.ejs +58 -15
- package/templates/rust/README.md.ejs +67 -4
- package/templates/typescript/README.md.ejs +56 -15
- /package/bin/{mcp-generator.js → mcp-new.js} +0 -0
|
@@ -314,6 +314,381 @@ async function promptMultipleResources() {
|
|
|
314
314
|
return resources;
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
+
// src/prompts/generation-method.ts
|
|
318
|
+
import inquirer6 from "inquirer";
|
|
319
|
+
async function promptGenerationMethod() {
|
|
320
|
+
const { method } = await inquirer6.prompt([
|
|
321
|
+
{
|
|
322
|
+
type: "list",
|
|
323
|
+
name: "method",
|
|
324
|
+
message: "How would you like to create your MCP server?",
|
|
325
|
+
choices: [
|
|
326
|
+
{
|
|
327
|
+
name: "From scratch (wizard)",
|
|
328
|
+
value: "wizard"
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
name: "From a preset template",
|
|
332
|
+
value: "preset"
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
name: "From OpenAPI/Swagger specification",
|
|
336
|
+
value: "openapi"
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
name: "Using AI (describe your API)",
|
|
340
|
+
value: "prompt"
|
|
341
|
+
}
|
|
342
|
+
],
|
|
343
|
+
default: "wizard"
|
|
344
|
+
}
|
|
345
|
+
]);
|
|
346
|
+
return method;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// src/prompts/preset.ts
|
|
350
|
+
import inquirer7 from "inquirer";
|
|
351
|
+
|
|
352
|
+
// src/presets/database.ts
|
|
353
|
+
var DATABASE_PRESET = {
|
|
354
|
+
id: "database",
|
|
355
|
+
name: "Database CRUD",
|
|
356
|
+
description: "Tools for database operations: query, insert, update, delete",
|
|
357
|
+
tools: [
|
|
358
|
+
{
|
|
359
|
+
name: "query",
|
|
360
|
+
description: "Execute a SQL query on the database",
|
|
361
|
+
parameters: [
|
|
362
|
+
{
|
|
363
|
+
name: "sql",
|
|
364
|
+
type: "string",
|
|
365
|
+
description: "SQL query to execute",
|
|
366
|
+
required: true
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
name: "params",
|
|
370
|
+
type: "array",
|
|
371
|
+
description: "Query parameters for prepared statements",
|
|
372
|
+
required: false
|
|
373
|
+
}
|
|
374
|
+
]
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
name: "insert",
|
|
378
|
+
description: "Insert a new record into a table",
|
|
379
|
+
parameters: [
|
|
380
|
+
{
|
|
381
|
+
name: "table",
|
|
382
|
+
type: "string",
|
|
383
|
+
description: "Table name",
|
|
384
|
+
required: true
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
name: "data",
|
|
388
|
+
type: "object",
|
|
389
|
+
description: "Record data as key-value pairs",
|
|
390
|
+
required: true
|
|
391
|
+
}
|
|
392
|
+
]
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
name: "update",
|
|
396
|
+
description: "Update records in a table",
|
|
397
|
+
parameters: [
|
|
398
|
+
{
|
|
399
|
+
name: "table",
|
|
400
|
+
type: "string",
|
|
401
|
+
description: "Table name",
|
|
402
|
+
required: true
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
name: "data",
|
|
406
|
+
type: "object",
|
|
407
|
+
description: "Fields to update as key-value pairs",
|
|
408
|
+
required: true
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
name: "where",
|
|
412
|
+
type: "object",
|
|
413
|
+
description: "WHERE conditions as key-value pairs",
|
|
414
|
+
required: true
|
|
415
|
+
}
|
|
416
|
+
]
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
name: "delete",
|
|
420
|
+
description: "Delete records from a table",
|
|
421
|
+
parameters: [
|
|
422
|
+
{
|
|
423
|
+
name: "table",
|
|
424
|
+
type: "string",
|
|
425
|
+
description: "Table name",
|
|
426
|
+
required: true
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
name: "where",
|
|
430
|
+
type: "object",
|
|
431
|
+
description: "WHERE conditions as key-value pairs",
|
|
432
|
+
required: true
|
|
433
|
+
}
|
|
434
|
+
]
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
name: "list_tables",
|
|
438
|
+
description: "List all tables in the database",
|
|
439
|
+
parameters: []
|
|
440
|
+
}
|
|
441
|
+
]
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
// src/presets/rest-api.ts
|
|
445
|
+
var REST_API_PRESET = {
|
|
446
|
+
id: "rest-api",
|
|
447
|
+
name: "REST API Wrapper",
|
|
448
|
+
description: "Tools for making HTTP requests: GET, POST, PUT, DELETE",
|
|
449
|
+
tools: [
|
|
450
|
+
{
|
|
451
|
+
name: "http_get",
|
|
452
|
+
description: "Make an HTTP GET request",
|
|
453
|
+
parameters: [
|
|
454
|
+
{
|
|
455
|
+
name: "url",
|
|
456
|
+
type: "string",
|
|
457
|
+
description: "URL to request (can be relative if base_url is set)",
|
|
458
|
+
required: true
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
name: "headers",
|
|
462
|
+
type: "object",
|
|
463
|
+
description: "Request headers as key-value pairs",
|
|
464
|
+
required: false
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
name: "query",
|
|
468
|
+
type: "object",
|
|
469
|
+
description: "Query parameters as key-value pairs",
|
|
470
|
+
required: false
|
|
471
|
+
}
|
|
472
|
+
]
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
name: "http_post",
|
|
476
|
+
description: "Make an HTTP POST request",
|
|
477
|
+
parameters: [
|
|
478
|
+
{
|
|
479
|
+
name: "url",
|
|
480
|
+
type: "string",
|
|
481
|
+
description: "URL to request",
|
|
482
|
+
required: true
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
name: "body",
|
|
486
|
+
type: "object",
|
|
487
|
+
description: "Request body (will be JSON encoded)",
|
|
488
|
+
required: false
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
name: "headers",
|
|
492
|
+
type: "object",
|
|
493
|
+
description: "Request headers as key-value pairs",
|
|
494
|
+
required: false
|
|
495
|
+
}
|
|
496
|
+
]
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
name: "http_put",
|
|
500
|
+
description: "Make an HTTP PUT request",
|
|
501
|
+
parameters: [
|
|
502
|
+
{
|
|
503
|
+
name: "url",
|
|
504
|
+
type: "string",
|
|
505
|
+
description: "URL to request",
|
|
506
|
+
required: true
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
name: "body",
|
|
510
|
+
type: "object",
|
|
511
|
+
description: "Request body (will be JSON encoded)",
|
|
512
|
+
required: false
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
name: "headers",
|
|
516
|
+
type: "object",
|
|
517
|
+
description: "Request headers as key-value pairs",
|
|
518
|
+
required: false
|
|
519
|
+
}
|
|
520
|
+
]
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
name: "http_delete",
|
|
524
|
+
description: "Make an HTTP DELETE request",
|
|
525
|
+
parameters: [
|
|
526
|
+
{
|
|
527
|
+
name: "url",
|
|
528
|
+
type: "string",
|
|
529
|
+
description: "URL to request",
|
|
530
|
+
required: true
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
name: "headers",
|
|
534
|
+
type: "object",
|
|
535
|
+
description: "Request headers as key-value pairs",
|
|
536
|
+
required: false
|
|
537
|
+
}
|
|
538
|
+
]
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
name: "set_base_url",
|
|
542
|
+
description: "Set the base URL for all subsequent requests",
|
|
543
|
+
parameters: [
|
|
544
|
+
{
|
|
545
|
+
name: "base_url",
|
|
546
|
+
type: "string",
|
|
547
|
+
description: "Base URL (e.g., https://api.example.com)",
|
|
548
|
+
required: true
|
|
549
|
+
}
|
|
550
|
+
]
|
|
551
|
+
}
|
|
552
|
+
]
|
|
553
|
+
};
|
|
554
|
+
|
|
555
|
+
// src/presets/filesystem.ts
|
|
556
|
+
var FILESYSTEM_PRESET = {
|
|
557
|
+
id: "filesystem",
|
|
558
|
+
name: "File System Tools",
|
|
559
|
+
description: "Tools for file operations: read, write, list, search",
|
|
560
|
+
tools: [
|
|
561
|
+
{
|
|
562
|
+
name: "read_file",
|
|
563
|
+
description: "Read the contents of a file",
|
|
564
|
+
parameters: [
|
|
565
|
+
{
|
|
566
|
+
name: "path",
|
|
567
|
+
type: "string",
|
|
568
|
+
description: "Path to the file to read",
|
|
569
|
+
required: true
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
name: "encoding",
|
|
573
|
+
type: "string",
|
|
574
|
+
description: "File encoding (default: utf-8)",
|
|
575
|
+
required: false
|
|
576
|
+
}
|
|
577
|
+
]
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
name: "write_file",
|
|
581
|
+
description: "Write content to a file",
|
|
582
|
+
parameters: [
|
|
583
|
+
{
|
|
584
|
+
name: "path",
|
|
585
|
+
type: "string",
|
|
586
|
+
description: "Path to the file to write",
|
|
587
|
+
required: true
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
name: "content",
|
|
591
|
+
type: "string",
|
|
592
|
+
description: "Content to write to the file",
|
|
593
|
+
required: true
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
name: "append",
|
|
597
|
+
type: "boolean",
|
|
598
|
+
description: "Append to file instead of overwriting (default: false)",
|
|
599
|
+
required: false
|
|
600
|
+
}
|
|
601
|
+
]
|
|
602
|
+
},
|
|
603
|
+
{
|
|
604
|
+
name: "list_directory",
|
|
605
|
+
description: "List files and directories in a path",
|
|
606
|
+
parameters: [
|
|
607
|
+
{
|
|
608
|
+
name: "path",
|
|
609
|
+
type: "string",
|
|
610
|
+
description: "Directory path to list",
|
|
611
|
+
required: true
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
name: "recursive",
|
|
615
|
+
type: "boolean",
|
|
616
|
+
description: "List recursively (default: false)",
|
|
617
|
+
required: false
|
|
618
|
+
}
|
|
619
|
+
]
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
name: "search_files",
|
|
623
|
+
description: "Search for files matching a pattern",
|
|
624
|
+
parameters: [
|
|
625
|
+
{
|
|
626
|
+
name: "path",
|
|
627
|
+
type: "string",
|
|
628
|
+
description: "Directory to search in",
|
|
629
|
+
required: true
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
name: "pattern",
|
|
633
|
+
type: "string",
|
|
634
|
+
description: "Glob pattern to match (e.g., *.txt)",
|
|
635
|
+
required: true
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
name: "recursive",
|
|
639
|
+
type: "boolean",
|
|
640
|
+
description: "Search recursively (default: true)",
|
|
641
|
+
required: false
|
|
642
|
+
}
|
|
643
|
+
]
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
name: "file_info",
|
|
647
|
+
description: "Get information about a file or directory",
|
|
648
|
+
parameters: [
|
|
649
|
+
{
|
|
650
|
+
name: "path",
|
|
651
|
+
type: "string",
|
|
652
|
+
description: "Path to the file or directory",
|
|
653
|
+
required: true
|
|
654
|
+
}
|
|
655
|
+
]
|
|
656
|
+
}
|
|
657
|
+
]
|
|
658
|
+
};
|
|
659
|
+
|
|
660
|
+
// src/presets/index.ts
|
|
661
|
+
var PRESETS = {
|
|
662
|
+
database: DATABASE_PRESET,
|
|
663
|
+
"rest-api": REST_API_PRESET,
|
|
664
|
+
filesystem: FILESYSTEM_PRESET
|
|
665
|
+
};
|
|
666
|
+
var PRESET_IDS = Object.keys(PRESETS);
|
|
667
|
+
function getPreset(id) {
|
|
668
|
+
return PRESETS[id];
|
|
669
|
+
}
|
|
670
|
+
function isValidPresetId(id) {
|
|
671
|
+
return id in PRESETS;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// src/prompts/preset.ts
|
|
675
|
+
async function promptPreset() {
|
|
676
|
+
const choices = Object.values(PRESETS).map((preset2) => ({
|
|
677
|
+
name: `${preset2.name} - ${preset2.description}`,
|
|
678
|
+
value: preset2.id
|
|
679
|
+
}));
|
|
680
|
+
const { preset } = await inquirer7.prompt([
|
|
681
|
+
{
|
|
682
|
+
type: "list",
|
|
683
|
+
name: "preset",
|
|
684
|
+
message: "Select a preset template:",
|
|
685
|
+
choices,
|
|
686
|
+
default: "database"
|
|
687
|
+
}
|
|
688
|
+
]);
|
|
689
|
+
return preset;
|
|
690
|
+
}
|
|
691
|
+
|
|
317
692
|
// src/prompts/index.ts
|
|
318
693
|
async function runWizard(options = {}) {
|
|
319
694
|
const name = await promptProjectName(options.defaultName);
|
|
@@ -530,11 +905,34 @@ var logger = {
|
|
|
530
905
|
},
|
|
531
906
|
nextSteps: (projectName, language) => {
|
|
532
907
|
logger.blank();
|
|
908
|
+
let installCmd;
|
|
909
|
+
let runCmd;
|
|
910
|
+
switch (language) {
|
|
911
|
+
case "typescript":
|
|
912
|
+
installCmd = "npm install";
|
|
913
|
+
runCmd = "npm run dev";
|
|
914
|
+
break;
|
|
915
|
+
case "python":
|
|
916
|
+
installCmd = "pip install -e .";
|
|
917
|
+
runCmd = "python -m src.server";
|
|
918
|
+
break;
|
|
919
|
+
case "go":
|
|
920
|
+
installCmd = "go mod download";
|
|
921
|
+
runCmd = "go run ./cmd/server";
|
|
922
|
+
break;
|
|
923
|
+
case "rust":
|
|
924
|
+
installCmd = "cargo build";
|
|
925
|
+
runCmd = "cargo run";
|
|
926
|
+
break;
|
|
927
|
+
default:
|
|
928
|
+
installCmd = "npm install";
|
|
929
|
+
runCmd = "npm run dev";
|
|
930
|
+
}
|
|
533
931
|
logger.box("Next steps:", [
|
|
534
932
|
"",
|
|
535
933
|
` ${chalk.cyan("cd")} ${projectName}`,
|
|
536
|
-
|
|
537
|
-
|
|
934
|
+
` ${chalk.cyan(installCmd)}`,
|
|
935
|
+
` ${chalk.cyan(runCmd)}`,
|
|
538
936
|
""
|
|
539
937
|
]);
|
|
540
938
|
}
|
|
@@ -814,7 +1212,7 @@ async function generateFromWizard(config, outputPath) {
|
|
|
814
1212
|
|
|
815
1213
|
// src/parsers/openapi.ts
|
|
816
1214
|
import YAML from "yaml";
|
|
817
|
-
import
|
|
1215
|
+
import inquirer8 from "inquirer";
|
|
818
1216
|
async function parseOpenAPISpec(content) {
|
|
819
1217
|
let spec;
|
|
820
1218
|
try {
|
|
@@ -914,7 +1312,7 @@ async function selectEndpoints(endpoints) {
|
|
|
914
1312
|
value: ep,
|
|
915
1313
|
checked: true
|
|
916
1314
|
}));
|
|
917
|
-
const { selected } = await
|
|
1315
|
+
const { selected } = await inquirer8.prompt([
|
|
918
1316
|
{
|
|
919
1317
|
type: "checkbox",
|
|
920
1318
|
name: "selected",
|
|
@@ -1050,7 +1448,7 @@ function mapOpenAPIType(type) {
|
|
|
1050
1448
|
|
|
1051
1449
|
// src/generators/from-prompt.ts
|
|
1052
1450
|
import Anthropic from "@anthropic-ai/sdk";
|
|
1053
|
-
import
|
|
1451
|
+
import inquirer9 from "inquirer";
|
|
1054
1452
|
var SYSTEM_PROMPT = `You are an expert at designing MCP (Model Context Protocol) servers.
|
|
1055
1453
|
Given a description of an API or functionality, you generate a list of tools that would be useful for that API.
|
|
1056
1454
|
|
|
@@ -1108,7 +1506,7 @@ var PromptGenerator = class extends BaseGenerator {
|
|
|
1108
1506
|
}
|
|
1109
1507
|
};
|
|
1110
1508
|
async function generateFromPrompt(baseConfig) {
|
|
1111
|
-
const { description } = await
|
|
1509
|
+
const { description } = await inquirer9.prompt([
|
|
1112
1510
|
{
|
|
1113
1511
|
type: "editor",
|
|
1114
1512
|
name: "description",
|
|
@@ -1164,7 +1562,7 @@ async function generateFromPrompt(baseConfig) {
|
|
|
1164
1562
|
logger.list([`${index + 1}. ${tool.name} - ${tool.description}`]);
|
|
1165
1563
|
});
|
|
1166
1564
|
logger.blank();
|
|
1167
|
-
const { confirm } = await
|
|
1565
|
+
const { confirm } = await inquirer9.prompt([
|
|
1168
1566
|
{
|
|
1169
1567
|
type: "confirm",
|
|
1170
1568
|
name: "confirm",
|
|
@@ -1191,10 +1589,85 @@ async function generateFromPrompt(baseConfig) {
|
|
|
1191
1589
|
await generator.generate();
|
|
1192
1590
|
}
|
|
1193
1591
|
|
|
1592
|
+
// src/generators/from-preset.ts
|
|
1593
|
+
var PresetGenerator = class extends BaseGenerator {
|
|
1594
|
+
presetName;
|
|
1595
|
+
constructor(context, presetName) {
|
|
1596
|
+
super(context);
|
|
1597
|
+
this.presetName = presetName;
|
|
1598
|
+
}
|
|
1599
|
+
async generate() {
|
|
1600
|
+
logger.title(`Creating ${this.config.name} from "${this.presetName}" preset`);
|
|
1601
|
+
const isSafe = await this.checkOutputDir();
|
|
1602
|
+
if (!isSafe) {
|
|
1603
|
+
throw new Error(
|
|
1604
|
+
`Directory ${this.outputDir} already exists and is not empty. Please choose a different name or delete the existing directory.`
|
|
1605
|
+
);
|
|
1606
|
+
}
|
|
1607
|
+
await withSpinner(
|
|
1608
|
+
"Creating project structure...",
|
|
1609
|
+
async () => {
|
|
1610
|
+
await this.createProjectStructure();
|
|
1611
|
+
},
|
|
1612
|
+
"Project structure created"
|
|
1613
|
+
);
|
|
1614
|
+
await withSpinner(
|
|
1615
|
+
"Generating files from templates...",
|
|
1616
|
+
async () => {
|
|
1617
|
+
await this.renderTemplates();
|
|
1618
|
+
},
|
|
1619
|
+
"Files generated"
|
|
1620
|
+
);
|
|
1621
|
+
await this.installDependencies();
|
|
1622
|
+
await this.initializeGit();
|
|
1623
|
+
logger.success(`Project ${this.config.name} created successfully!`);
|
|
1624
|
+
logger.info(`Preset: ${this.presetName}`);
|
|
1625
|
+
logger.info(`Tools included: ${this.config.tools.map((t) => t.name).join(", ")}`);
|
|
1626
|
+
logger.nextSteps(this.config.name, this.config.language);
|
|
1627
|
+
}
|
|
1628
|
+
};
|
|
1629
|
+
async function generateFromPreset(options) {
|
|
1630
|
+
const preset = getPreset(options.presetId);
|
|
1631
|
+
if (!preset) {
|
|
1632
|
+
throw new Error(`Invalid preset: ${options.presetId}`);
|
|
1633
|
+
}
|
|
1634
|
+
const name = options.projectName || await promptProjectName();
|
|
1635
|
+
const description = options.useDefaults ? "" : await promptProjectDescription();
|
|
1636
|
+
const language = options.language || (options.useDefaults ? "typescript" : await promptLanguage());
|
|
1637
|
+
const transport = options.useDefaults ? "stdio" : await promptTransport();
|
|
1638
|
+
const config = {
|
|
1639
|
+
name,
|
|
1640
|
+
description,
|
|
1641
|
+
language,
|
|
1642
|
+
transport,
|
|
1643
|
+
tools: preset.tools,
|
|
1644
|
+
resources: [],
|
|
1645
|
+
includeExampleTool: false,
|
|
1646
|
+
skipInstall: options.skipInstall || false,
|
|
1647
|
+
initGit: true
|
|
1648
|
+
};
|
|
1649
|
+
const context = createGeneratorContext(config);
|
|
1650
|
+
const generator = new PresetGenerator(context, preset.name);
|
|
1651
|
+
await generator.generate();
|
|
1652
|
+
}
|
|
1653
|
+
function validatePresetId(presetId) {
|
|
1654
|
+
if (!isValidPresetId(presetId)) {
|
|
1655
|
+
const validPresets = ["database", "rest-api", "filesystem"];
|
|
1656
|
+
throw new Error(
|
|
1657
|
+
`Invalid preset "${presetId}". Valid presets are: ${validPresets.join(", ")}`
|
|
1658
|
+
);
|
|
1659
|
+
}
|
|
1660
|
+
return true;
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1194
1663
|
// src/commands/create.ts
|
|
1195
1664
|
import path4 from "path";
|
|
1196
1665
|
async function createCommand(projectName, options) {
|
|
1197
1666
|
try {
|
|
1667
|
+
if (options.preset) {
|
|
1668
|
+
await handlePresetGeneration(projectName, options);
|
|
1669
|
+
return;
|
|
1670
|
+
}
|
|
1198
1671
|
if (options.fromOpenapi) {
|
|
1199
1672
|
await handleOpenAPIGeneration(projectName, options);
|
|
1200
1673
|
return;
|
|
@@ -1254,10 +1727,21 @@ async function handlePromptGeneration(projectName, options) {
|
|
|
1254
1727
|
skipInstall: options.skipInstall
|
|
1255
1728
|
});
|
|
1256
1729
|
}
|
|
1730
|
+
async function handlePresetGeneration(projectName, options) {
|
|
1731
|
+
const presetId = options.preset;
|
|
1732
|
+
validatePresetId(presetId);
|
|
1733
|
+
await generateFromPreset({
|
|
1734
|
+
projectName,
|
|
1735
|
+
presetId,
|
|
1736
|
+
language: options.typescript ? "typescript" : options.python ? "python" : options.go ? "go" : options.rust ? "rust" : void 0,
|
|
1737
|
+
skipInstall: options.skipInstall,
|
|
1738
|
+
useDefaults: options.yes
|
|
1739
|
+
});
|
|
1740
|
+
}
|
|
1257
1741
|
|
|
1258
1742
|
// src/commands/init.ts
|
|
1259
1743
|
import path5 from "path";
|
|
1260
|
-
import
|
|
1744
|
+
import inquirer10 from "inquirer";
|
|
1261
1745
|
async function initCommand(options) {
|
|
1262
1746
|
try {
|
|
1263
1747
|
const currentDir = process.cwd();
|
|
@@ -1267,7 +1751,7 @@ async function initCommand(options) {
|
|
|
1267
1751
|
const hasGoMod = await exists(path5.join(currentDir, "go.mod"));
|
|
1268
1752
|
const hasCargoToml = await exists(path5.join(currentDir, "Cargo.toml"));
|
|
1269
1753
|
if ((hasPackageJson || hasPyproject || hasGoMod || hasCargoToml) && !options.force) {
|
|
1270
|
-
const { proceed } = await
|
|
1754
|
+
const { proceed } = await inquirer10.prompt([
|
|
1271
1755
|
{
|
|
1272
1756
|
type: "confirm",
|
|
1273
1757
|
name: "proceed",
|
|
@@ -1734,6 +2218,8 @@ export {
|
|
|
1734
2218
|
promptAddResources,
|
|
1735
2219
|
promptResourceConfig,
|
|
1736
2220
|
promptMultipleResources,
|
|
2221
|
+
promptGenerationMethod,
|
|
2222
|
+
promptPreset,
|
|
1737
2223
|
runWizard,
|
|
1738
2224
|
runQuickWizard,
|
|
1739
2225
|
ensureDir,
|
|
@@ -1769,6 +2255,9 @@ export {
|
|
|
1769
2255
|
generateFromOpenAPI,
|
|
1770
2256
|
PromptGenerator,
|
|
1771
2257
|
generateFromPrompt,
|
|
2258
|
+
PresetGenerator,
|
|
2259
|
+
generateFromPreset,
|
|
2260
|
+
validatePresetId,
|
|
1772
2261
|
createCommand,
|
|
1773
2262
|
initCommand,
|
|
1774
2263
|
addToolCommand
|
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
addToolCommand,
|
|
4
4
|
createCommand,
|
|
5
5
|
initCommand
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BHGUGEHE.js";
|
|
7
7
|
|
|
8
8
|
// src/cli.ts
|
|
9
9
|
import { Command } from "commander";
|
|
@@ -11,14 +11,74 @@ import chalk from "chalk";
|
|
|
11
11
|
var program = new Command();
|
|
12
12
|
var logo = `
|
|
13
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-
|
|
14
|
+
${chalk.cyan("\u2551")} ${chalk.bold.white("mcp-new")} ${chalk.cyan("\u2551")}
|
|
15
15
|
${chalk.cyan("\u2551")} ${chalk.gray("Generate MCP servers in seconds")} ${chalk.cyan("\u2551")}
|
|
16
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")}
|
|
17
17
|
`;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
var examples = `
|
|
19
|
+
${chalk.bold("Examples:")}
|
|
20
|
+
|
|
21
|
+
${chalk.gray("# Create a new MCP server with interactive wizard")}
|
|
22
|
+
${chalk.cyan("$")} mcp-new my-server
|
|
23
|
+
|
|
24
|
+
${chalk.gray("# Create TypeScript server with defaults")}
|
|
25
|
+
${chalk.cyan("$")} mcp-new my-server -t -y
|
|
26
|
+
|
|
27
|
+
${chalk.gray("# Create Python server")}
|
|
28
|
+
${chalk.cyan("$")} mcp-new my-server -p
|
|
29
|
+
|
|
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
|
|
34
|
+
|
|
35
|
+
${chalk.gray("# Create from OpenAPI specification")}
|
|
36
|
+
${chalk.cyan("$")} mcp-new my-api --from-openapi ./openapi.yaml
|
|
37
|
+
|
|
38
|
+
${chalk.gray("# Create using AI (requires ANTHROPIC_API_KEY)")}
|
|
39
|
+
${chalk.cyan("$")} mcp-new my-server --from-prompt
|
|
40
|
+
|
|
41
|
+
${chalk.bold("Available Presets:")}
|
|
42
|
+
|
|
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)
|
|
46
|
+
|
|
47
|
+
${chalk.bold("Supported Languages:")}
|
|
48
|
+
|
|
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
|
|
53
|
+
|
|
54
|
+
${chalk.bold("Learn More:")}
|
|
55
|
+
|
|
56
|
+
Documentation: ${chalk.underline("https://github.com/d1maash/mcp-new")}
|
|
57
|
+
MCP Spec: ${chalk.underline("https://spec.modelcontextprotocol.io")}
|
|
58
|
+
`;
|
|
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);
|
|
60
|
+
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
|
+
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:")}
|
|
63
|
+
|
|
64
|
+
${chalk.gray("# Initialize in current directory")}
|
|
65
|
+
${chalk.cyan("$")} mcp-new init
|
|
66
|
+
|
|
67
|
+
${chalk.gray("# Initialize with TypeScript")}
|
|
68
|
+
${chalk.cyan("$")} mcp-new init -t
|
|
69
|
+
|
|
70
|
+
${chalk.gray("# Force initialize (overwrite existing files)")}
|
|
71
|
+
${chalk.cyan("$")} mcp-new init -f
|
|
72
|
+
`).action(initCommand);
|
|
73
|
+
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:")}
|
|
75
|
+
|
|
76
|
+
${chalk.gray("# Add tool interactively")}
|
|
77
|
+
${chalk.cyan("$")} mcp-new add-tool
|
|
78
|
+
|
|
79
|
+
${chalk.gray("# Add tool with name")}
|
|
80
|
+
${chalk.cyan("$")} mcp-new add-tool -n my_new_tool
|
|
81
|
+
`).action(addToolCommand);
|
|
22
82
|
program.parse();
|
|
23
83
|
if (process.argv.length === 2) {
|
|
24
84
|
program.help();
|