@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 CHANGED
@@ -1,4 +1,4 @@
1
- # mcpkit
1
+ # @eaperezc/mcpgen
2
2
 
3
3
  A TypeScript framework for building MCP (Model Context Protocol) servers with excellent developer experience.
4
4
 
@@ -9,14 +9,14 @@ A TypeScript framework for building MCP (Model Context Protocol) servers with ex
9
9
  - **Built-in Testing** - In-memory test client for unit testing your MCP servers
10
10
  - **Structured Logging** - Pino-based logging with correlation IDs
11
11
  - **Type-safe** - Full TypeScript support with Zod schema validation
12
- - **Production Ready** - Supports stdio and HTTP transports
12
+ - **Production Ready** - Supports HTTP and stdio transports
13
13
 
14
14
  ## Installation
15
15
 
16
16
  ```bash
17
- npm install mcpkit @modelcontextprotocol/sdk
17
+ npm install @eaperezc/mcpgen @modelcontextprotocol/sdk
18
18
  # or
19
- pnpm add mcpkit @modelcontextprotocol/sdk
19
+ pnpm add @eaperezc/mcpgen @modelcontextprotocol/sdk
20
20
  ```
21
21
 
22
22
  ## CLI - Scaffold New Projects
@@ -25,13 +25,13 @@ The fastest way to get started is using the CLI:
25
25
 
26
26
  ```bash
27
27
  # Install globally
28
- npm install -g mcpkit
28
+ npm install -g @eaperezc/mcpgen
29
29
 
30
- # Create a new project
31
- mcpkit init my-mcp-server
30
+ # Create a new project (HTTP by default)
31
+ mcpgen init my-mcp-server
32
32
 
33
- # Create with HTTP transport
34
- mcpkit init my-api --transport http
33
+ # Create with stdio transport
34
+ mcpgen init my-api --transport stdio
35
35
 
36
36
  # Navigate and start
37
37
  cd my-mcp-server
@@ -43,31 +43,31 @@ npm run dev
43
43
 
44
44
  ```bash
45
45
  # Generate a new tool
46
- mcpkit generate tool search-users
46
+ mcpgen make:tool search-users
47
47
 
48
48
  # Generate a new resource
49
- mcpkit g resource database
49
+ mcpgen make:resource database
50
50
 
51
51
  # Generate a new prompt
52
- mcpkit new prompt summarize
52
+ mcpgen make:prompt summarize
53
53
  ```
54
54
 
55
55
  ### CLI Commands
56
56
 
57
57
  | Command | Description |
58
58
  |---------|-------------|
59
- | `mcpkit init <name>` | Create a new MCP server project |
60
- | `mcpkit init <name> --transport http` | Create with HTTP transport |
61
- | `mcpkit generate tool <name>` | Generate a new tool |
62
- | `mcpkit generate resource <name>` | Generate a new resource |
63
- | `mcpkit generate prompt <name>` | Generate a new prompt |
59
+ | `mcpgen init <name>` | Create a new MCP server project (HTTP) |
60
+ | `mcpgen init <name> --transport stdio` | Create with stdio transport |
61
+ | `mcpgen make:tool <name>` | Generate a new tool |
62
+ | `mcpgen make:resource <name>` | Generate a new resource |
63
+ | `mcpgen make:prompt <name>` | Generate a new prompt |
64
64
 
65
65
  ## Quick Start
66
66
 
67
67
  ### Class-based API (Recommended)
68
68
 
69
69
  ```typescript
70
- import { McpServer, BaseTool, BaseResource } from 'mcpkit';
70
+ import { McpServer, BaseTool, BaseResource } from '@eaperezc/mcpgen';
71
71
  import { z } from 'zod';
72
72
 
73
73
  // Define a tool
@@ -98,6 +98,10 @@ class ConfigResource extends BaseResource {
98
98
  const server = new McpServer({
99
99
  name: 'my-server',
100
100
  version: '1.0.0',
101
+ transport: {
102
+ type: 'http',
103
+ port: 3000,
104
+ },
101
105
  });
102
106
 
103
107
  server.tool(new GreetTool());
@@ -108,7 +112,7 @@ server.start();
108
112
  ### Fluent Builder API
109
113
 
110
114
  ```typescript
111
- import { createServer } from 'mcpkit';
115
+ import { createServer } from '@eaperezc/mcpgen';
112
116
  import { z } from 'zod';
113
117
 
114
118
  const server = createServer({ name: 'my-server', version: '1.0.0' })
@@ -128,11 +132,11 @@ await server.start();
128
132
 
129
133
  ## Testing
130
134
 
131
- mcpkit includes a built-in test client for unit testing your MCP servers:
135
+ mcpgen includes a built-in test client for unit testing your MCP servers:
132
136
 
133
137
  ```typescript
134
138
  import { describe, it, expect } from 'vitest';
135
- import { createTestClient } from 'mcpkit/testing';
139
+ import { createTestClient } from '@eaperezc/mcpgen/testing';
136
140
  import { GreetTool } from './tools/GreetTool';
137
141
 
138
142
  describe('GreetTool', () => {
@@ -156,8 +160,8 @@ describe('GreetTool', () => {
156
160
  ### Testing with Server Builder
157
161
 
158
162
  ```typescript
159
- import { TestClient } from 'mcpkit/testing';
160
- import { createServer } from 'mcpkit';
163
+ import { TestClient } from '@eaperezc/mcpgen/testing';
164
+ import { createServer } from '@eaperezc/mcpgen';
161
165
 
162
166
  const server = createServer({ name: 'test', version: '1.0.0' })
163
167
  .tool('add', {
@@ -241,7 +245,7 @@ abstract class BasePrompt<TArgs extends z.ZodType> {
241
245
 
242
246
  ## Project Structure
243
247
 
244
- When building MCP servers with mcpkit, we recommend:
248
+ When building MCP servers with mcpgen, we recommend:
245
249
 
246
250
  ```
247
251
  my-mcp-server/
@@ -263,10 +267,10 @@ my-mcp-server/
263
267
 
264
268
  ## HTTP Transport
265
269
 
266
- mcpkit supports HTTP transport for remote MCP servers:
270
+ mcpgen uses HTTP transport by default:
267
271
 
268
272
  ```typescript
269
- import { McpServer } from 'mcpkit';
273
+ import { McpServer } from '@eaperezc/mcpgen';
270
274
 
271
275
  const server = new McpServer({
272
276
  name: 'my-http-server',
@@ -316,7 +320,7 @@ await server.start();
316
320
  - [x] HTTP transport (production-ready)
317
321
  - [x] Testing utilities
318
322
  - [x] Structured logging
319
- - [x] CLI scaffolding (`mcpkit init`, `mcpkit generate`)
323
+ - [x] CLI scaffolding (`mcpgen init`, `mcpgen make:*`)
320
324
  - [ ] SSE transport
321
325
  - [ ] OAuth 2.1 authentication
322
326
  - [ ] API key authentication
@@ -20,7 +20,7 @@ async function exists(path) {
20
20
  }
21
21
  }
22
22
  function toolTemplate(className, toolName) {
23
- return `import { BaseTool } from 'mcpkit';
23
+ return `import { BaseTool } from '@eaperezc/mcpgen';
24
24
  import { z } from 'zod';
25
25
 
26
26
  /**
@@ -46,8 +46,32 @@ export class ${className} extends BaseTool {
46
46
  }
47
47
  `;
48
48
  }
49
+ function toolTestTemplate(className, toolName) {
50
+ return `import { describe, it, expect } from 'vitest';
51
+ import { createTestClient } from '@eaperezc/mcpgen/testing';
52
+ import { ${className} } from './${className}.js';
53
+
54
+ describe('${className}', () => {
55
+ it('should execute successfully', async () => {
56
+ const client = createTestClient();
57
+ client.registerTool(new ${className}());
58
+
59
+ const result = await client.callTool('${toolName}', { input: 'test' });
60
+
61
+ expect(result.content).toHaveProperty('result');
62
+ });
63
+
64
+ it('should require input parameter', async () => {
65
+ const client = createTestClient();
66
+ client.registerTool(new ${className}());
67
+
68
+ await expect(client.callTool('${toolName}', {})).rejects.toThrow();
69
+ });
70
+ });
71
+ `;
72
+ }
49
73
  function resourceTemplate(className, resourceName) {
50
- return `import { BaseResource } from 'mcpkit';
74
+ return `import { BaseResource } from '@eaperezc/mcpgen';
51
75
 
52
76
  /**
53
77
  * ${className} - Description of what this resource provides
@@ -72,7 +96,7 @@ export class ${className} extends BaseResource {
72
96
  `;
73
97
  }
74
98
  function promptTemplate(className, promptName) {
75
- return `import { BasePrompt } from 'mcpkit';
99
+ return `import { BasePrompt } from '@eaperezc/mcpgen';
76
100
  import { z } from 'zod';
77
101
 
78
102
  /**
@@ -121,18 +145,21 @@ async function generateComponent(options) {
121
145
  const typeDir = type === "tool" ? "tools" : type === "resource" ? "resources" : "prompts";
122
146
  const srcDir = path.join(process.cwd(), "src", typeDir);
123
147
  const filePath = path.join(srcDir, `${fileName}.ts`);
148
+ const testFilePath = path.join(srcDir, `${fileName}.test.ts`);
124
149
  const indexPath = path.join(srcDir, "index.ts");
125
150
  if (!await exists(path.join(process.cwd(), "src"))) {
126
- throw new Error('No src/ directory found. Are you in an mcpkit project? Run "mcpkit init" first.');
151
+ throw new Error('No src/ directory found. Are you in an mcpgen project? Run "mcpgen init" first.');
127
152
  }
128
153
  await promises.mkdir(srcDir, { recursive: true });
129
154
  if (await exists(filePath)) {
130
155
  throw new Error(`${type} '${fileName}' already exists at ${filePath}`);
131
156
  }
132
157
  let content;
158
+ let testContent = null;
133
159
  switch (type) {
134
160
  case "tool":
135
161
  content = toolTemplate(className, kebabName);
162
+ testContent = toolTestTemplate(className, kebabName);
136
163
  break;
137
164
  case "resource":
138
165
  content = resourceTemplate(className, kebabName);
@@ -146,6 +173,10 @@ async function generateComponent(options) {
146
173
  await promises.writeFile(filePath, content);
147
174
  console.log(`
148
175
  \u2705 Created ${type}: ${filePath.replace(process.cwd(), ".")}`);
176
+ if (testContent) {
177
+ await promises.writeFile(testFilePath, testContent);
178
+ console.log(` Created test: ${testFilePath.replace(process.cwd(), ".")}`);
179
+ }
149
180
  await updateIndexFile(indexPath, className, fileName);
150
181
  console.log(` Updated: ${indexPath.replace(process.cwd(), ".")}`);
151
182
  console.log(`
@@ -154,8 +185,9 @@ Next steps:
154
185
  1. Edit src/${typeDir}/${fileName}.ts to implement your ${type}
155
186
  2. Register it in src/index.ts:
156
187
 
157
- import { ${className} } from './tools/${fileName}.js';
188
+ import { ${className} } from './${typeDir}/${fileName}.js';
158
189
  server.${type}(new ${className}());
190
+ 3. Run tests: npm test
159
191
  `);
160
192
  }
161
193
 
@@ -173,7 +205,8 @@ var packageJsonTemplate = (name, description) => `{
173
205
  "test": "vitest run",
174
206
  "test:watch": "vitest",
175
207
  "lint": "eslint src",
176
- "typecheck": "tsc --noEmit"
208
+ "typecheck": "tsc --noEmit",
209
+ "inspector": "npx @modelcontextprotocol/inspector"
177
210
  },
178
211
  "keywords": ["mcp", "model-context-protocol"],
179
212
  "license": "MIT",
@@ -338,9 +371,9 @@ export class ConfigResource extends BaseResource {
338
371
  var promptsIndexTemplate = () => `// Export your prompts here
339
372
  // export { SummarizePrompt } from './SummarizePrompt.js';
340
373
  `;
341
- var testExampleTemplate = () => `import { describe, it, expect } from 'vitest';
374
+ var greetToolTestTemplate = () => `import { describe, it, expect } from 'vitest';
342
375
  import { createTestClient } from '@eaperezc/mcpgen/testing';
343
- import { GreetTool } from '../src/tools/GreetTool.js';
376
+ import { GreetTool } from './GreetTool.js';
344
377
 
345
378
  describe('GreetTool', () => {
346
379
  it('should greet the user', async () => {
@@ -396,19 +429,32 @@ npm start
396
429
  npm test
397
430
  \`\`\`
398
431
 
432
+ ### MCP Inspector
433
+
434
+ To test and debug your server with the MCP Inspector:
435
+
436
+ \`\`\`bash
437
+ # Terminal 1: Start the server
438
+ npm run dev
439
+
440
+ # Terminal 2: Launch the inspector
441
+ npm run inspector
442
+ \`\`\`
443
+
444
+ Then connect to \`http://localhost:3000/mcp\` using **Streamable HTTP** transport.
445
+
399
446
  ## Project Structure
400
447
 
401
448
  \`\`\`
402
449
  ${name}/
403
450
  \u251C\u2500\u2500 src/
404
- \u2502 \u251C\u2500\u2500 tools/ # MCP tools
405
- \u2502 \u2502 \u2514\u2500\u2500 GreetTool.ts
406
- \u2502 \u251C\u2500\u2500 resources/ # MCP resources
451
+ \u2502 \u251C\u2500\u2500 tools/ # MCP tools
452
+ \u2502 \u2502 \u251C\u2500\u2500 GreetTool.ts
453
+ \u2502 \u2502 \u2514\u2500\u2500 GreetTool.test.ts
454
+ \u2502 \u251C\u2500\u2500 resources/ # MCP resources
407
455
  \u2502 \u2502 \u2514\u2500\u2500 ConfigResource.ts
408
- \u2502 \u251C\u2500\u2500 prompts/ # MCP prompts
409
- \u2502 \u2514\u2500\u2500 index.ts # Server entry point
410
- \u251C\u2500\u2500 tests/
411
- \u2502 \u2514\u2500\u2500 tools.test.ts
456
+ \u2502 \u251C\u2500\u2500 prompts/ # MCP prompts
457
+ \u2502 \u2514\u2500\u2500 index.ts # Server entry point
412
458
  \u251C\u2500\u2500 package.json
413
459
  \u2514\u2500\u2500 tsconfig.json
414
460
  \`\`\`
@@ -482,7 +528,7 @@ async function initProject(options) {
482
528
  const {
483
529
  name,
484
530
  description = `An MCP server built with @eaperezc/mcpgen`,
485
- transport = "stdio"
531
+ transport = "http"
486
532
  } = options;
487
533
  const projectDir = path.join(process.cwd(), name);
488
534
  if (await exists2(projectDir)) {
@@ -496,8 +542,7 @@ Creating new MCP server: ${name}
496
542
  path.join(projectDir, "src"),
497
543
  path.join(projectDir, "src", "tools"),
498
544
  path.join(projectDir, "src", "resources"),
499
- path.join(projectDir, "src", "prompts"),
500
- path.join(projectDir, "tests")
545
+ path.join(projectDir, "src", "prompts")
501
546
  ];
502
547
  for (const dir of dirs) {
503
548
  await promises.mkdir(dir, { recursive: true });
@@ -512,10 +557,10 @@ Creating new MCP server: ${name}
512
557
  { path: "src/index.ts", content: mainIndexTemplate(name, transport) },
513
558
  { path: "src/tools/index.ts", content: toolsIndexTemplate() },
514
559
  { path: "src/tools/GreetTool.ts", content: greetToolTemplate() },
560
+ { path: "src/tools/GreetTool.test.ts", content: greetToolTestTemplate() },
515
561
  { path: "src/resources/index.ts", content: resourcesIndexTemplate() },
516
562
  { path: "src/resources/ConfigResource.ts", content: configResourceTemplate(name) },
517
- { path: "src/prompts/index.ts", content: promptsIndexTemplate() },
518
- { path: "tests/tools.test.ts", content: testExampleTemplate() }
563
+ { path: "src/prompts/index.ts", content: promptsIndexTemplate() }
519
564
  ];
520
565
  for (const file of files) {
521
566
  const filePath = path.join(projectDir, file.path);
@@ -545,7 +590,7 @@ Happy building! \u{1F680}
545
590
  // src/cli/index.ts
546
591
  var program = new commander.Command();
547
592
  program.name("mcpgen").description("CLI for building MCP servers").version("0.1.0");
548
- 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 (stdio or http)", "stdio").option("--skip-install", "Skip npm install").action(async (name, options) => {
593
+ 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) => {
549
594
  try {
550
595
  await initProject({
551
596
  name,
@@ -594,14 +639,15 @@ program.addHelpText(
594
639
  "after",
595
640
  `
596
641
  Examples:
597
- $ mcpgen init my-mcp-server Create a new MCP server project
598
- $ mcpgen init my-api --transport http Create with HTTP transport
642
+ $ mcpgen init my-mcp-server Create a new MCP server (HTTP)
643
+ $ mcpgen init my-api --transport stdio Create with stdio transport
599
644
  $ mcpgen make:tool search Create a new tool
600
645
  $ mcpgen make:resource database Create a new resource
601
646
  $ mcpgen make:prompt summarize Create a new prompt
602
647
  `
603
648
  );
604
649
  if (process.argv.length <= 2) {
650
+ const yellow = "\x1B[33m";
605
651
  const cyan = "\x1B[36m";
606
652
  const dim = "\x1B[2m";
607
653
  const bold = "\x1B[1m";
@@ -609,7 +655,7 @@ if (process.argv.length <= 2) {
609
655
  console.log(`
610
656
  ${dim}+-------------------------------------+${reset}
611
657
  ${dim}|${reset} ${dim}|${reset}
612
- ${dim}|${reset} ${bold}${cyan}MCPGEN${reset} ${dim}v0.1.0${reset} ${dim}|${reset}
658
+ ${dim}|${reset} ${bold}${yellow}MCP-GEN${reset} ${dim}v0.1.0${reset} ${dim}|${reset}
613
659
  ${dim}|${reset} ${dim}|${reset}
614
660
  ${dim}|${reset} A TypeScript framework for ${dim}|${reset}
615
661
  ${dim}|${reset} building MCP servers ${dim}|${reset}
@@ -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":["access","readFile","writeFile","join","mkdir","exists","Command"],"mappings":"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","file":"index.cjs","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":["access","readFile","writeFile","join","mkdir","exists","Command"],"mappings":"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","file":"index.cjs","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"]}