@eaperezc/mcpgen 0.1.0 → 0.1.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 +31 -27
- package/dist/cli/index.cjs +70 -24
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +70 -24
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +86 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -22
- package/dist/index.d.ts +14 -22
- package/dist/index.js +86 -34
- package/dist/index.js.map +1 -1
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +2 -2
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js.map +1 -1
- package/dist/{types-B9yzEar_.d.cts → types-Bu1xVhfb.d.cts} +10 -1
- package/dist/{types-B9yzEar_.d.ts → types-Bu1xVhfb.d.ts} +10 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -18,7 +18,7 @@ async function exists(path) {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
function toolTemplate(className, toolName) {
|
|
21
|
-
return `import { BaseTool } from '
|
|
21
|
+
return `import { BaseTool } from '@eaperezc/mcpgen';
|
|
22
22
|
import { z } from 'zod';
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -44,8 +44,32 @@ export class ${className} extends BaseTool {
|
|
|
44
44
|
}
|
|
45
45
|
`;
|
|
46
46
|
}
|
|
47
|
+
function toolTestTemplate(className, toolName) {
|
|
48
|
+
return `import { describe, it, expect } from 'vitest';
|
|
49
|
+
import { createTestClient } from '@eaperezc/mcpgen/testing';
|
|
50
|
+
import { ${className} } from './${className}.js';
|
|
51
|
+
|
|
52
|
+
describe('${className}', () => {
|
|
53
|
+
it('should execute successfully', async () => {
|
|
54
|
+
const client = createTestClient();
|
|
55
|
+
client.registerTool(new ${className}());
|
|
56
|
+
|
|
57
|
+
const result = await client.callTool('${toolName}', { input: 'test' });
|
|
58
|
+
|
|
59
|
+
expect(result.content).toHaveProperty('result');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should require input parameter', async () => {
|
|
63
|
+
const client = createTestClient();
|
|
64
|
+
client.registerTool(new ${className}());
|
|
65
|
+
|
|
66
|
+
await expect(client.callTool('${toolName}', {})).rejects.toThrow();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
`;
|
|
70
|
+
}
|
|
47
71
|
function resourceTemplate(className, resourceName) {
|
|
48
|
-
return `import { BaseResource } from '
|
|
72
|
+
return `import { BaseResource } from '@eaperezc/mcpgen';
|
|
49
73
|
|
|
50
74
|
/**
|
|
51
75
|
* ${className} - Description of what this resource provides
|
|
@@ -70,7 +94,7 @@ export class ${className} extends BaseResource {
|
|
|
70
94
|
`;
|
|
71
95
|
}
|
|
72
96
|
function promptTemplate(className, promptName) {
|
|
73
|
-
return `import { BasePrompt } from '
|
|
97
|
+
return `import { BasePrompt } from '@eaperezc/mcpgen';
|
|
74
98
|
import { z } from 'zod';
|
|
75
99
|
|
|
76
100
|
/**
|
|
@@ -119,18 +143,21 @@ async function generateComponent(options) {
|
|
|
119
143
|
const typeDir = type === "tool" ? "tools" : type === "resource" ? "resources" : "prompts";
|
|
120
144
|
const srcDir = join(process.cwd(), "src", typeDir);
|
|
121
145
|
const filePath = join(srcDir, `${fileName}.ts`);
|
|
146
|
+
const testFilePath = join(srcDir, `${fileName}.test.ts`);
|
|
122
147
|
const indexPath = join(srcDir, "index.ts");
|
|
123
148
|
if (!await exists(join(process.cwd(), "src"))) {
|
|
124
|
-
throw new Error('No src/ directory found. Are you in an
|
|
149
|
+
throw new Error('No src/ directory found. Are you in an mcpgen project? Run "mcpgen init" first.');
|
|
125
150
|
}
|
|
126
151
|
await mkdir(srcDir, { recursive: true });
|
|
127
152
|
if (await exists(filePath)) {
|
|
128
153
|
throw new Error(`${type} '${fileName}' already exists at ${filePath}`);
|
|
129
154
|
}
|
|
130
155
|
let content;
|
|
156
|
+
let testContent = null;
|
|
131
157
|
switch (type) {
|
|
132
158
|
case "tool":
|
|
133
159
|
content = toolTemplate(className, kebabName);
|
|
160
|
+
testContent = toolTestTemplate(className, kebabName);
|
|
134
161
|
break;
|
|
135
162
|
case "resource":
|
|
136
163
|
content = resourceTemplate(className, kebabName);
|
|
@@ -144,6 +171,10 @@ async function generateComponent(options) {
|
|
|
144
171
|
await writeFile(filePath, content);
|
|
145
172
|
console.log(`
|
|
146
173
|
\u2705 Created ${type}: ${filePath.replace(process.cwd(), ".")}`);
|
|
174
|
+
if (testContent) {
|
|
175
|
+
await writeFile(testFilePath, testContent);
|
|
176
|
+
console.log(` Created test: ${testFilePath.replace(process.cwd(), ".")}`);
|
|
177
|
+
}
|
|
147
178
|
await updateIndexFile(indexPath, className, fileName);
|
|
148
179
|
console.log(` Updated: ${indexPath.replace(process.cwd(), ".")}`);
|
|
149
180
|
console.log(`
|
|
@@ -152,8 +183,9 @@ Next steps:
|
|
|
152
183
|
1. Edit src/${typeDir}/${fileName}.ts to implement your ${type}
|
|
153
184
|
2. Register it in src/index.ts:
|
|
154
185
|
|
|
155
|
-
import { ${className} } from '
|
|
186
|
+
import { ${className} } from './${typeDir}/${fileName}.js';
|
|
156
187
|
server.${type}(new ${className}());
|
|
188
|
+
3. Run tests: npm test
|
|
157
189
|
`);
|
|
158
190
|
}
|
|
159
191
|
|
|
@@ -171,7 +203,8 @@ var packageJsonTemplate = (name, description) => `{
|
|
|
171
203
|
"test": "vitest run",
|
|
172
204
|
"test:watch": "vitest",
|
|
173
205
|
"lint": "eslint src",
|
|
174
|
-
"typecheck": "tsc --noEmit"
|
|
206
|
+
"typecheck": "tsc --noEmit",
|
|
207
|
+
"inspector": "npx @modelcontextprotocol/inspector"
|
|
175
208
|
},
|
|
176
209
|
"keywords": ["mcp", "model-context-protocol"],
|
|
177
210
|
"license": "MIT",
|
|
@@ -336,9 +369,9 @@ export class ConfigResource extends BaseResource {
|
|
|
336
369
|
var promptsIndexTemplate = () => `// Export your prompts here
|
|
337
370
|
// export { SummarizePrompt } from './SummarizePrompt.js';
|
|
338
371
|
`;
|
|
339
|
-
var
|
|
372
|
+
var greetToolTestTemplate = () => `import { describe, it, expect } from 'vitest';
|
|
340
373
|
import { createTestClient } from '@eaperezc/mcpgen/testing';
|
|
341
|
-
import { GreetTool } from '
|
|
374
|
+
import { GreetTool } from './GreetTool.js';
|
|
342
375
|
|
|
343
376
|
describe('GreetTool', () => {
|
|
344
377
|
it('should greet the user', async () => {
|
|
@@ -394,19 +427,32 @@ npm start
|
|
|
394
427
|
npm test
|
|
395
428
|
\`\`\`
|
|
396
429
|
|
|
430
|
+
### MCP Inspector
|
|
431
|
+
|
|
432
|
+
To test and debug your server with the MCP Inspector:
|
|
433
|
+
|
|
434
|
+
\`\`\`bash
|
|
435
|
+
# Terminal 1: Start the server
|
|
436
|
+
npm run dev
|
|
437
|
+
|
|
438
|
+
# Terminal 2: Launch the inspector
|
|
439
|
+
npm run inspector
|
|
440
|
+
\`\`\`
|
|
441
|
+
|
|
442
|
+
Then connect to \`http://localhost:3000/mcp\` using **Streamable HTTP** transport.
|
|
443
|
+
|
|
397
444
|
## Project Structure
|
|
398
445
|
|
|
399
446
|
\`\`\`
|
|
400
447
|
${name}/
|
|
401
448
|
\u251C\u2500\u2500 src/
|
|
402
|
-
\u2502 \u251C\u2500\u2500 tools/
|
|
403
|
-
\u2502 \u2502 \
|
|
404
|
-
\u2502 \
|
|
449
|
+
\u2502 \u251C\u2500\u2500 tools/ # MCP tools
|
|
450
|
+
\u2502 \u2502 \u251C\u2500\u2500 GreetTool.ts
|
|
451
|
+
\u2502 \u2502 \u2514\u2500\u2500 GreetTool.test.ts
|
|
452
|
+
\u2502 \u251C\u2500\u2500 resources/ # MCP resources
|
|
405
453
|
\u2502 \u2502 \u2514\u2500\u2500 ConfigResource.ts
|
|
406
|
-
\u2502 \u251C\u2500\u2500 prompts/
|
|
407
|
-
\u2502 \u2514\u2500\u2500 index.ts
|
|
408
|
-
\u251C\u2500\u2500 tests/
|
|
409
|
-
\u2502 \u2514\u2500\u2500 tools.test.ts
|
|
454
|
+
\u2502 \u251C\u2500\u2500 prompts/ # MCP prompts
|
|
455
|
+
\u2502 \u2514\u2500\u2500 index.ts # Server entry point
|
|
410
456
|
\u251C\u2500\u2500 package.json
|
|
411
457
|
\u2514\u2500\u2500 tsconfig.json
|
|
412
458
|
\`\`\`
|
|
@@ -480,7 +526,7 @@ async function initProject(options) {
|
|
|
480
526
|
const {
|
|
481
527
|
name,
|
|
482
528
|
description = `An MCP server built with @eaperezc/mcpgen`,
|
|
483
|
-
transport = "
|
|
529
|
+
transport = "http"
|
|
484
530
|
} = options;
|
|
485
531
|
const projectDir = join(process.cwd(), name);
|
|
486
532
|
if (await exists2(projectDir)) {
|
|
@@ -494,8 +540,7 @@ Creating new MCP server: ${name}
|
|
|
494
540
|
join(projectDir, "src"),
|
|
495
541
|
join(projectDir, "src", "tools"),
|
|
496
542
|
join(projectDir, "src", "resources"),
|
|
497
|
-
join(projectDir, "src", "prompts")
|
|
498
|
-
join(projectDir, "tests")
|
|
543
|
+
join(projectDir, "src", "prompts")
|
|
499
544
|
];
|
|
500
545
|
for (const dir of dirs) {
|
|
501
546
|
await mkdir(dir, { recursive: true });
|
|
@@ -510,10 +555,10 @@ Creating new MCP server: ${name}
|
|
|
510
555
|
{ path: "src/index.ts", content: mainIndexTemplate(name, transport) },
|
|
511
556
|
{ path: "src/tools/index.ts", content: toolsIndexTemplate() },
|
|
512
557
|
{ path: "src/tools/GreetTool.ts", content: greetToolTemplate() },
|
|
558
|
+
{ path: "src/tools/GreetTool.test.ts", content: greetToolTestTemplate() },
|
|
513
559
|
{ path: "src/resources/index.ts", content: resourcesIndexTemplate() },
|
|
514
560
|
{ path: "src/resources/ConfigResource.ts", content: configResourceTemplate(name) },
|
|
515
|
-
{ path: "src/prompts/index.ts", content: promptsIndexTemplate() }
|
|
516
|
-
{ path: "tests/tools.test.ts", content: testExampleTemplate() }
|
|
561
|
+
{ path: "src/prompts/index.ts", content: promptsIndexTemplate() }
|
|
517
562
|
];
|
|
518
563
|
for (const file of files) {
|
|
519
564
|
const filePath = join(projectDir, file.path);
|
|
@@ -543,7 +588,7 @@ Happy building! \u{1F680}
|
|
|
543
588
|
// src/cli/index.ts
|
|
544
589
|
var program = new Command();
|
|
545
590
|
program.name("mcpgen").description("CLI for building MCP servers").version("0.1.0");
|
|
546
|
-
program.command("init").description("Initialize a new MCP server project").argument("<name>", "Project name").option("-d, --description <desc>", "Project description").option("-t, --transport <type>", "Transport type (
|
|
591
|
+
program.command("init").description("Initialize a new MCP server project").argument("<name>", "Project name").option("-d, --description <desc>", "Project description").option("-t, --transport <type>", "Transport type (http or stdio)", "http").option("--skip-install", "Skip npm install").action(async (name, options) => {
|
|
547
592
|
try {
|
|
548
593
|
await initProject({
|
|
549
594
|
name,
|
|
@@ -592,14 +637,15 @@ program.addHelpText(
|
|
|
592
637
|
"after",
|
|
593
638
|
`
|
|
594
639
|
Examples:
|
|
595
|
-
$ mcpgen init my-mcp-server
|
|
596
|
-
$ mcpgen init my-api --transport
|
|
640
|
+
$ mcpgen init my-mcp-server Create a new MCP server (HTTP)
|
|
641
|
+
$ mcpgen init my-api --transport stdio Create with stdio transport
|
|
597
642
|
$ mcpgen make:tool search Create a new tool
|
|
598
643
|
$ mcpgen make:resource database Create a new resource
|
|
599
644
|
$ mcpgen make:prompt summarize Create a new prompt
|
|
600
645
|
`
|
|
601
646
|
);
|
|
602
647
|
if (process.argv.length <= 2) {
|
|
648
|
+
const yellow = "\x1B[33m";
|
|
603
649
|
const cyan = "\x1B[36m";
|
|
604
650
|
const dim = "\x1B[2m";
|
|
605
651
|
const bold = "\x1B[1m";
|
|
@@ -607,7 +653,7 @@ if (process.argv.length <= 2) {
|
|
|
607
653
|
console.log(`
|
|
608
654
|
${dim}+-------------------------------------+${reset}
|
|
609
655
|
${dim}|${reset} ${dim}|${reset}
|
|
610
|
-
${dim}|${reset} ${bold}${
|
|
656
|
+
${dim}|${reset} ${bold}${yellow}MCP-GEN${reset} ${dim}v0.1.0${reset} ${dim}|${reset}
|
|
611
657
|
${dim}|${reset} ${dim}|${reset}
|
|
612
658
|
${dim}|${reset} A TypeScript framework for ${dim}|${reset}
|
|
613
659
|
${dim}|${reset} building MCP servers ${dim}|${reset}
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/generate.ts","../../src/cli/templates/index.ts","../../src/cli/commands/init.ts","../../src/cli/index.ts"],"names":["exists","access","join","mkdir","writeFile"],"mappings":"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","file":"index.js","sourcesContent":["import { mkdir, writeFile, access, readFile } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\n\nexport type ComponentType = 'tool' | 'resource' | 'prompt';\n\nexport interface GenerateOptions {\n type: ComponentType;\n name: string;\n}\n\n/**\n * Convert a name to PascalCase\n */\nfunction toPascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\n/**\n * Convert a name to kebab-case\n */\nfunction toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\n/**\n * Check if a file exists\n */\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Generate tool template\n */\nfunction toolTemplate(className: string, toolName: string): string {\n return `import { BaseTool } from 'mcpkit';\nimport { z } from 'zod';\n\n/**\n * ${className} - Description of what this tool does\n */\nexport class ${className} extends BaseTool {\n name = '${toolName}';\n description = 'TODO: Add description';\n\n schema = z.object({\n // TODO: Define your input schema\n input: z.string().describe('Input parameter'),\n });\n\n async execute(input: z.infer<typeof this.schema>) {\n // TODO: Implement your tool logic\n return {\n content: {\n result: \\`Processed: \\${input.input}\\`,\n },\n };\n }\n}\n`;\n}\n\n/**\n * Generate resource template\n */\nfunction resourceTemplate(className: string, resourceName: string): string {\n return `import { BaseResource } from 'mcpkit';\n\n/**\n * ${className} - Description of what this resource provides\n */\nexport class ${className} extends BaseResource {\n uri = '${resourceName}://data';\n name = '${className}';\n description = 'TODO: Add description';\n\n async read() {\n // TODO: Implement your resource logic\n return {\n contents: [\n this.json({\n // Your data here\n example: 'data',\n }),\n ],\n };\n }\n}\n`;\n}\n\n/**\n * Generate prompt template\n */\nfunction promptTemplate(className: string, promptName: string): string {\n return `import { BasePrompt } from 'mcpkit';\nimport { z } from 'zod';\n\n/**\n * ${className} - Description of what this prompt does\n */\nexport class ${className} extends BasePrompt {\n name = '${promptName}';\n description = 'TODO: Add description';\n\n arguments = z.object({\n // TODO: Define your arguments schema\n topic: z.string().describe('The topic to discuss'),\n });\n\n async render(args: z.infer<typeof this.arguments>) {\n // TODO: Implement your prompt logic\n return {\n messages: [\n this.user(\\`Please help me with: \\${args.topic}\\`),\n ],\n };\n }\n}\n`;\n}\n\n/**\n * Update index file to export the new component\n */\nasync function updateIndexFile(indexPath: string, className: string, fileName: string): Promise<void> {\n let content = '';\n\n if (await exists(indexPath)) {\n content = await readFile(indexPath, 'utf-8');\n }\n\n const exportLine = `export { ${className} } from './${fileName}.js';`;\n\n if (!content.includes(exportLine)) {\n // Remove comments and empty lines at the start for clean exports\n const lines = content.split('\\n').filter(line =>\n line.trim() && !line.trim().startsWith('//')\n );\n lines.push(exportLine);\n content = lines.join('\\n') + '\\n';\n await writeFile(indexPath, content);\n }\n}\n\n/**\n * Generate a new component\n */\nexport async function generateComponent(options: GenerateOptions): Promise<void> {\n const { type, name } = options;\n\n const className = toPascalCase(name) + (type === 'tool' ? 'Tool' : type === 'resource' ? 'Resource' : 'Prompt');\n const fileName = className;\n const kebabName = toKebabCase(name);\n\n // Determine directory\n const typeDir = type === 'tool' ? 'tools' : type === 'resource' ? 'resources' : 'prompts';\n const srcDir = join(process.cwd(), 'src', typeDir);\n const filePath = join(srcDir, `${fileName}.ts`);\n const indexPath = join(srcDir, 'index.ts');\n\n // Check if src directory exists (are we in an mcpkit project?)\n if (!(await exists(join(process.cwd(), 'src')))) {\n throw new Error('No src/ directory found. Are you in an mcpkit project? Run \"mcpkit init\" first.');\n }\n\n // Create directory if it doesn't exist\n await mkdir(srcDir, { recursive: true });\n\n // Check if file already exists\n if (await exists(filePath)) {\n throw new Error(`${type} '${fileName}' already exists at ${filePath}`);\n }\n\n // Generate content based on type\n let content: string;\n switch (type) {\n case 'tool':\n content = toolTemplate(className, kebabName);\n break;\n case 'resource':\n content = resourceTemplate(className, kebabName);\n break;\n case 'prompt':\n content = promptTemplate(className, kebabName);\n break;\n default:\n throw new Error(`Unknown component type: ${type}`);\n }\n\n // Write file\n await writeFile(filePath, content);\n console.log(`\\n✅ Created ${type}: ${filePath.replace(process.cwd(), '.')}`);\n\n // Update index file\n await updateIndexFile(indexPath, className, fileName);\n console.log(` Updated: ${indexPath.replace(process.cwd(), '.')}`);\n\n console.log(`\nNext steps:\n\n 1. Edit src/${typeDir}/${fileName}.ts to implement your ${type}\n 2. Register it in src/index.ts:\n\n import { ${className} } from './tools/${fileName}.js';\n server.${type}(new ${className}());\n`);\n}\n","/**\n * Templates for CLI scaffolding\n */\n\nexport const packageJsonTemplate = (name: string, description: string) => `{\n \"name\": \"${name}\",\n \"version\": \"0.1.0\",\n \"description\": \"${description}\",\n \"type\": \"module\",\n \"main\": \"dist/index.js\",\n \"scripts\": {\n \"build\": \"tsc\",\n \"dev\": \"tsx watch src/index.ts\",\n \"start\": \"node dist/index.js\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"lint\": \"eslint src\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"keywords\": [\"mcp\", \"model-context-protocol\"],\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@eaperezc/mcpgen\": \"^0.1.0\",\n \"@modelcontextprotocol/sdk\": \"^1.11.0\",\n \"zod\": \"^3.23.8\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.10.0\",\n \"typescript\": \"^5.7.2\",\n \"tsx\": \"^4.19.2\",\n \"vitest\": \"^2.1.8\"\n },\n \"engines\": {\n \"node\": \">=18.0.0\"\n }\n}\n`;\n\nexport const tsconfigTemplate = () => `{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"lib\": [\"ES2022\"],\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"forceConsistentCasingInFileNames\": true,\n \"declaration\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\",\n \"resolveJsonModule\": true\n },\n \"include\": [\"src/**/*\"],\n \"exclude\": [\"node_modules\", \"dist\"]\n}\n`;\n\nexport const gitignoreTemplate = () => `# Dependencies\nnode_modules/\n\n# Build output\ndist/\n\n# Environment files\n.env\n.env.local\n.env.*.local\n\n# IDE\n.idea/\n.vscode/\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\n`;\n\nexport const mainIndexTemplate = (name: string, transport: 'stdio' | 'http') => {\n if (transport === 'http') {\n return `import { McpServer } from '@eaperezc/mcpgen';\nimport { GreetTool } from './tools/GreetTool.js';\nimport { ConfigResource } from './resources/ConfigResource.js';\n\nconst server = new McpServer({\n name: '${name}',\n version: '0.1.0',\n transport: {\n type: 'http',\n port: 3000,\n cors: { origin: '*' },\n },\n logging: { level: 'info' },\n});\n\n// Register tools\nserver.tool(new GreetTool());\n\n// Register resources\nserver.resource(new ConfigResource());\n\n// Start the server\nserver.start().then(() => {\n console.log('MCP server running at http://localhost:3000/mcp');\n});\n`;\n }\n\n return `import { McpServer } from '@eaperezc/mcpgen';\nimport { GreetTool } from './tools/GreetTool.js';\nimport { ConfigResource } from './resources/ConfigResource.js';\n\nconst server = new McpServer({\n name: '${name}',\n version: '0.1.0',\n logging: { level: 'info' },\n});\n\n// Register tools\nserver.tool(new GreetTool());\n\n// Register resources\nserver.resource(new ConfigResource());\n\n// Start the server\nserver.start();\n`;\n};\n\nexport const toolsIndexTemplate = () => `export { GreetTool } from './GreetTool.js';\n`;\n\nexport const greetToolTemplate = () => `import { BaseTool } from '@eaperezc/mcpgen';\nimport { z } from 'zod';\n\n/**\n * Example tool that greets a user\n */\nexport class GreetTool extends BaseTool {\n name = 'greet';\n description = 'Greets a user by name';\n\n schema = z.object({\n name: z.string().describe('The name of the person to greet'),\n });\n\n async execute(input: z.infer<typeof this.schema>) {\n return {\n content: {\n greeting: \\`Hello, \\${input.name}! Welcome to your MCP server.\\`,\n },\n };\n }\n}\n`;\n\nexport const resourcesIndexTemplate = () => `export { ConfigResource } from './ConfigResource.js';\n`;\n\nexport const configResourceTemplate = (name: string) => `import { BaseResource } from '@eaperezc/mcpgen';\n\n/**\n * Example resource that provides server configuration\n */\nexport class ConfigResource extends BaseResource {\n uri = 'config://server';\n name = 'Server Configuration';\n description = 'Provides server configuration information';\n\n async read() {\n return {\n contents: [\n this.json({\n serverName: '${name}',\n version: '0.1.0',\n environment: process.env.NODE_ENV ?? 'development',\n }),\n ],\n };\n }\n}\n`;\n\nexport const promptsIndexTemplate = () => `// Export your prompts here\n// export { SummarizePrompt } from './SummarizePrompt.js';\n`;\n\nexport const testExampleTemplate = () => `import { describe, it, expect } from 'vitest';\nimport { createTestClient } from '@eaperezc/mcpgen/testing';\nimport { GreetTool } from '../src/tools/GreetTool.js';\n\ndescribe('GreetTool', () => {\n it('should greet the user', async () => {\n const client = createTestClient();\n client.registerTool(new GreetTool());\n\n const result = await client.callTool('greet', { name: 'Alice' });\n\n expect(result.content).toHaveProperty('greeting');\n expect((result.content as { greeting: string }).greeting).toContain('Alice');\n });\n\n it('should require a name', async () => {\n const client = createTestClient();\n client.registerTool(new GreetTool());\n\n await expect(client.callTool('greet', {})).rejects.toThrow();\n });\n});\n`;\n\nexport const readmeTemplate = (name: string, description: string) => `# ${name}\n\n${description}\n\n## Getting Started\n\n### Installation\n\n\\`\\`\\`bash\nnpm install\n\\`\\`\\`\n\n### Development\n\nRun the server in development mode with hot reload:\n\n\\`\\`\\`bash\nnpm run dev\n\\`\\`\\`\n\n### Production\n\nBuild and run:\n\n\\`\\`\\`bash\nnpm run build\nnpm start\n\\`\\`\\`\n\n### Testing\n\n\\`\\`\\`bash\nnpm test\n\\`\\`\\`\n\n## Project Structure\n\n\\`\\`\\`\n${name}/\n├── src/\n│ ├── tools/ # MCP tools\n│ │ └── GreetTool.ts\n│ ├── resources/ # MCP resources\n│ │ └── ConfigResource.ts\n│ ├── prompts/ # MCP prompts\n│ └── index.ts # Server entry point\n├── tests/\n│ └── tools.test.ts\n├── package.json\n└── tsconfig.json\n\\`\\`\\`\n\n## Adding New Components\n\n### Tools\n\nCreate a new file in \\`src/tools/\\`:\n\n\\`\\`\\`typescript\nimport { BaseTool } from '@eaperezc/mcpgen';\nimport { z } from 'zod';\n\nexport class MyTool extends BaseTool {\n name = 'my-tool';\n description = 'Description of what this tool does';\n\n schema = z.object({\n // Define your input schema\n });\n\n async execute(input: z.infer<typeof this.schema>) {\n // Implement your tool logic\n return { content: { result: 'success' } };\n }\n}\n\\`\\`\\`\n\n### Resources\n\nCreate a new file in \\`src/resources/\\`:\n\n\\`\\`\\`typescript\nimport { BaseResource } from '@eaperezc/mcpgen';\n\nexport class MyResource extends BaseResource {\n uri = 'my-resource://example';\n name = 'My Resource';\n\n async read() {\n return { contents: [this.json({ data: 'example' })] };\n }\n}\n\\`\\`\\`\n\n## License\n\nMIT\n`;\n\nexport const vitestConfigTemplate = () => `import { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n test: {\n globals: true,\n environment: 'node',\n },\n});\n`;\n","import { mkdir, writeFile, access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport {\n packageJsonTemplate,\n tsconfigTemplate,\n gitignoreTemplate,\n mainIndexTemplate,\n toolsIndexTemplate,\n greetToolTemplate,\n resourcesIndexTemplate,\n configResourceTemplate,\n promptsIndexTemplate,\n testExampleTemplate,\n readmeTemplate,\n vitestConfigTemplate,\n} from '../templates/index.js';\n\nexport interface InitOptions {\n name: string;\n description?: string;\n transport?: 'stdio' | 'http';\n skipInstall?: boolean;\n}\n\n/**\n * Check if a directory exists\n */\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Initialize a new MCP server project\n */\nexport async function initProject(options: InitOptions): Promise<void> {\n const {\n name,\n description = `An MCP server built with @eaperezc/mcpgen`,\n transport = 'stdio',\n } = options;\n\n const projectDir = join(process.cwd(), name);\n\n // Check if directory already exists\n if (await exists(projectDir)) {\n throw new Error(`Directory '${name}' already exists`);\n }\n\n console.log(`\\nCreating new MCP server: ${name}\\n`);\n\n // Create directories\n const dirs = [\n projectDir,\n join(projectDir, 'src'),\n join(projectDir, 'src', 'tools'),\n join(projectDir, 'src', 'resources'),\n join(projectDir, 'src', 'prompts'),\n join(projectDir, 'tests'),\n ];\n\n for (const dir of dirs) {\n await mkdir(dir, { recursive: true });\n console.log(` Created: ${dir.replace(process.cwd(), '.')}`);\n }\n\n // Create files\n const files: Array<{ path: string; content: string }> = [\n { path: 'package.json', content: packageJsonTemplate(name, description) },\n { path: 'tsconfig.json', content: tsconfigTemplate() },\n { path: '.gitignore', content: gitignoreTemplate() },\n { path: 'vitest.config.ts', content: vitestConfigTemplate() },\n { path: 'README.md', content: readmeTemplate(name, description) },\n { path: 'src/index.ts', content: mainIndexTemplate(name, transport) },\n { path: 'src/tools/index.ts', content: toolsIndexTemplate() },\n { path: 'src/tools/GreetTool.ts', content: greetToolTemplate() },\n { path: 'src/resources/index.ts', content: resourcesIndexTemplate() },\n { path: 'src/resources/ConfigResource.ts', content: configResourceTemplate(name) },\n { path: 'src/prompts/index.ts', content: promptsIndexTemplate() },\n { path: 'tests/tools.test.ts', content: testExampleTemplate() },\n ];\n\n for (const file of files) {\n const filePath = join(projectDir, file.path);\n await writeFile(filePath, file.content);\n console.log(` Created: ./${name}/${file.path}`);\n }\n\n console.log(`\n✅ Project created successfully!\n\nNext steps:\n\n cd ${name}\n npm install\n npm run dev\n\n${transport === 'http' ? 'Server will run at http://localhost:3000/mcp' : 'Server will run via stdio'}\n\nTo add new components:\n - Tools: Create files in src/tools/\n - Resources: Create files in src/resources/\n - Prompts: Create files in src/prompts/\n\nHappy building! 🚀\n`);\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { generateComponent } from './commands/generate.js';\nimport { initProject } from './commands/init.js';\n\nconst program = new Command();\n\nprogram.name('mcpgen').description('CLI for building MCP servers').version('0.1.0');\n\n// Init command\nprogram\n .command('init')\n .description('Initialize a new MCP server project')\n .argument('<name>', 'Project name')\n .option('-d, --description <desc>', 'Project description')\n .option('-t, --transport <type>', 'Transport type (stdio or http)', 'stdio')\n .option('--skip-install', 'Skip npm install')\n .action(async (name: string, options) => {\n try {\n await initProject({\n name,\n description: options.description,\n transport: options.transport as 'stdio' | 'http',\n skipInstall: options.skipInstall,\n });\n } catch (error) {\n console.error(`\\n❌ Error: ${error instanceof Error ? error.message : error}\\n`);\n process.exit(1);\n }\n });\n\n// make:tool command\nprogram\n .command('make:tool')\n .description('Create a new tool')\n .argument('<name>', 'Tool name')\n .action(async (name: string) => {\n try {\n await generateComponent({ type: 'tool', name });\n } catch (error) {\n console.error(`\\n❌ Error: ${error instanceof Error ? error.message : error}\\n`);\n process.exit(1);\n }\n });\n\n// make:resource command\nprogram\n .command('make:resource')\n .description('Create a new resource')\n .argument('<name>', 'Resource name')\n .action(async (name: string) => {\n try {\n await generateComponent({ type: 'resource', name });\n } catch (error) {\n console.error(`\\n❌ Error: ${error instanceof Error ? error.message : error}\\n`);\n process.exit(1);\n }\n });\n\n// make:prompt command\nprogram\n .command('make:prompt')\n .description('Create a new prompt')\n .argument('<name>', 'Prompt name')\n .action(async (name: string) => {\n try {\n await generateComponent({ type: 'prompt', name });\n } catch (error) {\n console.error(`\\n❌ Error: ${error instanceof Error ? error.message : error}\\n`);\n process.exit(1);\n }\n });\n\n// Add examples to help\nprogram.addHelpText(\n 'after',\n `\nExamples:\n $ mcpgen init my-mcp-server Create a new MCP server project\n $ mcpgen init my-api --transport http Create with HTTP transport\n $ mcpgen make:tool search Create a new tool\n $ mcpgen make:resource database Create a new resource\n $ mcpgen make:prompt summarize Create a new prompt\n`\n);\n\n// Show welcome message if no arguments provided\nif (process.argv.length <= 2) {\n const cyan = '\\x1b[36m';\n const dim = '\\x1b[2m';\n const bold = '\\x1b[1m';\n const reset = '\\x1b[0m';\n\n console.log(`\n${dim}+-------------------------------------+${reset}\n${dim}|${reset} ${dim}|${reset}\n${dim}|${reset} ${bold}${cyan}MCPGEN${reset} ${dim}v0.1.0${reset} ${dim}|${reset}\n${dim}|${reset} ${dim}|${reset}\n${dim}|${reset} A TypeScript framework for ${dim}|${reset}\n${dim}|${reset} building MCP servers ${dim}|${reset}\n${dim}|${reset} ${dim}|${reset}\n${dim}|${reset} Run ${cyan}mcpgen --help${reset} for commands ${dim}|${reset}\n${dim}|${reset} ${dim}|${reset}\n${dim}+-------------------------------------+${reset}\n`);\n} else {\n program.parse();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/generate.ts","../../src/cli/templates/index.ts","../../src/cli/commands/init.ts","../../src/cli/index.ts"],"names":["exists","access","join","mkdir","writeFile"],"mappings":"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","file":"index.js","sourcesContent":["import { mkdir, writeFile, access, readFile } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\n\nexport type ComponentType = 'tool' | 'resource' | 'prompt';\n\nexport interface GenerateOptions {\n type: ComponentType;\n name: string;\n}\n\n/**\n * Convert a name to PascalCase\n */\nfunction toPascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\n/**\n * Convert a name to kebab-case\n */\nfunction toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\n/**\n * Check if a file exists\n */\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Generate tool template\n */\nfunction toolTemplate(className: string, toolName: string): string {\n return `import { BaseTool } from '@eaperezc/mcpgen';\nimport { z } from 'zod';\n\n/**\n * ${className} - Description of what this tool does\n */\nexport class ${className} extends BaseTool {\n name = '${toolName}';\n description = 'TODO: Add description';\n\n schema = z.object({\n // TODO: Define your input schema\n input: z.string().describe('Input parameter'),\n });\n\n async execute(input: z.infer<typeof this.schema>) {\n // TODO: Implement your tool logic\n return {\n content: {\n result: \\`Processed: \\${input.input}\\`,\n },\n };\n }\n}\n`;\n}\n\n/**\n * Generate tool test template\n */\nfunction toolTestTemplate(className: string, toolName: string): string {\n return `import { describe, it, expect } from 'vitest';\nimport { createTestClient } from '@eaperezc/mcpgen/testing';\nimport { ${className} } from './${className}.js';\n\ndescribe('${className}', () => {\n it('should execute successfully', async () => {\n const client = createTestClient();\n client.registerTool(new ${className}());\n\n const result = await client.callTool('${toolName}', { input: 'test' });\n\n expect(result.content).toHaveProperty('result');\n });\n\n it('should require input parameter', async () => {\n const client = createTestClient();\n client.registerTool(new ${className}());\n\n await expect(client.callTool('${toolName}', {})).rejects.toThrow();\n });\n});\n`;\n}\n\n/**\n * Generate resource template\n */\nfunction resourceTemplate(className: string, resourceName: string): string {\n return `import { BaseResource } from '@eaperezc/mcpgen';\n\n/**\n * ${className} - Description of what this resource provides\n */\nexport class ${className} extends BaseResource {\n uri = '${resourceName}://data';\n name = '${className}';\n description = 'TODO: Add description';\n\n async read() {\n // TODO: Implement your resource logic\n return {\n contents: [\n this.json({\n // Your data here\n example: 'data',\n }),\n ],\n };\n }\n}\n`;\n}\n\n/**\n * Generate prompt template\n */\nfunction promptTemplate(className: string, promptName: string): string {\n return `import { BasePrompt } from '@eaperezc/mcpgen';\nimport { z } from 'zod';\n\n/**\n * ${className} - Description of what this prompt does\n */\nexport class ${className} extends BasePrompt {\n name = '${promptName}';\n description = 'TODO: Add description';\n\n arguments = z.object({\n // TODO: Define your arguments schema\n topic: z.string().describe('The topic to discuss'),\n });\n\n async render(args: z.infer<typeof this.arguments>) {\n // TODO: Implement your prompt logic\n return {\n messages: [\n this.user(\\`Please help me with: \\${args.topic}\\`),\n ],\n };\n }\n}\n`;\n}\n\n/**\n * Update index file to export the new component\n */\nasync function updateIndexFile(indexPath: string, className: string, fileName: string): Promise<void> {\n let content = '';\n\n if (await exists(indexPath)) {\n content = await readFile(indexPath, 'utf-8');\n }\n\n const exportLine = `export { ${className} } from './${fileName}.js';`;\n\n if (!content.includes(exportLine)) {\n // Remove comments and empty lines at the start for clean exports\n const lines = content.split('\\n').filter(line =>\n line.trim() && !line.trim().startsWith('//')\n );\n lines.push(exportLine);\n content = lines.join('\\n') + '\\n';\n await writeFile(indexPath, content);\n }\n}\n\n/**\n * Generate a new component\n */\nexport async function generateComponent(options: GenerateOptions): Promise<void> {\n const { type, name } = options;\n\n const className = toPascalCase(name) + (type === 'tool' ? 'Tool' : type === 'resource' ? 'Resource' : 'Prompt');\n const fileName = className;\n const kebabName = toKebabCase(name);\n\n // Determine directory\n const typeDir = type === 'tool' ? 'tools' : type === 'resource' ? 'resources' : 'prompts';\n const srcDir = join(process.cwd(), 'src', typeDir);\n const filePath = join(srcDir, `${fileName}.ts`);\n const testFilePath = join(srcDir, `${fileName}.test.ts`);\n const indexPath = join(srcDir, 'index.ts');\n\n // Check if src directory exists (are we in an mcpgen project?)\n if (!(await exists(join(process.cwd(), 'src')))) {\n throw new Error('No src/ directory found. Are you in an mcpgen project? Run \"mcpgen init\" first.');\n }\n\n // Create directory if it doesn't exist\n await mkdir(srcDir, { recursive: true });\n\n // Check if file already exists\n if (await exists(filePath)) {\n throw new Error(`${type} '${fileName}' already exists at ${filePath}`);\n }\n\n // Generate content based on type\n let content: string;\n let testContent: string | null = null;\n switch (type) {\n case 'tool':\n content = toolTemplate(className, kebabName);\n testContent = toolTestTemplate(className, kebabName);\n break;\n case 'resource':\n content = resourceTemplate(className, kebabName);\n break;\n case 'prompt':\n content = promptTemplate(className, kebabName);\n break;\n default:\n throw new Error(`Unknown component type: ${type}`);\n }\n\n // Write file\n await writeFile(filePath, content);\n console.log(`\\n✅ Created ${type}: ${filePath.replace(process.cwd(), '.')}`);\n\n // Write test file for tools\n if (testContent) {\n await writeFile(testFilePath, testContent);\n console.log(` Created test: ${testFilePath.replace(process.cwd(), '.')}`);\n }\n\n // Update index file\n await updateIndexFile(indexPath, className, fileName);\n console.log(` Updated: ${indexPath.replace(process.cwd(), '.')}`);\n\n console.log(`\nNext steps:\n\n 1. Edit src/${typeDir}/${fileName}.ts to implement your ${type}\n 2. Register it in src/index.ts:\n\n import { ${className} } from './${typeDir}/${fileName}.js';\n server.${type}(new ${className}());\n 3. Run tests: npm test\n`);\n}\n","/**\n * Templates for CLI scaffolding\n */\n\nexport const packageJsonTemplate = (name: string, description: string) => `{\n \"name\": \"${name}\",\n \"version\": \"0.1.0\",\n \"description\": \"${description}\",\n \"type\": \"module\",\n \"main\": \"dist/index.js\",\n \"scripts\": {\n \"build\": \"tsc\",\n \"dev\": \"tsx watch src/index.ts\",\n \"start\": \"node dist/index.js\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"lint\": \"eslint src\",\n \"typecheck\": \"tsc --noEmit\",\n \"inspector\": \"npx @modelcontextprotocol/inspector\"\n },\n \"keywords\": [\"mcp\", \"model-context-protocol\"],\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@eaperezc/mcpgen\": \"^0.1.0\",\n \"@modelcontextprotocol/sdk\": \"^1.11.0\",\n \"zod\": \"^3.23.8\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.10.0\",\n \"typescript\": \"^5.7.2\",\n \"tsx\": \"^4.19.2\",\n \"vitest\": \"^2.1.8\"\n },\n \"engines\": {\n \"node\": \">=18.0.0\"\n }\n}\n`;\n\nexport const tsconfigTemplate = () => `{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"lib\": [\"ES2022\"],\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"forceConsistentCasingInFileNames\": true,\n \"declaration\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\",\n \"resolveJsonModule\": true\n },\n \"include\": [\"src/**/*\"],\n \"exclude\": [\"node_modules\", \"dist\"]\n}\n`;\n\nexport const gitignoreTemplate = () => `# Dependencies\nnode_modules/\n\n# Build output\ndist/\n\n# Environment files\n.env\n.env.local\n.env.*.local\n\n# IDE\n.idea/\n.vscode/\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\n`;\n\nexport const mainIndexTemplate = (name: string, transport: 'stdio' | 'http') => {\n if (transport === 'http') {\n return `import { McpServer } from '@eaperezc/mcpgen';\nimport { GreetTool } from './tools/GreetTool.js';\nimport { ConfigResource } from './resources/ConfigResource.js';\n\nconst server = new McpServer({\n name: '${name}',\n version: '0.1.0',\n transport: {\n type: 'http',\n port: 3000,\n cors: { origin: '*' },\n },\n logging: { level: 'info' },\n});\n\n// Register tools\nserver.tool(new GreetTool());\n\n// Register resources\nserver.resource(new ConfigResource());\n\n// Start the server\nserver.start().then(() => {\n console.log('MCP server running at http://localhost:3000/mcp');\n});\n`;\n }\n\n return `import { McpServer } from '@eaperezc/mcpgen';\nimport { GreetTool } from './tools/GreetTool.js';\nimport { ConfigResource } from './resources/ConfigResource.js';\n\nconst server = new McpServer({\n name: '${name}',\n version: '0.1.0',\n logging: { level: 'info' },\n});\n\n// Register tools\nserver.tool(new GreetTool());\n\n// Register resources\nserver.resource(new ConfigResource());\n\n// Start the server\nserver.start();\n`;\n};\n\nexport const toolsIndexTemplate = () => `export { GreetTool } from './GreetTool.js';\n`;\n\nexport const greetToolTemplate = () => `import { BaseTool } from '@eaperezc/mcpgen';\nimport { z } from 'zod';\n\n/**\n * Example tool that greets a user\n */\nexport class GreetTool extends BaseTool {\n name = 'greet';\n description = 'Greets a user by name';\n\n schema = z.object({\n name: z.string().describe('The name of the person to greet'),\n });\n\n async execute(input: z.infer<typeof this.schema>) {\n return {\n content: {\n greeting: \\`Hello, \\${input.name}! Welcome to your MCP server.\\`,\n },\n };\n }\n}\n`;\n\nexport const resourcesIndexTemplate = () => `export { ConfigResource } from './ConfigResource.js';\n`;\n\nexport const configResourceTemplate = (name: string) => `import { BaseResource } from '@eaperezc/mcpgen';\n\n/**\n * Example resource that provides server configuration\n */\nexport class ConfigResource extends BaseResource {\n uri = 'config://server';\n name = 'Server Configuration';\n description = 'Provides server configuration information';\n\n async read() {\n return {\n contents: [\n this.json({\n serverName: '${name}',\n version: '0.1.0',\n environment: process.env.NODE_ENV ?? 'development',\n }),\n ],\n };\n }\n}\n`;\n\nexport const promptsIndexTemplate = () => `// Export your prompts here\n// export { SummarizePrompt } from './SummarizePrompt.js';\n`;\n\nexport const greetToolTestTemplate = () => `import { describe, it, expect } from 'vitest';\nimport { createTestClient } from '@eaperezc/mcpgen/testing';\nimport { GreetTool } from './GreetTool.js';\n\ndescribe('GreetTool', () => {\n it('should greet the user', async () => {\n const client = createTestClient();\n client.registerTool(new GreetTool());\n\n const result = await client.callTool('greet', { name: 'Alice' });\n\n expect(result.content).toHaveProperty('greeting');\n expect((result.content as { greeting: string }).greeting).toContain('Alice');\n });\n\n it('should require a name', async () => {\n const client = createTestClient();\n client.registerTool(new GreetTool());\n\n await expect(client.callTool('greet', {})).rejects.toThrow();\n });\n});\n`;\n\nexport const readmeTemplate = (name: string, description: string) => `# ${name}\n\n${description}\n\n## Getting Started\n\n### Installation\n\n\\`\\`\\`bash\nnpm install\n\\`\\`\\`\n\n### Development\n\nRun the server in development mode with hot reload:\n\n\\`\\`\\`bash\nnpm run dev\n\\`\\`\\`\n\n### Production\n\nBuild and run:\n\n\\`\\`\\`bash\nnpm run build\nnpm start\n\\`\\`\\`\n\n### Testing\n\n\\`\\`\\`bash\nnpm test\n\\`\\`\\`\n\n### MCP Inspector\n\nTo test and debug your server with the MCP Inspector:\n\n\\`\\`\\`bash\n# Terminal 1: Start the server\nnpm run dev\n\n# Terminal 2: Launch the inspector\nnpm run inspector\n\\`\\`\\`\n\nThen connect to \\`http://localhost:3000/mcp\\` using **Streamable HTTP** transport.\n\n## Project Structure\n\n\\`\\`\\`\n${name}/\n├── src/\n│ ├── tools/ # MCP tools\n│ │ ├── GreetTool.ts\n│ │ └── GreetTool.test.ts\n│ ├── resources/ # MCP resources\n│ │ └── ConfigResource.ts\n│ ├── prompts/ # MCP prompts\n│ └── index.ts # Server entry point\n├── package.json\n└── tsconfig.json\n\\`\\`\\`\n\n## Adding New Components\n\n### Tools\n\nCreate a new file in \\`src/tools/\\`:\n\n\\`\\`\\`typescript\nimport { BaseTool } from '@eaperezc/mcpgen';\nimport { z } from 'zod';\n\nexport class MyTool extends BaseTool {\n name = 'my-tool';\n description = 'Description of what this tool does';\n\n schema = z.object({\n // Define your input schema\n });\n\n async execute(input: z.infer<typeof this.schema>) {\n // Implement your tool logic\n return { content: { result: 'success' } };\n }\n}\n\\`\\`\\`\n\n### Resources\n\nCreate a new file in \\`src/resources/\\`:\n\n\\`\\`\\`typescript\nimport { BaseResource } from '@eaperezc/mcpgen';\n\nexport class MyResource extends BaseResource {\n uri = 'my-resource://example';\n name = 'My Resource';\n\n async read() {\n return { contents: [this.json({ data: 'example' })] };\n }\n}\n\\`\\`\\`\n\n## License\n\nMIT\n`;\n\nexport const vitestConfigTemplate = () => `import { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n test: {\n globals: true,\n environment: 'node',\n },\n});\n`;\n","import { mkdir, writeFile, access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport {\n packageJsonTemplate,\n tsconfigTemplate,\n gitignoreTemplate,\n mainIndexTemplate,\n toolsIndexTemplate,\n greetToolTemplate,\n greetToolTestTemplate,\n resourcesIndexTemplate,\n configResourceTemplate,\n promptsIndexTemplate,\n readmeTemplate,\n vitestConfigTemplate,\n} from '../templates/index.js';\n\nexport interface InitOptions {\n name: string;\n description?: string;\n transport?: 'stdio' | 'http';\n skipInstall?: boolean;\n}\n\n/**\n * Check if a directory exists\n */\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Initialize a new MCP server project\n */\nexport async function initProject(options: InitOptions): Promise<void> {\n const {\n name,\n description = `An MCP server built with @eaperezc/mcpgen`,\n transport = 'http',\n } = options;\n\n const projectDir = join(process.cwd(), name);\n\n // Check if directory already exists\n if (await exists(projectDir)) {\n throw new Error(`Directory '${name}' already exists`);\n }\n\n console.log(`\\nCreating new MCP server: ${name}\\n`);\n\n // Create directories\n const dirs = [\n projectDir,\n join(projectDir, 'src'),\n join(projectDir, 'src', 'tools'),\n join(projectDir, 'src', 'resources'),\n join(projectDir, 'src', 'prompts'),\n ];\n\n for (const dir of dirs) {\n await mkdir(dir, { recursive: true });\n console.log(` Created: ${dir.replace(process.cwd(), '.')}`);\n }\n\n // Create files\n const files: Array<{ path: string; content: string }> = [\n { path: 'package.json', content: packageJsonTemplate(name, description) },\n { path: 'tsconfig.json', content: tsconfigTemplate() },\n { path: '.gitignore', content: gitignoreTemplate() },\n { path: 'vitest.config.ts', content: vitestConfigTemplate() },\n { path: 'README.md', content: readmeTemplate(name, description) },\n { path: 'src/index.ts', content: mainIndexTemplate(name, transport) },\n { path: 'src/tools/index.ts', content: toolsIndexTemplate() },\n { path: 'src/tools/GreetTool.ts', content: greetToolTemplate() },\n { path: 'src/tools/GreetTool.test.ts', content: greetToolTestTemplate() },\n { path: 'src/resources/index.ts', content: resourcesIndexTemplate() },\n { path: 'src/resources/ConfigResource.ts', content: configResourceTemplate(name) },\n { path: 'src/prompts/index.ts', content: promptsIndexTemplate() },\n ];\n\n for (const file of files) {\n const filePath = join(projectDir, file.path);\n await writeFile(filePath, file.content);\n console.log(` Created: ./${name}/${file.path}`);\n }\n\n console.log(`\n✅ Project created successfully!\n\nNext steps:\n\n cd ${name}\n npm install\n npm run dev\n\n${transport === 'http' ? 'Server will run at http://localhost:3000/mcp' : 'Server will run via stdio'}\n\nTo add new components:\n - Tools: Create files in src/tools/\n - Resources: Create files in src/resources/\n - Prompts: Create files in src/prompts/\n\nHappy building! 🚀\n`);\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { generateComponent } from './commands/generate.js';\nimport { initProject } from './commands/init.js';\n\nconst program = new Command();\n\nprogram.name('mcpgen').description('CLI for building MCP servers').version('0.1.0');\n\n// Init command\nprogram\n .command('init')\n .description('Initialize a new MCP server project')\n .argument('<name>', 'Project name')\n .option('-d, --description <desc>', 'Project description')\n .option('-t, --transport <type>', 'Transport type (http or stdio)', 'http')\n .option('--skip-install', 'Skip npm install')\n .action(async (name: string, options) => {\n try {\n await initProject({\n name,\n description: options.description,\n transport: options.transport as 'stdio' | 'http',\n skipInstall: options.skipInstall,\n });\n } catch (error) {\n console.error(`\\n❌ Error: ${error instanceof Error ? error.message : error}\\n`);\n process.exit(1);\n }\n });\n\n// make:tool command\nprogram\n .command('make:tool')\n .description('Create a new tool')\n .argument('<name>', 'Tool name')\n .action(async (name: string) => {\n try {\n await generateComponent({ type: 'tool', name });\n } catch (error) {\n console.error(`\\n❌ Error: ${error instanceof Error ? error.message : error}\\n`);\n process.exit(1);\n }\n });\n\n// make:resource command\nprogram\n .command('make:resource')\n .description('Create a new resource')\n .argument('<name>', 'Resource name')\n .action(async (name: string) => {\n try {\n await generateComponent({ type: 'resource', name });\n } catch (error) {\n console.error(`\\n❌ Error: ${error instanceof Error ? error.message : error}\\n`);\n process.exit(1);\n }\n });\n\n// make:prompt command\nprogram\n .command('make:prompt')\n .description('Create a new prompt')\n .argument('<name>', 'Prompt name')\n .action(async (name: string) => {\n try {\n await generateComponent({ type: 'prompt', name });\n } catch (error) {\n console.error(`\\n❌ Error: ${error instanceof Error ? error.message : error}\\n`);\n process.exit(1);\n }\n });\n\n// Add examples to help\nprogram.addHelpText(\n 'after',\n `\nExamples:\n $ mcpgen init my-mcp-server Create a new MCP server (HTTP)\n $ mcpgen init my-api --transport stdio Create with stdio transport\n $ mcpgen make:tool search Create a new tool\n $ mcpgen make:resource database Create a new resource\n $ mcpgen make:prompt summarize Create a new prompt\n`\n);\n\n// Show welcome message if no arguments provided\nif (process.argv.length <= 2) {\n const yellow = '\\x1b[33m';\n const cyan = '\\x1b[36m';\n const dim = '\\x1b[2m';\n const bold = '\\x1b[1m';\n const reset = '\\x1b[0m';\n\n console.log(`\n${dim}+-------------------------------------+${reset}\n${dim}|${reset} ${dim}|${reset}\n${dim}|${reset} ${bold}${yellow}MCP-GEN${reset} ${dim}v0.1.0${reset} ${dim}|${reset}\n${dim}|${reset} ${dim}|${reset}\n${dim}|${reset} A TypeScript framework for ${dim}|${reset}\n${dim}|${reset} building MCP servers ${dim}|${reset}\n${dim}|${reset} ${dim}|${reset}\n${dim}|${reset} Run ${cyan}mcpgen --help${reset} for commands ${dim}|${reset}\n${dim}|${reset} ${dim}|${reset}\n${dim}+-------------------------------------+${reset}\n`);\n} else {\n program.parse();\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -879,8 +879,9 @@ var HttpTransport = class {
|
|
|
879
879
|
config;
|
|
880
880
|
logger;
|
|
881
881
|
httpServer = null;
|
|
882
|
-
mcpTransport = null;
|
|
883
882
|
running = false;
|
|
883
|
+
serverFactory = null;
|
|
884
|
+
sessions = /* @__PURE__ */ new Map();
|
|
884
885
|
constructor(config, logger2) {
|
|
885
886
|
this.config = {
|
|
886
887
|
...config,
|
|
@@ -892,17 +893,13 @@ var HttpTransport = class {
|
|
|
892
893
|
}
|
|
893
894
|
/**
|
|
894
895
|
* Start the HTTP transport
|
|
896
|
+
* @param serverFactory - Factory function to create new Server instances per session
|
|
895
897
|
*/
|
|
896
|
-
async start(
|
|
898
|
+
async start(serverFactory) {
|
|
897
899
|
if (this.running) {
|
|
898
900
|
throw new Error("Transport is already running");
|
|
899
901
|
}
|
|
900
|
-
this.
|
|
901
|
-
sessionIdGenerator: () => crypto.randomUUID()
|
|
902
|
-
});
|
|
903
|
-
if (mcpServer) {
|
|
904
|
-
await mcpServer.connect(this.mcpTransport);
|
|
905
|
-
}
|
|
902
|
+
this.serverFactory = serverFactory ?? null;
|
|
906
903
|
this.httpServer = http.createServer((req, res) => {
|
|
907
904
|
this.handleRequest(req, res);
|
|
908
905
|
});
|
|
@@ -930,10 +927,15 @@ var HttpTransport = class {
|
|
|
930
927
|
if (!this.running) {
|
|
931
928
|
return;
|
|
932
929
|
}
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
930
|
+
for (const [sessionId, session] of this.sessions) {
|
|
931
|
+
try {
|
|
932
|
+
await session.transport.close();
|
|
933
|
+
await session.server.close();
|
|
934
|
+
} catch (error) {
|
|
935
|
+
this.logger.error(`Error closing session ${sessionId}`, error instanceof Error ? error : void 0);
|
|
936
|
+
}
|
|
936
937
|
}
|
|
938
|
+
this.sessions.clear();
|
|
937
939
|
if (this.httpServer) {
|
|
938
940
|
return new Promise((resolve, reject) => {
|
|
939
941
|
this.httpServer.close((error) => {
|
|
@@ -957,10 +959,34 @@ var HttpTransport = class {
|
|
|
957
959
|
return this.running;
|
|
958
960
|
}
|
|
959
961
|
/**
|
|
960
|
-
* Get
|
|
962
|
+
* Get all active sessions (for debugging/monitoring)
|
|
963
|
+
*/
|
|
964
|
+
getActiveSessions() {
|
|
965
|
+
return Array.from(this.sessions.keys());
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* Get or create a session for the given session ID
|
|
961
969
|
*/
|
|
962
|
-
|
|
963
|
-
|
|
970
|
+
async getOrCreateSession(sessionId) {
|
|
971
|
+
let session = this.sessions.get(sessionId);
|
|
972
|
+
if (!session) {
|
|
973
|
+
if (!this.serverFactory) {
|
|
974
|
+
throw new Error("No server factory configured");
|
|
975
|
+
}
|
|
976
|
+
const transport = new streamableHttp_js.StreamableHTTPServerTransport({
|
|
977
|
+
sessionIdGenerator: () => sessionId
|
|
978
|
+
});
|
|
979
|
+
const server = this.serverFactory();
|
|
980
|
+
await server.connect(transport);
|
|
981
|
+
session = {
|
|
982
|
+
transport,
|
|
983
|
+
server,
|
|
984
|
+
createdAt: Date.now()
|
|
985
|
+
};
|
|
986
|
+
this.sessions.set(sessionId, session);
|
|
987
|
+
this.logger.debug("Created new session", { sessionId });
|
|
988
|
+
}
|
|
989
|
+
return session;
|
|
964
990
|
}
|
|
965
991
|
/**
|
|
966
992
|
* Handle incoming HTTP request
|
|
@@ -981,9 +1007,9 @@ var HttpTransport = class {
|
|
|
981
1007
|
return;
|
|
982
1008
|
}
|
|
983
1009
|
if (path === this.config.basePath || path === `${this.config.basePath}/`) {
|
|
984
|
-
if (!this.
|
|
1010
|
+
if (!this.serverFactory) {
|
|
985
1011
|
res.writeHead(503, { "Content-Type": "application/json" });
|
|
986
|
-
res.end(JSON.stringify({ error: "
|
|
1012
|
+
res.end(JSON.stringify({ error: "Server factory not configured" }));
|
|
987
1013
|
return;
|
|
988
1014
|
}
|
|
989
1015
|
try {
|
|
@@ -991,7 +1017,12 @@ var HttpTransport = class {
|
|
|
991
1017
|
if (req.method === "POST") {
|
|
992
1018
|
body = await this.parseBody(req);
|
|
993
1019
|
}
|
|
994
|
-
|
|
1020
|
+
let sessionId = req.headers["mcp-session-id"];
|
|
1021
|
+
if (!sessionId) {
|
|
1022
|
+
sessionId = crypto.randomUUID();
|
|
1023
|
+
}
|
|
1024
|
+
const session = await this.getOrCreateSession(sessionId);
|
|
1025
|
+
await session.transport.handleRequest(req, res, body);
|
|
995
1026
|
} catch (error) {
|
|
996
1027
|
this.logger.error("Error handling MCP request", error instanceof Error ? error : void 0);
|
|
997
1028
|
if (!res.headersSent) {
|
|
@@ -1108,10 +1139,17 @@ var McpServer = class {
|
|
|
1108
1139
|
};
|
|
1109
1140
|
}
|
|
1110
1141
|
/**
|
|
1111
|
-
* Set up MCP request handlers
|
|
1142
|
+
* Set up MCP request handlers on a server instance
|
|
1112
1143
|
*/
|
|
1113
1144
|
setupHandlers() {
|
|
1114
|
-
this.
|
|
1145
|
+
this.setupHandlersOnServer(this.server);
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Configure handlers on a given Server instance
|
|
1149
|
+
* This is used both for the main server (stdio) and for per-session servers (http)
|
|
1150
|
+
*/
|
|
1151
|
+
setupHandlersOnServer(server) {
|
|
1152
|
+
server.setRequestHandler(types_js.ListToolsRequestSchema, async () => {
|
|
1115
1153
|
return runInRequestContextAsync(async () => {
|
|
1116
1154
|
const tools = this.toolRegistry.getAll();
|
|
1117
1155
|
return {
|
|
@@ -1123,7 +1161,7 @@ var McpServer = class {
|
|
|
1123
1161
|
};
|
|
1124
1162
|
});
|
|
1125
1163
|
});
|
|
1126
|
-
|
|
1164
|
+
server.setRequestHandler(types_js.CallToolRequestSchema, async (request) => {
|
|
1127
1165
|
return runInRequestContextAsync(async () => {
|
|
1128
1166
|
const { name, arguments: args } = request.params;
|
|
1129
1167
|
const tool = this.toolRegistry.get(name);
|
|
@@ -1142,7 +1180,7 @@ var McpServer = class {
|
|
|
1142
1180
|
};
|
|
1143
1181
|
});
|
|
1144
1182
|
});
|
|
1145
|
-
|
|
1183
|
+
server.setRequestHandler(types_js.ListResourcesRequestSchema, async () => {
|
|
1146
1184
|
return runInRequestContextAsync(async () => {
|
|
1147
1185
|
const resources = this.resourceRegistry.getAll();
|
|
1148
1186
|
return {
|
|
@@ -1155,7 +1193,7 @@ var McpServer = class {
|
|
|
1155
1193
|
};
|
|
1156
1194
|
});
|
|
1157
1195
|
});
|
|
1158
|
-
|
|
1196
|
+
server.setRequestHandler(types_js.ReadResourceRequestSchema, async (request) => {
|
|
1159
1197
|
return runInRequestContextAsync(async () => {
|
|
1160
1198
|
const { uri } = request.params;
|
|
1161
1199
|
const resource = this.resourceRegistry.get(uri);
|
|
@@ -1171,7 +1209,7 @@ var McpServer = class {
|
|
|
1171
1209
|
};
|
|
1172
1210
|
});
|
|
1173
1211
|
});
|
|
1174
|
-
|
|
1212
|
+
server.setRequestHandler(types_js.ListPromptsRequestSchema, async () => {
|
|
1175
1213
|
return runInRequestContextAsync(async () => {
|
|
1176
1214
|
const prompts = this.promptRegistry.getAll();
|
|
1177
1215
|
return {
|
|
@@ -1190,7 +1228,7 @@ var McpServer = class {
|
|
|
1190
1228
|
};
|
|
1191
1229
|
});
|
|
1192
1230
|
});
|
|
1193
|
-
|
|
1231
|
+
server.setRequestHandler(types_js.GetPromptRequestSchema, async (request) => {
|
|
1194
1232
|
return runInRequestContextAsync(async () => {
|
|
1195
1233
|
const { name, arguments: args } = request.params;
|
|
1196
1234
|
const prompt = this.promptRegistry.get(name);
|
|
@@ -1208,6 +1246,24 @@ var McpServer = class {
|
|
|
1208
1246
|
});
|
|
1209
1247
|
});
|
|
1210
1248
|
}
|
|
1249
|
+
/**
|
|
1250
|
+
* Create a server factory for HTTP transport (creates per-session servers)
|
|
1251
|
+
*/
|
|
1252
|
+
createServerFactory() {
|
|
1253
|
+
return () => {
|
|
1254
|
+
const server = new index_js.Server(
|
|
1255
|
+
{
|
|
1256
|
+
name: this.config.name,
|
|
1257
|
+
version: this.config.version
|
|
1258
|
+
},
|
|
1259
|
+
{
|
|
1260
|
+
capabilities: this.getCapabilities()
|
|
1261
|
+
}
|
|
1262
|
+
);
|
|
1263
|
+
this.setupHandlersOnServer(server);
|
|
1264
|
+
return server;
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1211
1267
|
tool(toolOrName, definition) {
|
|
1212
1268
|
if (typeof toolOrName === "string" && definition) {
|
|
1213
1269
|
this.toolRegistry.registerInline(toolOrName, definition);
|
|
@@ -1251,14 +1307,6 @@ var McpServer = class {
|
|
|
1251
1307
|
}
|
|
1252
1308
|
const transportConfig = this.config.transport ?? "stdio";
|
|
1253
1309
|
const transportType = typeof transportConfig === "string" ? transportConfig : transportConfig.type;
|
|
1254
|
-
this.logger.info("Starting MCP server", {
|
|
1255
|
-
name: this.config.name,
|
|
1256
|
-
version: this.config.version,
|
|
1257
|
-
transport: transportType,
|
|
1258
|
-
tools: this.toolRegistry.size,
|
|
1259
|
-
resources: this.resourceRegistry.size,
|
|
1260
|
-
prompts: this.promptRegistry.size
|
|
1261
|
-
});
|
|
1262
1310
|
try {
|
|
1263
1311
|
await this.hooks.onBeforeStart?.();
|
|
1264
1312
|
if (transportType === "stdio") {
|
|
@@ -1267,7 +1315,7 @@ var McpServer = class {
|
|
|
1267
1315
|
} else if (transportType === "http") {
|
|
1268
1316
|
const httpConfig = transportConfig;
|
|
1269
1317
|
this.httpTransport = new HttpTransport(httpConfig, this.logger);
|
|
1270
|
-
await this.httpTransport.start(this.
|
|
1318
|
+
await this.httpTransport.start(this.createServerFactory());
|
|
1271
1319
|
} else if (transportType === "sse") {
|
|
1272
1320
|
throw new McpError({
|
|
1273
1321
|
code: "NOT_IMPLEMENTED" /* NOT_IMPLEMENTED */,
|
|
@@ -1276,8 +1324,12 @@ var McpServer = class {
|
|
|
1276
1324
|
}
|
|
1277
1325
|
this.running = true;
|
|
1278
1326
|
await this.hooks.onAfterStart?.();
|
|
1279
|
-
this.logger.info("MCP server started
|
|
1327
|
+
this.logger.info("MCP server started", {
|
|
1328
|
+
version: this.config.version,
|
|
1280
1329
|
transport: transportType,
|
|
1330
|
+
tools: this.toolRegistry.size,
|
|
1331
|
+
resources: this.resourceRegistry.size,
|
|
1332
|
+
prompts: this.promptRegistry.size,
|
|
1281
1333
|
...transportType === "http" && {
|
|
1282
1334
|
port: transportConfig.port,
|
|
1283
1335
|
host: transportConfig.host ?? "0.0.0.0"
|