create-mcp-use-app 0.4.8 → 0.4.9
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/index.js +303 -168
- package/dist/templates/apps-sdk/index.ts +16 -18
- package/dist/templates/apps-sdk/package.json +1 -1
- package/dist/templates/apps-sdk/resources/display-weather.tsx +55 -41
- package/dist/templates/apps-sdk/styles.css +3 -4
- package/dist/templates/apps-sdk/tsconfig.json +0 -1
- package/dist/templates/mcp-ui/index.ts +111 -103
- package/dist/templates/mcp-ui/package.json +1 -1
- package/dist/templates/mcp-ui/resources/kanban-board.tsx +228 -150
- package/dist/templates/mcp-ui/tsconfig.json +0 -1
- package/dist/templates/starter/index.ts +65 -66
- package/dist/templates/starter/package.json +1 -1
- package/dist/templates/starter/resources/display-weather.tsx +56 -42
- package/dist/templates/starter/resources/kanban-board.tsx +228 -150
- package/dist/templates/starter/styles.css +3 -4
- package/dist/templates/starter/tsconfig.json +0 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,7 +5,15 @@ import chalk from "chalk";
|
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import inquirer from "inquirer";
|
|
7
7
|
import { execSync, spawn } from "child_process";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
copyFileSync,
|
|
10
|
+
existsSync,
|
|
11
|
+
mkdirSync,
|
|
12
|
+
readdirSync,
|
|
13
|
+
readFileSync,
|
|
14
|
+
rmSync,
|
|
15
|
+
writeFileSync
|
|
16
|
+
} from "fs";
|
|
9
17
|
import { dirname, join, resolve } from "path";
|
|
10
18
|
import { fileURLToPath } from "url";
|
|
11
19
|
import ora from "ora";
|
|
@@ -135,8 +143,12 @@ function getCurrentPackageVersions(isDevelopment = false, useCanary = false) {
|
|
|
135
143
|
}
|
|
136
144
|
} catch (error) {
|
|
137
145
|
if (process.env.NODE_ENV === "development") {
|
|
138
|
-
console.warn(
|
|
139
|
-
|
|
146
|
+
console.warn(
|
|
147
|
+
"\u26A0\uFE0F Could not read workspace package versions, using defaults"
|
|
148
|
+
);
|
|
149
|
+
console.warn(
|
|
150
|
+
` Error: ${error instanceof Error ? error.message : String(error)}`
|
|
151
|
+
);
|
|
140
152
|
if (error instanceof Error && error.stack) {
|
|
141
153
|
console.warn(` Stack: ${error.stack}`);
|
|
142
154
|
}
|
|
@@ -149,199 +161,297 @@ function processTemplateFile(filePath, versions, isDevelopment = false, useCanar
|
|
|
149
161
|
let processedContent = content;
|
|
150
162
|
for (const [packageName, version] of Object.entries(versions)) {
|
|
151
163
|
const placeholder = `{{${packageName}_version}}`;
|
|
152
|
-
processedContent = processedContent.replace(
|
|
164
|
+
processedContent = processedContent.replace(
|
|
165
|
+
new RegExp(placeholder, "g"),
|
|
166
|
+
version
|
|
167
|
+
);
|
|
153
168
|
}
|
|
154
169
|
if (isDevelopment) {
|
|
155
|
-
processedContent = processedContent.replace(
|
|
156
|
-
|
|
157
|
-
|
|
170
|
+
processedContent = processedContent.replace(
|
|
171
|
+
/"mcp-use": "\^[^"]+"/,
|
|
172
|
+
'"mcp-use": "workspace:*"'
|
|
173
|
+
);
|
|
174
|
+
processedContent = processedContent.replace(
|
|
175
|
+
/"@mcp-use\/cli": "\^[^"]+"/,
|
|
176
|
+
'"@mcp-use/cli": "workspace:*"'
|
|
177
|
+
);
|
|
178
|
+
processedContent = processedContent.replace(
|
|
179
|
+
/"@mcp-use\/inspector": "\^[^"]+"/,
|
|
180
|
+
'"@mcp-use/inspector": "workspace:*"'
|
|
181
|
+
);
|
|
158
182
|
} else if (useCanary) {
|
|
159
|
-
processedContent = processedContent.replace(
|
|
160
|
-
|
|
161
|
-
|
|
183
|
+
processedContent = processedContent.replace(
|
|
184
|
+
/"mcp-use": "workspace:\*"/,
|
|
185
|
+
`"mcp-use": "canary"`
|
|
186
|
+
);
|
|
187
|
+
processedContent = processedContent.replace(
|
|
188
|
+
/"@mcp-use\/cli": "workspace:\*"/,
|
|
189
|
+
`"@mcp-use/cli": "canary"`
|
|
190
|
+
);
|
|
191
|
+
processedContent = processedContent.replace(
|
|
192
|
+
/"@mcp-use\/inspector": "workspace:\*"/,
|
|
193
|
+
`"@mcp-use/inspector": "canary"`
|
|
194
|
+
);
|
|
162
195
|
} else {
|
|
163
|
-
processedContent = processedContent.replace(
|
|
164
|
-
|
|
165
|
-
|
|
196
|
+
processedContent = processedContent.replace(
|
|
197
|
+
/"mcp-use": "workspace:\*"/,
|
|
198
|
+
`"mcp-use": "${versions["mcp-use"] || "latest"}"`
|
|
199
|
+
);
|
|
200
|
+
processedContent = processedContent.replace(
|
|
201
|
+
/"@mcp-use\/cli": "workspace:\*"/,
|
|
202
|
+
`"@mcp-use/cli": "${versions["@mcp-use/cli"] || "latest"}"`
|
|
203
|
+
);
|
|
204
|
+
processedContent = processedContent.replace(
|
|
205
|
+
/"@mcp-use\/inspector": "workspace:\*"/,
|
|
206
|
+
`"@mcp-use/inspector": "${versions["@mcp-use/inspector"] || "latest"}"`
|
|
207
|
+
);
|
|
166
208
|
}
|
|
167
209
|
return processedContent;
|
|
168
210
|
}
|
|
169
|
-
program.name("create-mcp-use-app").description("Create a new MCP server project").version(packageJson.version).argument("[project-name]", "Name of the MCP server project").option("-t, --template <template>", "Template to use", "simple").option("--no-install", "Skip installing dependencies").option("--no-git", "Skip initializing a git repository").option("--dev", "Use workspace dependencies for development").option("--canary", "Use canary versions of packages").option("--yarn", "Use yarn as package manager").option("--npm", "Use npm as package manager").option("--pnpm", "Use pnpm as package manager").action(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const sanitizedProjectName = projectName.trim();
|
|
183
|
-
if (!sanitizedProjectName) {
|
|
184
|
-
console.error(chalk.red("\u274C Project name cannot be empty"));
|
|
185
|
-
process.exit(1);
|
|
186
|
-
}
|
|
187
|
-
if (sanitizedProjectName.includes("..") || sanitizedProjectName.includes("/") || sanitizedProjectName.includes("\\")) {
|
|
188
|
-
console.error(chalk.red('\u274C Project name cannot contain path separators or ".."'));
|
|
189
|
-
console.error(chalk.yellow(' Use simple names like "my-mcp-server"'));
|
|
190
|
-
process.exit(1);
|
|
191
|
-
}
|
|
192
|
-
const protectedNames = ["node_modules", ".git", ".env", "package.json", "src", "dist"];
|
|
193
|
-
if (protectedNames.includes(sanitizedProjectName.toLowerCase())) {
|
|
194
|
-
console.error(chalk.red(`\u274C Cannot use protected name "${sanitizedProjectName}"`));
|
|
195
|
-
console.error(chalk.yellow(" Please choose a different project name"));
|
|
196
|
-
process.exit(1);
|
|
197
|
-
}
|
|
198
|
-
console.log(chalk.cyan(`\u{1F680} Creating MCP server "${sanitizedProjectName}"...`));
|
|
199
|
-
const projectPath = resolve(process.cwd(), sanitizedProjectName);
|
|
200
|
-
if (existsSync(projectPath)) {
|
|
201
|
-
console.error(chalk.red(`\u274C Directory "${sanitizedProjectName}" already exists!`));
|
|
202
|
-
console.error(chalk.yellow(" Please choose a different name or remove the existing directory"));
|
|
203
|
-
process.exit(1);
|
|
204
|
-
}
|
|
205
|
-
mkdirSync(projectPath, { recursive: true });
|
|
206
|
-
const validatedTemplate = validateTemplateName(selectedTemplate);
|
|
207
|
-
const versions = getCurrentPackageVersions(options.dev, options.canary);
|
|
208
|
-
await copyTemplate(projectPath, validatedTemplate, versions, options.dev, options.canary);
|
|
209
|
-
updatePackageJson(projectPath, sanitizedProjectName);
|
|
210
|
-
let usedPackageManager = "npm";
|
|
211
|
-
if (options.yarn) {
|
|
212
|
-
usedPackageManager = "yarn";
|
|
213
|
-
} else if (options.npm) {
|
|
214
|
-
usedPackageManager = "npm";
|
|
215
|
-
} else if (options.pnpm) {
|
|
216
|
-
usedPackageManager = "pnpm";
|
|
217
|
-
} else {
|
|
218
|
-
const detected = detectPackageManager();
|
|
219
|
-
if (detected) {
|
|
220
|
-
usedPackageManager = detected;
|
|
221
|
-
} else {
|
|
222
|
-
const defaultOrder = ["yarn", "npm", "pnpm"];
|
|
223
|
-
usedPackageManager = defaultOrder[0];
|
|
211
|
+
program.name("create-mcp-use-app").description("Create a new MCP server project").version(packageJson.version).argument("[project-name]", "Name of the MCP server project").option("-t, --template <template>", "Template to use", "simple").option("--no-install", "Skip installing dependencies").option("--no-git", "Skip initializing a git repository").option("--dev", "Use workspace dependencies for development").option("--canary", "Use canary versions of packages").option("--yarn", "Use yarn as package manager").option("--npm", "Use npm as package manager").option("--pnpm", "Use pnpm as package manager").action(
|
|
212
|
+
async (projectName, options) => {
|
|
213
|
+
try {
|
|
214
|
+
let selectedTemplate = options.template;
|
|
215
|
+
if (!projectName) {
|
|
216
|
+
console.log("");
|
|
217
|
+
renderLogo();
|
|
218
|
+
console.log("");
|
|
219
|
+
console.log(chalk.bold("Welcome to create-mcp-use-app!"));
|
|
220
|
+
console.log("");
|
|
221
|
+
projectName = await promptForProjectName();
|
|
222
|
+
console.log("");
|
|
223
|
+
selectedTemplate = await promptForTemplate();
|
|
224
224
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
225
|
+
const sanitizedProjectName = projectName.trim();
|
|
226
|
+
if (!sanitizedProjectName) {
|
|
227
|
+
console.error(chalk.red("\u274C Project name cannot be empty"));
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
if (sanitizedProjectName.includes("..") || sanitizedProjectName.includes("/") || sanitizedProjectName.includes("\\")) {
|
|
231
|
+
console.error(
|
|
232
|
+
chalk.red('\u274C Project name cannot contain path separators or ".."')
|
|
233
|
+
);
|
|
234
|
+
console.error(
|
|
235
|
+
chalk.yellow(' Use simple names like "my-mcp-server"')
|
|
236
|
+
);
|
|
237
|
+
process.exit(1);
|
|
238
|
+
}
|
|
239
|
+
const protectedNames = [
|
|
240
|
+
"node_modules",
|
|
241
|
+
".git",
|
|
242
|
+
".env",
|
|
243
|
+
"package.json",
|
|
244
|
+
"src",
|
|
245
|
+
"dist"
|
|
246
|
+
];
|
|
247
|
+
if (protectedNames.includes(sanitizedProjectName.toLowerCase())) {
|
|
248
|
+
console.error(
|
|
249
|
+
chalk.red(`\u274C Cannot use protected name "${sanitizedProjectName}"`)
|
|
250
|
+
);
|
|
251
|
+
console.error(
|
|
252
|
+
chalk.yellow(" Please choose a different project name")
|
|
253
|
+
);
|
|
254
|
+
process.exit(1);
|
|
255
|
+
}
|
|
256
|
+
console.log(
|
|
257
|
+
chalk.cyan(`\u{1F680} Creating MCP server "${sanitizedProjectName}"...`)
|
|
258
|
+
);
|
|
259
|
+
const projectPath = resolve(process.cwd(), sanitizedProjectName);
|
|
260
|
+
if (existsSync(projectPath)) {
|
|
261
|
+
console.error(
|
|
262
|
+
chalk.red(`\u274C Directory "${sanitizedProjectName}" already exists!`)
|
|
263
|
+
);
|
|
264
|
+
console.error(
|
|
265
|
+
chalk.yellow(
|
|
266
|
+
" Please choose a different name or remove the existing directory"
|
|
267
|
+
)
|
|
268
|
+
);
|
|
269
|
+
process.exit(1);
|
|
270
|
+
}
|
|
271
|
+
mkdirSync(projectPath, { recursive: true });
|
|
272
|
+
const validatedTemplate = validateTemplateName(selectedTemplate);
|
|
273
|
+
const versions = getCurrentPackageVersions(options.dev, options.canary);
|
|
274
|
+
await copyTemplate(
|
|
275
|
+
projectPath,
|
|
276
|
+
validatedTemplate,
|
|
277
|
+
versions,
|
|
278
|
+
options.dev,
|
|
279
|
+
options.canary
|
|
280
|
+
);
|
|
281
|
+
updatePackageJson(projectPath, sanitizedProjectName);
|
|
282
|
+
let usedPackageManager = "npm";
|
|
283
|
+
if (options.yarn) {
|
|
284
|
+
usedPackageManager = "yarn";
|
|
285
|
+
} else if (options.npm) {
|
|
286
|
+
usedPackageManager = "npm";
|
|
287
|
+
} else if (options.pnpm) {
|
|
288
|
+
usedPackageManager = "pnpm";
|
|
289
|
+
} else {
|
|
290
|
+
const detected = detectPackageManager();
|
|
291
|
+
if (detected) {
|
|
292
|
+
usedPackageManager = detected;
|
|
240
293
|
} else {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
294
|
+
const defaultOrder = ["yarn", "npm", "pnpm"];
|
|
295
|
+
usedPackageManager = defaultOrder[0];
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (options.install) {
|
|
299
|
+
const showSpinner = usedPackageManager !== "yarn" && usedPackageManager !== "npm";
|
|
300
|
+
const spinner = showSpinner ? ora("Installing packages...").start() : null;
|
|
301
|
+
try {
|
|
302
|
+
if (options.yarn || options.npm || options.pnpm || detectPackageManager()) {
|
|
303
|
+
if (!showSpinner) {
|
|
304
|
+
console.log("");
|
|
305
|
+
}
|
|
306
|
+
await runPackageManager(
|
|
307
|
+
usedPackageManager,
|
|
308
|
+
["install"],
|
|
309
|
+
projectPath
|
|
310
|
+
);
|
|
246
311
|
if (spinner) {
|
|
247
|
-
spinner.succeed(
|
|
312
|
+
spinner.succeed(
|
|
313
|
+
`Packages installed successfully with ${usedPackageManager}`
|
|
314
|
+
);
|
|
248
315
|
} else {
|
|
249
316
|
console.log("");
|
|
250
317
|
}
|
|
251
|
-
}
|
|
252
|
-
if (spinner)
|
|
318
|
+
} else {
|
|
319
|
+
if (spinner)
|
|
320
|
+
spinner.text = "Installing packages (trying yarn)...";
|
|
253
321
|
try {
|
|
254
|
-
|
|
255
|
-
|
|
322
|
+
if (!spinner) console.log("");
|
|
323
|
+
await runPackageManager("yarn", ["install"], projectPath);
|
|
324
|
+
usedPackageManager = "yarn";
|
|
256
325
|
if (spinner) {
|
|
257
|
-
spinner.succeed("Packages installed successfully with
|
|
326
|
+
spinner.succeed("Packages installed successfully with yarn");
|
|
258
327
|
} else {
|
|
259
328
|
console.log("");
|
|
260
329
|
}
|
|
261
330
|
} catch {
|
|
262
|
-
if (spinner) spinner.text = "
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
spinner
|
|
267
|
-
|
|
268
|
-
|
|
331
|
+
if (spinner) spinner.text = "yarn not found, trying npm...";
|
|
332
|
+
try {
|
|
333
|
+
await runPackageManager("npm", ["install"], projectPath);
|
|
334
|
+
usedPackageManager = "npm";
|
|
335
|
+
if (spinner) {
|
|
336
|
+
spinner.succeed("Packages installed successfully with npm");
|
|
337
|
+
} else {
|
|
338
|
+
console.log("");
|
|
339
|
+
}
|
|
340
|
+
} catch {
|
|
341
|
+
if (spinner) spinner.text = "npm not found, trying pnpm...";
|
|
342
|
+
await runPackageManager("pnpm", ["install"], projectPath);
|
|
343
|
+
usedPackageManager = "pnpm";
|
|
344
|
+
if (spinner) {
|
|
345
|
+
spinner.succeed(
|
|
346
|
+
"Packages installed successfully with pnpm"
|
|
347
|
+
);
|
|
348
|
+
} else {
|
|
349
|
+
console.log("");
|
|
350
|
+
}
|
|
269
351
|
}
|
|
270
352
|
}
|
|
271
353
|
}
|
|
354
|
+
} catch (error) {
|
|
355
|
+
if (spinner) {
|
|
356
|
+
spinner.fail("Package installation failed");
|
|
357
|
+
} else {
|
|
358
|
+
console.log("\u274C Package installation failed");
|
|
359
|
+
}
|
|
360
|
+
console.log(
|
|
361
|
+
'\u26A0\uFE0F Please run "npm install", "yarn install", or "pnpm install" manually'
|
|
362
|
+
);
|
|
272
363
|
}
|
|
273
|
-
} catch (error) {
|
|
274
|
-
if (spinner) {
|
|
275
|
-
spinner.fail("Package installation failed");
|
|
276
|
-
} else {
|
|
277
|
-
console.log("\u274C Package installation failed");
|
|
278
|
-
}
|
|
279
|
-
console.log('\u26A0\uFE0F Please run "npm install", "yarn install", or "pnpm install" manually');
|
|
280
364
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
console.log(" \u251C\u2500\u2500
|
|
299
|
-
console.log(" \u2502 \u2514\u2500\u2500
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
console.log(
|
|
319
|
-
}
|
|
320
|
-
console.log(chalk.cyan(` ${getDevCommand(usedPackageManager)}`));
|
|
321
|
-
console.log("");
|
|
322
|
-
if (options.dev) {
|
|
323
|
-
console.log(chalk.yellow("\u{1F4A1} Development mode: Your project uses workspace dependencies"));
|
|
324
|
-
console.log(chalk.yellow(" Make sure you're in the mcp-use workspace root for development"));
|
|
365
|
+
if (options.git) {
|
|
366
|
+
tryGitInit(projectPath);
|
|
367
|
+
}
|
|
368
|
+
console.log("");
|
|
369
|
+
console.log(chalk.green("\u2705 MCP server created successfully!"));
|
|
370
|
+
if (options.dev) {
|
|
371
|
+
console.log(
|
|
372
|
+
chalk.yellow("\u{1F527} Development mode: Using workspace dependencies")
|
|
373
|
+
);
|
|
374
|
+
} else if (options.canary) {
|
|
375
|
+
console.log(
|
|
376
|
+
chalk.blue("\u{1F680} Canary mode: Using canary versions of packages")
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
console.log("");
|
|
380
|
+
console.log(chalk.bold("\u{1F4C1} Project structure:"));
|
|
381
|
+
console.log(` ${sanitizedProjectName}/`);
|
|
382
|
+
console.log(" \u251C\u2500\u2500 src/");
|
|
383
|
+
console.log(" \u2502 \u2514\u2500\u2500 server.ts");
|
|
384
|
+
if (validatedTemplate === "apps-sdk") {
|
|
385
|
+
console.log(" \u251C\u2500\u2500 resources/");
|
|
386
|
+
console.log(" \u2502 \u2514\u2500\u2500 display-weather.tsx");
|
|
387
|
+
}
|
|
388
|
+
if (validatedTemplate === "mcp-ui") {
|
|
389
|
+
console.log(" \u251C\u2500\u2500 resources/");
|
|
390
|
+
console.log(" \u2502 \u2514\u2500\u2500 kanban-board.tsx");
|
|
391
|
+
}
|
|
392
|
+
if (validatedTemplate === "starter") {
|
|
393
|
+
console.log(" \u251C\u2500\u2500 resources/");
|
|
394
|
+
console.log(" \u2502 \u2514\u2500\u2500 kanban-board.tsx (MCP-UI example)");
|
|
395
|
+
console.log(
|
|
396
|
+
" \u2502 \u2514\u2500\u2500 display-weather.tsx (OpenAI Apps SDK example)"
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
console.log(" \u251C\u2500\u2500 index.ts (server entry point)");
|
|
400
|
+
console.log(" \u251C\u2500\u2500 package.json");
|
|
401
|
+
console.log(" \u251C\u2500\u2500 tsconfig.json");
|
|
402
|
+
console.log(" \u2514\u2500\u2500 README.md");
|
|
325
403
|
console.log("");
|
|
404
|
+
console.log(chalk.bold("\u{1F680} To get started:"));
|
|
405
|
+
console.log(chalk.cyan(` cd ${sanitizedProjectName}`));
|
|
406
|
+
if (!options.install) {
|
|
407
|
+
console.log(
|
|
408
|
+
chalk.cyan(` ${getInstallCommand(usedPackageManager)}`)
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
console.log(chalk.cyan(` ${getDevCommand(usedPackageManager)}`));
|
|
412
|
+
console.log("");
|
|
413
|
+
if (options.dev) {
|
|
414
|
+
console.log(
|
|
415
|
+
chalk.yellow(
|
|
416
|
+
"\u{1F4A1} Development mode: Your project uses workspace dependencies"
|
|
417
|
+
)
|
|
418
|
+
);
|
|
419
|
+
console.log(
|
|
420
|
+
chalk.yellow(
|
|
421
|
+
" Make sure you're in the mcp-use workspace root for development"
|
|
422
|
+
)
|
|
423
|
+
);
|
|
424
|
+
console.log("");
|
|
425
|
+
}
|
|
426
|
+
console.log(chalk.blue("\u{1F4DA} Learn more: https://docs.mcp-use.com"));
|
|
427
|
+
console.log(chalk.gray("\u{1F4AC} For feedback and bug reporting visit:"));
|
|
428
|
+
console.log(
|
|
429
|
+
chalk.gray(
|
|
430
|
+
" https://github.com/mcp-use/mcp-use or https://mcp-use.com"
|
|
431
|
+
)
|
|
432
|
+
);
|
|
433
|
+
} catch (error) {
|
|
434
|
+
console.error("\u274C Error creating MCP server:", error);
|
|
435
|
+
process.exit(1);
|
|
326
436
|
}
|
|
327
|
-
console.log(chalk.blue("\u{1F4DA} Learn more: https://docs.mcp-use.com"));
|
|
328
|
-
console.log(chalk.gray("\u{1F4AC} For feedback and bug reporting visit:"));
|
|
329
|
-
console.log(chalk.gray(" https://github.com/mcp-use/mcp-use or https://mcp-use.com"));
|
|
330
|
-
} catch (error) {
|
|
331
|
-
console.error("\u274C Error creating MCP server:", error);
|
|
332
|
-
process.exit(1);
|
|
333
437
|
}
|
|
334
|
-
|
|
438
|
+
);
|
|
335
439
|
function validateTemplateName(template) {
|
|
336
440
|
const sanitized = template.trim();
|
|
337
441
|
if (sanitized.includes("..") || sanitized.includes("/") || sanitized.includes("\\")) {
|
|
338
442
|
console.error(chalk.red("\u274C Invalid template name"));
|
|
339
|
-
console.error(
|
|
443
|
+
console.error(
|
|
444
|
+
chalk.yellow(" Template name cannot contain path separators")
|
|
445
|
+
);
|
|
340
446
|
process.exit(1);
|
|
341
447
|
}
|
|
342
448
|
if (!/^[a-zA-Z0-9_-]+$/.test(sanitized)) {
|
|
343
449
|
console.error(chalk.red("\u274C Invalid template name"));
|
|
344
|
-
console.error(
|
|
450
|
+
console.error(
|
|
451
|
+
chalk.yellow(
|
|
452
|
+
" Template name can only contain letters, numbers, hyphens, and underscores"
|
|
453
|
+
)
|
|
454
|
+
);
|
|
345
455
|
process.exit(1);
|
|
346
456
|
}
|
|
347
457
|
return sanitized;
|
|
@@ -352,17 +462,31 @@ async function copyTemplate(projectPath, template, versions, isDevelopment = fal
|
|
|
352
462
|
console.error(chalk.red(`\u274C Template "${template}" not found!`));
|
|
353
463
|
const templatesDir = join(__dirname, "templates");
|
|
354
464
|
if (existsSync(templatesDir)) {
|
|
355
|
-
const availableTemplates = readdirSync(templatesDir, {
|
|
465
|
+
const availableTemplates = readdirSync(templatesDir, {
|
|
466
|
+
withFileTypes: true
|
|
467
|
+
}).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name).sort();
|
|
356
468
|
console.log(`Available templates: ${availableTemplates.join(", ")}`);
|
|
357
469
|
} else {
|
|
358
470
|
console.log("No templates directory found");
|
|
359
471
|
}
|
|
360
|
-
console.log(
|
|
361
|
-
|
|
362
|
-
|
|
472
|
+
console.log(
|
|
473
|
+
'\u{1F4A1} Tip: Use "starter" template for a comprehensive MCP server with all features'
|
|
474
|
+
);
|
|
475
|
+
console.log(
|
|
476
|
+
'\u{1F4A1} Tip: Use "mcp-ui" template for a MCP server with mcp-ui resources'
|
|
477
|
+
);
|
|
478
|
+
console.log(
|
|
479
|
+
'\u{1F4A1} Tip: Use "apps-sdk" template for a MCP server with OpenAI Apps SDK integration'
|
|
480
|
+
);
|
|
363
481
|
process.exit(1);
|
|
364
482
|
}
|
|
365
|
-
copyDirectoryWithProcessing(
|
|
483
|
+
copyDirectoryWithProcessing(
|
|
484
|
+
templatePath,
|
|
485
|
+
projectPath,
|
|
486
|
+
versions,
|
|
487
|
+
isDevelopment,
|
|
488
|
+
useCanary
|
|
489
|
+
);
|
|
366
490
|
}
|
|
367
491
|
function copyDirectoryWithProcessing(src, dest, versions, isDevelopment, useCanary = false) {
|
|
368
492
|
const entries = readdirSync(src, { withFileTypes: true });
|
|
@@ -371,10 +495,21 @@ function copyDirectoryWithProcessing(src, dest, versions, isDevelopment, useCana
|
|
|
371
495
|
const destPath = join(dest, entry.name);
|
|
372
496
|
if (entry.isDirectory()) {
|
|
373
497
|
mkdirSync(destPath, { recursive: true });
|
|
374
|
-
copyDirectoryWithProcessing(
|
|
498
|
+
copyDirectoryWithProcessing(
|
|
499
|
+
srcPath,
|
|
500
|
+
destPath,
|
|
501
|
+
versions,
|
|
502
|
+
isDevelopment,
|
|
503
|
+
useCanary
|
|
504
|
+
);
|
|
375
505
|
} else {
|
|
376
506
|
if (entry.name === "package.json" || entry.name.endsWith(".json")) {
|
|
377
|
-
const processedContent = processTemplateFile(
|
|
507
|
+
const processedContent = processTemplateFile(
|
|
508
|
+
srcPath,
|
|
509
|
+
versions,
|
|
510
|
+
isDevelopment,
|
|
511
|
+
useCanary
|
|
512
|
+
);
|
|
378
513
|
writeFileSync(destPath, processedContent);
|
|
379
514
|
} else {
|
|
380
515
|
copyFileSync(srcPath, destPath);
|
|
@@ -1,38 +1,36 @@
|
|
|
1
|
-
import { createMCPServer } from
|
|
1
|
+
import { createMCPServer } from "mcp-use/server";
|
|
2
2
|
|
|
3
|
-
const server = createMCPServer(
|
|
4
|
-
version:
|
|
5
|
-
description:
|
|
6
|
-
host: process.env.HOST ||
|
|
3
|
+
const server = createMCPServer("test-app", {
|
|
4
|
+
version: "1.0.0",
|
|
5
|
+
description: "Test MCP server with automatic UI widget registration",
|
|
6
|
+
host: process.env.HOST || "localhost",
|
|
7
7
|
baseUrl: process.env.MCP_URL, // Full base URL (e.g., https://myserver.com)
|
|
8
|
-
})
|
|
8
|
+
});
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* AUTOMATIC UI WIDGET REGISTRATION
|
|
12
12
|
* All React components in the `resources/` folder are automatically registered as MCP tools and resources.
|
|
13
13
|
* Just export widgetMetadata with description and Zod schema, and mcp-use handles the rest!
|
|
14
|
-
*
|
|
14
|
+
*
|
|
15
15
|
* It will automatically add to your MCP server:
|
|
16
16
|
* - server.tool('display-weather')
|
|
17
17
|
* - server.resource('ui://widget/display-weather')
|
|
18
|
-
*
|
|
18
|
+
*
|
|
19
19
|
* See docs: https://docs.mcp-use.com/typescript/server/ui-widgets
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
|
|
23
22
|
/**
|
|
24
23
|
* Add here yourtandard MCP tools, resources and prompts
|
|
25
24
|
*/
|
|
26
25
|
server.tool({
|
|
27
|
-
name:
|
|
28
|
-
description:
|
|
26
|
+
name: "get-my-city",
|
|
27
|
+
description: "Get my city",
|
|
29
28
|
cb: async () => {
|
|
30
|
-
return { content: [{ type:
|
|
29
|
+
return { content: [{ type: "text", text: `My city is San Francisco` }] };
|
|
31
30
|
},
|
|
32
|
-
})
|
|
33
|
-
|
|
31
|
+
});
|
|
34
32
|
|
|
35
|
-
const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3000
|
|
36
|
-
const HOST = process.env.HOST ||
|
|
37
|
-
server.listen(PORT)
|
|
38
|
-
console.log(`Server running at http://${HOST}:${PORT}`)
|
|
33
|
+
const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3000;
|
|
34
|
+
const HOST = process.env.HOST || "localhost";
|
|
35
|
+
server.listen(PORT);
|
|
36
|
+
console.log(`Server running at http://${HOST}:${PORT}`);
|