Skip to content
This repository was archived by the owner on May 21, 2026. It is now read-only.

Commit 03bfe4a

Browse files
committed
feat: create mcp app v0
1 parent f6d86cd commit 03bfe4a

3 files changed

Lines changed: 115 additions & 131 deletions

File tree

packages/create-mcp-use-app/package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
{
22
"name": "create-mcp-use-app",
33
"version": "0.1.0",
4+
"type": "module",
45
"description": "Create MCP-Use apps with one command",
56
"bin": {
67
"create-mcp-use-app": "./dist/index.js"
78
},
89
"scripts": {
9-
"build": "tsc --build",
10+
"build": "npm run clean && tsc --build && npm run copy-templates",
11+
"clean": "rm -rf dist tsconfig.tsbuildinfo",
12+
"copy-templates": "mkdir -p dist/templates && cp -r src/templates/* dist/templates/",
1013
"dev": "tsc --build --watch",
1114
"test": "vitest",
1215
"lint": "eslint ."
1316
},
17+
"files": [
18+
"dist",
19+
"README.md"
20+
],
1421
"dependencies": {
1522
"commander": "^11.0.0",
1623
"prompts": "^2.4.2",
Lines changed: 104 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,124 @@
11
#!/usr/bin/env node
2-
import { Command } from 'commander';
3-
import prompts from 'prompts';
4-
import chalk from 'chalk';
5-
import fs from 'fs-extra';
6-
import path from 'path';
72

8-
const program = new Command();
3+
import { execSync } from 'node:child_process'
4+
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'
5+
import { dirname, join, resolve } from 'node:path'
6+
import { fileURLToPath } from 'node:url'
7+
import { Command } from 'commander'
8+
9+
const __filename = fileURLToPath(import.meta.url)
10+
const __dirname = dirname(__filename)
11+
12+
const program = new Command()
913

1014
program
1115
.name('create-mcp-use-app')
12-
.description('Create a new MCP-Use application')
16+
.description('Create a new MCP server project')
1317
.version('0.1.0')
14-
.argument('[project-name]', 'Name of the project')
15-
.option('-t, --template <template>', 'Template to use (basic, advanced)', 'basic')
16-
.option('--typescript', 'Use TypeScript', true)
17-
.option('--no-typescript', 'Use JavaScript')
18-
.option('--git', 'Initialize git repository', true)
19-
.option('--no-git', 'Skip git initialization')
20-
.action(async (projectName, options) => {
21-
if (!projectName) {
22-
const response = await prompts({
23-
type: 'text',
24-
name: 'projectName',
25-
message: 'What is your project named?',
26-
initial: 'my-mcp-app'
27-
});
28-
projectName = response.projectName;
18+
.argument('<project-name>', 'Name of the MCP server project')
19+
.option('-t, --template <template>', 'Template to use', 'basic')
20+
.option('--no-install', 'Skip installing dependencies')
21+
.action(async (projectName: string, options: { template: string, install: boolean }) => {
22+
try {
23+
console.log(`🚀 Creating MCP server "${projectName}"...`)
24+
25+
const projectPath = resolve(process.cwd(), projectName)
26+
27+
// Check if directory already exists
28+
if (existsSync(projectPath)) {
29+
console.error(`❌ Directory "${projectName}" already exists!`)
30+
process.exit(1)
31+
}
32+
33+
// Create project directory
34+
mkdirSync(projectPath, { recursive: true })
35+
36+
// Copy template files
37+
await copyTemplate(projectPath, options.template)
38+
39+
// Update package.json with project name
40+
updatePackageJson(projectPath, projectName)
41+
42+
// Install dependencies if requested
43+
if (options.install) {
44+
console.log('📦 Installing dependencies...')
45+
try {
46+
execSync('pnpm install', { cwd: projectPath, stdio: 'inherit' })
47+
}
48+
catch {
49+
console.log('⚠️ pnpm not found, trying npm...')
50+
try {
51+
execSync('npm install', { cwd: projectPath, stdio: 'inherit' })
52+
}
53+
catch {
54+
console.log('⚠️ npm install failed, please run "npm install" manually')
55+
}
56+
}
57+
}
58+
59+
console.log('✅ MCP server created successfully!')
60+
console.log('')
61+
console.log('📁 Project structure:')
62+
console.log(` ${projectName}/`)
63+
console.log(' ├── src/')
64+
console.log(' │ └── server.ts')
65+
console.log(' ├── package.json')
66+
console.log(' ├── tsconfig.json')
67+
console.log(' └── README.md')
68+
console.log('')
69+
console.log('🚀 To get started:')
70+
console.log(` cd ${projectName}`)
71+
if (!options.install) {
72+
console.log(' npm install')
73+
}
74+
console.log(' npm run dev')
75+
console.log('')
76+
console.log('📚 Learn more: https://docs.mcp-use.io')
2977
}
30-
31-
if (!projectName) {
32-
console.log(chalk.red('Project name is required'));
33-
process.exit(1);
78+
catch (error) {
79+
console.error('❌ Error creating MCP server:', error)
80+
process.exit(1)
3481
}
82+
})
3583

36-
const projectPath = path.join(process.cwd(), projectName);
84+
async function copyTemplate(projectPath: string, template: string) {
85+
const templatePath = join(__dirname, 'templates', template)
3786

38-
if (fs.existsSync(projectPath)) {
39-
console.log(chalk.red(`Directory ${projectName} already exists`));
40-
process.exit(1);
41-
}
87+
if (!existsSync(templatePath)) {
88+
console.error(`❌ Template "${template}" not found!`)
89+
console.log('Available templates: basic, filesystem, api, ui')
90+
process.exit(1)
91+
}
4292

43-
console.log(chalk.green(`Creating ${projectName}...`));
44-
45-
// Create project directory
46-
fs.ensureDirSync(projectPath);
47-
48-
// Create package.json
49-
const packageJson = {
50-
name: projectName,
51-
version: '0.1.0',
52-
private: true,
53-
scripts: {
54-
dev: 'node src/index.js',
55-
build: options.typescript ? 'tsc' : 'echo "No build step"',
56-
start: 'node dist/index.js'
57-
},
58-
dependencies: {
59-
'mcp-use': '^0.1.20'
60-
},
61-
devDependencies: options.typescript ? {
62-
'@types/node': '^20.0.0',
63-
'typescript': '^5.0.0'
64-
} : {}
65-
};
66-
67-
fs.writeJsonSync(path.join(projectPath, 'package.json'), packageJson, { spaces: 2 });
68-
69-
// Create source files
70-
const srcDir = path.join(projectPath, 'src');
71-
fs.ensureDirSync(srcDir);
72-
73-
const ext = options.typescript ? 'ts' : 'js';
74-
const indexContent = `import { MCPClient } from 'mcp-use';
75-
76-
async function main() {
77-
const client = new MCPClient({
78-
name: '${projectName}',
79-
version: '0.1.0'
80-
});
81-
82-
// Add your MCP logic here
83-
84-
console.log('MCP app initialized');
93+
copyDirectory(templatePath, projectPath)
8594
}
8695

87-
main().catch(console.error);
88-
`;
89-
90-
fs.writeFileSync(path.join(srcDir, `index.${ext}`), indexContent);
91-
92-
// Create tsconfig if TypeScript
93-
if (options.typescript) {
94-
const tsconfig = {
95-
compilerOptions: {
96-
target: 'ES2022',
97-
module: 'commonjs',
98-
lib: ['ES2022'],
99-
outDir: './dist',
100-
rootDir: './src',
101-
strict: true,
102-
esModuleInterop: true,
103-
skipLibCheck: true,
104-
forceConsistentCasingInFileNames: true
105-
},
106-
include: ['src/**/*'],
107-
exclude: ['node_modules', 'dist']
108-
};
109-
fs.writeJsonSync(path.join(projectPath, 'tsconfig.json'), tsconfig, { spaces: 2 });
110-
}
111-
112-
// Create README
113-
const readme = `# ${projectName}
96+
function copyDirectory(src: string, dest: string) {
97+
const entries = readdirSync(src, { withFileTypes: true })
11498

115-
An MCP-Use application
99+
for (const entry of entries) {
100+
const srcPath = join(src, entry.name)
101+
const destPath = join(dest, entry.name)
116102

117-
## Getting Started
118-
119-
\`\`\`bash
120-
npm install
121-
npm run dev
122-
\`\`\`
103+
if (entry.isDirectory()) {
104+
mkdirSync(destPath, { recursive: true })
105+
copyDirectory(srcPath, destPath)
106+
}
107+
else {
108+
copyFileSync(srcPath, destPath)
109+
}
110+
}
111+
}
123112

124-
## License
113+
function updatePackageJson(projectPath: string, projectName: string) {
114+
const packageJsonPath = join(projectPath, 'package.json')
115+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))
125116

126-
MIT
127-
`;
128-
fs.writeFileSync(path.join(projectPath, 'README.md'), readme);
117+
packageJson.name = projectName
118+
packageJson.description = `MCP server: ${projectName}`
129119

130-
// Initialize git if requested
131-
if (options.git) {
132-
const gitignore = `node_modules/
133-
dist/
134-
.env
135-
*.log
136-
`;
137-
fs.writeFileSync(path.join(projectPath, '.gitignore'), gitignore);
138-
}
120+
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
121+
}
139122

140-
console.log(chalk.green('✓ Project created successfully!'));
141-
console.log();
142-
console.log('Next steps:');
143-
console.log(chalk.cyan(` cd ${projectName}`));
144-
console.log(chalk.cyan(' npm install'));
145-
console.log(chalk.cyan(' npm run dev'));
146-
});
123+
program.parse()
147124

148-
program.parse();

packages/create-mcp-use-app/tsconfig.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"compilerOptions": {
33
"composite": true,
44
"target": "ES2022",
5-
"module": "commonjs",
5+
"module": "NodeNext",
6+
"moduleResolution": "NodeNext",
67
"lib": ["ES2022"],
78
"outDir": "./dist",
89
"rootDir": "./src",
@@ -16,5 +17,5 @@
1617
"resolveJsonModule": true
1718
},
1819
"include": ["src/**/*"],
19-
"exclude": ["node_modules", "dist", "**/*.test.ts"]
20+
"exclude": ["node_modules", "dist", "**/*.test.ts", "src/templates/**/*"]
2021
}

0 commit comments

Comments
 (0)