frontmcp 0.1.5 → 0.1.7
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/dist/cli.js +61 -24
- package/package.json +7 -7
- package/src/cli.ts +66 -21
package/dist/cli.js
CHANGED
|
@@ -71,7 +71,7 @@ ${c('bold', 'Usage')}
|
|
|
71
71
|
frontmcp <command> [options]
|
|
72
72
|
|
|
73
73
|
${c('bold', 'Commands')}
|
|
74
|
-
dev Start in development mode (tsx --watch <entry>)
|
|
74
|
+
dev Start in development mode (tsx --watch <entry> + async type-check)
|
|
75
75
|
build Compile entry with TypeScript (tsc)
|
|
76
76
|
init Create or fix a tsconfig.json suitable for FrontMCP
|
|
77
77
|
doctor Check Node/npm versions and tsconfig requirements
|
|
@@ -151,14 +151,16 @@ function resolveEntry(cwd, explicit) {
|
|
|
151
151
|
const pkg = yield readJSON(pkgPath);
|
|
152
152
|
if (pkg && typeof pkg.main === 'string' && pkg.main.trim()) {
|
|
153
153
|
const mainCandidates = tryCandidates(path.resolve(cwd, pkg.main));
|
|
154
|
-
for (const p of mainCandidates)
|
|
154
|
+
for (const p of mainCandidates) {
|
|
155
155
|
if (yield fileExists(p))
|
|
156
156
|
return p;
|
|
157
|
+
}
|
|
157
158
|
const asDir = path.resolve(cwd, pkg.main);
|
|
158
159
|
const idxCandidates = tryCandidates(path.join(asDir, 'index'));
|
|
159
|
-
for (const p of idxCandidates)
|
|
160
|
+
for (const p of idxCandidates) {
|
|
160
161
|
if (yield fileExists(p))
|
|
161
162
|
return p;
|
|
163
|
+
}
|
|
162
164
|
}
|
|
163
165
|
}
|
|
164
166
|
const fallback = path.join(cwd, 'src', 'main.ts');
|
|
@@ -219,22 +221,61 @@ function sanitizeForNpm(name) {
|
|
|
219
221
|
/* ------------------------ Self-version detection -------------------------- */
|
|
220
222
|
function getSelfVersion() {
|
|
221
223
|
return __awaiter(this, void 0, void 0, function* () {
|
|
222
|
-
|
|
224
|
+
const binPath = process.argv[1] || __filename;
|
|
225
|
+
const candidates = [
|
|
226
|
+
path.resolve(path.dirname(binPath), '../package.json'),
|
|
227
|
+
path.resolve(path.dirname(binPath), '../../package.json'),
|
|
228
|
+
];
|
|
229
|
+
for (const p of candidates) {
|
|
230
|
+
const j = yield readJSON(p);
|
|
231
|
+
if (j === null || j === void 0 ? void 0 : j.version)
|
|
232
|
+
return j.version;
|
|
233
|
+
}
|
|
234
|
+
return '0.0.0';
|
|
223
235
|
});
|
|
224
236
|
}
|
|
225
237
|
/* --------------------------------- Actions -------------------------------- */
|
|
238
|
+
function isTsLike(p) {
|
|
239
|
+
return /\.tsx?$/i.test(p);
|
|
240
|
+
}
|
|
241
|
+
function killQuiet(proc) {
|
|
242
|
+
try {
|
|
243
|
+
proc && proc.kill('SIGINT');
|
|
244
|
+
}
|
|
245
|
+
catch (_a) { }
|
|
246
|
+
}
|
|
226
247
|
function runDev(opts) {
|
|
227
248
|
return __awaiter(this, void 0, void 0, function* () {
|
|
228
249
|
const cwd = process.cwd();
|
|
229
250
|
const entry = yield resolveEntry(cwd, opts.entry);
|
|
230
251
|
console.log(`${c('cyan', '[dev]')} using entry: ${path.relative(cwd, entry)}`);
|
|
252
|
+
console.log(`${c('gray', '[dev]')} starting ${c('bold', 'tsx --watch')} and ${c('bold', 'tsc --noEmit --watch')} (async type-checker)`);
|
|
231
253
|
console.log(`${c('gray', 'hint:')} press Ctrl+C to stop`);
|
|
232
|
-
|
|
254
|
+
// Start tsx watcher (app run)
|
|
255
|
+
const app = (0, child_process_1.spawn)('npx', ['-y', 'tsx', '--watch', entry], { stdio: 'inherit', shell: true });
|
|
256
|
+
// Start tsc in watch mode for async type-checking (non-blocking)
|
|
257
|
+
const checker = (0, child_process_1.spawn)('npx', ['-y', 'tsc', '--noEmit', '--pretty', '--watch'], { stdio: 'inherit', shell: true });
|
|
258
|
+
const cleanup = () => {
|
|
259
|
+
killQuiet(checker);
|
|
260
|
+
killQuiet(app);
|
|
261
|
+
};
|
|
262
|
+
process.on('SIGINT', () => {
|
|
263
|
+
cleanup();
|
|
264
|
+
process.exit(0);
|
|
265
|
+
});
|
|
266
|
+
yield new Promise((resolve, reject) => {
|
|
267
|
+
app.on('close', (_code) => {
|
|
268
|
+
// When app exits, stop checker too.
|
|
269
|
+
cleanup();
|
|
270
|
+
resolve();
|
|
271
|
+
});
|
|
272
|
+
app.on('error', (err) => {
|
|
273
|
+
cleanup();
|
|
274
|
+
reject(err);
|
|
275
|
+
});
|
|
276
|
+
});
|
|
233
277
|
});
|
|
234
278
|
}
|
|
235
|
-
function isTsLike(p) {
|
|
236
|
-
return /\.tsx?$/i.test(p);
|
|
237
|
-
}
|
|
238
279
|
function runBuild(opts) {
|
|
239
280
|
return __awaiter(this, void 0, void 0, function* () {
|
|
240
281
|
const cwd = process.cwd();
|
|
@@ -273,7 +314,7 @@ const RECOMMENDED_TSCONFIG = {
|
|
|
273
314
|
module: REQUIRED_DECORATOR_FIELDS.module,
|
|
274
315
|
emitDecoratorMetadata: REQUIRED_DECORATOR_FIELDS.emitDecoratorMetadata,
|
|
275
316
|
experimentalDecorators: REQUIRED_DECORATOR_FIELDS.experimentalDecorators,
|
|
276
|
-
moduleResolution: '
|
|
317
|
+
moduleResolution: 'NodeNext',
|
|
277
318
|
strict: true,
|
|
278
319
|
esModuleInterop: true,
|
|
279
320
|
resolveJsonModule: true,
|
|
@@ -465,19 +506,19 @@ function upsertPackageJson(cwd, nameOverride, selfVersion) {
|
|
|
465
506
|
npm: '>=10',
|
|
466
507
|
},
|
|
467
508
|
dependencies: {
|
|
468
|
-
'@frontmcp/sdk': '
|
|
509
|
+
'@frontmcp/sdk': '^0.1.3',
|
|
469
510
|
zod: '^3.23.8',
|
|
470
511
|
'reflect-metadata': '^0.2.2',
|
|
471
512
|
},
|
|
472
513
|
devDependencies: {
|
|
473
|
-
frontmcp: selfVersion, // exact version used by npx
|
|
514
|
+
frontmcp: selfVersion, // exact CLI version used by npx
|
|
474
515
|
tsx: '^4.20.6',
|
|
475
516
|
typescript: '^5.5.3',
|
|
476
517
|
},
|
|
477
518
|
};
|
|
478
519
|
if (!existing) {
|
|
479
520
|
yield writeJSON(pkgPath, base);
|
|
480
|
-
console.log(c('green', '✅ Created package.json (pinned
|
|
521
|
+
console.log(c('green', '✅ Created package.json (pinned versions + exact frontmcp)'));
|
|
481
522
|
return;
|
|
482
523
|
}
|
|
483
524
|
const merged = Object.assign(Object.assign({}, base), existing);
|
|
@@ -486,12 +527,8 @@ function upsertPackageJson(cwd, nameOverride, selfVersion) {
|
|
|
486
527
|
merged.type = existing.type || base.type;
|
|
487
528
|
merged.scripts = Object.assign(Object.assign(Object.assign({}, base.scripts), (existing.scripts || {})), { dev: (_b = (_a = existing.scripts) === null || _a === void 0 ? void 0 : _a.dev) !== null && _b !== void 0 ? _b : base.scripts.dev, build: (_d = (_c = existing.scripts) === null || _c === void 0 ? void 0 : _c.build) !== null && _d !== void 0 ? _d : base.scripts.build, inspect: (_f = (_e = existing.scripts) === null || _e === void 0 ? void 0 : _e.inspect) !== null && _f !== void 0 ? _f : base.scripts.inspect, doctor: (_h = (_g = existing.scripts) === null || _g === void 0 ? void 0 : _g.doctor) !== null && _h !== void 0 ? _h : base.scripts.doctor });
|
|
488
529
|
merged.engines = Object.assign(Object.assign({}, (existing.engines || {})), { node: ((_j = existing.engines) === null || _j === void 0 ? void 0 : _j.node) || base.engines.node, npm: ((_k = existing.engines) === null || _k === void 0 ? void 0 : _k.npm) || base.engines.npm });
|
|
489
|
-
merged.dependencies = Object.assign(Object.assign(Object.assign({}, base.dependencies), (existing.dependencies || {})), {
|
|
490
|
-
|
|
491
|
-
zod: '^3.23.8', 'reflect-metadata': '^0.2.2' });
|
|
492
|
-
merged.devDependencies = Object.assign(Object.assign(Object.assign({}, base.devDependencies), (existing.devDependencies || {})), {
|
|
493
|
-
// ensure pins
|
|
494
|
-
frontmcp: selfVersion, tsx: '^4.20.6', typescript: '^5.5.3' });
|
|
530
|
+
merged.dependencies = Object.assign(Object.assign(Object.assign({}, base.dependencies), (existing.dependencies || {})), { zod: '^3.23.8', 'reflect-metadata': '^0.2.2' });
|
|
531
|
+
merged.devDependencies = Object.assign(Object.assign(Object.assign({}, base.devDependencies), (existing.devDependencies || {})), { frontmcp: selfVersion, tsx: '^4.20.6', typescript: '^5.5.3' });
|
|
495
532
|
yield writeJSON(pkgPath, merged);
|
|
496
533
|
console.log(c('green', '✅ Updated package.json (ensured exact frontmcp and pinned versions)'));
|
|
497
534
|
});
|
|
@@ -541,9 +578,9 @@ import { z } from 'zod';
|
|
|
541
578
|
const AddTool = tool({
|
|
542
579
|
name: 'add',
|
|
543
580
|
description: 'Add two numbers',
|
|
544
|
-
inputSchema:
|
|
545
|
-
outputSchema:
|
|
546
|
-
})((input, _ctx) => {
|
|
581
|
+
inputSchema: { a: z.number(), b: z.number() },
|
|
582
|
+
outputSchema: { result: z.number() },
|
|
583
|
+
})(async (input, _ctx) => {
|
|
547
584
|
return { result: input.a + input.b };
|
|
548
585
|
});
|
|
549
586
|
|
|
@@ -573,7 +610,7 @@ function runCreate(projectArg) {
|
|
|
573
610
|
process.chdir(targetDir);
|
|
574
611
|
// 1) tsconfig
|
|
575
612
|
yield runInit(targetDir);
|
|
576
|
-
// 2) package.json (
|
|
613
|
+
// 2) package.json (pinned deps + exact CLI version)
|
|
577
614
|
const selfVersion = yield getSelfVersion();
|
|
578
615
|
yield upsertPackageJson(targetDir, pkgName, selfVersion);
|
|
579
616
|
// 3) files
|
|
@@ -583,7 +620,7 @@ function runCreate(projectArg) {
|
|
|
583
620
|
console.log('\nNext steps:');
|
|
584
621
|
console.log(` 1) cd ${folder}`);
|
|
585
622
|
console.log(' 2) npm install');
|
|
586
|
-
console.log(' 3) npm run dev ', c('gray', '#
|
|
623
|
+
console.log(' 3) npm run dev ', c('gray', '# tsx watcher + async tsc type-check'));
|
|
587
624
|
console.log(' 4) npm run inspect ', c('gray', '# launch MCP Inspector'));
|
|
588
625
|
console.log(' 5) npm run build ', c('gray', '# compile with tsc via frontmcp build'));
|
|
589
626
|
});
|
|
@@ -617,7 +654,7 @@ function main() {
|
|
|
617
654
|
yield runInspector();
|
|
618
655
|
break;
|
|
619
656
|
case 'create': {
|
|
620
|
-
const projectName = parsed._[1];
|
|
657
|
+
const projectName = parsed._[1];
|
|
621
658
|
yield runCreate(projectName);
|
|
622
659
|
break;
|
|
623
660
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frontmcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "FrontMCP command line interface",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -12,15 +12,15 @@
|
|
|
12
12
|
"prepare": "npm run build"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@frontmcp/sdk": "0.1.3",
|
|
16
|
-
"@frontmcp/core": "0.1.3",
|
|
17
|
-
"@frontmcp/plugins": "0.1.3",
|
|
18
|
-
"@frontmcp/adapters": "0.1.3",
|
|
19
|
-
"tsx": "^4.
|
|
15
|
+
"@frontmcp/sdk": "^0.1.3",
|
|
16
|
+
"@frontmcp/core": "^0.1.3",
|
|
17
|
+
"@frontmcp/plugins": "^0.1.3",
|
|
18
|
+
"@frontmcp/adapters": "^0.1.3",
|
|
19
|
+
"tsx": "^4.16.0",
|
|
20
20
|
"typescript": "^5.5.3"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@types/node": "20.
|
|
23
|
+
"@types/node": "^20.11.30",
|
|
24
24
|
"@modelcontextprotocol/inspector": "^0.17.2"
|
|
25
25
|
}
|
|
26
26
|
}
|
package/src/cli.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import * as fs from 'fs';
|
|
8
8
|
import {promises as fsp} from 'fs';
|
|
9
9
|
import * as path from 'path';
|
|
10
|
-
import {spawn} from 'child_process';
|
|
10
|
+
import {spawn, ChildProcess} from 'child_process';
|
|
11
11
|
|
|
12
12
|
/* ----------------------------- Types & Helpers ---------------------------- */
|
|
13
13
|
|
|
@@ -42,7 +42,7 @@ ${c('bold', 'Usage')}
|
|
|
42
42
|
frontmcp <command> [options]
|
|
43
43
|
|
|
44
44
|
${c('bold', 'Commands')}
|
|
45
|
-
dev Start in development mode (tsx --watch <entry>)
|
|
45
|
+
dev Start in development mode (tsx --watch <entry> + async type-check)
|
|
46
46
|
build Compile entry with TypeScript (tsc)
|
|
47
47
|
init Create or fix a tsconfig.json suitable for FrontMCP
|
|
48
48
|
doctor Check Node/npm versions and tsconfig requirements
|
|
@@ -109,17 +109,23 @@ async function resolveEntry(cwd: string, explicit?: string): Promise<string> {
|
|
|
109
109
|
if (await fileExists(full)) return full;
|
|
110
110
|
throw new Error(`Entry override not found: ${explicit}`);
|
|
111
111
|
}
|
|
112
|
+
|
|
112
113
|
const pkgPath = path.join(cwd, 'package.json');
|
|
113
114
|
if (await fileExists(pkgPath)) {
|
|
114
115
|
const pkg = await readJSON<any>(pkgPath);
|
|
115
116
|
if (pkg && typeof pkg.main === 'string' && pkg.main.trim()) {
|
|
116
117
|
const mainCandidates = tryCandidates(path.resolve(cwd, pkg.main));
|
|
117
|
-
for (const p of mainCandidates)
|
|
118
|
+
for (const p of mainCandidates) {
|
|
119
|
+
if (await fileExists(p)) return p;
|
|
120
|
+
}
|
|
118
121
|
const asDir = path.resolve(cwd, pkg.main);
|
|
119
122
|
const idxCandidates = tryCandidates(path.join(asDir, 'index'));
|
|
120
|
-
for (const p of idxCandidates)
|
|
123
|
+
for (const p of idxCandidates) {
|
|
124
|
+
if (await fileExists(p)) return p;
|
|
125
|
+
}
|
|
121
126
|
}
|
|
122
127
|
}
|
|
128
|
+
|
|
123
129
|
const fallback = path.join(cwd, 'src', 'main.ts');
|
|
124
130
|
if (await fileExists(fallback)) return fallback;
|
|
125
131
|
|
|
@@ -177,21 +183,62 @@ function sanitizeForNpm(name: string): string {
|
|
|
177
183
|
/* ------------------------ Self-version detection -------------------------- */
|
|
178
184
|
|
|
179
185
|
async function getSelfVersion(): Promise<string> {
|
|
180
|
-
|
|
186
|
+
const binPath = process.argv[1] || __filename;
|
|
187
|
+
const candidates = [
|
|
188
|
+
path.resolve(path.dirname(binPath), '../package.json'),
|
|
189
|
+
path.resolve(path.dirname(binPath), '../../package.json'),
|
|
190
|
+
];
|
|
191
|
+
for (const p of candidates) {
|
|
192
|
+
const j = await readJSON<any>(p);
|
|
193
|
+
if (j?.version) return j.version;
|
|
194
|
+
}
|
|
195
|
+
return '0.0.0';
|
|
181
196
|
}
|
|
182
197
|
|
|
183
198
|
/* --------------------------------- Actions -------------------------------- */
|
|
184
199
|
|
|
200
|
+
function isTsLike(p: string): boolean {
|
|
201
|
+
return /\.tsx?$/i.test(p);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function killQuiet(proc?: ChildProcess) {
|
|
205
|
+
try { proc && proc.kill('SIGINT'); } catch {}
|
|
206
|
+
}
|
|
207
|
+
|
|
185
208
|
async function runDev(opts: ParsedArgs): Promise<void> {
|
|
186
209
|
const cwd = process.cwd();
|
|
187
210
|
const entry = await resolveEntry(cwd, opts.entry);
|
|
211
|
+
|
|
188
212
|
console.log(`${c('cyan', '[dev]')} using entry: ${path.relative(cwd, entry)}`);
|
|
213
|
+
console.log(`${c('gray', '[dev]')} starting ${c('bold', 'tsx --watch')} and ${c('bold', 'tsc --noEmit --watch')} (async type-checker)`);
|
|
189
214
|
console.log(`${c('gray', 'hint:')} press Ctrl+C to stop`);
|
|
190
|
-
await runCmd('npx', ['-y', 'tsx', '--watch', entry]);
|
|
191
|
-
}
|
|
192
215
|
|
|
193
|
-
|
|
194
|
-
|
|
216
|
+
// Start tsx watcher (app run)
|
|
217
|
+
const app = spawn('npx', ['-y', 'tsx', '--watch', entry], {stdio: 'inherit', shell: true});
|
|
218
|
+
// Start tsc in watch mode for async type-checking (non-blocking)
|
|
219
|
+
const checker = spawn('npx', ['-y', 'tsc', '--noEmit', '--pretty', '--watch'], {stdio: 'inherit', shell: true});
|
|
220
|
+
|
|
221
|
+
const cleanup = () => {
|
|
222
|
+
killQuiet(checker);
|
|
223
|
+
killQuiet(app);
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
process.on('SIGINT', () => {
|
|
227
|
+
cleanup();
|
|
228
|
+
process.exit(0);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
await new Promise<void>((resolve, reject) => {
|
|
232
|
+
app.on('close', (_code) => {
|
|
233
|
+
// When app exits, stop checker too.
|
|
234
|
+
cleanup();
|
|
235
|
+
resolve();
|
|
236
|
+
});
|
|
237
|
+
app.on('error', (err) => {
|
|
238
|
+
cleanup();
|
|
239
|
+
reject(err);
|
|
240
|
+
});
|
|
241
|
+
});
|
|
195
242
|
}
|
|
196
243
|
|
|
197
244
|
async function runBuild(opts: ParsedArgs): Promise<void> {
|
|
@@ -239,7 +286,7 @@ const RECOMMENDED_TSCONFIG = {
|
|
|
239
286
|
emitDecoratorMetadata: REQUIRED_DECORATOR_FIELDS.emitDecoratorMetadata,
|
|
240
287
|
experimentalDecorators: REQUIRED_DECORATOR_FIELDS.experimentalDecorators,
|
|
241
288
|
|
|
242
|
-
moduleResolution: '
|
|
289
|
+
moduleResolution: 'NodeNext',
|
|
243
290
|
strict: true,
|
|
244
291
|
esModuleInterop: true,
|
|
245
292
|
resolveJsonModule: true,
|
|
@@ -428,12 +475,12 @@ async function upsertPackageJson(cwd: string, nameOverride: string | undefined,
|
|
|
428
475
|
npm: '>=10',
|
|
429
476
|
},
|
|
430
477
|
dependencies: {
|
|
431
|
-
'@frontmcp/sdk': '
|
|
478
|
+
'@frontmcp/sdk': '^0.1.3',
|
|
432
479
|
zod: '^3.23.8',
|
|
433
480
|
'reflect-metadata': '^0.2.2',
|
|
434
481
|
},
|
|
435
482
|
devDependencies: {
|
|
436
|
-
frontmcp: selfVersion, // exact version used by npx
|
|
483
|
+
frontmcp: selfVersion, // exact CLI version used by npx
|
|
437
484
|
tsx: '^4.20.6',
|
|
438
485
|
typescript: '^5.5.3',
|
|
439
486
|
},
|
|
@@ -441,7 +488,7 @@ async function upsertPackageJson(cwd: string, nameOverride: string | undefined,
|
|
|
441
488
|
|
|
442
489
|
if (!existing) {
|
|
443
490
|
await writeJSON(pkgPath, base);
|
|
444
|
-
console.log(c('green', '✅ Created package.json (pinned
|
|
491
|
+
console.log(c('green', '✅ Created package.json (pinned versions + exact frontmcp)'));
|
|
445
492
|
return;
|
|
446
493
|
}
|
|
447
494
|
|
|
@@ -469,7 +516,6 @@ async function upsertPackageJson(cwd: string, nameOverride: string | undefined,
|
|
|
469
516
|
merged.dependencies = {
|
|
470
517
|
...base.dependencies,
|
|
471
518
|
...(existing.dependencies || {}),
|
|
472
|
-
// ensure pins
|
|
473
519
|
zod: '^3.23.8',
|
|
474
520
|
'reflect-metadata': '^0.2.2',
|
|
475
521
|
};
|
|
@@ -477,7 +523,6 @@ async function upsertPackageJson(cwd: string, nameOverride: string | undefined,
|
|
|
477
523
|
merged.devDependencies = {
|
|
478
524
|
...base.devDependencies,
|
|
479
525
|
...(existing.devDependencies || {}),
|
|
480
|
-
// ensure pins
|
|
481
526
|
frontmcp: selfVersion,
|
|
482
527
|
tsx: '^4.20.6',
|
|
483
528
|
typescript: '^5.5.3',
|
|
@@ -533,9 +578,9 @@ import { z } from 'zod';
|
|
|
533
578
|
const AddTool = tool({
|
|
534
579
|
name: 'add',
|
|
535
580
|
description: 'Add two numbers',
|
|
536
|
-
inputSchema:
|
|
537
|
-
outputSchema:
|
|
538
|
-
})((input, _ctx) => {
|
|
581
|
+
inputSchema: { a: z.number(), b: z.number() },
|
|
582
|
+
outputSchema: { result: z.number() },
|
|
583
|
+
})(async (input, _ctx) => {
|
|
539
584
|
return { result: input.a + input.b };
|
|
540
585
|
});
|
|
541
586
|
|
|
@@ -569,7 +614,7 @@ async function runCreate(projectArg?: string): Promise<void> {
|
|
|
569
614
|
// 1) tsconfig
|
|
570
615
|
await runInit(targetDir);
|
|
571
616
|
|
|
572
|
-
// 2) package.json (
|
|
617
|
+
// 2) package.json (pinned deps + exact CLI version)
|
|
573
618
|
const selfVersion = await getSelfVersion();
|
|
574
619
|
await upsertPackageJson(targetDir, pkgName, selfVersion);
|
|
575
620
|
|
|
@@ -581,7 +626,7 @@ async function runCreate(projectArg?: string): Promise<void> {
|
|
|
581
626
|
console.log('\nNext steps:');
|
|
582
627
|
console.log(` 1) cd ${folder}`);
|
|
583
628
|
console.log(' 2) npm install');
|
|
584
|
-
console.log(' 3) npm run dev ', c('gray', '#
|
|
629
|
+
console.log(' 3) npm run dev ', c('gray', '# tsx watcher + async tsc type-check'));
|
|
585
630
|
console.log(' 4) npm run inspect ', c('gray', '# launch MCP Inspector'));
|
|
586
631
|
console.log(' 5) npm run build ', c('gray', '# compile with tsc via frontmcp build'));
|
|
587
632
|
}
|
|
@@ -617,7 +662,7 @@ async function main(): Promise<void> {
|
|
|
617
662
|
await runInspector();
|
|
618
663
|
break;
|
|
619
664
|
case 'create': {
|
|
620
|
-
const projectName = parsed._[1];
|
|
665
|
+
const projectName = parsed._[1];
|
|
621
666
|
await runCreate(projectName);
|
|
622
667
|
break;
|
|
623
668
|
}
|